mirror of
https://github.com/yairm210/Unciv.git
synced 2025-08-03 16:49:15 +07:00
added gameParameter option to disable start bias (#7241)
* disable start bias * better indentation * improved * improvedx2 * now for generated maps too * made it choose a random location instead of the last one * -||- * checks * forgot I can write directly on github :)
This commit is contained in:
@ -357,6 +357,7 @@ Inner Sea =
|
|||||||
Number of City-States =
|
Number of City-States =
|
||||||
One City Challenge =
|
One City Challenge =
|
||||||
No Barbarians =
|
No Barbarians =
|
||||||
|
Disable starting bias =
|
||||||
Raging Barbarians =
|
Raging Barbarians =
|
||||||
No Ancient Ruins =
|
No Ancient Ruins =
|
||||||
No Natural Wonders =
|
No Natural Wonders =
|
||||||
|
@ -22,8 +22,10 @@ import kotlin.collections.HashSet
|
|||||||
object GameStarter {
|
object GameStarter {
|
||||||
// temporary instrumentation while tuning/debugging
|
// temporary instrumentation while tuning/debugging
|
||||||
private const val consoleTimings = false
|
private const val consoleTimings = false
|
||||||
|
private lateinit var gameSetupInfo: GameSetupInfo
|
||||||
|
|
||||||
fun startNewGame(gameSetupInfo: GameSetupInfo): GameInfo {
|
fun startNewGame(gameSetupInfo: GameSetupInfo): GameInfo {
|
||||||
|
this.gameSetupInfo = gameSetupInfo
|
||||||
if (consoleTimings)
|
if (consoleTimings)
|
||||||
debug("\nGameStarter run with parameters %s, map %s", gameSetupInfo.gameParameters, gameSetupInfo.mapParameters)
|
debug("\nGameStarter run with parameters %s, map %s", gameSetupInfo.gameParameters, gameSetupInfo.mapParameters)
|
||||||
|
|
||||||
@ -57,7 +59,7 @@ object GameStarter {
|
|||||||
} else runAndMeasure("generateMap") {
|
} else runAndMeasure("generateMap") {
|
||||||
// The mapgen needs to know what civs are in the game to generate regions, starts and resources
|
// The mapgen needs to know what civs are in the game to generate regions, starts and resources
|
||||||
addCivilizations(gameSetupInfo.gameParameters, gameInfo, ruleset, existingMap = false)
|
addCivilizations(gameSetupInfo.gameParameters, gameInfo, ruleset, existingMap = false)
|
||||||
tileMap = mapGen.generateMap(gameSetupInfo.mapParameters, gameInfo.civilizations)
|
tileMap = mapGen.generateMap(gameSetupInfo.mapParameters, gameSetupInfo.gameParameters, gameInfo.civilizations)
|
||||||
tileMap.mapParameters = gameSetupInfo.mapParameters
|
tileMap.mapParameters = gameSetupInfo.mapParameters
|
||||||
// Now forget them for a moment! MapGen can silently fail to place some city states, so then we'll use the old fallback method to place those.
|
// Now forget them for a moment! MapGen can silently fail to place some city states, so then we'll use the old fallback method to place those.
|
||||||
gameInfo.civilizations.clear()
|
gameInfo.civilizations.clear()
|
||||||
@ -415,9 +417,9 @@ object GameStarter {
|
|||||||
.sortedBy { civ ->
|
.sortedBy { civ ->
|
||||||
when {
|
when {
|
||||||
civ.civName in tileMap.startingLocationsByNation -> 1 // harshest requirements
|
civ.civName in tileMap.startingLocationsByNation -> 1 // harshest requirements
|
||||||
civ.nation.startBias.any { it in tileMap.naturalWonders } -> 2
|
civ.nation.startBias.any { it in tileMap.naturalWonders } && !gameSetupInfo.gameParameters.noStartBias -> 2
|
||||||
civ.nation.startBias.contains(Constants.tundra) -> 3 // Tundra starts are hard to find, so let's do them first
|
civ.nation.startBias.contains(Constants.tundra) && !gameSetupInfo.gameParameters.noStartBias -> 3 // Tundra starts are hard to find, so let's do them first
|
||||||
civ.nation.startBias.isNotEmpty() -> 4 // less harsh
|
civ.nation.startBias.isNotEmpty() && !gameSetupInfo.gameParameters.noStartBias -> 4 // less harsh
|
||||||
else -> 5 // no requirements
|
else -> 5 // no requirements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -457,6 +459,9 @@ object GameStarter {
|
|||||||
freeTiles: MutableList<TileInfo>,
|
freeTiles: MutableList<TileInfo>,
|
||||||
startScores: HashMap<TileInfo, Float>
|
startScores: HashMap<TileInfo, Float>
|
||||||
): TileInfo {
|
): TileInfo {
|
||||||
|
if (gameSetupInfo.gameParameters.noStartBias) {
|
||||||
|
return freeTiles.random()
|
||||||
|
}
|
||||||
if (civ.nation.startBias.any { it in tileMap.naturalWonders }) {
|
if (civ.nation.startBias.any { it in tileMap.naturalWonders }) {
|
||||||
// startPref wants Natural wonder neighbor: Rare and very likely to be outside getDistanceFromEdge
|
// startPref wants Natural wonder neighbor: Rare and very likely to be outside getDistanceFromEdge
|
||||||
val wonderNeighbor = tileMap.values.asSequence()
|
val wonderNeighbor = tileMap.values.asSequence()
|
||||||
@ -485,6 +490,6 @@ object GameStarter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return preferredTiles.lastOrNull() ?: freeTiles.last()
|
return preferredTiles.randomOrNull() ?: freeTiles.random()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ import com.unciv.logic.map.Perlin
|
|||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.logic.map.TileMap
|
import com.unciv.logic.map.TileMap
|
||||||
import com.unciv.models.Counter
|
import com.unciv.models.Counter
|
||||||
|
import com.unciv.models.metadata.GameParameters
|
||||||
|
import com.unciv.models.metadata.GameSetupInfo
|
||||||
import com.unciv.models.ruleset.Ruleset
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
import com.unciv.models.ruleset.tile.Terrain
|
import com.unciv.models.ruleset.tile.Terrain
|
||||||
@ -71,7 +73,7 @@ class MapGenerator(val ruleset: Ruleset) {
|
|||||||
getMatchingUniques(UniqueType.TileGenerationConditions)
|
getMatchingUniques(UniqueType.TileGenerationConditions)
|
||||||
.map { unique -> TerrainOccursRange(this, unique) }
|
.map { unique -> TerrainOccursRange(this, unique) }
|
||||||
|
|
||||||
fun generateMap(mapParameters: MapParameters, civilizations: List<CivilizationInfo> = emptyList()): TileMap {
|
fun generateMap(mapParameters: MapParameters, gameParameters: GameParameters = GameParameters(), civilizations: List<CivilizationInfo> = emptyList()): TileMap {
|
||||||
val mapSize = mapParameters.mapSize
|
val mapSize = mapParameters.mapSize
|
||||||
val mapType = mapParameters.type
|
val mapType = mapParameters.type
|
||||||
|
|
||||||
@ -134,7 +136,7 @@ class MapGenerator(val ruleset: Ruleset) {
|
|||||||
regions.generateRegions(map, civilizations.count { ruleset.nations[it.civName]!!.isMajorCiv() })
|
regions.generateRegions(map, civilizations.count { ruleset.nations[it.civName]!!.isMajorCiv() })
|
||||||
}
|
}
|
||||||
runAndMeasure("assignRegions") {
|
runAndMeasure("assignRegions") {
|
||||||
regions.assignRegions(map, civilizations.filter { ruleset.nations[it.civName]!!.isMajorCiv() })
|
regions.assignRegions(map, civilizations.filter { ruleset.nations[it.civName]!!.isMajorCiv() }, gameParameters)
|
||||||
}
|
}
|
||||||
runAndMeasure("placeResourcesAndMinorCivs") {
|
runAndMeasure("placeResourcesAndMinorCivs") {
|
||||||
regions.placeResourcesAndMinorCivs(map, civilizations.filter { ruleset.nations[it.civName]!!.isCityState() })
|
regions.placeResourcesAndMinorCivs(map, civilizations.filter { ruleset.nations[it.civName]!!.isCityState() })
|
||||||
|
@ -9,6 +9,7 @@ import com.unciv.logic.map.MapResources
|
|||||||
import com.unciv.logic.map.MapShape
|
import com.unciv.logic.map.MapShape
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.logic.map.TileMap
|
import com.unciv.logic.map.TileMap
|
||||||
|
import com.unciv.models.metadata.GameParameters
|
||||||
import com.unciv.models.ruleset.Ruleset
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
import com.unciv.models.ruleset.tile.Terrain
|
import com.unciv.models.ruleset.tile.Terrain
|
||||||
@ -211,7 +212,7 @@ class MapRegions (val ruleset: Ruleset){
|
|||||||
return Pair(splitOffRegion, regionToSplit)
|
return Pair(splitOffRegion, regionToSplit)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assignRegions(tileMap: TileMap, civilizations: List<CivilizationInfo>) {
|
fun assignRegions(tileMap: TileMap, civilizations: List<CivilizationInfo>, gameParameters: GameParameters) {
|
||||||
if (civilizations.isEmpty()) return
|
if (civilizations.isEmpty()) return
|
||||||
|
|
||||||
// first assign region types
|
// first assign region types
|
||||||
@ -269,6 +270,12 @@ class MapRegions (val ruleset: Ruleset){
|
|||||||
|
|
||||||
// First assign coast bias civs
|
// First assign coast bias civs
|
||||||
for (civ in coastBiasCivs) {
|
for (civ in coastBiasCivs) {
|
||||||
|
// If noStartBias is enabled consider these to be randomCivs
|
||||||
|
if (gameParameters.noStartBias) {
|
||||||
|
randomCivs.addAll(coastBiasCivs)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find a coastal start, preferably a really coastal one
|
// Try to find a coastal start, preferably a really coastal one
|
||||||
var startRegion = unpickedRegions.filter { tileMap[it.startPosition!!].isCoastalTile() }
|
var startRegion = unpickedRegions.filter { tileMap[it.startPosition!!].isCoastalTile() }
|
||||||
.maxByOrNull { it.terrainCounts["Coastal"] ?: 0 }
|
.maxByOrNull { it.terrainCounts["Coastal"] ?: 0 }
|
||||||
@ -307,6 +314,12 @@ class MapRegions (val ruleset: Ruleset){
|
|||||||
|
|
||||||
// Next do positive bias civs
|
// Next do positive bias civs
|
||||||
for (civ in positiveBiasCivs) {
|
for (civ in positiveBiasCivs) {
|
||||||
|
// If noStartBias is enabled consider these to be randomCivs
|
||||||
|
if (gameParameters.noStartBias) {
|
||||||
|
randomCivs.addAll(positiveBiasCivs)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find a start that matches any of the desired regions, ideally with lots of desired terrain
|
// Try to find a start that matches any of the desired regions, ideally with lots of desired terrain
|
||||||
val preferred = ruleset.nations[civ.civName]!!.startBias
|
val preferred = ruleset.nations[civ.civName]!!.startBias
|
||||||
val startRegion = unpickedRegions.filter { it.type in preferred }
|
val startRegion = unpickedRegions.filter { it.type in preferred }
|
||||||
@ -331,6 +344,12 @@ class MapRegions (val ruleset: Ruleset){
|
|||||||
|
|
||||||
// Next do negative bias ones (ie "Avoid []")
|
// Next do negative bias ones (ie "Avoid []")
|
||||||
for (civ in negativeBiasCivs) {
|
for (civ in negativeBiasCivs) {
|
||||||
|
// If noStartBias is enabled consider these to be randomCivs
|
||||||
|
if (gameParameters.noStartBias) {
|
||||||
|
randomCivs.addAll(negativeBiasCivs)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
val avoided = ruleset.nations[civ.civName]!!.startBias.map { it.getPlaceholderParameters()[0] }
|
val avoided = ruleset.nations[civ.civName]!!.startBias.map { it.getPlaceholderParameters()[0] }
|
||||||
// Try to find a region not of the avoided types, secondary sort by least number of undesired terrains
|
// Try to find a region not of the avoided types, secondary sort by least number of undesired terrains
|
||||||
val startRegion = unpickedRegions.filterNot { it.type in avoided }
|
val startRegion = unpickedRegions.filterNot { it.type in avoided }
|
||||||
|
@ -26,6 +26,7 @@ class GameParameters { // Default values are the default new game
|
|||||||
var godMode = false
|
var godMode = false
|
||||||
var nuclearWeaponsEnabled = true
|
var nuclearWeaponsEnabled = true
|
||||||
var religionEnabled = false
|
var religionEnabled = false
|
||||||
|
var noStartBias = false
|
||||||
|
|
||||||
var victoryTypes: ArrayList<String> = arrayListOf()
|
var victoryTypes: ArrayList<String> = arrayListOf()
|
||||||
var startingEra = "Ancient era"
|
var startingEra = "Ancient era"
|
||||||
|
@ -72,6 +72,7 @@ class GameOptionsTable(
|
|||||||
checkboxTable.addNuclearWeaponsCheckbox()
|
checkboxTable.addNuclearWeaponsCheckbox()
|
||||||
checkboxTable.addIsOnlineMultiplayerCheckbox()
|
checkboxTable.addIsOnlineMultiplayerCheckbox()
|
||||||
checkboxTable.addReligionCheckbox(cityStateSlider)
|
checkboxTable.addReligionCheckbox(cityStateSlider)
|
||||||
|
checkboxTable.addNoStartBiasCheckbox()
|
||||||
add(checkboxTable).center().row()
|
add(checkboxTable).center().row()
|
||||||
|
|
||||||
if (!isPortrait)
|
if (!isPortrait)
|
||||||
@ -124,6 +125,10 @@ class GameOptionsTable(
|
|||||||
cityStateSlider?.run { setRange(0f, numberOfCityStates().toFloat()) }
|
cityStateSlider?.run { setRange(0f, numberOfCityStates().toFloat()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Table.addNoStartBiasCheckbox() =
|
||||||
|
addCheckbox("Disable starting bias", gameParameters.noStartBias)
|
||||||
|
{ gameParameters.noStartBias = it }
|
||||||
|
|
||||||
private fun Table.addCityStatesSlider(): UncivSlider? {
|
private fun Table.addCityStatesSlider(): UncivSlider? {
|
||||||
val maxCityStates = numberOfCityStates()
|
val maxCityStates = numberOfCityStates()
|
||||||
if (maxCityStates == 0) return null
|
if (maxCityStates == 0) return null
|
||||||
|
Reference in New Issue
Block a user