mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 06:16:37 -04:00
Solved "AI doesn't declare war" bug
This commit is contained in:
parent
fff22e66cd
commit
4876687e48
@ -10,6 +10,7 @@ import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
|||||||
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
||||||
import com.unciv.logic.map.BFS
|
import com.unciv.logic.map.BFS
|
||||||
import com.unciv.logic.map.MapUnit
|
import com.unciv.logic.map.MapUnit
|
||||||
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.logic.trade.*
|
import com.unciv.logic.trade.*
|
||||||
import com.unciv.models.ruleset.ModOptionsConstants
|
import com.unciv.models.ruleset.ModOptionsConstants
|
||||||
import com.unciv.models.ruleset.VictoryType
|
import com.unciv.models.ruleset.VictoryType
|
||||||
@ -200,7 +201,7 @@ object NextTurnAutomation {
|
|||||||
policyBranchPriority.indexOf(it.branch.name) else 10
|
policyBranchPriority.indexOf(it.branch.name) else 10
|
||||||
}
|
}
|
||||||
|
|
||||||
val preferredPolicies = policiesByPreference.minBy { it.key }!!.value
|
val preferredPolicies = policiesByPreference.minByOrNull { it.key }!!.value
|
||||||
|
|
||||||
val policyToAdopt = preferredPolicies.random()
|
val policyToAdopt = preferredPolicies.random()
|
||||||
civInfo.policies.adopt(policyToAdopt)
|
civInfo.policies.adopt(policyToAdopt)
|
||||||
@ -329,7 +330,7 @@ object NextTurnAutomation {
|
|||||||
val enemyCivs = civInfo.getKnownCivs()
|
val enemyCivs = civInfo.getKnownCivs()
|
||||||
.filterNot {
|
.filterNot {
|
||||||
it == civInfo || it.cities.isEmpty() || !civInfo.getDiplomacyManager(it).canDeclareWar()
|
it == civInfo || it.cities.isEmpty() || !civInfo.getDiplomacyManager(it).canDeclareWar()
|
||||||
|| (it.cities.none { civInfo.exploredTiles.contains(it.location) })
|
|| it.cities.none { civInfo.exploredTiles.contains(it.location) }
|
||||||
}
|
}
|
||||||
// If the AI declares war on a civ without knowing the location of any cities, it'll just keep amassing an army and not sending it anywhere,
|
// If the AI declares war on a civ without knowing the location of any cities, it'll just keep amassing an army and not sending it anywhere,
|
||||||
// and end up at a massive disadvantage
|
// and end up at a massive disadvantage
|
||||||
@ -338,7 +339,7 @@ object NextTurnAutomation {
|
|||||||
|
|
||||||
val civWithBestMotivationToAttack = enemyCivs
|
val civWithBestMotivationToAttack = enemyCivs
|
||||||
.map { Pair(it, motivationToAttack(civInfo, it)) }
|
.map { Pair(it, motivationToAttack(civInfo, it)) }
|
||||||
.maxBy { it.second }!!
|
.maxByOrNull { it.second }!!
|
||||||
|
|
||||||
if (civWithBestMotivationToAttack.second >= 20)
|
if (civWithBestMotivationToAttack.second >= 20)
|
||||||
civInfo.getDiplomacyManager(civWithBestMotivationToAttack.first).declareWar()
|
civInfo.getDiplomacyManager(civWithBestMotivationToAttack.first).declareWar()
|
||||||
@ -350,7 +351,13 @@ object NextTurnAutomation {
|
|||||||
if (theirCombatStrength > ourCombatStrength) return 0
|
if (theirCombatStrength > ourCombatStrength) return 0
|
||||||
|
|
||||||
|
|
||||||
val reachableEnemyCitiesBfs = BFS(civInfo.getCapital().getCenterTile()) { it.canCivEnter(civInfo) }
|
fun isTileCanMoveThrough(tileInfo: TileInfo): Boolean {
|
||||||
|
val owner = tileInfo.getOwner()
|
||||||
|
return !tileInfo.isImpassible()
|
||||||
|
&& (owner == otherCiv || owner == null || civInfo.canEnterTiles(owner))
|
||||||
|
}
|
||||||
|
|
||||||
|
val reachableEnemyCitiesBfs = BFS(civInfo.getCapital().getCenterTile()) { isTileCanMoveThrough(it) }
|
||||||
reachableEnemyCitiesBfs.stepToEnd()
|
reachableEnemyCitiesBfs.stepToEnd()
|
||||||
val reachableEnemyCities = otherCiv.cities.filter { reachableEnemyCitiesBfs.hasReachedTile(it.getCenterTile()) }
|
val reachableEnemyCities = otherCiv.cities.filter { reachableEnemyCitiesBfs.hasReachedTile(it.getCenterTile()) }
|
||||||
if (reachableEnemyCities.isEmpty()) return 0 // Can't even reach the enemy city, no point in war.
|
if (reachableEnemyCities.isEmpty()) return 0 // Can't even reach the enemy city, no point in war.
|
||||||
@ -375,9 +382,7 @@ object NextTurnAutomation {
|
|||||||
modifierMap["Far away cities"] = -10
|
modifierMap["Far away cities"] = -10
|
||||||
|
|
||||||
val landPathBFS = BFS(ourCity.getCenterTile()) {
|
val landPathBFS = BFS(ourCity.getCenterTile()) {
|
||||||
val owner = it.getOwner()
|
it.isLand && isTileCanMoveThrough(it)
|
||||||
it.isLand && !it.isImpassible()
|
|
||||||
&& (owner == otherCiv || owner == null || civInfo.canEnterTiles(owner))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
landPathBFS.stepUntilDestination(theirCity.getCenterTile())
|
landPathBFS.stepUntilDestination(theirCity.getCenterTile())
|
||||||
@ -507,9 +512,9 @@ object NextTurnAutomation {
|
|||||||
currentConstruction is BaseUnit && currentConstruction.uniques.contains(Constants.settlerUnique)
|
currentConstruction is BaseUnit && currentConstruction.uniques.contains(Constants.settlerUnique)
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
val bestCity = civInfo.cities.maxBy { it.cityStats.currentCityStats.production }!!
|
val bestCity = civInfo.cities.maxByOrNull { it.cityStats.currentCityStats.production }!!
|
||||||
if (bestCity.cityConstructions.builtBuildings.size > 1) // 2 buildings or more, otherwise focus on self first
|
if (bestCity.cityConstructions.builtBuildings.size > 1) // 2 buildings or more, otherwise focus on self first
|
||||||
bestCity.cityConstructions.currentConstructionFromQueue = settlerUnits.minBy { it.cost }!!.name
|
bestCity.cityConstructions.currentConstructionFromQueue = settlerUnits.minByOrNull { it.cost }!!.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,6 +559,6 @@ object NextTurnAutomation {
|
|||||||
cityDistances += CityDistance(civ1city, civ2city,
|
cityDistances += CityDistance(civ1city, civ2city,
|
||||||
civ1city.getCenterTile().aerialDistanceTo(civ2city.getCenterTile()))
|
civ1city.getCenterTile().aerialDistanceTo(civ2city.getCenterTile()))
|
||||||
|
|
||||||
return cityDistances.minBy { it.aerialDistance }!!
|
return cityDistances.minByOrNull { it.aerialDistance }!!
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -502,7 +502,8 @@ open class TileInfo {
|
|||||||
if (!ruleset.terrains.containsKey(baseTerrain)) return "Base terrain $baseTerrain does not exist in ruleset!"
|
if (!ruleset.terrains.containsKey(baseTerrain)) return "Base terrain $baseTerrain does not exist in ruleset!"
|
||||||
if (terrainFeature != null && !ruleset.terrains.containsKey(terrainFeature)) return "Terrain feature $terrainFeature does not exist in ruleset!"
|
if (terrainFeature != null && !ruleset.terrains.containsKey(terrainFeature)) return "Terrain feature $terrainFeature does not exist in ruleset!"
|
||||||
if (resource != null && !ruleset.tileResources.containsKey(resource)) return "Resource $resource does not exist in ruleset!"
|
if (resource != null && !ruleset.tileResources.containsKey(resource)) return "Resource $resource does not exist in ruleset!"
|
||||||
if (improvement != null && !ruleset.tileImprovements.containsKey(improvement)) return "Improvement $improvement does not exist in ruleset!"
|
if (improvement != null && !improvement!!.startsWith("StartingLocation")
|
||||||
|
&& !ruleset.tileImprovements.containsKey(improvement)) return "Improvement $improvement does not exist in ruleset!"
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user