mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-10 07:16:54 +07:00
Initial AutoPlay implementation (#10315)
* AutoPlay initial hack * Removed extra changes * Added canceling AutoPlay and its own button * Victory screen showing up stops AutoPlay * Removed AutomateTurn for the spectator * Right Clicking AutoPlay Button starts AutoPlay immediately * Renamed NextTurnMenu to AutoPlayMenu * AutoPlay can now only begin on the players turn * Added specific unit actions AutoPlay * AutoPlay stops on VictoryScreen and GreatPersonPickerScreen * AutoPlay now stops when loading a new game * Hovering the mouse over the AutoPlayStatusButton now stops AutoPlay * Removed temporary right click NextTurnButton functionality * Removed multi-turn AutoPlay from multiplayer games * Loading a multiplayer game now stops AutoPlay * AutoPlayStatusButton persists over reloading WorldScreen * Victory popup now stops autoplay * AutoPlay now automatically picks great person * Full AutoPlay now captures cities * Added settings.isAutoPlaying and fixed bug with closing game in the middle of AutoPlaying a turn * AutoPlay now correctly stops when a victory screen is shown * AutoPlay now automates city constructions without autoAssignCityProduction being on * Reordered NextTurnAction * Removed extra condition for displaying AutoPlay text on next turn button * Moved AutoPlay settings to new tab * Changed AutoPlay slider * Refactored Settings to have AutoPlay to be in a new subclass * Added an show AutoPlay button setting, commented out unimplemented settings * Opening the exit game window stops autoPlay * Made cyclopedia entry * Added translations * AutoPlayStatusButton now ends with a new line * Commented out extra code and removed extra import statements * Fixed UncivSlider Change * Fixed merge conflicts * Settlers no longer stuck in endless loops wanting to found cities on tiles they can't reach @tuvus * Support for Leader voices (#10395) * Prepare Leader Voices: Framework * Leader Voices: Hooks and corresponding text field comments * Leader Voices: wiki * Leader Voices: oops, comments * Decouple voice play calls to make global modification easier * Move voices to own folder and give them a separate volume setting * Oops, template needed too * Oops, wiki needed too * Resolved #10366 - City centers don't provide resources you don't have tech to extract * Add a TriggerUponDiscoveringTile unique type (#10523) * Add a TriggerUponDiscoveringTile unique type * Add a check for trigger presence * Add gain stat modified by speed and improvement speed by filter uniques (#10443) * Add gain stat modified by speed and improvement speed by filter uniques * Fix rulesets * Remove nonfunctional leftover resource text * Reword improvement unqiue as suggested * Add the SellBuilding Unique (#10514) * Restored the SellBuilding Unique * Rephrased SellBuilding unique * Version rollout (#10530) * Bump version and create initial changelog entry * Update Brazilian_Portuguese.properties (#10528) * Update French.properties (#10524) * Update Italian.properties (#10522) * Update Polish.properties (#10521) * Update Polish.properties * Added Fastlane_short_description * Update Malay.properties (#10520) Translated line 33 to line 325. Not at all finished. This time though I didn't mess up. --------- Co-authored-by: yairm210 <yairm210@users.noreply.github.com> Co-authored-by: Vitor Gabriel <59321138+Ranbut@users.noreply.github.com> Co-authored-by: Ouaz <Ouaz@users.noreply.github.com> Co-authored-by: Giuseppe D'Addio <41149920+Smashfanful@users.noreply.github.com> Co-authored-by: Lesiakower <125187776+Lesiakower@users.noreply.github.com> Co-authored-by: Mikhail <151419244+MetaFBMI@users.noreply.github.com> * Better performance for 'best tile to found city' (minimized canReach calls) @tuvus * 4.9.0 * [Translation] Add back "general" unit types (#10526) * Add back "general" unit types These entries have been removed from translation files, making them untranslated in-game (in Civilopedia articles) * Revert changes in template.properties * Fix missing unit type translations Fix by @SomeTroglodyte * Changed some parts of GameSettings back to master. * Changed right clicking to call startAutoPlay instead of setting it itself * Fixed some !isHuman() conditions to also include full AutoPlay and refactored some other AutoPlay code --------- Co-authored-by: Yair Morgenstern <yairm210@hotmail.com> Co-authored-by: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Co-authored-by: Sergey <serdav74@inbox.ru> Co-authored-by: SeventhM <127357473+SeventhM@users.noreply.github.com> Co-authored-by: PLynx <pawelrys2011@gmail.com> Co-authored-by: yairm210 <yairm210@users.noreply.github.com> Co-authored-by: Vitor Gabriel <59321138+Ranbut@users.noreply.github.com> Co-authored-by: Ouaz <Ouaz@users.noreply.github.com> Co-authored-by: Giuseppe D'Addio <41149920+Smashfanful@users.noreply.github.com> Co-authored-by: Lesiakower <125187776+Lesiakower@users.noreply.github.com> Co-authored-by: Mikhail <151419244+MetaFBMI@users.noreply.github.com>
This commit is contained in:
parent
03698e47ef
commit
4b261a9257
@ -284,6 +284,17 @@
|
||||
"What you don't see: The phone/tablet's back button will pop the question whether you wish to leave Unciv and go back to Real Life. On desktop versions, you can use the ESC key."
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AutoPlay",
|
||||
"steps": ["When at later stages of the game, you might have a lot of units but only a little to do. To help you we have implemented an AutoPlay feature that lets you use the AI to play part or all of your turn.",
|
||||
"To enable AutoPlay, go to options and open the AutoPlay tab and press \"Show AutoPlay button\".",
|
||||
"Clicking on the AutoPlay button opens a popup menue for choosing to AutoPlay parts or all of your turn.",
|
||||
"Clicking Start AutoPlay in the pop-up menue or long pressing the AutoPlay button begins the multi-turn AutoPlay. This will play your next turns as if you were an AI.",
|
||||
"To cancel multi-turn AutoPlay you can press the AutoPlay button, next turn button or open the options menue.",
|
||||
"Multi-turn AutoPlay is not advised on harder difficulty levels as your AI will not play better against an AI with modifiers.",
|
||||
"Multi-turn AutoPlay for multiplayer is not yet supported."
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Faith",
|
||||
"steps": [
|
||||
|
@ -857,6 +857,16 @@ Hide =
|
||||
HIGHLY EXPERIMENTAL - YOU HAVE BEEN WARNED! =
|
||||
You need to restart the game for this change to take effect. =
|
||||
|
||||
# AutoPlay
|
||||
AutoPlay =
|
||||
Show AutoPlay button =
|
||||
Multi-turn AutoPlay amount =
|
||||
|
||||
Start AutoPlay =
|
||||
AutoPlay End Turn =
|
||||
AutoPlay Military Once =
|
||||
AutoPlay Civilians Once =
|
||||
AutoPlay Economy Once =
|
||||
|
||||
# Notifications
|
||||
|
||||
|
@ -292,6 +292,7 @@ open class UncivGame(val isConsoleMode: Boolean = false) : Game(), PlatformSpeci
|
||||
fun popScreen(): BaseScreen? {
|
||||
if (screenStack.size == 1) {
|
||||
musicController.pause()
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
ConfirmPopup(
|
||||
screen = screenStack.last(),
|
||||
question = "Do you want to exit the game?",
|
||||
|
@ -339,7 +339,7 @@ object NextTurnAutomation {
|
||||
for (unit in sortedUnits) UnitAutomation.automateUnitMoves(unit)
|
||||
}
|
||||
|
||||
private fun getUnitPriority(unit: MapUnit, isAtWar: Boolean): Int {
|
||||
fun getUnitPriority(unit: MapUnit, isAtWar: Boolean): Int {
|
||||
if (unit.isCivilian() && !unit.isGreatPersonOfType("War")) return 1 // Civilian
|
||||
if (unit.baseUnit.isAirUnit()) return 2
|
||||
val distance = if (!isAtWar) 0 else unit.civ.threatManager.getDistanceToClosestEnemyUnit(unit.getTile(),6)
|
||||
@ -356,7 +356,7 @@ object NextTurnAutomation {
|
||||
for (city in civInfo.cities) UnitAutomation.tryBombardEnemy(city)
|
||||
}
|
||||
|
||||
private fun automateCities(civInfo: Civilization) {
|
||||
fun automateCities(civInfo: Civilization) {
|
||||
val ownMilitaryStrength = civInfo.getStatForRanking(RankingType.Force)
|
||||
val sumOfEnemiesMilitaryStrength =
|
||||
civInfo.gameInfo.civilizations
|
||||
|
@ -125,8 +125,8 @@ object UnitAutomation {
|
||||
}
|
||||
|
||||
internal fun tryUpgradeUnit(unit: MapUnit): Boolean {
|
||||
val isHuman = unit.civ.isHuman()
|
||||
if (!UncivGame.Current.settings.automatedUnitsCanUpgrade && isHuman) return false
|
||||
if (unit.civ.isHuman() && (!UncivGame.Current.settings.automatedUnitsCanUpgrade
|
||||
|| UncivGame.Current.settings.autoPlay.isAutoPlayingAndFullAI())) return false
|
||||
if (unit.baseUnit.upgradesTo == null) return false
|
||||
val upgradedUnit = unit.upgrade.getUnitToUpgradeTo()
|
||||
if (!upgradedUnit.isBuildable(unit.civ)) return false // for resource reasons, usually
|
||||
|
@ -50,7 +50,8 @@ class WorkerAutomation(
|
||||
private val bestRoadAvailable: RoadStatus =
|
||||
cloningSource?.bestRoadAvailable ?:
|
||||
//Player can choose not to auto-build roads & railroads.
|
||||
if (civInfo.isHuman() && !UncivGame.Current.settings.autoBuildingRoads)
|
||||
if (civInfo.isHuman() && (!UncivGame.Current.settings.autoBuildingRoads
|
||||
|| UncivGame.Current.settings.autoPlay.isAutoPlayingAndFullAI()))
|
||||
RoadStatus.None
|
||||
else civInfo.tech.getBestRoadAvailable()
|
||||
|
||||
@ -340,11 +341,12 @@ class WorkerAutomation(
|
||||
|
||||
//If the tile is a junk improvement or a fort placed in a bad location.
|
||||
val junkImprovement = tile.getTileImprovement()?.hasUnique(UniqueType.AutomatedWorkersWillReplace) == true
|
||||
|| (tile.improvement == Constants.fort && !evaluateFortSuroundings(tile, false) && !civInfo.isHuman())
|
||||
|| (tile.improvement == Constants.fort && !evaluateFortSuroundings(tile, false)
|
||||
&& (!civInfo.isHuman() || UncivGame.Current.settings.autoPlay.isAutoPlayingAndFullAI()))
|
||||
|
||||
if (tile.improvement != null && !junkImprovement
|
||||
&& !UncivGame.Current.settings.automatedWorkersReplaceImprovements
|
||||
&& unit.civ.isHuman())
|
||||
&& unit.civ.isHuman() && !UncivGame.Current.settings.autoPlay.isAutoPlayingAndFullAI())
|
||||
return false
|
||||
|
||||
if (tile.improvement == null || junkImprovement) {
|
||||
|
@ -2,6 +2,7 @@ package com.unciv.logic.battle
|
||||
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.unciv.Constants
|
||||
import com.unciv.GUI
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.automation.civilization.NextTurnAutomation
|
||||
import com.unciv.logic.city.City
|
||||
@ -535,7 +536,7 @@ object Battle {
|
||||
city.puppetCity(attackerCiv)
|
||||
//Although in Civ5 Venice is unable to re-annex their capital, that seems a bit silly. No check for May not annex cities here.
|
||||
city.annexCity()
|
||||
} else if (attackerCiv.isHuman()) {
|
||||
} else if (attackerCiv.isHuman() && !(UncivGame.Current.settings.autoPlay.isAutoPlayingAndFullAI())) {
|
||||
// we're not taking our former capital
|
||||
attackerCiv.popupAlerts.add(PopupAlert(AlertType.CityConquered, city.id))
|
||||
} else automateCityConquer(attackerCiv, city)
|
||||
|
@ -697,7 +697,8 @@ class CityConstructions : IsPartOfGameInfoSerialization {
|
||||
|
||||
val isCurrentPlayersTurn = city.civ.gameInfo.isUsersTurn()
|
||||
|| !city.civ.gameInfo.gameParameters.isOnlineMultiplayer
|
||||
if ((UncivGame.Current.settings.autoAssignCityProduction && isCurrentPlayersTurn) // only automate if the active human player has the setting to automate production
|
||||
if ((isCurrentPlayersTurn && (UncivGame.Current.settings.autoAssignCityProduction
|
||||
|| UncivGame.Current.settings.autoPlay.isAutoPlayingAndFullAI())) // only automate if the active human player has the setting to automate production
|
||||
|| !city.civ.isHuman() || city.isPuppet) {
|
||||
ConstructionAutomation(this).chooseNextConstruction()
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ class DiplomacyFunctions(val civInfo: Civilization) {
|
||||
if (diplomacyManager != null && (diplomacyManager.hasOpenBorders || diplomacyManager.diplomaticStatus == DiplomaticStatus.War))
|
||||
return true
|
||||
// Players can always pass through city-state tiles
|
||||
if (civInfo.isHuman() && otherCiv.isCityState()) return true
|
||||
if ((civInfo.isHuman() && !UncivGame.Current.settings.autoPlay.isAutoPlayingAndFullAI()) && otherCiv.isCityState()) return true
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,7 @@ class OnlineMultiplayer {
|
||||
} else if (onlinePreview != null && hasNewerGameState(preview, onlinePreview)) {
|
||||
onlineGame.doManualUpdate(preview)
|
||||
}
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
UncivGame.Current.loadGame(gameInfo)
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,8 @@ class GameSettings {
|
||||
var androidHideSystemUi = true
|
||||
|
||||
var multiplayer = GameSettingsMultiplayer()
|
||||
|
||||
var autoPlay = GameSettingsAutoPlay()
|
||||
|
||||
var enableEspionageOption = false
|
||||
|
||||
@ -322,6 +324,35 @@ class GameSettings {
|
||||
}
|
||||
}
|
||||
|
||||
class GameSettingsAutoPlay {
|
||||
var showAutoPlayButton: Boolean = false
|
||||
var autoPlayMaxTurns = 10
|
||||
var fullAutoPlayAI: Boolean = true
|
||||
var autoPlayMilitary: Boolean = true
|
||||
var autoPlayCivilian: Boolean = true
|
||||
var autoPlayEconomy: Boolean = true
|
||||
var autoPlayTechnology: Boolean = true
|
||||
var autoPlayPolicies: Boolean = true
|
||||
var autoPlayReligion: Boolean = true
|
||||
var autoPlayDiplomacy: Boolean = true
|
||||
|
||||
var turnsToAutoPlay: Int = 0
|
||||
var autoPlayTurnInProgress: Boolean = false
|
||||
|
||||
fun startAutoPlay() {
|
||||
turnsToAutoPlay = autoPlayMaxTurns
|
||||
}
|
||||
|
||||
fun stopAutoPlay() {
|
||||
turnsToAutoPlay = 0
|
||||
autoPlayTurnInProgress = false
|
||||
}
|
||||
|
||||
fun isAutoPlaying(): Boolean = turnsToAutoPlay > 0
|
||||
|
||||
fun isAutoPlayingAndFullAI():Boolean = isAutoPlaying() && fullAutoPlayAI
|
||||
}
|
||||
|
||||
@Suppress("SuspiciousCallableReferenceInLambda") // By @Azzurite, safe as long as that warning below is followed
|
||||
enum class GameSetting(
|
||||
val kClass: KClass<*>,
|
||||
|
@ -209,7 +209,7 @@ object UniqueTriggerActivation {
|
||||
val greatPeople = civInfo.greatPeople.getGreatPeople()
|
||||
if (unique.type == UniqueType.MayanGainGreatPerson && civInfo.greatPeople.longCountGPPool.isEmpty())
|
||||
civInfo.greatPeople.longCountGPPool = greatPeople.map { it.name }.toHashSet()
|
||||
if (civInfo.isHuman()) {
|
||||
if (civInfo.isHuman() && !UncivGame.Current.settings.autoPlay.isAutoPlayingAndFullAI()) {
|
||||
civInfo.greatPeople.freeGreatPeople++
|
||||
// Anyone an idea for a good icon?
|
||||
if (unique.type == UniqueType.MayanGainGreatPerson) {
|
||||
|
91
core/src/com/unciv/ui/popups/options/AutoPlayTab.kt
Normal file
91
core/src/com/unciv/ui/popups/options/AutoPlayTab.kt
Normal file
@ -0,0 +1,91 @@
|
||||
package com.unciv.ui.popups.options
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.models.metadata.GameSettings
|
||||
import com.unciv.ui.components.widgets.UncivSlider
|
||||
import com.unciv.ui.components.extensions.toLabel
|
||||
import com.unciv.ui.screens.basescreen.BaseScreen
|
||||
|
||||
fun autoPlayTab(
|
||||
optionsPopup: OptionsPopup
|
||||
): Table = Table(BaseScreen.skin).apply {
|
||||
pad(10f)
|
||||
defaults().pad(5f)
|
||||
|
||||
val settings = optionsPopup.settings
|
||||
// fun addAutoPlaySections() {
|
||||
// optionsPopup.addCheckbox(
|
||||
// this,
|
||||
// "AutoPlay Military",
|
||||
// settings.autoPlay.autoPlayMilitary, false
|
||||
// ) { settings.autoPlay.autoPlayMilitary = it }
|
||||
// optionsPopup.addCheckbox(
|
||||
// this,
|
||||
// "AutoPlay Civilian",
|
||||
// settings.autoPlay.autoPlayCivilian, false
|
||||
// ) { settings.autoPlay.autoPlayCivilian = it }
|
||||
// optionsPopup.addCheckbox(
|
||||
// this,
|
||||
// "AutoPlay Economy",
|
||||
// settings.autoPlay.autoPlayEconomy, false
|
||||
// ) { settings.autoPlay.autoPlayEconomy = it }
|
||||
// optionsPopup.addCheckbox(
|
||||
// this,
|
||||
// "AutoPlay Diplomacy",
|
||||
// settings.autoPlay.autoPlayDiplomacy, false
|
||||
// ) { settings.autoPlay.autoPlayDiplomacy = it }
|
||||
// optionsPopup.addCheckbox(
|
||||
// this,
|
||||
// "AutoPlay Technology",
|
||||
// settings.autoPlay.autoPlayTechnology, false
|
||||
// ) { settings.autoPlay.autoPlayTechnology = it }
|
||||
// optionsPopup.addCheckbox(
|
||||
// this,
|
||||
// "AutoPlay Policies",
|
||||
// settings.autoPlay.autoPlayPolicies, false
|
||||
// ) { settings.autoPlay.autoPlayPolicies = it }
|
||||
// optionsPopup.addCheckbox(
|
||||
// this,
|
||||
// "AutoPlay Religion",
|
||||
// settings.autoPlay.autoPlayReligion, false
|
||||
// ) { settings.autoPlay.autoPlayReligion = it }
|
||||
// }
|
||||
|
||||
optionsPopup.addCheckbox(
|
||||
this,
|
||||
"Show AutoPlay button",
|
||||
settings.autoPlay.showAutoPlayButton, true
|
||||
) { settings.autoPlay.showAutoPlayButton = it
|
||||
settings.autoPlay.stopAutoPlay() }
|
||||
|
||||
|
||||
addAutoPlayMaxTurnsSlider(this, settings, optionsPopup.selectBoxMinWidth)
|
||||
// optionsPopup.addCheckbox(
|
||||
// this,
|
||||
// "Full AutoPlay AI",
|
||||
// settings.autoPlay.fullAutoPlayAI, false
|
||||
// ) { settings.autoPlay.fullAutoPlayAI = it
|
||||
// if (!it) addAutoPlaySections()
|
||||
// else optionsPopup.tabs.replacePage(optionsPopup.tabs.activePage, autoPlayTab(optionsPopup))
|
||||
// }
|
||||
// if (!settings.autoPlay.fullAutoPlayAI)
|
||||
// addAutoPlaySections()
|
||||
}
|
||||
|
||||
private fun addAutoPlayMaxTurnsSlider(
|
||||
table: Table,
|
||||
settings: GameSettings,
|
||||
selectBoxMinWidth: Float
|
||||
) {
|
||||
table.add("Multi-turn AutoPlay amount".toLabel()).left().fillX()
|
||||
|
||||
val minimapSlider = UncivSlider(
|
||||
1f, 200f, 1f,
|
||||
initial = settings.autoPlay.autoPlayMaxTurns.toFloat()
|
||||
) {
|
||||
val turns = it.toInt()
|
||||
settings.autoPlay.autoPlayMaxTurns = turns
|
||||
}
|
||||
table.add(minimapSlider).minWidth(selectBoxMinWidth).pad(10f).row()
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import com.unciv.ui.screens.basescreen.BaseScreen
|
||||
|
||||
fun gameplayTab(
|
||||
optionsPopup: OptionsPopup
|
||||
) = Table(BaseScreen.skin).apply {
|
||||
): Table = Table(BaseScreen.skin).apply {
|
||||
pad(10f)
|
||||
defaults().pad(5f)
|
||||
|
||||
|
@ -88,6 +88,11 @@ class OptionsPopup(
|
||||
gameplayTab(this),
|
||||
ImageGetter.getImage("OtherIcons/Options"), 24f
|
||||
)
|
||||
tabs.addPage(
|
||||
"AutoPlay",
|
||||
autoPlayTab(this),
|
||||
ImageGetter.getImage("OtherIcons/NationSwap"), 24f
|
||||
)
|
||||
tabs.addPage(
|
||||
"Language",
|
||||
LanguageTab(this, ::reloadWorldAndOptions),
|
||||
|
@ -14,6 +14,7 @@ class GreatPersonPickerScreen(val civInfo:Civilization) : PickerScreen() {
|
||||
private var theChosenOne: BaseUnit? = null
|
||||
|
||||
init {
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
closeButton.isVisible = false
|
||||
rightSideButton.setText("Choose a free great person".tr())
|
||||
|
||||
|
@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.badlogic.gdx.utils.SerializationException
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.MissingModsException
|
||||
import com.unciv.logic.UncivShowableException
|
||||
import com.unciv.logic.files.PlatformSaverLoader
|
||||
@ -121,6 +122,7 @@ class LoadGameScreen : LoadOrSaveScreen() {
|
||||
}
|
||||
|
||||
private fun onLoadGame() {
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
if (selectedSave == null) return
|
||||
val loadingPopup = LoadingPopup(this)
|
||||
Concurrency.run(loadGame) {
|
||||
|
@ -35,6 +35,7 @@ object QuickSave {
|
||||
}
|
||||
|
||||
fun load(screen: WorldScreen) {
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
val files = UncivGame.Current.files
|
||||
val toast = ToastPopup("Quickloading...", screen)
|
||||
Concurrency.run("QuickLoadGame") {
|
||||
@ -57,6 +58,7 @@ object QuickSave {
|
||||
}
|
||||
|
||||
fun autoLoadGame(screen: MainMenuScreen) {
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
val loadingPopup = LoadingPopup(screen)
|
||||
Concurrency.run("autoLoadGame") {
|
||||
// Load game from file to class on separate thread to avoid ANR...
|
||||
|
@ -85,6 +85,7 @@ class VictoryScreen(
|
||||
}
|
||||
|
||||
init {
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
//**************** Set up the tabs ****************
|
||||
splitPane.setFirstWidget(tabs)
|
||||
val iconSize = Constants.headingFontSize.toFloat()
|
||||
@ -158,6 +159,7 @@ class VictoryScreen(
|
||||
displayWonOrLost("[$winningCiv] has won a [$victoryType] Victory!", victory.defeatString)
|
||||
music.chooseTrack(playerCiv.civName, MusicMood.Defeat, EnumSet.of(MusicTrackChooserFlags.SuffixMustMatch))
|
||||
}
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
}
|
||||
|
||||
private fun displayWonOrLost(vararg descriptions: String) {
|
||||
|
@ -11,6 +11,7 @@ import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.UncivShowableException
|
||||
import com.unciv.logic.civilization.AlertType
|
||||
import com.unciv.logic.civilization.Civilization
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||
@ -58,6 +59,7 @@ import com.unciv.ui.screens.worldscreen.bottombar.BattleTable
|
||||
import com.unciv.ui.screens.worldscreen.bottombar.TileInfoTable
|
||||
import com.unciv.ui.screens.worldscreen.mainmenu.WorldScreenMusicPopup
|
||||
import com.unciv.ui.screens.worldscreen.minimap.MinimapHolder
|
||||
import com.unciv.ui.screens.worldscreen.status.AutoPlayStatusButton
|
||||
import com.unciv.ui.screens.worldscreen.status.MultiplayerStatusButton
|
||||
import com.unciv.ui.screens.worldscreen.status.NextTurnButton
|
||||
import com.unciv.ui.screens.worldscreen.status.NextTurnProgress
|
||||
@ -92,7 +94,7 @@ class WorldScreen(
|
||||
/** Indicates it's the player's ([viewingCiv]) turn */
|
||||
var isPlayersTurn = viewingCiv.isCurrentPlayer()
|
||||
internal set // only this class is allowed to make changes
|
||||
|
||||
|
||||
/** Selected civilization, used in spectator and replay mode, equals viewingCiv in ordinary games */
|
||||
var selectedCiv = viewingCiv
|
||||
|
||||
@ -412,7 +414,13 @@ class WorldScreen(
|
||||
fogOfWarButton.isEnabled = !selectedCiv.isSpectator()
|
||||
fogOfWarButton.setPosition(10f, topBar.y - fogOfWarButton.height - 10f)
|
||||
|
||||
if (!hasOpenPopups() && isPlayersTurn) {
|
||||
// If the game has ended, lets stop AutoPlay
|
||||
if (game.settings.autoPlay.isAutoPlaying()
|
||||
&& !gameInfo.oneMoreTurnMode && (viewingCiv.isDefeated() || gameInfo.checkForVictory())) {
|
||||
game.settings.autoPlay.stopAutoPlay()
|
||||
}
|
||||
|
||||
if (!hasOpenPopups() && !game.settings.autoPlay.isAutoPlaying() && isPlayersTurn) {
|
||||
when {
|
||||
viewingCiv.shouldShowDiplomaticVotingResults() ->
|
||||
UncivGame.Current.pushScreen(DiplomaticVoteResultScreen(gameInfo.diplomaticVictoryVotesCast, viewingCiv))
|
||||
@ -694,6 +702,7 @@ class WorldScreen(
|
||||
private fun updateGameplayButtons() {
|
||||
nextTurnButton.update()
|
||||
|
||||
updateAutoPlayStatusButton()
|
||||
updateMultiplayerStatusButton()
|
||||
|
||||
statusButtons.wrap(false)
|
||||
@ -707,6 +716,18 @@ class WorldScreen(
|
||||
statusButtons.setPosition(stage.width - statusButtons.width - 10f, topBar.y - statusButtons.height - 10f)
|
||||
}
|
||||
|
||||
private fun updateAutoPlayStatusButton() {
|
||||
if (statusButtons.autoPlayStatusButton == null) {
|
||||
if (game.settings.autoPlay.showAutoPlayButton)
|
||||
statusButtons.autoPlayStatusButton = AutoPlayStatusButton(this, nextTurnButton)
|
||||
} else {
|
||||
if (!game.settings.autoPlay.showAutoPlayButton) {
|
||||
statusButtons.autoPlayStatusButton = null
|
||||
game.settings.autoPlay.stopAutoPlay()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateMultiplayerStatusButton() {
|
||||
if (gameInfo.gameParameters.isOnlineMultiplayer || game.settings.multiplayer.statusButtonInSinglePlayer) {
|
||||
if (statusButtons.multiplayerStatusButton != null) return
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.unciv.ui.screens.worldscreen.mainmenu
|
||||
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.ui.components.input.KeyboardBinding
|
||||
import com.unciv.ui.components.input.onLongPress
|
||||
import com.unciv.ui.popups.Popup
|
||||
@ -10,6 +11,7 @@ import com.unciv.ui.screens.worldscreen.WorldScreen
|
||||
|
||||
class WorldScreenMenuPopup(val worldScreen: WorldScreen) : Popup(worldScreen, scrollable = Scrollability.All) {
|
||||
init {
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
defaults().fillX()
|
||||
|
||||
addButton("Main menu") {
|
||||
|
@ -0,0 +1,81 @@
|
||||
package com.unciv.ui.popups
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.GUI
|
||||
import com.unciv.logic.automation.civilization.NextTurnAutomation
|
||||
import com.unciv.logic.automation.unit.UnitAutomation
|
||||
import com.unciv.logic.civilization.managers.TurnManager
|
||||
import com.unciv.ui.components.input.KeyboardBinding
|
||||
import com.unciv.ui.screens.worldscreen.WorldScreen
|
||||
import com.unciv.ui.screens.worldscreen.status.NextTurnButton
|
||||
|
||||
//todo Check move/top/end for "place one improvement" buildings
|
||||
//todo Check add/remove-all for "place one improvement" buildings
|
||||
|
||||
/**
|
||||
* Adds a number of options
|
||||
*/
|
||||
class AutoPlayMenu(
|
||||
stage: Stage,
|
||||
positionNextTo: Actor,
|
||||
private val nextTurnButton: NextTurnButton,
|
||||
private val worldScreen: WorldScreen
|
||||
) : AnimatedMenuPopup(stage, getActorTopRight(positionNextTo)) {
|
||||
private val settings = GUI.getSettings()
|
||||
|
||||
init {
|
||||
closeListeners.add {
|
||||
}
|
||||
}
|
||||
|
||||
override fun createContentTable(): Table? {
|
||||
val table = super.createContentTable()!!
|
||||
if (!worldScreen.gameInfo.gameParameters.isOnlineMultiplayer)
|
||||
table.add(getButton("Start AutoPlay", KeyboardBinding.RaisePriority, ::autoPlay)).row()
|
||||
table.add(getButton("AutoPlay End Turn", KeyboardBinding.RaisePriority, ::autoPlayEndTurn)).row()
|
||||
table.add(getButton("AutoPlay Military Once", KeyboardBinding.RaisePriority, ::autoPlayMilitary)).row()
|
||||
table.add(getButton("AutoPlay Civilians Once", KeyboardBinding.RaisePriority, ::autoPlayCivilian)).row()
|
||||
table.add(getButton("AutoPlay Economy Once", KeyboardBinding.RaisePriority, ::autoPlayEconomy)).row()
|
||||
|
||||
return table.takeUnless { it.cells.isEmpty }
|
||||
}
|
||||
|
||||
private fun autoPlayEndTurn() {
|
||||
TurnManager(worldScreen.viewingCiv).automateTurn()
|
||||
worldScreen.nextTurn()
|
||||
}
|
||||
|
||||
private fun autoPlay() {
|
||||
settings.autoPlay.startAutoPlay()
|
||||
nextTurnButton.update()
|
||||
}
|
||||
|
||||
private fun autoPlayMilitary() {
|
||||
val civInfo = worldScreen.viewingCiv
|
||||
val isAtWar = civInfo.isAtWar()
|
||||
val sortedUnits = civInfo.units.getCivUnits().filter { it.isMilitary() }.sortedBy { unit -> NextTurnAutomation.getUnitPriority(unit, isAtWar) }
|
||||
for (unit in sortedUnits) UnitAutomation.automateUnitMoves(unit)
|
||||
|
||||
for (city in civInfo.cities) UnitAutomation.tryBombardEnemy(city)
|
||||
worldScreen.shouldUpdate = true
|
||||
worldScreen.render(0f)
|
||||
}
|
||||
|
||||
private fun autoPlayCivilian() {
|
||||
val civInfo = worldScreen.viewingCiv
|
||||
val isAtWar = civInfo.isAtWar()
|
||||
val sortedUnits = civInfo.units.getCivUnits().filter { it.isCivilian() }.sortedBy { unit -> NextTurnAutomation.getUnitPriority(unit, isAtWar) }
|
||||
for (unit in sortedUnits) UnitAutomation.automateUnitMoves(unit)
|
||||
worldScreen.shouldUpdate = true
|
||||
worldScreen.render(0f)
|
||||
}
|
||||
|
||||
private fun autoPlayEconomy() {
|
||||
val civInfo = worldScreen.viewingCiv
|
||||
NextTurnAutomation.automateCities(civInfo)
|
||||
worldScreen.shouldUpdate = true
|
||||
worldScreen.render(0f)
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.unciv.ui.screens.worldscreen.status
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Button
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Stack
|
||||
import com.badlogic.gdx.utils.Disposable
|
||||
import com.unciv.GUI
|
||||
import com.unciv.ui.components.extensions.setSize
|
||||
import com.unciv.ui.components.input.onClick
|
||||
import com.unciv.ui.components.input.onRightClick
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.popups.AutoPlayMenu
|
||||
import com.unciv.ui.screens.basescreen.BaseScreen
|
||||
import com.unciv.ui.screens.worldscreen.WorldScreen
|
||||
|
||||
class AutoPlayStatusButton(
|
||||
val worldScreen: WorldScreen,
|
||||
nextTurnButton: NextTurnButton
|
||||
) : Button(BaseScreen.skin), Disposable {
|
||||
private val autoPlayImage = createAutoplayImage()
|
||||
|
||||
|
||||
init {
|
||||
add(Stack(autoPlayImage)).pad(5f)
|
||||
val settings = GUI.getSettings()
|
||||
onClick {
|
||||
if (settings.autoPlay.isAutoPlaying())
|
||||
settings.autoPlay.stopAutoPlay()
|
||||
else if (worldScreen.viewingCiv == worldScreen.gameInfo.currentPlayerCiv)
|
||||
AutoPlayMenu(stage,this, nextTurnButton, worldScreen)
|
||||
}
|
||||
onRightClick {
|
||||
if (!worldScreen.gameInfo.gameParameters.isOnlineMultiplayer
|
||||
&& worldScreen.viewingCiv == worldScreen.gameInfo.currentPlayerCiv) {
|
||||
settings.autoPlay.startAutoPlay()
|
||||
nextTurnButton.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createAutoplayImage(): Image {
|
||||
val img = ImageGetter.getImage("OtherIcons/NationSwap")
|
||||
img.setSize(40f)
|
||||
return img
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
val settings = GUI.getSettings()
|
||||
if (isPressed && settings.autoPlay.isAutoPlaying()) {
|
||||
settings.autoPlay.stopAutoPlay()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.unciv.ui.screens.worldscreen.status
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.civilization.managers.ReligionManager
|
||||
import com.unciv.logic.civilization.managers.ReligionState
|
||||
import com.unciv.models.Counter
|
||||
@ -24,6 +25,12 @@ enum class NextTurnAction(protected val text: String, val color: Color) {
|
||||
override val icon get() = null
|
||||
override fun isChoice(worldScreen: WorldScreen) = false
|
||||
},
|
||||
AutoPlay("AutoPlay", Color.WHITE) {
|
||||
override fun isChoice(worldScreen: WorldScreen) =
|
||||
UncivGame.Current.settings.autoPlay.isAutoPlaying()
|
||||
override fun action(worldScreen: WorldScreen) =
|
||||
UncivGame.Current.settings.autoPlay.stopAutoPlay()
|
||||
},
|
||||
Working(Constants.working, Color.GRAY) {
|
||||
override fun isChoice(worldScreen: WorldScreen) =
|
||||
worldScreen.isNextTurnUpdateRunning()
|
||||
@ -120,7 +127,7 @@ enum class NextTurnAction(protected val text: String, val color: Color) {
|
||||
},
|
||||
|
||||
;
|
||||
open val icon: String? get() = "NotificationIcons/$name"
|
||||
open val icon: String? get() = if (text != "AutoPlay") "NotificationIcons/$name" else "NotificationIcons/Working"
|
||||
open fun getText(worldScreen: WorldScreen) = text
|
||||
abstract fun isChoice(worldScreen: WorldScreen): Boolean
|
||||
open fun action(worldScreen: WorldScreen) {}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.unciv.ui.screens.worldscreen.status
|
||||
|
||||
import com.unciv.GUI
|
||||
import com.unciv.logic.civilization.managers.TurnManager
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.UncivTooltip.Companion.addTooltip
|
||||
import com.unciv.ui.components.extensions.isEnabled
|
||||
@ -16,7 +18,6 @@ class NextTurnButton(
|
||||
private val worldScreen: WorldScreen
|
||||
) : IconTextButton("", null, 30) {
|
||||
private var nextTurnAction = NextTurnAction.Default
|
||||
|
||||
init {
|
||||
// label.setFontSize(30)
|
||||
labelCell.pad(10f)
|
||||
@ -30,10 +31,20 @@ class NextTurnButton(
|
||||
fun update() {
|
||||
nextTurnAction = getNextTurnAction(worldScreen)
|
||||
updateButton(nextTurnAction)
|
||||
|
||||
isEnabled = !worldScreen.hasOpenPopups() && worldScreen.isPlayersTurn
|
||||
&& !worldScreen.waitingForAutosave && !worldScreen.isNextTurnUpdateRunning()
|
||||
|
||||
val settings = GUI.getSettings()
|
||||
if (!settings.autoPlay.autoPlayTurnInProgress && settings.autoPlay.isAutoPlaying()
|
||||
&& worldScreen.isPlayersTurn && !worldScreen.waitingForAutosave && !worldScreen.isNextTurnUpdateRunning()) {
|
||||
settings.autoPlay.autoPlayTurnInProgress = true
|
||||
if (!worldScreen.viewingCiv.isSpectator())
|
||||
TurnManager(worldScreen.viewingCiv).automateTurn()
|
||||
worldScreen.nextTurn()
|
||||
settings.autoPlay.turnsToAutoPlay--
|
||||
settings.autoPlay.autoPlayTurnInProgress = false
|
||||
}
|
||||
|
||||
isEnabled = nextTurnAction.getText (worldScreen) == "AutoPlay"
|
||||
|| (!worldScreen.hasOpenPopups() && worldScreen.isPlayersTurn
|
||||
&& !worldScreen.waitingForAutosave && !worldScreen.isNextTurnUpdateRunning())
|
||||
if (isEnabled) addTooltip(KeyboardBinding.NextTurn) else addTooltip("")
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.GUI
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.metadata.GameParameters
|
||||
import com.unciv.ui.components.extensions.disable
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
@ -97,7 +98,9 @@ class NextTurnProgress(
|
||||
// On first update the button text is not yet updated. To stabilize geometry, do it now
|
||||
if (progress == 0) nextTurnButton?.apply {
|
||||
disable()
|
||||
updateButton(NextTurnAction.Working)
|
||||
if (UncivGame.Current.settings.autoPlay.isAutoPlaying())
|
||||
updateButton(NextTurnAction.AutoPlay)
|
||||
else updateButton(NextTurnAction.Working)
|
||||
barWidth = width - removeHorizontalPad -
|
||||
(background.leftWidth + background.rightWidth) // "cut off" the rounded parts of the button
|
||||
this@NextTurnProgress.setPosition((width - barWidth) / 2, barYPos)
|
||||
|
@ -5,8 +5,17 @@ import com.badlogic.gdx.utils.Disposable
|
||||
|
||||
class StatusButtons(
|
||||
nextTurnButton: NextTurnButton,
|
||||
autoPlayStatusButton: AutoPlayStatusButton? = null,
|
||||
multiplayerStatusButton: MultiplayerStatusButton? = null
|
||||
) : HorizontalGroup(), Disposable {
|
||||
var autoPlayStatusButton: AutoPlayStatusButton? = autoPlayStatusButton
|
||||
set(button) {
|
||||
autoPlayStatusButton?.remove()
|
||||
field = button
|
||||
if (button != null) {
|
||||
addActorAt(0, button)
|
||||
}
|
||||
}
|
||||
var multiplayerStatusButton: MultiplayerStatusButton? = multiplayerStatusButton
|
||||
set(button) {
|
||||
multiplayerStatusButton?.remove()
|
||||
@ -15,6 +24,7 @@ class StatusButtons(
|
||||
addActorAt(0, button)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
space(10f)
|
||||
@ -22,6 +32,9 @@ class StatusButtons(
|
||||
wrapReverse()
|
||||
wrapSpace(10f)
|
||||
rowRight()
|
||||
if (autoPlayStatusButton != null) {
|
||||
addActor(autoPlayStatusButton)
|
||||
}
|
||||
if (multiplayerStatusButton != null) {
|
||||
addActor(multiplayerStatusButton)
|
||||
}
|
||||
@ -29,6 +42,7 @@ class StatusButtons(
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
autoPlayStatusButton?.dispose()
|
||||
multiplayerStatusButton?.dispose()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user