mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-13 01:08:25 +07:00
AI behaviour changes (#11839)
* AI behaviour changes * Update Automation.kt * Update Automation.kt * Update Automation.kt * Update Automation.kt * Update Automation.kt * Update ConstructionAutomation.kt * Update Automation.kt * Reverting some changes * Changes * revert changes * revert changes * revert changes * revert changes * Update CityLocationTileRanker.kt * Citizen assignment for stat conversion * Update CityLocationTileRanker.kt * Reduce AI settling * Avoid AI building units when in negative Supply * Update CityLocationTileRanker.kt * Update CityLocationTileRanker.kt * Update CityLocationTileRanker.kt * Update ConstructionAutomation.kt * Update build.gradle.kts * Update gradle-wrapper.properties * Update CityLocationTileRanker.kt * Update CityLocationTileRanker.kt * Update ConstructionAutomation.kt * Update CityLocationTileRanker.kt
This commit is contained in:
@ -9,6 +9,7 @@ import com.unciv.logic.map.mapunit.MapUnit
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.models.ruleset.Building
|
||||
import com.unciv.models.ruleset.INonPerpetualConstruction
|
||||
import com.unciv.models.ruleset.PerpetualConstruction
|
||||
import com.unciv.models.ruleset.Victory
|
||||
import com.unciv.models.ruleset.nation.PersonalityValue
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
@ -48,6 +49,9 @@ object Automation {
|
||||
val yieldStats = stats.clone()
|
||||
val civPersonality = city.civ.getPersonality()
|
||||
val cityStatsObj = city.cityStats
|
||||
val civInfo = city.civ
|
||||
val allTechsAreResearched = civInfo.gameInfo.ruleset.technologies.values
|
||||
.all { civInfo.tech.isResearched(it.name) || !civInfo.tech.canBeResearched(it.name)}
|
||||
|
||||
if (areWeRankingSpecialist) {
|
||||
// If you have the Food Bonus, count as 1 extra food production (base is 2food)
|
||||
@ -99,6 +103,21 @@ object Automation {
|
||||
|
||||
if (city.civ.getHappiness() < 0)
|
||||
yieldStats.happiness *= 2
|
||||
}
|
||||
|
||||
if (city.civ.getHappiness() < 0) {
|
||||
// 75% of excess food is wasted when in negative happiness
|
||||
yieldStats.food /= 4
|
||||
}
|
||||
|
||||
if (allTechsAreResearched) {
|
||||
// Science is useless at this point
|
||||
yieldStats.science *= 0
|
||||
}
|
||||
|
||||
if (city.cityConstructions.getCurrentConstruction() is PerpetualConstruction) {
|
||||
// With 4:1 conversion of production to gold, production is overvalued by a factor (12*4)/8 = 6
|
||||
yieldStats.production /= 6
|
||||
}
|
||||
|
||||
for (stat in Stat.values()) {
|
||||
|
@ -165,6 +165,8 @@ class ConstructionAutomation(val cityConstructions: CityConstructions) {
|
||||
|
||||
private fun addMilitaryUnitChoice() {
|
||||
if (!isAtWar && !cityIsOverAverageProduction) return // don't make any military units here. Infrastructure first!
|
||||
if (civInfo.stats.getUnitSupplyDeficit() > 0) return // we don't want more units if it's already hurting our empire
|
||||
// todo: add worker disbandment and consumption of great persons if under attack & short on unit supply
|
||||
if (!isAtWar && (civInfo.stats.statsForNextTurn.gold < 0 || militaryUnits > max(7, cities * 5))) return
|
||||
if (civInfo.gold < -50) return
|
||||
|
||||
@ -263,6 +265,8 @@ class ConstructionAutomation(val cityConstructions: CityConstructions) {
|
||||
private fun addBuildingChoices() {
|
||||
for (building in buildings.filterBuildable()) {
|
||||
if (building.isWonder && city.isPuppet) continue
|
||||
// We shouldn't try to build wonders in undeveloped empires
|
||||
if (building.isWonder && civInfo.cities.size < 3) continue
|
||||
addChoice(relativeCostEffectiveness, building.name, getValueOfBuilding(building))
|
||||
}
|
||||
}
|
||||
|
@ -84,11 +84,17 @@ object CityLocationTileRanker {
|
||||
tileValue += getDistanceToCityModifier(newCityTile, nearbyCities, civ)
|
||||
|
||||
val onCoast = newCityTile.isCoastalTile()
|
||||
val onHill = newCityTile.isHill()
|
||||
val isNextToMountain = newCityTile.isAdjacentTo("Mountain")
|
||||
// Only count a luxary resource that we don't have yet as unique once
|
||||
val newUniqueLuxuryResources = HashSet<String>()
|
||||
|
||||
if (onCoast) tileValue += 8
|
||||
if (newCityTile.isAdjacentToRiver()) tileValue += 10
|
||||
if (onCoast) tileValue += 3
|
||||
// Hills are free production and defence
|
||||
if (onHill) tileValue += 7
|
||||
// Observatories are good, but current implementation no mod-friendly
|
||||
if (isNextToMountain) tileValue += 5
|
||||
if (newCityTile.isAdjacentToRiver()) tileValue += 14
|
||||
if (newCityTile.terrainHasUnique(UniqueType.FreshWater)) tileValue += 5
|
||||
// We want to found the city on an oasis because it can't be improved otherwise
|
||||
if (newCityTile.terrainHasUnique(UniqueType.Unbuildable)) tileValue += 3
|
||||
@ -118,25 +124,15 @@ object CityLocationTileRanker {
|
||||
// If it is not higher the settler may get stuck when it ranks the same tile differently
|
||||
// as it moves away from the city and doesn't include it in the calculation
|
||||
// and values it higher than when it moves closer to the city
|
||||
distanceToCity == 7 -> 5f // Perfect location, there aren't any unused tiles in between
|
||||
distanceToCity == 6 -> -4f
|
||||
distanceToCity == 5 -> -8f
|
||||
distanceToCity == 4 -> -20f
|
||||
distanceToCity == 7 -> 2f
|
||||
distanceToCity == 6 -> 4f
|
||||
distanceToCity == 5 -> 8f // Settling further away sacrifices tempo
|
||||
distanceToCity == 4 -> 6f
|
||||
distanceToCity == 3 -> -25f
|
||||
distanceToCity < 3 -> -30f // Even if it is a mod that lets us settle closer, lets still not do it
|
||||
else -> 0f
|
||||
}
|
||||
// Bigger cities will expand more so we want to stay away from them
|
||||
// Reduces the chance that we don't settle at the begining
|
||||
distanceToCityModifier *= when {
|
||||
city.population.population >= 12 -> 2f
|
||||
city.population.population >= 8 -> 1.5f
|
||||
city.population.population >= 3 -> 1.2f
|
||||
else -> 1f
|
||||
}
|
||||
// It is worse to settle cities near our own compare to near another civ
|
||||
// Do not settle near our capital unless really necessary
|
||||
// Having a strong capital is esential to constructing wonders
|
||||
// We want a defensive ring around our capital
|
||||
if (city.civ == civ) distanceToCityModifier *= if (city.isCapital()) 2 else 1
|
||||
modifier += distanceToCityModifier
|
||||
}
|
||||
|
Reference in New Issue
Block a user