From cf7f5a1c525b8fc7fca9251eac235b1e2688cf99 Mon Sep 17 00:00:00 2001 From: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Date: Sat, 8 Jun 2024 20:58:19 +0200 Subject: [PATCH] Remove 'Strategic Balance' and 'Legendary Start' from resource abundance select (#11699) * Convert MapResources into an Enum * Fix IsPartOfGameInfoSerialization where actually only the String is part of serialization * Refactor MapResources to own file, package mapgenerator * Refactor MapSize/MapSizeNew to own file and rename --- .../civilization/managers/PolicyManager.kt | 10 +- .../civilization/managers/TechManager.kt | 15 +- core/src/com/unciv/logic/map/MapParameters.kt | 150 ++---------------- core/src/com/unciv/logic/map/MapSize.kt | 137 ++++++++++++++++ .../map/mapgenerator/MapResourceSetting.kt | 23 +++ .../LuxuryResourcePlacementLogic.kt | 28 +--- .../map/mapgenerator/mapregions/MapRegions.kt | 9 +- .../mapregions/StartNormalizer.kt | 7 +- core/src/com/unciv/logic/map/tile/Tile.kt | 6 +- .../screens/mainmenuscreen/MainMenuScreen.kt | 4 +- .../mapeditorscreen/MapEditorScreen.kt | 3 +- .../MapEditorWesnothImporter.kt | 4 +- .../newgamescreen/MapParametersTable.kt | 31 ++-- .../ui/screens/worldscreen/minimap/Minimap.kt | 1 - .../com/unciv/app/desktop/ConsoleLauncher.kt | 3 +- .../com/unciv/logic/GameSerializationTests.kt | 3 +- tests/src/com/unciv/testing/TestGame.kt | 8 +- 17 files changed, 214 insertions(+), 228 deletions(-) create mode 100644 core/src/com/unciv/logic/map/MapSize.kt create mode 100644 core/src/com/unciv/logic/map/mapgenerator/MapResourceSetting.kt diff --git a/core/src/com/unciv/logic/civilization/managers/PolicyManager.kt b/core/src/com/unciv/logic/civilization/managers/PolicyManager.kt index 78b5d40db0..b1ea0ee4a2 100644 --- a/core/src/com/unciv/logic/civilization/managers/PolicyManager.kt +++ b/core/src/com/unciv/logic/civilization/managers/PolicyManager.kt @@ -4,7 +4,6 @@ import com.unciv.logic.IsPartOfGameInfoSerialization import com.unciv.logic.civilization.Civilization import com.unciv.logic.civilization.NotificationCategory import com.unciv.logic.civilization.NotificationIcon -import com.unciv.logic.map.MapSize import com.unciv.models.ruleset.Policy import com.unciv.models.ruleset.Policy.PolicyBranchType import com.unciv.models.ruleset.PolicyBranch @@ -157,14 +156,7 @@ class PolicyManager : IsPartOfGameInfoSerialization { fun getPolicyCultureCost(numberOfAdoptedPolicies: Int): Int { var policyCultureCost = 25 + (numberOfAdoptedPolicies * 6).toDouble().pow(1.7) - // https://civilization.fandom.com/wiki/Map_(Civ5) - val worldSizeModifier = with(civInfo.gameInfo.tileMap.mapParameters.mapSize) { - when { - radius >= MapSize.Huge.radius -> 0.05f - radius >= MapSize.Large.radius -> 0.075f - else -> 0.1f - } - } + val worldSizeModifier = civInfo.gameInfo.tileMap.mapParameters.mapSize.getPredefinedOrNextSmaller().policyCostPerCityModifier var cityModifier = worldSizeModifier * (civInfo.cities.count { !it.isPuppet } - 1) for (unique in civInfo.getMatchingUniques(UniqueType.LessPolicyCostFromCities)) cityModifier *= 1 - unique.params[0].toFloat() / 100 diff --git a/core/src/com/unciv/logic/civilization/managers/TechManager.kt b/core/src/com/unciv/logic/civilization/managers/TechManager.kt index d196c5e21d..53815d8af2 100644 --- a/core/src/com/unciv/logic/civilization/managers/TechManager.kt +++ b/core/src/com/unciv/logic/civilization/managers/TechManager.kt @@ -13,7 +13,6 @@ import com.unciv.logic.civilization.PlayerType import com.unciv.logic.civilization.PolicyAction import com.unciv.logic.civilization.PopupAlert import com.unciv.logic.civilization.TechAction -import com.unciv.logic.map.MapSize import com.unciv.logic.map.tile.RoadStatus import com.unciv.models.ruleset.INonPerpetualConstruction import com.unciv.models.ruleset.tech.Era @@ -114,17 +113,9 @@ class TechManager : IsPartOfGameInfoSerialization { techCost *= civInfo.getDifficulty().researchCostModifier techCost *= civInfo.gameInfo.speed.scienceCostModifier techCost /= getScienceModifier(techName) - // https://civilization.fandom.com/wiki/Map_(Civ5) - val worldSizeModifier = with (civInfo.gameInfo.tileMap.mapParameters.mapSize) { - when { - radius >= MapSize.Huge.radius -> floatArrayOf(1.3f, 0.025f) - radius >= MapSize.Large.radius -> floatArrayOf(1.2f, 0.0375f) - radius >= MapSize.Medium.radius -> floatArrayOf(1.1f, 0.05f) - else -> floatArrayOf(1f, 0.05f) - } - } - techCost *= worldSizeModifier[0] - techCost *= 1 + (civInfo.cities.size - 1) * worldSizeModifier[1] + val mapSizePredef = civInfo.gameInfo.tileMap.mapParameters.mapSize.getPredefinedOrNextSmaller() + techCost *= mapSizePredef.techCostMultiplier + techCost *= 1 + (civInfo.cities.size - 1) * mapSizePredef.techCostPerCityModifier return techCost.toInt() } diff --git a/core/src/com/unciv/logic/map/MapParameters.kt b/core/src/com/unciv/logic/map/MapParameters.kt index 8c3eb1e873..9315a74a84 100644 --- a/core/src/com/unciv/logic/map/MapParameters.kt +++ b/core/src/com/unciv/logic/map/MapParameters.kt @@ -1,134 +1,18 @@ package com.unciv.logic.map import com.unciv.logic.IsPartOfGameInfoSerialization -import com.unciv.logic.map.HexMath.getEquivalentHexagonalRadius -import com.unciv.logic.map.HexMath.getEquivalentRectangularSize import com.unciv.logic.map.HexMath.getNumberOfTilesInHexagon +import com.unciv.logic.map.mapgenerator.MapResourceSetting import com.unciv.models.metadata.BaseRuleset -/* Predefined Map Sizes - ours are a little lighter than the original values. For reference those are: - Civ5Duel(40,24,17), - Civ5Tiny(56,36,25), - Civ5Small(66,42,30), - Civ5Medium(80,52,37), - Civ5Large(104,64,47), - Civ5Huge(128,80,58), - */ -enum class MapSize(val radius: Int, val width: Int, val height: Int) { - Tiny(10, 23, 15), - Small(15, 33, 21), - Medium(20, 44, 29), - Large(30, 66, 43), - Huge(40, 87, 57); - - companion object { - /** Not a predefined [MapSize] enum value, but a String - * used in [MapParameters.mapSize] to indicate user-defined dimensions. - * Do not mistake for [MapGeneratedMainType.custom]. */ - const val custom = "Custom" - } -} - -class MapSizeNew : IsPartOfGameInfoSerialization { - var radius = 0 - var width = 0 - var height = 0 - var name = "" - - /** Needed for Json parsing */ - @Suppress("unused") - constructor() - - private fun fromPredefined(predefined: MapSize) { - name = predefined.name - radius = predefined.radius - width = predefined.width - height = predefined.height - } - - constructor(size: MapSize) { - fromPredefined(size) - } - - constructor(name: String) { - try { - fromPredefined(MapSize.valueOf(name)) - } catch (_: Exception) { - fromPredefined(MapSize.Tiny) - } - } - - constructor(radius: Int) { - name = MapSize.custom - setNewRadius(radius) - } - - constructor(width: Int, height: Int) { - name = MapSize.custom - this.width = width - this.height = height - this.radius = getEquivalentHexagonalRadius(width, height) - } - - fun clone() = MapSizeNew().also { - it.name = name - it.radius = radius - it.width = width - it.height = height - } - - /** Check custom dimensions, fix if too extreme - * @param worldWrap whether world wrap is on - * @return null if size was acceptable, otherwise untranslated reason message - */ - fun fixUndesiredSizes(worldWrap: Boolean): String? { - if (name != MapSize.custom) return null // predefined sizes are OK - // world-wrap mas must always have an even width, so round down silently - if (worldWrap && width % 2 != 0 ) width-- - // check for any bad condition and bail if none of them - val message = when { - worldWrap && width < 32 -> // otherwise horizontal scrolling will show edges, empirical - "World wrap requires a minimum width of 32 tiles" - width < 3 || height < 3 || radius < 2 -> - "The provided map dimensions were too small" - radius > 500 -> - "The provided map dimensions were too big" - height * 16 < width || width * 16 < height -> // aspect ratio > 16:1 - "The provided map dimensions had an unacceptable aspect ratio" - else -> null - } ?: return null - - // fix the size - not knowing whether hexagonal or rectangular is used - setNewRadius(when { - radius < 2 -> 2 - radius > 500 -> 500 - worldWrap && radius < 15 -> 15 // minimum for hexagonal but more than required for rectangular - else -> radius - }) - - // tell the caller that map dimensions have changed and why - return message - } - - private fun setNewRadius(radius: Int) { - this.radius = radius - val size = getEquivalentRectangularSize(radius) - width = size.x.toInt() - height = size.y.toInt() - } - - // For debugging and MapGenerator console output - override fun toString() = if (name == MapSize.custom) "${width}x${height}" else name -} - -object MapShape : IsPartOfGameInfoSerialization { +object MapShape { const val hexagonal = "Hexagonal" const val flatEarth = "Flat Earth Hexagonal" const val rectangular = "Rectangular" } -object MapGeneratedMainType : IsPartOfGameInfoSerialization { +object MapGeneratedMainType { const val generated = "Generated" // Randomly choose a generated map type const val randomGenerated = "Random Generated" @@ -137,7 +21,7 @@ object MapGeneratedMainType : IsPartOfGameInfoSerialization { } -object MapType : IsPartOfGameInfoSerialization { +object MapType { const val perlin = "Perlin" const val pangaea = "Pangaea" const val continentAndIslands = "Continent and Islands" @@ -154,22 +38,12 @@ object MapType : IsPartOfGameInfoSerialization { const val empty = "Empty" } -object MapResources { - const val sparse = "Sparse" - const val default = "Default" - const val abundant = "Abundant" - @Deprecated("Since 4.10.7, moved to mapParameters") - const val strategicBalance = "Strategic Balance" - @Deprecated("Since 4.10.7, moved to mapParameters") - const val legendaryStart = "Legendary Start" -} - class MapParameters : IsPartOfGameInfoSerialization { var name = "" var type = MapType.pangaea var shape = MapShape.hexagonal - var mapSize = MapSizeNew(MapSize.Medium) - var mapResources = MapResources.default + var mapSize = MapSize.Medium + var mapResources = MapResourceSetting.default.label var noRuins = false var noNaturalWonders = false var worldWrap = false @@ -239,12 +113,20 @@ class MapParameters : IsPartOfGameInfoSerialization { waterThreshold = 0f } + fun getMapResources() = MapResourceSetting.safeValueOf(mapResources) + @Suppress("DEPRECATION") // This IS the legacy support + @JvmName("strategicBalanceGetter") + fun getStrategicBalance() = strategicBalance || mapResources == MapResourceSetting.strategicBalance.label + @Suppress("DEPRECATION") // This IS the legacy support + @JvmName("legendaryStartGetter") + fun getLegendaryStart() = legendaryStart || mapResources == MapResourceSetting.legendaryStart.label + fun getArea() = when { shape == MapShape.hexagonal || shape == MapShape.flatEarth -> getNumberOfTilesInHexagon(mapSize.radius) worldWrap && mapSize.width % 2 != 0 -> (mapSize.width - 1) * mapSize.height else -> mapSize.width * mapSize.height } - fun displayMapDimensions() = mapSize.run { + private fun displayMapDimensions() = mapSize.run { (if (shape == MapShape.hexagonal || shape == MapShape.flatEarth) "R$radius" else "${width}x$height") + (if (worldWrap) "w" else "") } @@ -261,7 +143,7 @@ class MapParameters : IsPartOfGameInfoSerialization { if (worldWrap) yield("{World Wrap} ") yield("{$shape}") yield(" " + displayMapDimensions() + ")") - if(mapResources != MapResources.default) yield(" {Resource Setting}: {$mapResources}") + if (mapResources != MapResourceSetting.default.label) yield(" {Resource Setting}: {$mapResources}") if (strategicBalance) yield(" {Strategic Balance}") if (legendaryStart) yield(" {Legendary Start}") if (name.isEmpty()) return@sequence diff --git a/core/src/com/unciv/logic/map/MapSize.kt b/core/src/com/unciv/logic/map/MapSize.kt new file mode 100644 index 0000000000..e6c4597d68 --- /dev/null +++ b/core/src/com/unciv/logic/map/MapSize.kt @@ -0,0 +1,137 @@ +package com.unciv.logic.map + +import com.unciv.logic.IsPartOfGameInfoSerialization + + +/** + * Encapsulates the "map size" concept, without also choosing a shape. + * + * Predefined sizes are kept in the [Predefined] enum, instances derived from these have the same [name] and copied dimensions. + * Custom sizes always have [custom] as [name], even if created with the exact same dimensions as a [Predefined]. + * + * @property name + * @property radius + * @property width + * @property height + * @see MapShape + */ +/* + * The architecture is not as elegant as I'd like - an interface implemented by both an enum and a "custom" subclass would be shorter and nicer to read, + * but the obstacle of Json deserialization has -for the moment- the heavier weight. Instance creation would have to be customized, and with the Gdx.Json + * model, that would mean the simpler Serializable interface won't do, needing the clunky setSerializer instead. + */ +class MapSize private constructor( + val name: String, + var radius: Int, + var width: Int, + var height: Int, +) : IsPartOfGameInfoSerialization { + + /** Needed for Json parsing */ + @Suppress("unused") + private constructor() : this("", 0, 0, 0) + + constructor(size: Predefined) : this(size.name, size.radius, size.width, size.height) + + constructor(name: String) : this(Predefined.safeValueOf(name)) + + constructor(radius: Int) : this(custom, radius, 0, 0) { + setNewRadius(radius) + } + + constructor(width: Int, height: Int) : this(custom, HexMath.getEquivalentHexagonalRadius(width, height), width, height) + + /** Predefined Map Sizes, their name can appear in json only as copy in MapSize */ + enum class Predefined( + val radius: Int, + val width: Int, + val height: Int, + // https://civilization.fandom.com/wiki/Map_(Civ5) + val techCostMultiplier: Float = 1f, + val techCostPerCityModifier: Float = 0.05f, + val policyCostPerCityModifier: Float = 0.1f, + ) { + Tiny(10, 23, 15), + Small(15, 33, 21), + Medium(20, 44, 29, 1.1f), + Large(30, 66, 43, 1.2f, 0.0375f,0.075f), + Huge(40, 87, 57, 1.3f, 0.025f,0.05f); + /* - ours are a little lighter than the original values. For reference those are: + Civ5Duel(40,24,17), + Civ5Tiny(56,36,25), + Civ5Small(66,42,30), + Civ5Medium(80,52,37), + Civ5Large(104,64,47), + Civ5Huge(128,80,58), + */ + + companion object { + fun safeValueOf(name: String) = values().firstOrNull { it.name == name } ?: Tiny + } + } + + companion object { + /** Not a [Predefined] enum value, but a String + * used in [name] to indicate user-defined dimensions. + * Do not mistake for [MapGeneratedMainType.custom]. */ + const val custom = "Custom" + val Tiny get() = MapSize(Predefined.Tiny) + val Small get() = MapSize(Predefined.Small) + val Medium get() = MapSize(Predefined.Medium) + val Huge get() = MapSize(Predefined.Huge) + fun names() = Predefined.values().map { it.name } + } + + fun clone() = MapSize(name, radius, width, height) + + fun getPredefinedOrNextSmaller(): Predefined { + if (name != custom) return Predefined.safeValueOf(name) + for (predef in Predefined.values().reversed()) { + if (radius >= predef.radius) return predef + } + return Predefined.Tiny + } + + /** Check custom dimensions, fix if too extreme + * @param worldWrap whether world wrap is on + * @return null if size was acceptable, otherwise untranslated reason message + */ + fun fixUndesiredSizes(worldWrap: Boolean): String? { + if (name != custom) return null // predefined sizes are OK + // world-wrap mas must always have an even width, so round down silently + if (worldWrap && width % 2 != 0 ) width-- + // check for any bad condition and bail if none of them + val message = when { + worldWrap && width < 32 -> // otherwise horizontal scrolling will show edges, empirical + "World wrap requires a minimum width of 32 tiles" + width < 3 || height < 3 || radius < 2 -> + "The provided map dimensions were too small" + radius > 500 -> + "The provided map dimensions were too big" + height * 16 < width || width * 16 < height -> // aspect ratio > 16:1 + "The provided map dimensions had an unacceptable aspect ratio" + else -> null + } ?: return null + + // fix the size - not knowing whether hexagonal or rectangular is used + setNewRadius(when { + radius < 2 -> 2 + radius > 500 -> 500 + worldWrap && radius < 15 -> 15 // minimum for hexagonal but more than required for rectangular + else -> radius + }) + + // tell the caller that map dimensions have changed and why + return message + } + + private fun setNewRadius(radius: Int) { + this.radius = radius + val size = HexMath.getEquivalentRectangularSize(radius) + width = size.x.toInt() + height = size.y.toInt() + } + + // For debugging and MapGenerator console output + override fun toString() = if (name == custom) "${width}x${height}" else name +} diff --git a/core/src/com/unciv/logic/map/mapgenerator/MapResourceSetting.kt b/core/src/com/unciv/logic/map/mapgenerator/MapResourceSetting.kt new file mode 100644 index 0000000000..761d066f50 --- /dev/null +++ b/core/src/com/unciv/logic/map/mapgenerator/MapResourceSetting.kt @@ -0,0 +1,23 @@ +package com.unciv.logic.map.mapgenerator + +enum class MapResourceSetting( + val label: String, + val randomLuxuriesPercent: Int = 100, + val regionalLuxuriesDelta: Int = 0, + val specialLuxuriesTargetFactor: Float = 0.75f, + val bonusFrequencyMultiplier: Float = 1f +) { + sparse("Sparse", 80, -1, 0.5f, 1.5f), + default("Default"), + abundant("Abundant", 133, 1, 0.9f, 0.6667f), + @Deprecated("Since 4.10.7, moved to mapParameters") + strategicBalance("Strategic Balance"), + @Deprecated("Since 4.10.7, moved to mapParameters") + legendaryStart("Legendary Start"), + ; + private fun active() = declaringJavaClass.getField(name).getAnnotation(Deprecated::class.java) == null + companion object { + fun activeLabels() = values().filter { it.active() }.map { it.label } + fun safeValueOf(label: String) = values().firstOrNull { it.label == label } ?: default + } +} diff --git a/core/src/com/unciv/logic/map/mapgenerator/mapregions/LuxuryResourcePlacementLogic.kt b/core/src/com/unciv/logic/map/mapgenerator/mapregions/LuxuryResourcePlacementLogic.kt index 399030f531..735f1d8f6d 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/mapregions/LuxuryResourcePlacementLogic.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/mapregions/LuxuryResourcePlacementLogic.kt @@ -1,6 +1,6 @@ package com.unciv.logic.map.mapgenerator.mapregions -import com.unciv.logic.map.MapResources +import com.unciv.logic.map.mapgenerator.MapResourceSetting import com.unciv.logic.map.TileMap import com.unciv.logic.map.tile.Tile import com.unciv.models.ruleset.Ruleset @@ -210,11 +210,7 @@ object LuxuryResourcePlacementLogic { tileData: TileDataMap ) { for (special in specialLuxuries) { - val targetNumber = when (tileMap.mapParameters.mapResources) { - MapResources.sparse -> (regions.size * 0.5f).toInt() - MapResources.abundant -> (regions.size * 0.9f).toInt() - else -> (regions.size * 0.75f).toInt() - } + val targetNumber = (regions.size * tileMap.mapParameters.getMapResources().specialLuxuriesTargetFactor).toInt() val numberToPlace = max(2, targetNumber - placedSpecials[special.name]!!) MapRegionResources.tryAddingResourceToTiles( tileData, special, numberToPlace, tileMap.values.asSequence().shuffled(), 1f, @@ -233,12 +229,11 @@ object LuxuryResourcePlacementLogic { ruleset: Ruleset, placedSpecials: HashMap ) { - if (tileMap.mapParameters.mapResources == MapResources.sparse) return + if (tileMap.mapParameters.mapResources == MapResourceSetting.sparse.label) return for (region in regions) { val tilesToCheck = tileMap[region.startPosition!!].getTilesInDistanceRange(1..2) val candidateLuxuries = randomLuxuries.shuffled().toMutableList() - if (tileMap.mapParameters.mapResources != MapResources.strategicBalance && - !tileMap.mapParameters.strategicBalance) + if (!tileMap.mapParameters.getStrategicBalance()) candidateLuxuries += specialLuxuries.shuffled() .map { it.name } // Include marble! candidateLuxuries += cityStateLuxuries.shuffled() @@ -268,11 +263,7 @@ object LuxuryResourcePlacementLogic { ) { if (randomLuxuries.isEmpty()) return var targetRandomLuxuries = tileData.size.toFloat().pow(0.45f).toInt() // Approximately - targetRandomLuxuries *= when (tileMap.mapParameters.mapResources) { - MapResources.sparse -> 80 - MapResources.abundant -> 133 - else -> 100 - } + targetRandomLuxuries *= tileMap.mapParameters.getMapResources().randomLuxuriesPercent targetRandomLuxuries /= 100 targetRandomLuxuries += Random.nextInt(regions.size) // Add random number based on number of civs val minimumRandomLuxuries = tileData.size.toFloat().pow(0.2f).toInt() // Approximately @@ -308,11 +299,7 @@ object LuxuryResourcePlacementLogic { val idealCivsForMapSize = max(2, tileData.size / 500) var regionTargetNumber = (tileData.size / 600) - (0.3f * abs(regions.size - idealCivsForMapSize)).toInt() - regionTargetNumber += when (tileMap.mapParameters.mapResources) { - MapResources.abundant -> 1 - MapResources.sparse -> -1 - else -> 0 - } + regionTargetNumber += tileMap.mapParameters.getMapResources().regionalLuxuriesDelta regionTargetNumber = max(1, regionTargetNumber) for (region in regions) { val resource = ruleset.tileResources[region.luxury] ?: continue @@ -380,8 +367,7 @@ object LuxuryResourcePlacementLogic { regions.sumOf { it.totalFertility } / regions.sumOf { it.tiles.size }.toFloat() for (region in regions) { var targetLuxuries = 1 - if (tileMap.mapParameters.mapResources == MapResources.legendaryStart || - tileMap.mapParameters.legendaryStart) + if (tileMap.mapParameters.getLegendaryStart()) targetLuxuries++ if (region.totalFertility / region.tiles.size.toFloat() < averageFertilityDensity) { targetLuxuries++ diff --git a/core/src/com/unciv/logic/map/mapgenerator/mapregions/MapRegions.kt b/core/src/com/unciv/logic/map/mapgenerator/mapregions/MapRegions.kt index 101c8aa41e..04c0c05c80 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/mapregions/MapRegions.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/mapregions/MapRegions.kt @@ -4,7 +4,6 @@ import com.badlogic.gdx.math.Rectangle import com.badlogic.gdx.math.Vector2 import com.unciv.Constants import com.unciv.logic.civilization.Civilization -import com.unciv.logic.map.MapResources import com.unciv.logic.map.MapShape import com.unciv.logic.map.TileMap import com.unciv.logic.map.mapgenerator.mapregions.MapRegions.BiasTypes.PositiveFallback @@ -218,7 +217,7 @@ class MapRegions (val ruleset: Ruleset) { if (widerThanTall) { splitOffRegion.rect.width = bestSplitPoint.toFloat() regionToSplit.rect.x = splitOffRegion.rect.x + splitOffRegion.rect.width - regionToSplit.rect.width = regionToSplit.rect.width- bestSplitPoint + regionToSplit.rect.width = regionToSplit.rect.width - bestSplitPoint } else { splitOffRegion.rect.height = bestSplitPoint.toFloat() regionToSplit.rect.y = splitOffRegion.rect.y + splitOffRegion.rect.height @@ -698,11 +697,7 @@ class MapRegions (val ruleset: Ruleset) { We also save a list of all land tiles for minor deposit generation. */ // Determines number tiles per resource - val bonusMultiplier = when (tileMap.mapParameters.mapResources) { - MapResources.sparse -> 1.5f - MapResources.abundant -> 0.6667f - else -> 1f - } + val bonusMultiplier = tileMap.mapParameters.getMapResources().bonusFrequencyMultiplier val landList = ArrayList() // For minor deposits val ruleLists = HashMap>() // For rule-based generation diff --git a/core/src/com/unciv/logic/map/mapgenerator/mapregions/StartNormalizer.kt b/core/src/com/unciv/logic/map/mapgenerator/mapregions/StartNormalizer.kt index fef5b7621d..b677c21cb4 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/mapregions/StartNormalizer.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/mapregions/StartNormalizer.kt @@ -1,7 +1,6 @@ package com.unciv.logic.map.mapgenerator.mapregions import com.unciv.Constants -import com.unciv.logic.map.MapResources import com.unciv.logic.map.TileMap import com.unciv.logic.map.tile.Tile import com.unciv.models.ruleset.Ruleset @@ -29,8 +28,7 @@ object StartNormalizer { } } - if (tileMap.mapParameters.mapResources == MapResources.strategicBalance || - tileMap.mapParameters.strategicBalance) + if (tileMap.mapParameters.getStrategicBalance()) placeStrategicBalanceResources(startTile, ruleset, tileData) normalizeProduction(startTile, isMinorCiv, ruleset, tileData) @@ -217,8 +215,7 @@ object StartNormalizer { else -> 0 } } - if (tileMap.mapParameters.mapResources == MapResources.legendaryStart || - tileMap.mapParameters.legendaryStart) + if (tileMap.mapParameters.getLegendaryStart()) bonusesNeeded += 2 // Attempt to place one grassland at a plains-only spot (nor for minors) diff --git a/core/src/com/unciv/logic/map/tile/Tile.kt b/core/src/com/unciv/logic/map/tile/Tile.kt index f7afbc8b0a..6d9c579b02 100644 --- a/core/src/com/unciv/logic/map/tile/Tile.kt +++ b/core/src/com/unciv/logic/map/tile/Tile.kt @@ -10,7 +10,7 @@ import com.unciv.logic.civilization.Civilization import com.unciv.logic.civilization.PlayerType import com.unciv.logic.map.HexMath import com.unciv.logic.map.MapParameters -import com.unciv.logic.map.MapResources +import com.unciv.logic.map.mapgenerator.MapResourceSetting import com.unciv.logic.map.TileMap import com.unciv.logic.map.mapgenerator.MapGenerator import com.unciv.logic.map.mapunit.MapUnit @@ -741,8 +741,8 @@ class Tile : IsPartOfGameInfoSerialization { val majorDepositFinal = majorDeposit ?: (rng.nextDouble() < approximateMajorDepositDistribution()) val depositAmounts = if (majorDepositFinal) newResource.majorDepositAmount else newResource.minorDepositAmount resourceAmount = when (tileMap.mapParameters.mapResources) { - MapResources.sparse -> depositAmounts.sparse - MapResources.abundant -> depositAmounts.abundant + MapResourceSetting.sparse.label -> depositAmounts.sparse + MapResourceSetting.abundant.label -> depositAmounts.abundant else -> depositAmounts.default } } diff --git a/core/src/com/unciv/ui/screens/mainmenuscreen/MainMenuScreen.kt b/core/src/com/unciv/ui/screens/mainmenuscreen/MainMenuScreen.kt index 4284ba9daa..6220c11d99 100644 --- a/core/src/com/unciv/ui/screens/mainmenuscreen/MainMenuScreen.kt +++ b/core/src/com/unciv/ui/screens/mainmenuscreen/MainMenuScreen.kt @@ -14,7 +14,6 @@ import com.unciv.logic.UncivShowableException import com.unciv.logic.map.MapParameters import com.unciv.logic.map.MapShape import com.unciv.logic.map.MapSize -import com.unciv.logic.map.MapSizeNew import com.unciv.logic.map.MapType import com.unciv.logic.map.mapgenerator.MapGenerator import com.unciv.models.metadata.BaseRuleset @@ -42,7 +41,6 @@ import com.unciv.ui.popups.hasOpenPopups import com.unciv.ui.popups.popups import com.unciv.ui.screens.basescreen.BaseScreen import com.unciv.ui.screens.basescreen.RecreateOnResize -import com.unciv.ui.screens.civilopediascreen.CivilopediaScreen import com.unciv.ui.screens.mainmenuscreen.EasterEggRulesets.modifyForEasterEgg import com.unciv.ui.screens.mapeditorscreen.EditorMapHolder import com.unciv.ui.screens.mapeditorscreen.MapEditorScreen @@ -226,7 +224,7 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize { val newMap = MapGenerator(backgroundMapRuleset, this) .generateMap(MapParameters().apply { shape = MapShape.rectangular - mapSize = MapSizeNew(MapSize.Small) + mapSize = MapSize.Small type = MapType.pangaea temperatureExtremeness = .7f waterThreshold = -0.1f // mainly land, gets about 30% water diff --git a/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorScreen.kt b/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorScreen.kt index 2f42065252..bcb71b3a6a 100644 --- a/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorScreen.kt +++ b/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorScreen.kt @@ -14,7 +14,6 @@ import com.unciv.UncivGame import com.unciv.logic.map.MapParameters import com.unciv.logic.map.MapShape import com.unciv.logic.map.MapSize -import com.unciv.logic.map.MapSizeNew import com.unciv.logic.map.TileMap import com.unciv.logic.map.tile.Tile import com.unciv.models.metadata.BaseRuleset @@ -97,7 +96,7 @@ class MapEditorScreen(map: TileMap? = null) : BaseScreen(), RecreateOnResize { if (map == null) { ruleset = RulesetCache[BaseRuleset.Civ_V_GnK.fullName]!! tileMap = TileMap(MapSize.Tiny.radius, ruleset, false).apply { - mapParameters.mapSize = MapSizeNew(MapSize.Tiny) + mapParameters.mapSize = MapSize.Tiny } } else { ruleset = map.ruleset ?: RulesetCache.getComplexRuleset(map.mapParameters) diff --git a/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorWesnothImporter.kt b/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorWesnothImporter.kt index f9d76139fa..abd29fc9d4 100644 --- a/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorWesnothImporter.kt +++ b/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorWesnothImporter.kt @@ -8,7 +8,7 @@ import com.unciv.logic.UncivShowableException import com.unciv.logic.files.FileChooser import com.unciv.logic.map.HexMath import com.unciv.logic.map.MapShape -import com.unciv.logic.map.MapSizeNew +import com.unciv.logic.map.MapSize import com.unciv.logic.map.MapType import com.unciv.logic.map.TileMap import com.unciv.logic.map.tile.Tile @@ -118,7 +118,7 @@ class MapEditorWesnothImporter(private val editorScreen: MapEditorScreen) : Disp map.mapParameters.apply { type = MapType.empty shape = MapShape.rectangular - mapSize = MapSizeNew(width, height) + mapSize = MapSize(width, height) } val colOffset = 1 + width / 2 diff --git a/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt index b2f2c1e023..9b45bc1699 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt @@ -9,10 +9,9 @@ import com.badlogic.gdx.utils.Align import com.unciv.UncivGame import com.unciv.logic.map.MapGeneratedMainType import com.unciv.logic.map.MapParameters -import com.unciv.logic.map.MapResources +import com.unciv.logic.map.mapgenerator.MapResourceSetting import com.unciv.logic.map.MapShape import com.unciv.logic.map.MapSize -import com.unciv.logic.map.MapSizeNew import com.unciv.logic.map.MapType import com.unciv.ui.components.UncivTextField import com.unciv.ui.components.extensions.pad @@ -178,18 +177,18 @@ class MapParametersTable( private fun addWorldSizeTable() { if (mapGeneratedMainType == MapGeneratedMainType.randomGenerated) { - val mapSizes = MapSize.values().map { it.name } + val mapSizes = MapSize.names() mapSizesOptionsValues = mapSizes.toHashSet() val optionsTable = MultiCheckboxTable("{Enabled World Sizes}", "NewGameWorldSizes", mapSizesOptionsValues) { if (mapSizesOptionsValues.isEmpty()) { - mapParameters.mapSize = MapSizeNew(mapSizes.random()) + mapParameters.mapSize = MapSize(mapSizes.random()) } else { - mapParameters.mapSize = MapSizeNew(mapSizesOptionsValues.random()) + mapParameters.mapSize = MapSize(mapSizesOptionsValues.random()) } } add(optionsTable).colspan(2).grow().row() } else { - val mapSizes = MapSize.values().map { it.name } + listOf(MapSize.custom) + val mapSizes = MapSize.names() + listOf(MapSize.custom) worldSizeSelectBox = TranslatedSelectBox(mapSizes, mapParameters.mapSize.name, skin) worldSizeSelectBox.onChange { updateWorldSizeTable() } @@ -210,7 +209,7 @@ class MapParametersTable( textFieldFilter = DigitsOnlyFilter() } customMapSizeRadius.onChange { - mapParameters.mapSize = MapSizeNew(customMapSizeRadius.text.toIntOrNull() ?: 0 ) + mapParameters.mapSize = MapSize(customMapSizeRadius.text.toIntOrNull() ?: 0 ) } hexagonalSizeTable.add("{Radius}:".toLabel()).grow().left() hexagonalSizeTable.add(customMapSizeRadius).right().row() @@ -230,10 +229,10 @@ class MapParametersTable( } customMapWidth.onChange { - mapParameters.mapSize = MapSizeNew(customMapWidth.text.toIntOrNull() ?: 0, customMapHeight.text.toIntOrNull() ?: 0) + mapParameters.mapSize = MapSize(customMapWidth.text.toIntOrNull() ?: 0, customMapHeight.text.toIntOrNull() ?: 0) } customMapHeight.onChange { - mapParameters.mapSize = MapSizeNew(customMapWidth.text.toIntOrNull() ?: 0, customMapHeight.text.toIntOrNull() ?: 0) + mapParameters.mapSize = MapSize(customMapWidth.text.toIntOrNull() ?: 0, customMapHeight.text.toIntOrNull() ?: 0) } rectangularSizeTable.defaults().pad(5f) @@ -253,23 +252,13 @@ class MapParametersTable( else if (mapParameters.shape == MapShape.rectangular && worldSizeSelectBox.selected.value == MapSize.custom) customWorldSizeTable.add(rectangularSizeTable).grow().row() else - mapParameters.mapSize = MapSizeNew(worldSizeSelectBox.selected.value) + mapParameters.mapSize = MapSize(worldSizeSelectBox.selected.value) sizeChangedCallback?.invoke() } private fun addResourceSelectBox() { - val mapResources = if (forMapEditor) listOf( - MapResources.sparse, - MapResources.default, - MapResources.abundant, - ) else listOf( - MapResources.sparse, - MapResources.default, - MapResources.abundant, - MapResources.strategicBalance, - MapResources.legendaryStart - ) + val mapResources = MapResourceSetting.activeLabels() if (mapGeneratedMainType == MapGeneratedMainType.randomGenerated) { mapResourcesOptionsValues = mapResources.toHashSet() diff --git a/core/src/com/unciv/ui/screens/worldscreen/minimap/Minimap.kt b/core/src/com/unciv/ui/screens/worldscreen/minimap/Minimap.kt index 9a722fb54b..1b8db84f68 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/minimap/Minimap.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/minimap/Minimap.kt @@ -250,4 +250,3 @@ class Minimap(val mapHolder: WorldMapHolder, minimapSize: Int, private val civIn // For debugging purposes override fun draw(batch: Batch?, parentAlpha: Float) = super.draw(batch, parentAlpha) } - diff --git a/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt b/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt index b56fddaf26..9d84681a7f 100644 --- a/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt +++ b/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt @@ -7,7 +7,6 @@ import com.unciv.logic.GameStarter import com.unciv.logic.civilization.PlayerType import com.unciv.logic.map.MapParameters import com.unciv.logic.map.MapSize -import com.unciv.logic.map.MapSizeNew import com.unciv.models.metadata.GameParameters import com.unciv.models.metadata.GameSettings import com.unciv.models.metadata.Player @@ -53,7 +52,7 @@ internal object ConsoleLauncher { private fun getMapParameters(): MapParameters { return MapParameters().apply { - mapSize = MapSizeNew(MapSize.Tiny) + mapSize = MapSize.Tiny noRuins = true noNaturalWonders = true } diff --git a/tests/src/com/unciv/logic/GameSerializationTests.kt b/tests/src/com/unciv/logic/GameSerializationTests.kt index f16047cfd9..123dbc6945 100644 --- a/tests/src/com/unciv/logic/GameSerializationTests.kt +++ b/tests/src/com/unciv/logic/GameSerializationTests.kt @@ -8,7 +8,6 @@ import com.unciv.logic.civilization.PlayerType import com.unciv.logic.files.UncivFiles import com.unciv.logic.map.MapParameters import com.unciv.logic.map.MapSize -import com.unciv.logic.map.MapSizeNew import com.unciv.models.metadata.GameParameters import com.unciv.models.metadata.GameSettings import com.unciv.models.metadata.GameSetupInfo @@ -56,7 +55,7 @@ class GameSerializationTests { players.add(Player("Greece")) } val mapParameters = MapParameters().apply { - mapSize = MapSizeNew(MapSize.Tiny) + mapSize = MapSize.Tiny seed = 42L } val setup = GameSetupInfo(param, mapParameters) diff --git a/tests/src/com/unciv/testing/TestGame.kt b/tests/src/com/unciv/testing/TestGame.kt index d50092f4d6..ee5eed0195 100644 --- a/tests/src/com/unciv/testing/TestGame.kt +++ b/tests/src/com/unciv/testing/TestGame.kt @@ -8,7 +8,7 @@ import com.unciv.logic.city.City import com.unciv.logic.city.managers.CityFounder import com.unciv.logic.civilization.Civilization import com.unciv.logic.civilization.PlayerType -import com.unciv.logic.map.MapSizeNew +import com.unciv.logic.map.MapSize import com.unciv.logic.map.TileMap import com.unciv.logic.map.mapunit.MapUnit import com.unciv.logic.map.tile.Tile @@ -59,7 +59,7 @@ class TestGame { // Create a tilemap, needed for city centers gameInfo.tileMap = TileMap(0, ruleset, false) - tileMap.mapParameters.mapSize = MapSizeNew(0, 0) + tileMap.mapParameters.mapSize = MapSize(0) tileMap.ruleset = ruleset tileMap.gameInfo = gameInfo @@ -70,7 +70,7 @@ class TestGame { /** Makes a new rectangular tileMap and sets it in gameInfo. Removes all existing tiles. All new tiles have terrain [baseTerrain] */ fun makeRectangularMap(newHeight: Int, newWidth: Int, baseTerrain: String = Constants.desert) { val newTileMap = TileMap(newWidth, newHeight, ruleset, tileMap.mapParameters.worldWrap) - newTileMap.mapParameters.mapSize = MapSizeNew(newWidth, newHeight) + newTileMap.mapParameters.mapSize = MapSize(newWidth, newHeight) for (row in tileMap.tileMatrix) for (tile in row) @@ -86,7 +86,7 @@ class TestGame { */ fun makeHexagonalMap(newRadius: Int, baseTerrain: String = Constants.desert) { val newTileMap = TileMap(newRadius, ruleset, tileMap.mapParameters.worldWrap) - newTileMap.mapParameters.mapSize = MapSizeNew(newRadius) + newTileMap.mapParameters.mapSize = MapSize(newRadius) for (row in tileMap.tileMatrix) for (tile in row)