"Skip turn" automation (#12105)

* "Skip turn" automation

* Better descriptions for multiplayer games
This commit is contained in:
Yair Morgenstern 2024-08-14 09:48:23 +03:00 committed by GitHub
parent 5eb2d39d5c
commit e3ecab44ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 12 deletions

View File

@ -32,14 +32,16 @@ import kotlin.random.Random
object NextTurnAutomation { object NextTurnAutomation {
/** Top-level AI turn task list */ /** Top-level AI turn task list */
fun automateCivMoves(civInfo: Civilization) { fun automateCivMoves(civInfo: Civilization,
/** set false for 'forced' automation, such as skip turn */
tradeAndChangeState: Boolean = true) {
if (civInfo.isBarbarian) return BarbarianAutomation(civInfo).automate() if (civInfo.isBarbarian) return BarbarianAutomation(civInfo).automate()
if (civInfo.isSpectator()) return // When there's a spectator in multiplayer games, it's processed automatically, but shouldn't be able to actually do anything if (civInfo.isSpectator()) return // When there's a spectator in multiplayer games, it's processed automatically, but shouldn't be able to actually do anything
respondToPopupAlerts(civInfo) respondToPopupAlerts(civInfo)
TradeAutomation.respondToTradeRequests(civInfo) TradeAutomation.respondToTradeRequests(civInfo, tradeAndChangeState)
if (civInfo.isMajorCiv()) { if (tradeAndChangeState && civInfo.isMajorCiv()) {
if (!civInfo.gameInfo.ruleset.modOptions.hasUnique(UniqueType.DiplomaticRelationshipsCannotChange)) { if (!civInfo.gameInfo.ruleset.modOptions.hasUnique(UniqueType.DiplomaticRelationshipsCannotChange)) {
DiplomacyAutomation.declareWar(civInfo) DiplomacyAutomation.declareWar(civInfo)
DiplomacyAutomation.offerPeaceTreaty(civInfo) DiplomacyAutomation.offerPeaceTreaty(civInfo)
@ -56,21 +58,21 @@ object NextTurnAutomation {
issueRequests(civInfo) issueRequests(civInfo)
adoptPolicy(civInfo) // todo can take a second - why? adoptPolicy(civInfo) // todo can take a second - why?
freeUpSpaceResources(civInfo) freeUpSpaceResources(civInfo)
} else { } else if (civInfo.isCityState) {
civInfo.cityStateFunctions.getFreeTechForCityState() civInfo.cityStateFunctions.getFreeTechForCityState()
civInfo.cityStateFunctions.updateDiplomaticRelationshipForCityState() civInfo.cityStateFunctions.updateDiplomaticRelationshipForCityState()
} }
chooseTechToResearch(civInfo) chooseTechToResearch(civInfo)
automateCityBombardment(civInfo) automateCityBombardment(civInfo)
UseGoldAutomation.useGold(civInfo) if (tradeAndChangeState) UseGoldAutomation.useGold(civInfo)
if (!civInfo.isCityState) { if (tradeAndChangeState && !civInfo.isCityState) {
protectCityStates(civInfo) protectCityStates(civInfo)
bullyCityStates(civInfo) bullyCityStates(civInfo)
} }
automateUnits(civInfo) // this is the most expensive part automateUnits(civInfo) // this is the most expensive part
if (civInfo.isMajorCiv()) { if (tradeAndChangeState && civInfo.isMajorCiv()) {
if (civInfo.gameInfo.isReligionEnabled()) { if (civInfo.gameInfo.isReligionEnabled()) {
// Can only be done now, as the prophet first has to decide to found/enhance a religion // Can only be done now, as the prophet first has to decide to found/enhance a religion
ReligionAutomation.chooseReligiousBeliefs(civInfo) ReligionAutomation.chooseReligiousBeliefs(civInfo)
@ -82,7 +84,8 @@ object NextTurnAutomation {
} }
automateCities(civInfo) // second most expensive automateCities(civInfo) // second most expensive
trainSettler(civInfo) if (tradeAndChangeState) trainSettler(civInfo)
// I'm not sure what will happen if we *don't* vote when we can, so automate vote even when forced automation
tryVoteForDiplomaticVictory(civInfo) tryVoteForDiplomaticVictory(civInfo)
} }

View File

@ -17,10 +17,11 @@ import kotlin.math.min
object TradeAutomation { object TradeAutomation {
fun respondToTradeRequests(civInfo: Civilization) { fun respondToTradeRequests(civInfo: Civilization, tradeAndChangeState: Boolean) {
for (tradeRequest in civInfo.tradeRequests.toList()) { for (tradeRequest in civInfo.tradeRequests.toList()) {
val otherCiv = civInfo.gameInfo.getCivilization(tradeRequest.requestingCiv) val otherCiv = civInfo.gameInfo.getCivilization(tradeRequest.requestingCiv)
if (!TradeEvaluation().isTradeValid(tradeRequest.trade, civInfo, otherCiv)) // Treat 'no trade' state as if all trades are invalid - thus AIs will not update its "turns to offer"
if (!tradeAndChangeState || !TradeEvaluation().isTradeValid(tradeRequest.trade, civInfo, otherCiv))
continue continue
val tradeLogic = TradeLogic(civInfo, otherCiv) val tradeLogic = TradeLogic(civInfo, otherCiv)

View File

@ -8,6 +8,7 @@ import com.unciv.logic.multiplayer.MultiplayerGame
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.components.extensions.formatShort import com.unciv.ui.components.extensions.formatShort
import com.unciv.ui.components.extensions.toCheckBox import com.unciv.ui.components.extensions.toCheckBox
import com.unciv.ui.components.fonts.Fonts
import com.unciv.ui.popups.Popup import com.unciv.ui.popups.Popup
import com.unciv.ui.screens.basescreen.BaseScreen import com.unciv.ui.screens.basescreen.BaseScreen
import com.unciv.ui.screens.savescreens.LoadGameScreen import com.unciv.ui.screens.savescreens.LoadGameScreen
@ -35,7 +36,7 @@ object MultiplayerHelpers {
} }
} }
fun buildDescriptionText(multiplayerGame: MultiplayerGame): StringBuilder { fun buildDescriptionText(multiplayerGame: MultiplayerGame): String {
val descriptionText = StringBuilder() val descriptionText = StringBuilder()
val ex = multiplayerGame.error val ex = multiplayerGame.error
if (ex != null) { if (ex != null) {
@ -58,8 +59,17 @@ object MultiplayerHelpers {
val playerText = "{${preview.currentPlayer}}{ }({$playerDescriptor})" val playerText = "{${preview.currentPlayer}}{ }({$playerDescriptor})"
descriptionText.appendLine("Current Turn: [$playerText] since [${Duration.between(currentTurnStartTime, Instant.now()).formatShort()}] ago".tr()) descriptionText.appendLine("Current Turn: [$playerText] since [${Duration.between(currentTurnStartTime, Instant.now()).formatShort()}] ago".tr())
val playerCivName = preview.civilizations
.firstOrNull{ it.playerId == UncivGame.Current.settings.multiplayer.userId }?.civName ?: "Unknown"
descriptionText.appendLine("{$playerCivName}, ${preview.difficulty.tr()}, ${Fonts.turn}${preview.turns}")
descriptionText.appendLine("{Base ruleset:} ${preview.gameParameters.baseRuleset}")
if (preview.gameParameters.mods.isNotEmpty())
descriptionText.appendLine("{Mods:} " + preview.gameParameters.mods.joinToString())
} }
return descriptionText return descriptionText.toString().tr()
} }
fun showDropboxWarning(screen: BaseScreen) { fun showDropboxWarning(screen: BaseScreen) {