Make AI diplomatic marriage safe from concurrent modification issues (#9244)

This commit is contained in:
SomeTroglodyte
2023-04-21 16:16:52 +02:00
committed by GitHub
parent a3de63efbe
commit cafcbbad4b

View File

@ -290,38 +290,44 @@ object NextTurnAutomation {
return return
} }
/** allow AI to spend money to purchase city-state friendship, buildings & unit */ private fun useGoldForCityStates(civ: Civilization) {
private fun useGold(civInfo: Civilization) { val knownCityStates = civ.getKnownCivs().filter { it.isCityState() }
if (civInfo.getHappiness() > 0 && civInfo.hasUnique(UniqueType.CityStateCanBeBoughtForGold)) {
for (cityState in civInfo.getKnownCivs().filter { it.isCityState() } ) { // canBeMarriedBy checks actual cost, but it can't be below 500*speedmodifier, and the later check is expensive
if (cityState.cityStateFunctions.canBeMarriedBy(civInfo)) if (civ.gold >= 330 && civ.getHappiness() > 0 && civ.hasUnique(UniqueType.CityStateCanBeBoughtForGold)) {
cityState.cityStateFunctions.diplomaticMarriage(civInfo) for (cityState in knownCityStates.toList() ) { // Materialize sequence as diplomaticMarriage may kill a CS
if (civInfo.getHappiness() <= 0) break // Stop marrying if happiness is getting too low if (cityState.cityStateFunctions.canBeMarriedBy(civ))
cityState.cityStateFunctions.diplomaticMarriage(civ)
if (civ.getHappiness() <= 0) break // Stop marrying if happiness is getting too low
} }
} }
if (civInfo.wantsToFocusOn(Victory.Focus.Culture)) { if (civ.gold < 250) return // skip checks if tryGainInfluence will bail anyway
for (cityState in civInfo.getKnownCivs() if (civ.wantsToFocusOn(Victory.Focus.Culture)) {
.filter { it.isCityState() && it.cityStateFunctions.canProvideStat(Stat.Culture) }) { for (cityState in knownCityStates.filter { it.cityStateFunctions.canProvideStat(Stat.Culture) }) {
val diploManager = cityState.getDiplomacyManager(civInfo) val diploManager = cityState.getDiplomacyManager(civ)
if (diploManager.getInfluence() < 40) { // we want to gain influence with them if (diploManager.getInfluence() < 40) { // we want to gain influence with them
tryGainInfluence(civInfo, cityState) tryGainInfluence(civ, cityState)
} }
} }
} }
if (!civInfo.isCityState()) { if (civ.gold < 250 || knownCityStates.none()) return
val potentialAllies = civInfo.getKnownCivs().filter { it.isCityState() } val cityState = knownCityStates
if (potentialAllies.any()) { .filter { it.getAllyCiv() != civ.civName }
val cityState = .associateWith { valueCityStateAlliance(civ, it) }
potentialAllies.maxByOrNull { valueCityStateAlliance(civInfo, it) }!! .maxByOrNull { it.value }?.takeIf { it.value > 0 }?.key
if (cityState.getAllyCiv() != civInfo.civName && valueCityStateAlliance(civInfo, cityState) > 0) { if (cityState != null) {
tryGainInfluence(civInfo, cityState) tryGainInfluence(civ, cityState)
}
}
} }
}
for (city in civInfo.cities.sortedByDescending { it.population.population }) { /** allow AI to spend money to purchase city-state friendship, buildings & unit */
private fun useGold(civ: Civilization) {
if (civ.isMajorCiv())
useGoldForCityStates(civ)
for (city in civ.cities.sortedByDescending { it.population.population }) {
val construction = city.cityConstructions.getCurrentConstruction() val construction = city.cityConstructions.getCurrentConstruction()
if (construction is PerpetualConstruction) continue if (construction is PerpetualConstruction) continue
if ((construction as INonPerpetualConstruction).canBePurchasedWithStat(city, Stat.Gold) if ((construction as INonPerpetualConstruction).canBePurchasedWithStat(city, Stat.Gold)
@ -330,7 +336,7 @@ object NextTurnAutomation {
} }
} }
maybeBuyCityTiles(civInfo) maybeBuyCityTiles(civ)
} }
private fun maybeBuyCityTiles(civInfo: Civilization) { private fun maybeBuyCityTiles(civInfo: Civilization) {