Settler 'by name' recognition changed to 'by unique' recognition, allowing for modded settler-like units
This commit is contained in:
parent
a930ad6360
commit
002d0cc7f6
10 changed files with 38 additions and 34 deletions
|
@ -133,7 +133,7 @@
|
|||
"movement": 4,
|
||||
"cost": 30,
|
||||
"requiredTech": "Sailing",
|
||||
"uniques": ["Cannot enter ocean tiles until Astronomy","May create improvements on water resources"],
|
||||
"uniques": ["Cannot enter ocean tiles until Astronomy", "May create improvements on water resources"],
|
||||
"hurryCostModifier": 20
|
||||
},
|
||||
{
|
||||
|
@ -175,7 +175,7 @@
|
|||
"requiredResource": "Horses",
|
||||
"upgradesTo": "Knight",
|
||||
"obsoleteTech": "Chivalry",
|
||||
"uniques": ["No defensive terrain bonus","Rough terrain penalty"],
|
||||
"uniques": ["No defensive terrain bonus", "Rough terrain penalty"],
|
||||
"hurryCostModifier": 20,
|
||||
"attackSound": "arrow"
|
||||
},
|
||||
|
@ -191,7 +191,7 @@
|
|||
"requiredTech": "The Wheel",
|
||||
"upgradesTo": "Knight",
|
||||
"obsoleteTech": "Chivalry",
|
||||
"uniques": ["No defensive terrain bonus","Rough terrain penalty"],
|
||||
"uniques": ["No defensive terrain bonus", "Rough terrain penalty"],
|
||||
"hurryCostModifier": 20,
|
||||
"attackSound": "arrow"
|
||||
},
|
||||
|
|
|
@ -4,6 +4,7 @@ object Constants {
|
|||
const val worker = "Worker"
|
||||
const val workerUnique = "Can build improvements on tiles"
|
||||
const val settler = "Settler"
|
||||
const val settlerUnique = "Founds a new city"
|
||||
const val greatGeneral = "Great General"
|
||||
|
||||
const val impassable = "Impassable"
|
||||
|
|
|
@ -107,7 +107,8 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
|||
else if (isAtWar) modifier *= unitsToCitiesRatio * 2
|
||||
if (!cityIsOverAverageProduction) modifier /= 5 // higher production cities will deal with this
|
||||
|
||||
if (cityInfo.getCenterTile().civilianUnit?.name == Constants.settler
|
||||
val civilianUnit = cityInfo.getCenterTile().civilianUnit
|
||||
if (civilianUnit != null && civilianUnit.hasUnique(Constants.settlerUnique)
|
||||
&& cityInfo.getCenterTile().getTilesInDistance(5).none { it.militaryUnit?.civInfo == civInfo })
|
||||
modifier = 5f // there's a settler just sitting here, doing nothing - BAD
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.unciv.models.ruleset.ModOptions
|
|||
import com.unciv.models.ruleset.ModOptionsConstants
|
||||
import com.unciv.models.ruleset.VictoryType
|
||||
import com.unciv.models.ruleset.tech.Technology
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.translations.tr
|
||||
import kotlin.math.min
|
||||
|
||||
|
@ -480,14 +481,20 @@ object NextTurnAutomation{
|
|||
if (civInfo.isCityState()) return
|
||||
if (civInfo.isAtWar()) return // don't train settlers when you could be training troops.
|
||||
if (civInfo.victoryType() == VictoryType.Cultural && civInfo.cities.size > 3) return
|
||||
if (civInfo.cities.any()
|
||||
&& civInfo.getHappiness() > civInfo.cities.size + 5
|
||||
&& civInfo.getCivUnits().none { it.name == Constants.settler }
|
||||
&& civInfo.cities.none { it.cityConstructions.currentConstructionFromQueue == Constants.settler }) {
|
||||
if (civInfo.cities.none() || civInfo.getHappiness() <= civInfo.cities.size + 5) return
|
||||
|
||||
val settlerUnits = civInfo.gameInfo.ruleSet.units.values
|
||||
.filter { it.uniques.contains(Constants.settlerUnique) && it.isBuildable(civInfo) }
|
||||
if (settlerUnits.isEmpty()) return
|
||||
if (civInfo.getCivUnits().none { it.hasUnique(Constants.settlerUnique) }
|
||||
&& civInfo.cities.none {
|
||||
val currentConstruction = it.cityConstructions.getCurrentConstruction()
|
||||
currentConstruction is BaseUnit && currentConstruction.uniques.contains(Constants.settlerUnique)
|
||||
}) {
|
||||
|
||||
val bestCity = civInfo.cities.maxBy { it.cityStats.currentCityStats.production }!!
|
||||
if (bestCity.cityConstructions.builtBuildings.size > 1) // 2 buildings or more, otherwise focus on self first
|
||||
bestCity.cityConstructions.currentConstructionFromQueue = Constants.settler
|
||||
bestCity.cityConstructions.currentConstructionFromQueue = settlerUnits.minBy { it.cost }!!.name
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ object UnitAutomation {
|
|||
throw IllegalStateException("Barbarians is not allowed here.")
|
||||
|
||||
if(unit.type.isCivilian()) {
|
||||
if (unit.name == Constants.settler)
|
||||
if (unit.hasUnique(Constants.settlerUnique))
|
||||
return SpecificUnitAutomation.automateSettlerActions(unit)
|
||||
|
||||
if (unit.hasUnique(Constants.workerUnique))
|
||||
|
@ -261,7 +261,8 @@ object UnitAutomation {
|
|||
val settlerOrGreatPersonToAccompany = unit.civInfo.getCivUnits()
|
||||
.firstOrNull {
|
||||
val tile = it.currentTile
|
||||
(it.name == Constants.settler || it.name in GreatPersonManager().statToGreatPersonMapping.values)
|
||||
it.type==UnitType.Civilian &&
|
||||
(it.hasUnique(Constants.settlerUnique) || unit.name in GreatPersonManager().statToGreatPersonMapping.values)
|
||||
&& tile.militaryUnit == null && unit.movement.canMoveTo(tile) && unit.movement.canReach(tile)
|
||||
}
|
||||
if (settlerOrGreatPersonToAccompany == null) return false
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.unciv.ui.utils.withItem
|
|||
import com.unciv.ui.utils.withoutItem
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
|
@ -194,7 +195,7 @@ class CityConstructions {
|
|||
// Since this is only ever used for UI purposes, I feel fine with having it be a bit inefficient
|
||||
// and recalculating the entire city stats
|
||||
// We don't want to change our current construction queue - what if we have an empty queue, too many changes to check for -
|
||||
// So we ust clone it and see what would happen f that was our construction
|
||||
// So we must clone it and see what would happen if that was our construction
|
||||
val cityConstructionsClone = clone()
|
||||
cityConstructionsClone.currentConstructionFromQueue = constructionName
|
||||
cityConstructionsClone.cityInfo = cityInfo
|
||||
|
@ -210,7 +211,7 @@ class CityConstructions {
|
|||
var production = cityStatsForConstruction.production.roundToInt()
|
||||
if (constructionName == Constants.settler) production += cityStatsForConstruction.food.toInt()
|
||||
|
||||
return Math.ceil((workLeft / production.toDouble())).toInt()
|
||||
return ceil(workLeft / production.toDouble()).toInt()
|
||||
}
|
||||
//endregion
|
||||
|
||||
|
|
|
@ -219,34 +219,26 @@ class CityInfo {
|
|||
return 0
|
||||
}
|
||||
|
||||
fun isGrowing(): Boolean {
|
||||
return foodForNextTurn() > 0 && cityConstructions.currentConstructionFromQueue != Constants.settler
|
||||
}
|
||||
fun isGrowing() = foodForNextTurn() > 0
|
||||
|
||||
fun isStarving(): Boolean = foodForNextTurn() < 0
|
||||
fun isStarving() = foodForNextTurn() < 0
|
||||
|
||||
private fun foodForNextTurn() = cityStats.currentCityStats.food.roundToInt()
|
||||
|
||||
/** Take null to mean infinity. */
|
||||
fun getNumTurnsToNewPopulation(): Int? {
|
||||
if (isGrowing()) {
|
||||
val roundedFoodPerTurn = foodForNextTurn().toFloat()
|
||||
val remainingFood = population.getFoodToNextPopulation() - population.foodStored
|
||||
var turnsToGrowth = ceil( remainingFood / roundedFoodPerTurn).toInt()
|
||||
if (turnsToGrowth < 1) turnsToGrowth = 1
|
||||
return turnsToGrowth
|
||||
}
|
||||
|
||||
return null
|
||||
if (!isGrowing()) return null
|
||||
val roundedFoodPerTurn = foodForNextTurn().toFloat()
|
||||
val remainingFood = population.getFoodToNextPopulation() - population.foodStored
|
||||
var turnsToGrowth = ceil( remainingFood / roundedFoodPerTurn).toInt()
|
||||
if (turnsToGrowth < 1) turnsToGrowth = 1
|
||||
return turnsToGrowth
|
||||
}
|
||||
|
||||
/** Take null to mean infinity. */
|
||||
fun getNumTurnsToStarvation(): Int? {
|
||||
if (isStarving()) {
|
||||
return population.foodStored / -foodForNextTurn() + 1
|
||||
}
|
||||
|
||||
return null
|
||||
if (!isStarving()) return null
|
||||
return population.foodStored / -foodForNextTurn() + 1
|
||||
}
|
||||
|
||||
fun containsBuildingUnique(unique:String) = cityConstructions.getBuiltBuildings().any { it.uniques.contains(unique) }
|
||||
|
|
|
@ -277,7 +277,7 @@ class CivilizationInfo {
|
|||
if (gameInfo.gameParameters.victoryTypes.contains(VictoryType.Scenario))
|
||||
return cities.isEmpty() && getCivUnits().none()
|
||||
else return cities.isEmpty() // No cities
|
||||
&& (citiesCreated > 0 || !getCivUnits().any { it.name == Constants.settler })
|
||||
&& (citiesCreated > 0 || !getCivUnits().any { it.hasUnique(Constants.settlerUnique) })
|
||||
}
|
||||
|
||||
fun getEra(): String {
|
||||
|
|
|
@ -137,8 +137,8 @@ class BaseUnit : INamed, IConstruction {
|
|||
if (uniques.contains("Requires Manhattan Project") && !civInfo.hasUnique("Enables nuclear weapon"))
|
||||
return "Requires Manhattan Project"
|
||||
if (requiredResource!=null && !civInfo.hasResource(requiredResource!!) && !civInfo.gameInfo.gameParameters.godMode) return "Consumes 1 [$requiredResource]"
|
||||
if (name == Constants.settler && civInfo.isCityState()) return "No settler for city-states"
|
||||
if (name == Constants.settler && civInfo.isOneCityChallenger()) return "No settler for players in One City Challenge"
|
||||
if (uniques.contains(Constants.settlerUnique) && civInfo.isCityState()) return "No settler for city-states"
|
||||
if (uniques.contains(Constants.settlerUnique) && civInfo.isOneCityChallenger()) return "No settler for players in One City Challenge"
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
|
@ -209,6 +209,7 @@ object TranslationFileWriter {
|
|||
RulesetCache.getBaseRuleset().tileImprovements.containsKey(parameter) -> "tileImprovement"
|
||||
RulesetCache.getBaseRuleset().tileResources.containsKey(parameter) -> "resource"
|
||||
RulesetCache.getBaseRuleset().technologies.containsKey(parameter) -> "tech"
|
||||
RulesetCache.getBaseRuleset().unitPromotions.containsKey(parameter) -> "promotion"
|
||||
RulesetCache.getBaseRuleset().buildings.containsKey(parameter)
|
||||
|| parameter == "Wonders" -> "building"
|
||||
|
||||
|
|
Loading…
Reference in a new issue