mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-06 01:02:29 +07:00
AI focuses production of units on cities with high production, so the weaker ones can build infrastructure
Organized ChooseNextConstruction automation
This commit is contained in:
parent
273b06aa3a
commit
e81844c053
@ -21,8 +21,8 @@ android {
|
||||
applicationId "com.unciv.app"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 28
|
||||
versionCode 266
|
||||
versionName "2.17.12-patch1"
|
||||
versionCode 267
|
||||
versionName "2.17.13"
|
||||
}
|
||||
|
||||
// Had to add this crap for Travis to build, it wanted to sign the app
|
||||
|
@ -1,24 +1,14 @@
|
||||
package com.unciv.logic.automation
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.battle.CityCombatant
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.city.SpecialConstruction
|
||||
import com.unciv.logic.civilization.CityAction
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.map.BFS
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.gamebasics.Building
|
||||
import com.unciv.models.gamebasics.VictoryType
|
||||
import com.unciv.models.gamebasics.unit.BaseUnit
|
||||
import com.unciv.models.gamebasics.unit.UnitType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class Automation {
|
||||
@ -84,192 +74,6 @@ class Automation {
|
||||
}
|
||||
|
||||
|
||||
fun chooseNextConstruction(cityConstructions: CityConstructions) {
|
||||
cityConstructions.run {
|
||||
if(!UnCivGame.Current.settings.autoAssignCityProduction) return
|
||||
if (getCurrentConstruction() !is SpecialConstruction) return // don't want to be stuck on these forever
|
||||
|
||||
val buildableNotWonders = getBuildableBuildings().filterNot { it.isWonder || it.isNationalWonder }
|
||||
val buildableWonders = getBuildableBuildings().filter { it.isWonder || it.isNationalWonder }
|
||||
|
||||
val civUnits = cityInfo.civInfo.getCivUnits()
|
||||
val militaryUnits = civUnits.filter { !it.type.isCivilian()}.size
|
||||
val workers = civUnits.filter { it.name == Constants.worker }.size.toFloat()
|
||||
val cities = cityInfo.civInfo.cities.size
|
||||
val canBuildWorkboat = cityInfo.cityConstructions.getConstructableUnits().map { it.name }.contains("Work Boats")
|
||||
&& !cityInfo.getTiles().any { it.civilianUnit?.name == "Work Boats" }
|
||||
val needWorkboat = canBuildWorkboat
|
||||
&& cityInfo.getTiles().any { it.isWater && it.hasViewableResource(cityInfo.civInfo) && it.improvement == null }
|
||||
|
||||
val isAtWar = cityInfo.civInfo.isAtWar()
|
||||
val preferredVictoryType = cityInfo.civInfo.victoryType()
|
||||
|
||||
data class ConstructionChoice(val choice:String, var choiceModifier:Float){
|
||||
val remainingWork:Int = getRemainingWork(choice)
|
||||
}
|
||||
|
||||
val relativeCostEffectiveness = ArrayList<ConstructionChoice>()
|
||||
|
||||
//Food buildings : Granary and lighthouse and hospital
|
||||
val foodBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Food) }
|
||||
.minBy{ it.cost }
|
||||
if (foodBuilding!=null) {
|
||||
val choice = ConstructionChoice(foodBuilding.name,1f)
|
||||
if (cityInfo.population.population < 5) choice.choiceModifier=1.3f
|
||||
relativeCostEffectiveness.add(choice)
|
||||
}
|
||||
|
||||
//Production buildings : Workshop, factory
|
||||
val productionBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Production) }
|
||||
.minBy{it.cost}
|
||||
if (productionBuilding!=null) {
|
||||
relativeCostEffectiveness.add(ConstructionChoice(productionBuilding.name, 1.5f))
|
||||
}
|
||||
|
||||
//Gold buildings : Market, bank
|
||||
val goldBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Gold) }
|
||||
.minBy{it.cost}
|
||||
if (goldBuilding!=null) {
|
||||
val choice = ConstructionChoice(goldBuilding.name,1.2f)
|
||||
if (cityInfo.civInfo.statsForNextTurn.gold<0) {
|
||||
choice.choiceModifier=3f
|
||||
}
|
||||
relativeCostEffectiveness.add(choice)
|
||||
}
|
||||
|
||||
//Science buildings
|
||||
val scienceBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Science) }
|
||||
.minBy{it.cost}
|
||||
if (scienceBuilding!=null) {
|
||||
var modifier = 1.1f
|
||||
if(preferredVictoryType==VictoryType.Scientific)
|
||||
modifier*=1.4f
|
||||
val choice = ConstructionChoice(scienceBuilding.name,modifier)
|
||||
relativeCostEffectiveness.add(choice)
|
||||
}
|
||||
|
||||
//Happiness
|
||||
val happinessBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Happiness) }
|
||||
.minBy{it.cost}
|
||||
if (happinessBuilding!=null) {
|
||||
val choice = ConstructionChoice(happinessBuilding.name,1f)
|
||||
val civHappiness = cityInfo.civInfo.getHappiness()
|
||||
if (civHappiness > 5) choice.choiceModifier = 1/2f // less desperate
|
||||
if (civHappiness < 0) choice.choiceModifier = 3f // more desperate
|
||||
relativeCostEffectiveness.add(choice)
|
||||
}
|
||||
|
||||
//Defensive building
|
||||
val defensiveBuilding = buildableNotWonders.filter { it.cityStrength>0 }
|
||||
.minBy { it.cost }
|
||||
if(defensiveBuilding!=null && (isAtWar || preferredVictoryType!=VictoryType.Cultural)){
|
||||
var modifier = 0.2f
|
||||
if(isAtWar) modifier = 0.5f
|
||||
|
||||
// If this city is the closest city to another civ, that makes it a likely candidate for attack
|
||||
if(cityInfo.civInfo.getKnownCivs()
|
||||
.any{ NextTurnAutomation().getClosestCities(cityInfo.civInfo,it).city1 == cityInfo })
|
||||
modifier *= 1.5f
|
||||
|
||||
relativeCostEffectiveness.add(ConstructionChoice(defensiveBuilding.name, modifier))
|
||||
}
|
||||
|
||||
val unitTrainingBuilding = buildableNotWonders.filter { it.xpForNewUnits>0}
|
||||
.minBy { it.cost }
|
||||
//cityInfo.civInfo.cities.sortedByDescending { } // todo don't build if this is a weak production city
|
||||
if (unitTrainingBuilding!=null && (preferredVictoryType!=VictoryType.Cultural || isAtWar)) {
|
||||
var modifier = 0.5f
|
||||
if(isAtWar) modifier = 1f
|
||||
if(preferredVictoryType==VictoryType.Domination)
|
||||
modifier *= 1.3f
|
||||
relativeCostEffectiveness.add(ConstructionChoice(unitTrainingBuilding.name,modifier))
|
||||
}
|
||||
|
||||
//Wonders
|
||||
if (buildableWonders.isNotEmpty()) {
|
||||
fun getWonderPriority(wonder: Building): Float {
|
||||
if(preferredVictoryType==VictoryType.Cultural
|
||||
&& wonder.name in listOf("Sistine Chapel","Eiffel Tower","Cristo Redentor","Neuschwanstein","Sydney Opera House"))
|
||||
return 3f
|
||||
if(wonder.isStatRelated(Stat.Science)){
|
||||
if(preferredVictoryType==VictoryType.Scientific) return 1.5f
|
||||
else return 1.3f
|
||||
}
|
||||
if(wonder.isStatRelated(Stat.Happiness)) return 1.2f
|
||||
if(wonder.isStatRelated(Stat.Production)) return 1.1f
|
||||
return 1f
|
||||
}
|
||||
val wondersByPriority = buildableWonders
|
||||
.sortedByDescending { getWonderPriority(it) }
|
||||
val wonder = wondersByPriority.first()
|
||||
val citiesBuildingWonders = cityInfo.civInfo.cities
|
||||
.count { it.cityConstructions.isBuildingWonder() }
|
||||
|
||||
relativeCostEffectiveness.add(ConstructionChoice(wonder.name,
|
||||
3.5f * getWonderPriority(wonder) / (citiesBuildingWonders + 1)))
|
||||
}
|
||||
|
||||
// culture buildings
|
||||
val cultureBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Culture) }.minBy { it.cost }
|
||||
if(cultureBuilding!=null){
|
||||
var modifier = 0.8f
|
||||
if(preferredVictoryType==VictoryType.Cultural) modifier =1.6f
|
||||
relativeCostEffectiveness.add(ConstructionChoice(cultureBuilding.name, modifier))
|
||||
}
|
||||
|
||||
//other buildings
|
||||
val other = buildableNotWonders.minBy{it.cost}
|
||||
if (other!=null) {
|
||||
relativeCostEffectiveness.add(ConstructionChoice(other.name,0.8f))
|
||||
}
|
||||
|
||||
//worker
|
||||
val citiesCountedTowardsWorkers = min(5, cities) // above 5 cities, extra cities won't make us want more workers - see #
|
||||
if (workers < citiesCountedTowardsWorkers * 0.6f) {
|
||||
relativeCostEffectiveness.add(ConstructionChoice(Constants.worker,citiesCountedTowardsWorkers/(workers+0.1f)))
|
||||
}
|
||||
|
||||
//Work boat
|
||||
if (needWorkboat) {
|
||||
relativeCostEffectiveness.add(ConstructionChoice("Work Boats",0.6f))
|
||||
}
|
||||
|
||||
//Army
|
||||
if((!isAtWar && cityInfo.civInfo.statsForNextTurn.gold>0 && militaryUnits<cities*2)
|
||||
|| (isAtWar && cityInfo.civInfo.gold > -50)) {
|
||||
val militaryUnit = chooseMilitaryUnit(cityInfo)
|
||||
val unitsToCitiesRatio = cities.toFloat() / (militaryUnits + 1)
|
||||
// most buildings and civ units contribute the the civ's growth, military units are anti-growth
|
||||
val militaryChoice = ConstructionChoice(militaryUnit, unitsToCitiesRatio / 2)
|
||||
if (isAtWar) militaryChoice.choiceModifier = unitsToCitiesRatio * 2
|
||||
else if (preferredVictoryType == VictoryType.Domination) militaryChoice.choiceModifier = unitsToCitiesRatio * 1.5f
|
||||
relativeCostEffectiveness.add(militaryChoice)
|
||||
}
|
||||
|
||||
val production = cityInfo.cityStats.currentCityStats.production
|
||||
|
||||
val theChosenOne:String
|
||||
if(relativeCostEffectiveness.isEmpty()){ // choose one of the special constructions instead
|
||||
// add science!
|
||||
if(SpecialConstruction.science.isBuildable(cityConstructions))
|
||||
theChosenOne="Science"
|
||||
else if(SpecialConstruction.gold.isBuildable(cityConstructions))
|
||||
theChosenOne="Gold"
|
||||
else theChosenOne = "Nothing"
|
||||
}
|
||||
else if(relativeCostEffectiveness.any { it.remainingWork < production*30 }) {
|
||||
relativeCostEffectiveness.removeAll { it.remainingWork >= production * 30 }
|
||||
theChosenOne = relativeCostEffectiveness.minBy { it.remainingWork/it.choiceModifier }!!.choice
|
||||
}
|
||||
// it's possible that this is a new city and EVERYTHING is way expensive - ignore modifiers, go for the cheapest.
|
||||
// Nobody can plan 30 turns ahead, I don't care how cost-efficient you are.
|
||||
else theChosenOne = relativeCostEffectiveness.minBy { it.remainingWork }!!.choice
|
||||
|
||||
currentConstruction = theChosenOne
|
||||
cityInfo.civInfo.addNotification("Work has started on [$currentConstruction]", Color.BROWN, CityAction(cityInfo.location))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun evaluteCombatStrength(civInfo: CivilizationInfo): Int {
|
||||
// Since units become exponentially stronger per combat strength increase, we square em all
|
||||
|
232
core/src/com/unciv/logic/automation/ConstructionAutomation.kt
Normal file
232
core/src/com/unciv/logic/automation/ConstructionAutomation.kt
Normal file
@ -0,0 +1,232 @@
|
||||
package com.unciv.logic.automation
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.city.SpecialConstruction
|
||||
import com.unciv.logic.civilization.CityAction
|
||||
import com.unciv.models.gamebasics.Building
|
||||
import com.unciv.models.gamebasics.VictoryType
|
||||
import com.unciv.models.stats.Stat
|
||||
import kotlin.math.min
|
||||
|
||||
class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
|
||||
val cityInfo = cityConstructions.cityInfo
|
||||
val civInfo = cityInfo.civInfo
|
||||
|
||||
val buildableNotWonders = cityConstructions.getBuildableBuildings().filterNot { it.isWonder || it.isNationalWonder }
|
||||
val buildableWonders = cityConstructions.getBuildableBuildings().filter { it.isWonder || it.isNationalWonder }
|
||||
|
||||
val civUnits = civInfo.getCivUnits()
|
||||
val militaryUnits = civUnits.filter { !it.type.isCivilian()}.size
|
||||
val workers = civUnits.filter { it.name == Constants.worker }.size.toFloat()
|
||||
val cities = civInfo.cities.size
|
||||
val canBuildWorkboat = cityInfo.cityConstructions.getConstructableUnits().map { it.name }.contains("Work Boats")
|
||||
&& !cityInfo.getTiles().any { it.civilianUnit?.name == "Work Boats" }
|
||||
val needWorkboat = canBuildWorkboat
|
||||
&& cityInfo.getTiles().any { it.isWater && it.hasViewableResource(civInfo) && it.improvement == null }
|
||||
|
||||
val isAtWar = civInfo.isAtWar()
|
||||
val preferredVictoryType = civInfo.victoryType()
|
||||
|
||||
val averageProduction = civInfo.cities.map { it.cityStats.currentCityStats.production }.average()
|
||||
val cityIsOverAverageProduction = cityInfo.cityStats.currentCityStats.production >= averageProduction
|
||||
|
||||
val relativeCostEffectiveness = ArrayList<ConstructionChoice>()
|
||||
|
||||
data class ConstructionChoice(val choice:String, var choiceModifier:Float,val remainingWork:Int)
|
||||
|
||||
fun addChoice(choices:ArrayList<ConstructionChoice>, choice:String, choiceModifier: Float){
|
||||
choices.add(ConstructionChoice(choice,choiceModifier,cityConstructions.getRemainingWork(choice)))
|
||||
}
|
||||
|
||||
fun chooseNextConstruction() {
|
||||
if (!UnCivGame.Current.settings.autoAssignCityProduction) return
|
||||
if (cityConstructions.getCurrentConstruction() !is SpecialConstruction) return // don't want to be stuck on these forever
|
||||
|
||||
addFoodBuildingChoice()
|
||||
addProductionBuildingChoice()
|
||||
addGoldBuildingChoice()
|
||||
addScienceBuildingChoice()
|
||||
addHappinessBuildingChoice()
|
||||
addDefenceBuildingChoice()
|
||||
addUnitTrainingBuildingChoice()
|
||||
addWondersChoice()
|
||||
addCultureBuildingChoice()
|
||||
addWorkerChoice()
|
||||
addWorkBoatChoice()
|
||||
addMilitaryUnitChoice()
|
||||
|
||||
val production = cityInfo.cityStats.currentCityStats.production
|
||||
|
||||
val theChosenOne: String
|
||||
if (relativeCostEffectiveness.isEmpty()) { // choose one of the special constructions instead
|
||||
// add science!
|
||||
if (SpecialConstruction.science.isBuildable(cityConstructions))
|
||||
theChosenOne = "Science"
|
||||
else if (SpecialConstruction.gold.isBuildable(cityConstructions))
|
||||
theChosenOne = "Gold"
|
||||
else theChosenOne = "Nothing"
|
||||
} else if (relativeCostEffectiveness.any { it.remainingWork < production * 30 }) {
|
||||
relativeCostEffectiveness.removeAll { it.remainingWork >= production * 30 }
|
||||
theChosenOne = relativeCostEffectiveness.minBy { it.remainingWork / it.choiceModifier }!!.choice
|
||||
}
|
||||
// it's possible that this is a new city and EVERYTHING is way expensive - ignore modifiers, go for the cheapest.
|
||||
// Nobody can plan 30 turns ahead, I don't care how cost-efficient you are.
|
||||
else theChosenOne = relativeCostEffectiveness.minBy { it.remainingWork }!!.choice
|
||||
|
||||
civInfo.addNotification("Work has started on [$theChosenOne]", Color.BROWN, CityAction(cityInfo.location))
|
||||
cityConstructions.currentConstruction = theChosenOne
|
||||
}
|
||||
|
||||
private fun addMilitaryUnitChoice() {
|
||||
if ((!isAtWar && civInfo.statsForNextTurn.gold > 0 && militaryUnits < cities * 2)
|
||||
|| (isAtWar && civInfo.gold > -50)) {
|
||||
val militaryUnit = Automation().chooseMilitaryUnit(cityInfo)
|
||||
val unitsToCitiesRatio = cities.toFloat() / (militaryUnits + 1)
|
||||
// most buildings and civ units contribute the the civ's growth, military units are anti-growth
|
||||
var modifier = unitsToCitiesRatio / 2
|
||||
if (preferredVictoryType == VictoryType.Domination) modifier *= 3
|
||||
else if (isAtWar) modifier *= unitsToCitiesRatio * 2
|
||||
if (!cityIsOverAverageProduction) modifier /= 5 // higher production cities will deal with this
|
||||
|
||||
if (cityInfo.getCenterTile().civilianUnit?.name == Constants.settler
|
||||
&& cityInfo.getCenterTile().getTilesInDistance(5).none { it.militaryUnit?.civInfo == civInfo })
|
||||
modifier = 5f // there's a settler just sitting here, doing nothing - BAD
|
||||
|
||||
addChoice(relativeCostEffectiveness, militaryUnit, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addWorkBoatChoice() {
|
||||
if (needWorkboat) {
|
||||
addChoice(relativeCostEffectiveness, "Work Boats", 0.6f)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addWorkerChoice() {
|
||||
val citiesCountedTowardsWorkers = min(5, cities) // above 5 cities, extra cities won't make us want more workers
|
||||
if (workers < citiesCountedTowardsWorkers * 0.6f) {
|
||||
var modifier = citiesCountedTowardsWorkers / (workers + 0.1f)
|
||||
if (!cityIsOverAverageProduction) modifier /= 5 // higher production cities will deal with this
|
||||
addChoice(relativeCostEffectiveness, Constants.worker, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addCultureBuildingChoice() {
|
||||
val cultureBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Culture) }.minBy { it.cost }
|
||||
if (cultureBuilding != null) {
|
||||
var modifier = 0.8f
|
||||
if (preferredVictoryType == VictoryType.Cultural) modifier = 1.6f
|
||||
addChoice(relativeCostEffectiveness, cultureBuilding.name, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addWondersChoice() {
|
||||
if (buildableWonders.isNotEmpty()) {
|
||||
fun getWonderPriority(wonder: Building): Float {
|
||||
if (preferredVictoryType == VictoryType.Cultural
|
||||
&& wonder.name in listOf("Sistine Chapel", "Eiffel Tower", "Cristo Redentor", "Neuschwanstein", "Sydney Opera House"))
|
||||
return 3f
|
||||
if (wonder.isStatRelated(Stat.Science)) {
|
||||
if (preferredVictoryType == VictoryType.Scientific) return 1.5f
|
||||
else return 1.3f
|
||||
}
|
||||
if (wonder.isStatRelated(Stat.Happiness)) return 1.2f
|
||||
if (wonder.isStatRelated(Stat.Production)) return 1.1f
|
||||
return 1f
|
||||
}
|
||||
|
||||
val wondersByPriority = buildableWonders
|
||||
.sortedByDescending { getWonderPriority(it) }
|
||||
val wonder = wondersByPriority.first()
|
||||
val citiesBuildingWonders = civInfo.cities
|
||||
.count { it.cityConstructions.isBuildingWonder() }
|
||||
|
||||
var modifier = 3.5f * getWonderPriority(wonder) / (citiesBuildingWonders + 1)
|
||||
if (!cityIsOverAverageProduction) modifier /= 5 // higher production cities will deal with this
|
||||
addChoice(relativeCostEffectiveness, wonder.name, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addUnitTrainingBuildingChoice() {
|
||||
val unitTrainingBuilding = buildableNotWonders.filter { it.xpForNewUnits > 0 }
|
||||
.minBy { it.cost }
|
||||
if (unitTrainingBuilding != null && (preferredVictoryType != VictoryType.Cultural || isAtWar)) {
|
||||
var modifier = if (cityIsOverAverageProduction) 0.5f else 0.1f // You shouldn't be cranking out units anytime soon
|
||||
if (isAtWar) modifier *= 2
|
||||
if (preferredVictoryType == VictoryType.Domination)
|
||||
modifier *= 1.3f
|
||||
addChoice(relativeCostEffectiveness, unitTrainingBuilding.name, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addDefenceBuildingChoice() {
|
||||
val defensiveBuilding = buildableNotWonders.filter { it.cityStrength > 0 }
|
||||
.minBy { it.cost }
|
||||
if (defensiveBuilding != null && (isAtWar || preferredVictoryType != VictoryType.Cultural)) {
|
||||
var modifier = 0.2f
|
||||
if (isAtWar) modifier = 0.5f
|
||||
|
||||
// If this city is the closest city to another civ, that makes it a likely candidate for attack
|
||||
if (civInfo.getKnownCivs().filter { it.cities.isNotEmpty() }
|
||||
.any { NextTurnAutomation().getClosestCities(civInfo, it).city1 == cityInfo })
|
||||
modifier *= 1.5f
|
||||
|
||||
addChoice(relativeCostEffectiveness, defensiveBuilding.name, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addHappinessBuildingChoice() {
|
||||
val happinessBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Happiness) }
|
||||
.minBy { it.cost }
|
||||
if (happinessBuilding != null) {
|
||||
var modifier = 1f
|
||||
val civHappiness = civInfo.getHappiness()
|
||||
if (civHappiness > 5) modifier = 1 / 2f // less desperate
|
||||
if (civHappiness < 0) modifier = 3f // more desperate
|
||||
addChoice(relativeCostEffectiveness, happinessBuilding.name, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addScienceBuildingChoice() {
|
||||
val scienceBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Science) }
|
||||
.minBy { it.cost }
|
||||
if (scienceBuilding != null) {
|
||||
var modifier = 1.1f
|
||||
if (preferredVictoryType == VictoryType.Scientific)
|
||||
modifier *= 1.4f
|
||||
addChoice(relativeCostEffectiveness, scienceBuilding.name, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addGoldBuildingChoice() {
|
||||
val goldBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Gold) }
|
||||
.minBy { it.cost }
|
||||
if (goldBuilding != null) {
|
||||
val modifier = if (civInfo.statsForNextTurn.gold < 0) 3f else 1.2f
|
||||
addChoice(relativeCostEffectiveness, goldBuilding.name, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addProductionBuildingChoice() {
|
||||
val productionBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Production) }
|
||||
.minBy { it.cost }
|
||||
if (productionBuilding != null) {
|
||||
addChoice(relativeCostEffectiveness, productionBuilding.name, 1.5f)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addFoodBuildingChoice() {
|
||||
val foodBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Food) }
|
||||
.minBy { it.cost }
|
||||
if (foodBuilding != null) {
|
||||
var modifier = 1f
|
||||
if (cityInfo.population.population < 5) modifier = 1.3f
|
||||
addChoice(relativeCostEffectiveness, foodBuilding.name, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,7 @@ package com.unciv.logic.city
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.automation.Automation
|
||||
import com.unciv.logic.automation.ConstructionAutomation
|
||||
import com.unciv.models.gamebasics.Building
|
||||
import com.unciv.models.gamebasics.GameBasics
|
||||
import com.unciv.models.gamebasics.tr
|
||||
@ -243,7 +243,7 @@ class CityConstructions {
|
||||
|
||||
fun chooseNextConstruction() {
|
||||
if(currentConstructionIsUserSet) return
|
||||
Automation().chooseNextConstruction(this)
|
||||
ConstructionAutomation(this).chooseNextConstruction()
|
||||
}
|
||||
//endregion
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user