From e8ab73df980fe206ce35782b49ebe10f0783b5ac Mon Sep 17 00:00:00 2001 From: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Date: Fri, 25 Mar 2022 15:28:24 +0100 Subject: [PATCH] Make max Zoom out a setting and fix a merge mistake (#6420) --- .../com/unciv/models/metadata/GameSettings.kt | 13 +++-- .../com/unciv/ui/utils/ZoomableScrollPane.kt | 4 +- .../unciv/ui/worldscreen/WorldMapHolder.kt | 25 +++++++-- .../com/unciv/ui/worldscreen/WorldScreen.kt | 1 + .../ui/worldscreen/mainmenu/OptionsPopup.kt | 55 +++++++++++-------- 5 files changed, 63 insertions(+), 35 deletions(-) diff --git a/core/src/com/unciv/models/metadata/GameSettings.kt b/core/src/com/unciv/models/metadata/GameSettings.kt index 7a53f87701..faec35589a 100644 --- a/core/src/com/unciv/models/metadata/GameSettings.kt +++ b/core/src/com/unciv/models/metadata/GameSettings.kt @@ -54,10 +54,10 @@ class GameSettings { var windowState = WindowState() var isFreshlyCreated = false var visualMods = HashSet() - - + + var multiplayerServer = Constants.dropboxMultiplayerServer - + var showExperimentalWorldWrap = false // We're keeping this as a config due to ANR problems on Android phones for people who don't know what they're doing :/ @@ -70,6 +70,9 @@ class GameSettings { var fontFamily: String = Fonts.DEFAULT_FONT_FAMILY + /** Maximum zoom-out of the map - performance heavy */ + var maxWorldZoomOut = 2f + init { // 26 = Android Oreo. Versions below may display permanent icon in notification bar. if (Gdx.app?.type == Application.ApplicationType.Android && Gdx.app.version < 26) { @@ -115,9 +118,9 @@ class GameSettings { * * @param base Path to the directory where the file should be - if not set, the OS current directory is used (which is "/" on Android) */ - fun getSettingsForPlatformLaunchers(base: String = ""): GameSettings { + fun getSettingsForPlatformLaunchers(base: String = "."): GameSettings { // FileHandle is Gdx, but the class and JsonParser are not dependent on app initialization - // If fact, at this point Gdx.app or Gdx.files are null but this still works. + // In fact, at this point Gdx.app or Gdx.files are null but this still works. val file = FileHandle(base + File.separator + GameSaver.settingsFileName) return if (file.exists()) JsonParser().getFromJson( diff --git a/core/src/com/unciv/ui/utils/ZoomableScrollPane.kt b/core/src/com/unciv/ui/utils/ZoomableScrollPane.kt index fc32912ee0..62feb88f82 100644 --- a/core/src/com/unciv/ui/utils/ZoomableScrollPane.kt +++ b/core/src/com/unciv/ui/utils/ZoomableScrollPane.kt @@ -7,7 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener import kotlin.math.sqrt -open class ZoomableScrollPane: ScrollPane(null) { +open class ZoomableScrollPane : ScrollPane(null) { var continuousScrollingX = false init{ @@ -15,7 +15,7 @@ open class ZoomableScrollPane: ScrollPane(null) { } open fun zoom(zoomScale: Float) { - if (zoomScale < 0.25f || zoomScale > 2f) return + if (zoomScale < 0.5f || zoomScale > 2f) return setScale(zoomScale) } fun zoomIn() { diff --git a/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt b/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt index 433ad9d8bc..27206f62c1 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt @@ -30,8 +30,6 @@ import com.unciv.ui.tilegroups.TileGroup import com.unciv.ui.tilegroups.TileSetStrings import com.unciv.ui.tilegroups.WorldTileGroup import com.unciv.ui.utils.* -//import com.unciv.ui.worldscreen.unit.UnitMovementsOverlayGroup -import kotlin.concurrent.thread class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: TileMap): ZoomableScrollPane() { @@ -47,9 +45,19 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap private val unitMovementPaths: HashMap> = HashMap() + private var maxWorldZoomOut = 2f + private var minZoomScale = 0.5f + init { if (Gdx.app.type == Application.ApplicationType.Desktop) this.setFlingTime(0f) continuousScrollingX = tileMap.mapParameters.worldWrap + reloadMaxZoom() + } + + internal fun reloadMaxZoom() { + maxWorldZoomOut = UncivGame.Current.settings.maxWorldZoomOut + minZoomScale = 1f / maxWorldZoomOut + if (scaleX < minZoomScale) zoom(1f) // since normally min isn't reached exactly, only powers of 0.8 } // Interface for classes that contain the data required to draw a button @@ -62,7 +70,11 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap internal fun addTiles() { val tileSetStrings = TileSetStrings() val daTileGroups = tileMap.values.map { WorldTileGroup(worldScreen, it, tileSetStrings) } - val tileGroupMap = TileGroupMap(daTileGroups, worldScreen.stage.width, worldScreen.stage.height, continuousScrollingX) + val tileGroupMap = TileGroupMap( + daTileGroups, + worldScreen.stage.width * maxWorldZoomOut / 2, + worldScreen.stage.height * maxWorldZoomOut / 2, + continuousScrollingX) val mirrorTileGroups = tileGroupMap.getMirrorTiles() for (tileGroup in daTileGroups) { @@ -130,7 +142,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap actor = tileGroupMap - setSize(worldScreen.stage.width * 2, worldScreen.stage.height * 2) + setSize(worldScreen.stage.width * maxWorldZoomOut, worldScreen.stage.height * maxWorldZoomOut) setOrigin(width / 2, height / 2) center(worldScreen.stage) @@ -702,12 +714,13 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap } override fun zoom(zoomScale: Float) { - super.zoom(zoomScale) + if (zoomScale < minZoomScale || zoomScale > 2f) return + setScale(zoomScale) val scale = 1 / scaleX // don't use zoomScale itself, in case it was out of bounds and not applied if (scale >= 1) for (tileGroup in allWorldTileGroups) tileGroup.cityButtonLayerGroup.isTransform = false // to save on rendering time to improve framerate - if (scale < 1 && scale > 0.5f) + if (scale < 1 && scale >= minZoomScale) for (tileGroup in allWorldTileGroups) { // ONLY set those groups that have active city buttons as transformable! // This is massively framerate-improving! diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index 64781e0bec..dab771f7ad 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -713,6 +713,7 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas * to re-enable the next turn button within its Close button action */ fun enableNextTurnButtonAfterOptions() { + mapHolder.reloadMaxZoom() nextTurnButton.isEnabled = isPlayersTurn && !waitingForAutosave } diff --git a/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt b/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt index ae167b3de0..86d9892eed 100644 --- a/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt +++ b/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt @@ -4,7 +4,6 @@ import com.badlogic.gdx.Application import com.badlogic.gdx.Gdx import com.badlogic.gdx.Input import com.badlogic.gdx.Net -import com.badlogic.gdx.Net.HttpResponseListener import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.SelectBox @@ -16,7 +15,6 @@ import com.unciv.MainMenuScreen import com.unciv.UncivGame import com.unciv.logic.MapSaver import com.unciv.logic.civilization.PlayerType -import com.unciv.logic.multiplayer.FileStorageConflictException import com.unciv.models.UncivSound import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.Ruleset.RulesetError @@ -38,7 +36,6 @@ import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip import com.unciv.ui.worldscreen.WorldScreen import java.io.BufferedReader import java.io.DataOutputStream -import java.io.FileNotFoundException import java.io.InputStreamReader import java.net.DatagramSocket import java.net.HttpURLConnection @@ -62,6 +59,7 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { private var modCheckBaseSelect: TranslatedSelectBox? = null private val modCheckResultTable = Table() private val selectBoxMinWidth: Float + private val previousMaxWorldZoom = settings.maxWorldZoomOut //endregion @@ -240,7 +238,7 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { private fun getMultiplayerTab(): Table = Table(BaseScreen.skin).apply { pad(10f) defaults().pad(5f) - + // at the moment the notification service only exists on Android if (Gdx.app.type == Application.ApplicationType.Android) { addCheckbox("Enable out-of-game turn notifications", @@ -258,9 +256,9 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { { settings.multiplayerTurnCheckerPersistentNotificationEnabled = it } } } - + val connectionToServerButton = "Check connection to server".toTextButton() - + val ipAddress = getIpAddress() add("{Current IP address}: $ipAddress".toTextButton().onClick { Gdx.app.clipboard.contents = ipAddress.toString() @@ -269,7 +267,7 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { val multiplayerServerTextField = TextField(settings.multiplayerServer, BaseScreen.skin) multiplayerServerTextField.programmaticChangeEvents = true val serverIpTable = Table() - + serverIpTable.add("Server's IP address".toLabel().onClick { multiplayerServerTextField.text = Gdx.app.clipboard.contents }).padRight(10f) @@ -280,17 +278,17 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { } serverIpTable.add(multiplayerServerTextField) add(serverIpTable).row() - + add("Reset to Dropbox".toTextButton().onClick { multiplayerServerTextField.text = Constants.dropboxMultiplayerServer }).row() - + add(connectionToServerButton.onClick { val popup = Popup(screen).apply { addGoodSizedLabel("Awaiting response...").row() } popup.open(true) - + successfullyConnectedToServer { success: Boolean, result: String -> if (success) { popup.addGoodSizedLabel("Success!").row() @@ -302,27 +300,27 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { } }).row() } - + fun getIpAddress(): String? { DatagramSocket().use { socket -> socket.connect(InetAddress.getByName("8.8.8.8"), 10002) - return socket.getLocalAddress().getHostAddress() + return socket.localAddress.hostAddress } } - - object SimpleHttp{ - fun sendGetRequest(url:String, action: (success: Boolean, result:String)->Unit){ + + object SimpleHttp { + fun sendGetRequest(url: String, action: (success: Boolean, result: String)->Unit) { sendRequest(Net.HttpMethods.GET, url, "", action) } - - fun sendRequest(method:String, url:String, content:String, action: (success:Boolean, result:String)->Unit){ + + fun sendRequest(method: String, url: String, content: String, action: (success: Boolean, result: String)->Unit) { with(URL(url).openConnection() as HttpURLConnection) { requestMethod = method // default is GET doOutput = true try { - if (content != "") { + if (content.isNotEmpty()) { // StandardCharsets.UTF_8 requires API 19 val postData: ByteArray = content.toByteArray(Charset.forName("UTF-8")) val outputStream = DataOutputStream(outputStream) @@ -342,10 +340,10 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { } } } - + } - - fun successfullyConnectedToServer(action: (Boolean, String)->Unit){ + + private fun successfullyConnectedToServer(action: (Boolean, String)->Unit){ SimpleHttp.sendGetRequest( "http://"+ settings.multiplayerServer+":8080/isalive", action) } @@ -360,6 +358,8 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { settings.showExperimentalWorldWrap = it } + addMaxZoomSlider() + if (previousScreen.game.limitOrientationsHelper != null) { addCheckbox("Enable portrait orientation", settings.allowAndroidPortrait) { settings.allowAndroidPortrait = it @@ -554,7 +554,7 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { if (mod.name.contains("mod")) println("mod") - + val filesToReplace = listOf( "Beliefs.json", "Buildings.json", @@ -881,6 +881,17 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { } } + private fun Table.addMaxZoomSlider() { + add("Max zoom out".tr()).left().fillX() + val maxZoomSlider = UncivSlider(2f, 6f, 1f, + initial = settings.maxWorldZoomOut + ) { + settings.maxWorldZoomOut = it + settings.save() + } + add(maxZoomSlider).pad(5f).row() + } + private fun Table.addFontFamilySelect(fonts: Collection) { if (fonts.isEmpty()) return