Unified AI and Human gold purchase logic

This commit is contained in:
yairm210 2024-07-11 13:23:44 +03:00
parent 51dbb3e6ed
commit 075a5c70c7
4 changed files with 24 additions and 27 deletions

View File

@ -5,13 +5,11 @@ import com.unciv.logic.civilization.Civilization
import com.unciv.logic.map.BFS import com.unciv.logic.map.BFS
import com.unciv.logic.map.tile.Tile import com.unciv.logic.map.tile.Tile
import com.unciv.models.ruleset.INonPerpetualConstruction import com.unciv.models.ruleset.INonPerpetualConstruction
import com.unciv.models.ruleset.PerpetualConstruction
import com.unciv.models.ruleset.Victory import com.unciv.models.ruleset.Victory
import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.Stat import com.unciv.models.stats.Stat
import java.util.SortedMap import java.util.*
import java.util.TreeMap
object UseGoldAutomation { object UseGoldAutomation {
@ -23,12 +21,12 @@ object UseGoldAutomation {
for (city in civ.cities.sortedByDescending { it.population.population }) { 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 INonPerpetualConstruction) continue
if ((construction as INonPerpetualConstruction).canBePurchasedWithStat(city, Stat.Gold) val statBuyCost = construction.getStatBuyCost(city, Stat.Gold) ?: continue
&& city.civ.gold / 3 >= construction.getStatBuyCost(city, Stat.Gold)!!) { if (!city.cityConstructions.isConstructionPurchaseAllowed(construction, Stat.Gold, statBuyCost)) continue
if (civ.gold < statBuyCost / 3) continue
city.cityConstructions.purchaseConstruction(construction, 0, true) city.cityConstructions.purchaseConstruction(construction, 0, true)
} }
}
maybeBuyCityTiles(civ) maybeBuyCityTiles(civ)
} }

View File

@ -155,7 +155,7 @@ class CityConstructions : IsPartOfGameInfoSerialization {
if (buildable) if (buildable)
lines += (if (currentProgress == 0) "" else "$currentProgress/") + lines += (if (currentProgress == 0) "" else "$currentProgress/") +
"$cost${Fonts.production} $turnsToConstruction${Fonts.turn}" "$cost${Fonts.production} $turnsToConstruction${Fonts.turn}"
val otherStats = Stat.values().filter { val otherStats = Stat.entries.filter {
(it != Stat.Gold || !buildable) && // Don't show rush cost for consistency (it != Stat.Gold || !buildable) && // Don't show rush cost for consistency
construction.canBePurchasedWithStat(city, it) construction.canBePurchasedWithStat(city, it)
}.joinToString(" / ") { "${construction.getStatBuyCost(city, it)}${it.character}" } }.joinToString(" / ") { "${construction.getStatBuyCost(city, it)}${it.character}" }
@ -698,6 +698,20 @@ class CityConstructions : IsPartOfGameInfoSerialization {
return true return true
} }
/** This tests whether the buy button should be _enabled_ */
fun isConstructionPurchaseAllowed(construction: INonPerpetualConstruction, stat: Stat, constructionBuyCost: Int): Boolean {
return when {
city.isPuppet && !city.getMatchingUniques(UniqueType.MayBuyConstructionsInPuppets).any() -> false
city.isInResistance() -> false
!construction.isPurchasable(city.cityConstructions) -> false // checks via 'rejection reason'
construction is BaseUnit && !city.canPlaceNewUnit(construction) -> false
city.civ.gameInfo.gameParameters.godMode -> true
constructionBuyCost == 0 -> true
else -> city.getStatReserve(stat) >= constructionBuyCost
}
}
private fun removeCurrentConstruction() = removeFromQueue(0, true) private fun removeCurrentConstruction() = removeFromQueue(0, true)
fun chooseNextConstruction() { fun chooseNextConstruction() {

View File

@ -67,7 +67,6 @@ interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques {
} }
fun canBePurchasedWithAnyStat(city: City): Boolean { fun canBePurchasedWithAnyStat(city: City): Boolean {
return statsUsableToBuy.any { canBePurchasedWithStat(city, it) } return statsUsableToBuy.any { canBePurchasedWithStat(city, it) }
} }

View File

@ -644,7 +644,8 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
button.disable() button.disable()
buyButtonOnClick(construction, stat) buyButtonOnClick(construction, stat)
} }
button.isEnabled = isConstructionPurchaseAllowed(construction, stat, constructionBuyCost) button.isEnabled = cityScreen.canCityBeChanged() &&
city.cityConstructions.isConstructionPurchaseAllowed(construction, stat, constructionBuyCost)
preferredBuyStat = stat // Not very intelligent, but the least common currency "wins" preferredBuyStat = stat // Not very intelligent, but the least common currency "wins"
} }
@ -679,7 +680,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
if (!isConstructionPurchaseShown(construction, stat)) return if (!isConstructionPurchaseShown(construction, stat)) return
val city = cityScreen.city val city = cityScreen.city
val constructionStatBuyCost = construction.getStatBuyCost(city, stat)!! val constructionStatBuyCost = construction.getStatBuyCost(city, stat)!!
if (!isConstructionPurchaseAllowed(construction, stat, constructionStatBuyCost)) return if (!city.cityConstructions.isConstructionPurchaseAllowed(construction, stat, constructionStatBuyCost)) return
cityScreen.closeAllPopups() cityScreen.closeAllPopups()
ConfirmBuyPopup(construction, stat,constructionStatBuyCost, tile) ConfirmBuyPopup(construction, stat,constructionStatBuyCost, tile)
@ -728,21 +729,6 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
return construction.canBePurchasedWithStat(city, stat) return construction.canBePurchasedWithStat(city, stat)
} }
/** This tests whether the buy button should be _enabled_ */
private fun isConstructionPurchaseAllowed(construction: INonPerpetualConstruction, stat: Stat, constructionBuyCost: Int): Boolean {
val city = cityScreen.city
return when {
city.isPuppet && !city.getMatchingUniques(UniqueType.MayBuyConstructionsInPuppets).any() -> false
!cityScreen.canChangeState -> false
city.isInResistance() -> false
!construction.isPurchasable(city.cityConstructions) -> false // checks via 'rejection reason'
construction is BaseUnit && !city.canPlaceNewUnit(construction) -> false
city.civ.gameInfo.gameParameters.godMode -> true
constructionBuyCost == 0 -> true
else -> city.getStatReserve(stat) >= constructionBuyCost
}
}
/** Called only by askToBuyConstruction's Yes answer - not to be confused with [CityConstructions.purchaseConstruction] /** Called only by askToBuyConstruction's Yes answer - not to be confused with [CityConstructions.purchaseConstruction]
* @param tile supports [UniqueType.CreatesOneImprovement] * @param tile supports [UniqueType.CreatesOneImprovement]
*/ */