mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-14 17:59:11 +07:00
Added Multiplayer Turn Notification Service (#1947)
* Added Multiplayer Turn Notification Service https://github.com/yairm210/Unciv/issues/1680 * Minor update on Credits.md (#1949) # Nations - Fix typo on word "crescent" - Fix link that flew off on word "sword" * 3.5.14-patch1 * Edit startgame screen. (#1950) Co-authored-by: u-ndefine <41176671+u-ndefine@users.noreply.github.com> * Small improvements suggested in pull request review https://github.com/yairm210/Unciv/pull/1947 * Removed potential concurrency hazzards caused by access to non-final variables. Added option to turn off persistent notification (may be necessary on pre-Oreo phones.) Added suggested comments. https://github.com/yairm210/Unciv/pull/1947 * Fixed miscommited debug code. https://github.com/yairm210/Unciv/pull/1947 Co-authored-by: u-ndefine <41176671+u-ndefine@users.noreply.github.com> Co-authored-by: Yair Morgenstern <yairm210@hotmail.com> Co-authored-by: lishaoxia1985 <49801619+lishaoxia1985@users.noreply.github.com>
This commit is contained in:
@ -14,6 +14,7 @@
|
||||
android:theme="@style/GdxTheme" >
|
||||
<activity
|
||||
android:name="com.unciv.app.AndroidLauncher"
|
||||
android:launchMode="singleTask"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="userLandscape"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
|
@ -1734,3 +1734,16 @@ Haka War Dance = Haka-Kriegstanz
|
||||
-10% combat strength for adjacent enemy units = -10% Kampfstärke für angrenzende feindliche Einheiten
|
||||
Rejuvenation = Verjüngung
|
||||
All healing effects doubled = Alle Heilungseffekte verdoppelt
|
||||
# Multiplayer Turn Checker Service
|
||||
An error has occured = Ein Fehler ist aufgetreten
|
||||
Multiplayer turn notifier service terminated = Multiplayer Zug Benachrichtigungsdienst wurde beendet
|
||||
Your friends are waiting on your turn. = Deine Freunde warten auf deinen Zug.
|
||||
Unciv - It's your turn! = Unciv - Du bist am Zug!
|
||||
Unciv will inform you when it's your turn. = Unciv wird dich benachrichtigen wenn du am Zug bist.
|
||||
Last checked: [lastTimeChecked]. Checks ca. every [checkPeriod] minute(s) when Internet available. = Zuletzt geprüft: [lastTimeChecked]. Prüft etwa alle [checkPeriod] Minute(n) wenn Internet vorhanden.
|
||||
Configurable in Unciv options menu. = Konfigurierbar im Unciv Optionsmenü.
|
||||
Unciv multiplayer turn notifier running = Unciv Multiplayer Zug Benachrichtiger läuft.
|
||||
Multiplayer options = Multiplayer Einstellungen
|
||||
Enable out-of-game turn notifications = Aktiviere Zug Benachrichtigungen außerhalb des Spiels
|
||||
Time between turn checks out-of-game (in minutes) = Intervall zwischen Zug Prüfungen (in Minuten)
|
||||
Show persistent notification for turn notifier service = Zeige persistente Benachrichtung für den Zug Benachrichtungsdienst
|
@ -1720,3 +1720,16 @@ Haka War Dance =
|
||||
-10% combat strength for adjacent enemy units =
|
||||
Rejuvenation =
|
||||
All healing effects doubled =
|
||||
# Multiplayer Turn Checker Service
|
||||
An error has occured =
|
||||
Multiplayer turn notifier service terminated =
|
||||
Your friends are waiting on your turn. =
|
||||
Unciv - It's your turn! =
|
||||
Unciv will inform you when it's your turn. =
|
||||
Last checked: [lastTimeChecked]. Checks ca. every [checkPeriod] minute(s) when Internet available. =
|
||||
Configurable in Unciv options menu. =
|
||||
Unciv multiplayer turn notifier running =
|
||||
Multiplayer options =
|
||||
Enable out-of-game turn notifications =
|
||||
Time between turn checks out-of-game (in minutes) =
|
||||
Show persistent notification for turn notifier service =
|
@ -27,6 +27,11 @@ android {
|
||||
archivesBaseName = "Unciv"
|
||||
}
|
||||
|
||||
// necessary for Android Work lib
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
|
||||
// Had to add this crap for Travis to build, it wanted to sign the app
|
||||
// but couldn't create the debug keystore for some reason
|
||||
|
||||
@ -116,6 +121,11 @@ task run(type: Exec) {
|
||||
commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.unciv.app/AndroidLauncher'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.core:core:1.2.0'
|
||||
implementation "androidx.work:work-runtime-ktx:2.3.1"
|
||||
}
|
||||
|
||||
// sets up the Android Eclipse project, using the old Ant based build.
|
||||
eclipse {
|
||||
// need to specify Java source sets explicitly, SpringSource Gradle Eclipse plugin
|
||||
|
@ -2,6 +2,8 @@ package com.unciv.app
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.work.WorkManager
|
||||
import com.badlogic.gdx.backends.android.AndroidApplication
|
||||
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration
|
||||
import com.unciv.UncivGame
|
||||
@ -10,6 +12,7 @@ import java.io.File
|
||||
class AndroidLauncher : AndroidApplication() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
createNotificationChannels()
|
||||
|
||||
// Only allow mods on KK+, to avoid READ_EXTERNAL_STORAGE permission earlier versions need
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
@ -23,6 +26,14 @@ class AndroidLauncher : AndroidApplication() {
|
||||
initialize(game, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Necessary for Multiplayer Turner Checker, starting with Android Oreo
|
||||
*/
|
||||
private fun createNotificationChannels() {
|
||||
MultiplayerTurnCheckWorker.createNotificationChannelInfo(context)
|
||||
MultiplayerTurnCheckWorker.createNotificationChannelService(context)
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies mods from external data directory (where users can access) to the private one (where
|
||||
* libGDX reads from). Note: deletes all files currently in the private mod directory and
|
||||
@ -43,4 +54,22 @@ class AndroidLauncher : AndroidApplication() {
|
||||
if (!externalModsDir.exists()) externalModsDir.mkdirs()
|
||||
externalModsDir.copyRecursively(internalModsDir)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
if (UncivGame.Current.settings.multiplayerTurnCheckerEnabled
|
||||
&& UncivGame.Current.isGameInfoInitialized()
|
||||
&& UncivGame.Current.gameInfo.gameParameters.isOnlineMultiplayer) {
|
||||
MultiplayerTurnCheckWorker.startTurnChecker(applicationContext, UncivGame.Current.gameInfo, UncivGame.Current.settings)
|
||||
}
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
WorkManager.getInstance(applicationContext).cancelAllWorkByTag(MultiplayerTurnCheckWorker.WORK_TAG)
|
||||
with(NotificationManagerCompat.from(this)) {
|
||||
cancel(MultiplayerTurnCheckWorker.NOTIFICATION_ID_INFO)
|
||||
cancel(MultiplayerTurnCheckWorker.NOTIFICATION_ID_SERVICE)
|
||||
}
|
||||
super.onResume()
|
||||
}
|
||||
}
|
235
android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt
Normal file
235
android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt
Normal file
@ -0,0 +1,235 @@
|
||||
package com.unciv.app
|
||||
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationCompat.DEFAULT_VIBRATE
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.work.*
|
||||
import com.badlogic.gdx.backends.android.AndroidApplication
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.models.metadata.GameSettings
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.worldscreen.mainmenu.OnlineMultiplayer
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParameters)
|
||||
: Worker(appContext, workerParams) {
|
||||
|
||||
companion object {
|
||||
const val WORK_TAG = "UNCIV_MULTIPLAYER_TURN_CHECKER_WORKER"
|
||||
const val NOTIFICATION_ID_SERVICE = 1
|
||||
const val NOTIFICATION_ID_INFO = 2
|
||||
private const val NOTIFICATION_CHANNEL_ID_INFO = "UNCIV_NOTIFICATION_CHANNEL_INFO"
|
||||
private const val NOTIFICATION_CHANNEL_ID_SERVICE = "UNCIV_NOTIFICATION_CHANNEL_SERVICE"
|
||||
|
||||
@Volatile private var failCount = 0
|
||||
@Volatile private var gameId = ""
|
||||
@Volatile private var userId = ""
|
||||
@Volatile private var configuredDelay = 5L
|
||||
@Volatile private var persistentNotificationEnabled = true
|
||||
|
||||
fun enqueue(appContext: Context, delayInMinutes: Long) {
|
||||
val constraints = Constraints.Builder()
|
||||
// If no internet is available, worker waits before becoming active.
|
||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||
.build()
|
||||
|
||||
val checkTurnWork = OneTimeWorkRequestBuilder<MultiplayerTurnCheckWorker>()
|
||||
.setConstraints(constraints)
|
||||
.setInitialDelay(delayInMinutes, TimeUnit.MINUTES)
|
||||
.addTag(WORK_TAG)
|
||||
.build()
|
||||
|
||||
WorkManager.getInstance(appContext).enqueue(checkTurnWork)
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Channel for 'It's your turn' and error notifications.
|
||||
*
|
||||
* This code is necessary for API level >= 26
|
||||
* API level < 26 does not support Notification Channels
|
||||
* For more infos: https://developer.android.com/training/notify-user/channels.html#CreateChannel
|
||||
*/
|
||||
fun createNotificationChannelInfo(appContext: Context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val name = "Unciv Multiplayer Turn Checker Alert"
|
||||
val descriptionText = "Informs you when it's your turn in multiplayer."
|
||||
val importance = NotificationManager.IMPORTANCE_HIGH
|
||||
val mChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID_INFO, name, importance)
|
||||
mChannel.description = descriptionText
|
||||
mChannel.setShowBadge(true)
|
||||
mChannel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
|
||||
val notificationManager = appContext.getSystemService(AndroidApplication.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationManager.createNotificationChannel(mChannel)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Channel for persistent service notification.
|
||||
*
|
||||
* This code is necessary for API level >= 26
|
||||
* API level < 26 does not support Notification Channels
|
||||
* For more infos: https://developer.android.com/training/notify-user/channels.html#CreateChannel
|
||||
*/
|
||||
fun createNotificationChannelService(appContext: Context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val name = "Unciv Multiplayer Turn Checker Persistent Status"
|
||||
val descriptionText = "Shown constantly to inform you about background checking."
|
||||
val importance = NotificationManager.IMPORTANCE_MIN
|
||||
val mChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID_SERVICE, name, importance)
|
||||
mChannel.description = descriptionText
|
||||
|
||||
val notificationManager = appContext.getSystemService(AndroidApplication.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationManager.createNotificationChannel(mChannel)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The persistent notification is purely for informational reasons.
|
||||
* It is not technically necessary for the Worker, since it is not a Service.
|
||||
*/
|
||||
fun showPersistentNotification(appContext: Context, lastTimeChecked: String, checkPeriod: String) {
|
||||
if (persistentNotificationEnabled) {
|
||||
val pendingIntent: PendingIntent =
|
||||
Intent(appContext, AndroidLauncher::class.java).let { notificationIntent ->
|
||||
PendingIntent.getActivity(appContext, 0, notificationIntent, 0)
|
||||
}
|
||||
|
||||
val notification: NotificationCompat.Builder = NotificationCompat.Builder(appContext, NOTIFICATION_CHANNEL_ID_SERVICE)
|
||||
.setPriority(NotificationManagerCompat.IMPORTANCE_MIN) // it's only a status
|
||||
.setContentTitle("Unciv multiplayer turn notifier running".tr())
|
||||
.setStyle(NotificationCompat.BigTextStyle()
|
||||
.bigText("Unciv will inform you when it's your turn.".tr() + "\n" +
|
||||
"Last checked: [$lastTimeChecked]. Checks ca. every [$checkPeriod] minute(s) when Internet available.".tr()
|
||||
+ " " + "Configurable in Unciv options menu.".tr()))
|
||||
.setSmallIcon(R.drawable.uncivicon2)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setCategory(NotificationCompat.CATEGORY_SERVICE)
|
||||
.setOnlyAlertOnce(true)
|
||||
.setOngoing(true)
|
||||
|
||||
with(NotificationManagerCompat.from(appContext)) {
|
||||
notify(NOTIFICATION_ID_INFO, notification.build())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun notifyUserAboutTurn(applicationContext: Context) {
|
||||
val pendingIntent: PendingIntent =
|
||||
Intent(applicationContext, AndroidLauncher::class.java).let { notificationIntent ->
|
||||
PendingIntent.getActivity(applicationContext, 0, notificationIntent, 0)
|
||||
}
|
||||
|
||||
val contentTitle = "Unciv - It's your turn!".tr()
|
||||
val notification: NotificationCompat.Builder = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL_ID_INFO)
|
||||
.setPriority(NotificationManagerCompat.IMPORTANCE_HIGH) // people are waiting!
|
||||
.setContentTitle(contentTitle)
|
||||
.setContentText("Your friends are waiting on your turn.".tr())
|
||||
.setTicker(contentTitle)
|
||||
// without at least vibrate, some Android versions don't show a heads-up notification
|
||||
.setDefaults(DEFAULT_VIBRATE)
|
||||
.setLights(Color.YELLOW, 300, 100)
|
||||
.setSmallIcon(R.drawable.uncivicon2)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setCategory(NotificationCompat.CATEGORY_SOCIAL)
|
||||
.setOngoing(false)
|
||||
|
||||
with(NotificationManagerCompat.from(applicationContext)) {
|
||||
notify(NOTIFICATION_ID_INFO, notification.build())
|
||||
}
|
||||
}
|
||||
|
||||
fun startTurnChecker(applicationContext: Context, gameInfo: GameInfo, settings: GameSettings) {
|
||||
if (gameInfo.currentPlayerCiv.playerId == settings.userId) {
|
||||
// May be useful to remind a player that he forgot to complete his turn.
|
||||
notifyUserAboutTurn(applicationContext)
|
||||
} else {
|
||||
gameId = gameInfo.gameId
|
||||
userId = settings.userId
|
||||
configuredDelay = settings.multiplayerTurnCheckerDelayInMinutes
|
||||
persistentNotificationEnabled = settings.multiplayerTurnCheckerPermanentNotificationEnabled
|
||||
|
||||
showPersistentNotification(applicationContext,
|
||||
"—", settings.multiplayerTurnCheckerDelayInMinutes.toString())
|
||||
// Initial check always happens after a minute, ignoring delay config. Better user experience this way.
|
||||
enqueue(applicationContext, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun doWork(): Result {
|
||||
try {
|
||||
val latestGame = OnlineMultiplayer().tryDownloadGame(gameId)
|
||||
if (latestGame.currentPlayerCiv.playerId == userId) {
|
||||
notifyUserAboutTurn(applicationContext)
|
||||
with(NotificationManagerCompat.from(applicationContext)) {
|
||||
cancel(NOTIFICATION_ID_SERVICE)
|
||||
}
|
||||
} else {
|
||||
enqueue(applicationContext, configuredDelay)
|
||||
updatePersistentNotification()
|
||||
}
|
||||
failCount = 0
|
||||
} catch (ex: Exception) {
|
||||
if (failCount++ > 3) {
|
||||
showErrorNotification()
|
||||
with(NotificationManagerCompat.from(applicationContext)) {
|
||||
cancel(NOTIFICATION_ID_SERVICE)
|
||||
}
|
||||
return Result.failure()
|
||||
} else {
|
||||
// If check fails, retry in one minute.
|
||||
// Makes sense, since checks only happen if Internet is available in principle.
|
||||
// Therefore a failure means either a problem with the GameInfo or with Dropbox.
|
||||
enqueue(applicationContext, 1)
|
||||
updatePersistentNotification()
|
||||
}
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
private fun updatePersistentNotification() {
|
||||
val cal = GregorianCalendar.getInstance()
|
||||
val hour = cal.get(GregorianCalendar.HOUR_OF_DAY).toString()
|
||||
var minute = cal.get(GregorianCalendar.MINUTE).toString()
|
||||
if (minute.length == 1) {
|
||||
minute = "0$minute"
|
||||
}
|
||||
val displayTime = "$hour:$minute"
|
||||
|
||||
showPersistentNotification(applicationContext, displayTime,
|
||||
configuredDelay.toString())
|
||||
}
|
||||
|
||||
private fun showErrorNotification() {
|
||||
val pendingIntent: PendingIntent =
|
||||
Intent(applicationContext, AndroidLauncher::class.java).let { notificationIntent ->
|
||||
PendingIntent.getActivity(applicationContext, 0, notificationIntent, 0)
|
||||
}
|
||||
|
||||
val notification: NotificationCompat.Builder = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL_ID_INFO)
|
||||
.setPriority(NotificationManagerCompat.IMPORTANCE_DEFAULT) // No direct user action expected
|
||||
.setContentTitle("An error has occured".tr())
|
||||
.setContentText("Multiplayer turn notifier service terminated".tr())
|
||||
.setSmallIcon(R.drawable.uncivicon2)
|
||||
// without at least vibrate, some Android versions don't show a heads-up notification
|
||||
.setDefaults(DEFAULT_VIBRATE)
|
||||
.setLights(Color.YELLOW, 300, 100)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setCategory(NotificationCompat.CATEGORY_ERROR)
|
||||
.setOngoing(false)
|
||||
|
||||
with(NotificationManagerCompat.from(applicationContext)) {
|
||||
notify(NOTIFICATION_ID_INFO, notification.build())
|
||||
}
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ class UncivGame(
|
||||
constructor(version: String) : this(version, null)
|
||||
|
||||
lateinit var gameInfo: GameInfo
|
||||
fun isGameInfoInitialized() = ::gameInfo.isInitialized
|
||||
lateinit var settings : GameSettings
|
||||
lateinit var crashController: CrashController
|
||||
/**
|
||||
|
@ -26,6 +26,9 @@ class GameSettings {
|
||||
var nuclearWeaponEnabled = false
|
||||
var continuousRendering = true
|
||||
var userId = ""
|
||||
var multiplayerTurnCheckerEnabled = true
|
||||
var multiplayerTurnCheckerPermanentNotificationEnabled = true
|
||||
var multiplayerTurnCheckerDelayInMinutes = 5L
|
||||
|
||||
fun save(){
|
||||
GameSaver().setGeneralSettings(this)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.unciv.ui.worldscreen.mainmenu
|
||||
|
||||
import com.badlogic.gdx.Application
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
@ -39,38 +40,38 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen){
|
||||
innerTable.add("Display options".toLabel(fontSize = 24)).colspan(2).row()
|
||||
|
||||
innerTable.add("Show worked tiles".toLabel())
|
||||
addButton(innerTable, if (settings.showWorkedTiles) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.showWorkedTiles) "Yes" else "No") {
|
||||
settings.showWorkedTiles= !settings.showWorkedTiles
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Show resources and improvements".toLabel())
|
||||
addButton(innerTable, if (settings.showResourcesAndImprovements) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.showResourcesAndImprovements) "Yes" else "No") {
|
||||
settings.showResourcesAndImprovements = !settings.showResourcesAndImprovements
|
||||
update()
|
||||
}
|
||||
|
||||
|
||||
innerTable.add("Show tutorials".toLabel())
|
||||
addButton(innerTable, if (settings.showTutorials) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.showTutorials) "Yes" else "No") {
|
||||
settings.showTutorials = !settings.showTutorials
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Show minimap".toLabel())
|
||||
addButton(innerTable, if (settings.showMinimap) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.showMinimap) "Yes" else "No") {
|
||||
settings.showMinimap = !settings.showMinimap
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Show pixel units".toLabel())
|
||||
addButton(innerTable, if (settings.showPixelUnits) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.showPixelUnits) "Yes" else "No") {
|
||||
settings.showPixelUnits = !settings.showPixelUnits
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Show pixel improvements".toLabel())
|
||||
addButton(innerTable, if (settings.showPixelImprovements) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.showPixelImprovements) "Yes" else "No") {
|
||||
settings.showPixelImprovements = !settings.showPixelImprovements
|
||||
update()
|
||||
}
|
||||
@ -83,56 +84,76 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen){
|
||||
|
||||
// Do not add to template.properties yet please.
|
||||
innerTable.add("Continuous rendering\n(HIGHLY EXPERIMENTAL)".toLabel())
|
||||
addButton(innerTable, if (settings.continuousRendering) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.continuousRendering) "Yes" else "No") {
|
||||
settings.continuousRendering = !settings.continuousRendering
|
||||
Gdx.graphics.isContinuousRendering = settings.continuousRendering
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Gameplay options".toLabel(fontSize = 24)).colspan(2).row()
|
||||
innerTable.add("Gameplay options".toLabel(fontSize = 24)).colspan(2).padTop(20f).row()
|
||||
|
||||
|
||||
innerTable.add("Check for idle units".toLabel())
|
||||
addButton(innerTable, if (settings.checkForDueUnits) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.checkForDueUnits) "Yes" else "No") {
|
||||
settings.checkForDueUnits = !settings.checkForDueUnits
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Move units with a single tap".toLabel())
|
||||
addButton(innerTable, if (settings.singleTapMove) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.singleTapMove) "Yes" else "No") {
|
||||
settings.singleTapMove = !settings.singleTapMove
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Auto-assign city production".toLabel())
|
||||
addButton(innerTable, if (settings.autoAssignCityProduction) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.autoAssignCityProduction) "Yes" else "No") {
|
||||
settings.autoAssignCityProduction = !settings.autoAssignCityProduction
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Auto-build roads".toLabel())
|
||||
addButton(innerTable, if (settings.autoBuildingRoads) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.autoBuildingRoads) "Yes" else "No") {
|
||||
settings.autoBuildingRoads = !settings.autoBuildingRoads
|
||||
update()
|
||||
}
|
||||
|
||||
|
||||
innerTable.add("Enable nuclear weapons".toLabel())
|
||||
addButton(innerTable, if (settings.nuclearWeaponEnabled) "Yes".tr() else "No".tr()) {
|
||||
addButton(innerTable, if (settings.nuclearWeaponEnabled) "Yes" else "No") {
|
||||
settings.nuclearWeaponEnabled = !settings.nuclearWeaponEnabled
|
||||
update()
|
||||
}
|
||||
|
||||
addAutosaveTurnsSelectBox(innerTable)
|
||||
|
||||
innerTable.add("Other options".toLabel(fontSize = 24)).colspan(2).row()
|
||||
// at the moment the notification service only exists on Android
|
||||
if (Gdx.app.type == Application.ApplicationType.Android) {
|
||||
innerTable.add("Multiplayer options".toLabel(fontSize = 24)).colspan(2).padTop(20f).row()
|
||||
|
||||
innerTable.add("Enable out-of-game turn notifications".toLabel())
|
||||
addButton(innerTable, if (settings.multiplayerTurnCheckerEnabled) "Yes" else "No") {
|
||||
settings.multiplayerTurnCheckerEnabled = !settings.multiplayerTurnCheckerEnabled
|
||||
update()
|
||||
}
|
||||
if (settings.multiplayerTurnCheckerEnabled) {
|
||||
addMultiplayerTurnCheckerDelayBox(innerTable)
|
||||
|
||||
innerTable.add("Show persistent notification for turn notifier service".toLabel())
|
||||
addButton(innerTable, if (settings.multiplayerTurnCheckerPermanentNotificationEnabled) "Yes" else "No") {
|
||||
settings.multiplayerTurnCheckerPermanentNotificationEnabled = !settings.multiplayerTurnCheckerPermanentNotificationEnabled
|
||||
update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
innerTable.add("Other options".toLabel(fontSize = 24)).colspan(2).padTop(20f).row()
|
||||
|
||||
|
||||
addSoundEffectsVolumeSlider(innerTable)
|
||||
addMusicVolumeSlider(innerTable)
|
||||
|
||||
innerTable.add("Version".toLabel())
|
||||
innerTable.add(UncivGame.Current.version.toLabel()).row()
|
||||
innerTable.add("Version".toLabel()).pad(10f)
|
||||
innerTable.add(UncivGame.Current.version.toLabel()).pad(10f).row()
|
||||
|
||||
|
||||
val scrollPane = ScrollPane(innerTable, skin)
|
||||
@ -167,7 +188,7 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen){
|
||||
Sounds.play(UncivSound.Click)
|
||||
}
|
||||
})
|
||||
innerTable.add(soundEffectsVolumeSlider).row()
|
||||
innerTable.add(soundEffectsVolumeSlider).pad(10f).row()
|
||||
}
|
||||
|
||||
private fun addMusicVolumeSlider(innerTable: Table) {
|
||||
@ -184,7 +205,7 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen){
|
||||
UncivGame.Current.music?.volume = 0.4f * musicVolumeSlider.value
|
||||
}
|
||||
})
|
||||
innerTable.add(musicVolumeSlider).row()
|
||||
innerTable.add(musicVolumeSlider).pad(10f).row()
|
||||
}
|
||||
else{
|
||||
val downloadMusicButton = TextButton("Download music".tr(),CameraStageBaseScreen.skin)
|
||||
@ -276,6 +297,26 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen){
|
||||
})
|
||||
}
|
||||
|
||||
private fun addMultiplayerTurnCheckerDelayBox(innerTable: Table) {
|
||||
innerTable.add("Time between turn checks out-of-game (in minutes)".toLabel())
|
||||
|
||||
val checkDelaySelectBox = SelectBox<Long>(skin)
|
||||
val possibleDelaysArray = Array<Long>()
|
||||
possibleDelaysArray.addAll(1L, 2L, 5L, 15L)
|
||||
checkDelaySelectBox.items = possibleDelaysArray
|
||||
checkDelaySelectBox.selected = UncivGame.Current.settings.multiplayerTurnCheckerDelayInMinutes
|
||||
|
||||
innerTable.add(checkDelaySelectBox).pad(10f).row()
|
||||
|
||||
checkDelaySelectBox.addListener(object : ChangeListener() {
|
||||
override fun changed(event: ChangeEvent?, actor: Actor?) {
|
||||
UncivGame.Current.settings.multiplayerTurnCheckerDelayInMinutes = checkDelaySelectBox.selected
|
||||
UncivGame.Current.settings.save()
|
||||
update()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun addLanguageSelectBox(innerTable: Table) {
|
||||
val languageSelectBox = SelectBox<Language>(skin)
|
||||
val languageArray = Array<Language>()
|
||||
|
Reference in New Issue
Block a user