From 91116f8df3a9f6b2b763682fd9516ccea029fd3b Mon Sep 17 00:00:00 2001 From: alexban011 Date: Thu, 18 May 2023 10:12:33 +0300 Subject: [PATCH] Fixed more warnings (#9401) * fix: fix FunctionParameterNaming warnings * fix: fix InvalidPackageDeclaration warnings * fix: fix MatchingDeclarationName warnings * fix: fix WrongEqualsTypeParameter warnings * fix: fix UnusedPrivateProperty warnings * fix: fix UseCheckOrError warningsU * fix: fix UseRequire warningsU * detekt: disabled SpreadOperator rule * fix: resolve MemberNameEqualsClassName rule * detekt: disabled ForbiddenComment rule * fix: resolved SwallowedException warning * fix: resolved ThrowingExceptionsWithoutMessageOrCause warning * fix: resolved EmptyFunctionBlock warning * fix: resolved EmptyFunctionBlock warning * fix: resolved InstanceOfCheckForError warning * detekt: disable TooGenericExceptionCaught warning * detekt: disable TooGenericExceptionThrown warning * fix: resolve part of NestedBlockDepth warnings --- .../unciv/app/MultiplayerTurnCheckWorker.kt | 2 +- .../src/main/kotlin/AndroidImagePacker.kt | 18 +-- buildSrc/src/main/kotlin/BuildConfig.kt | 1 + core/src/com/unciv/UncivGame.kt | 2 +- .../com/unciv/logic/BackwardCompatibility.kt | 5 +- core/src/com/unciv/logic/GameStarter.kt | 99 +++++++++------ core/src/com/unciv/logic/IdChecker.kt | 114 ++++++++++++++++++ core/src/com/unciv/logic/IdHelper.kt | 114 ------------------ .../automation/ai/TacticalAnalysisMap.kt | 8 +- .../automation/city/ConstructionAutomation.kt | 2 +- .../civilization/NextTurnAutomation.kt | 5 +- .../logic/automation/unit/UnitAutomation.kt | 5 +- core/src/com/unciv/logic/battle/Battle.kt | 4 +- .../city/managers/CityPopulationManager.kt | 2 +- .../logic/civilization/ExploredRegion.kt | 2 +- core/src/com/unciv/logic/files/MapSaver.kt | 5 +- core/src/com/unciv/logic/files/UncivFiles.kt | 10 +- core/src/com/unciv/logic/map/TileMap.kt | 9 +- .../logic/map/mapgenerator/MapRegions.kt | 8 +- .../unciv/logic/map/mapgenerator/Perlin.kt | 4 +- .../logic/map/mapgenerator/RiverGenerator.kt | 4 +- .../com/unciv/logic/multiplayer/FriendList.kt | 26 ++-- .../logic/multiplayer/OnlineMultiplayer.kt | 8 +- .../multiplayer/OnlineMultiplayerGame.kt | 2 +- core/src/com/unciv/logic/trade/TradeOffer.kt | 2 +- .../unciv/models/metadata/GameParameters.kt | 2 +- .../com/unciv/models/metadata/GameSettings.kt | 2 +- .../unciv/models/ruleset/TextSimilarity.kt | 2 +- .../ruleset/unique/UniqueTriggerActivation.kt | 2 +- .../simulation/{Utils.kt => MutableInt.kt} | 0 .../com/unciv/models/simulation/Simulation.kt | 2 +- core/src/com/unciv/models/stats/Stats.kt | 2 +- .../unciv/ui/audio/MusicTrackController.kt | 9 +- core/src/com/unciv/ui/components/Fonts.kt | 2 +- .../com/unciv/ui/components/TabbedPager.kt | 10 +- .../tilegroups/layers/TileLayerBorders.kt | 2 +- core/src/com/unciv/ui/images/Portrait.kt | 3 +- core/src/com/unciv/ui/popups/AuthPopup.kt | 2 +- .../unciv/ui/popups/options/AdvancedTab.kt | 2 +- .../com/unciv/ui/popups/options/SoundTab.kt | 2 +- .../ui/screens/cityscreen/CityStatsTable.kt | 2 +- .../screens/mainmenuscreen/MainMenuScreen.kt | 6 +- .../mapeditorscreen/tabs/MapEditorLoadTab.kt | 2 + .../multiplayerscreens/AddFriendScreen.kt | 2 +- .../AddMultiplayerGameScreen.kt | 2 +- .../multiplayerscreens/EditFriendScreen.kt | 2 +- .../EditMultiplayerGameInfoScreen.kt | 18 +-- .../newgamescreen/MapParametersTable.kt | 2 +- .../ui/screens/newgamescreen/NewGameScreen.kt | 4 +- .../newgamescreen/PlayerPickerTable.kt | 6 +- ...ityOverviewTable.kt => CityOverviewTab.kt} | 0 ...verviewTable.kt => ReligionOverviewTab.kt} | 0 ...erviewTable.kt => ResourcesOverviewTab.kt} | 0 ...tsOverviewTable.kt => StatsOverviewTab.kt} | 0 ...sOverviewTable.kt => TradesOverviewTab.kt} | 6 +- ...nitOverviewTable.kt => UnitOverviewTab.kt} | 0 ...rOverviewTable.kt => WonderOverviewTab.kt} | 3 +- .../unciv/ui/screens/pickerscreens/GitHub.kt | 1 + .../pickerscreens/ModManagementScreen.kt | 8 +- .../screens/savescreens/LoadOrSaveScreen.kt | 6 +- .../unciv/ui/screens/savescreens/QuickSave.kt | 6 +- .../ui/screens/victoryscreen/ReplayMap.kt | 1 + .../ui/screens/worldscreen/WorldMapHolder.kt | 15 ++- .../ui/screens/worldscreen/WorldScreen.kt | 42 ++++--- .../unciv/utils/{Debug.kt => DebugUtils.kt} | 0 core/src/com/unciv/utils/Log.kt | 1 + .../src/com/unciv/app/desktop/DesktopFont.kt | 2 +- .../com/unciv/app/desktop/DiscordUpdater.kt | 2 +- .../src/com/unciv/app/desktop/SystemUtils.kt | 6 +- detekt/config/detekt-warnings.yml | 8 +- .../src/com/unciv/dev/FasterUIDevelopment.kt | 1 + tests/src/com/unciv/testing/BasicTests.kt | 2 +- .../com/unciv/testing/SerializationTests.kt | 2 +- ...RankingTypeTest.kt => RankingTypeTests.kt} | 0 74 files changed, 361 insertions(+), 302 deletions(-) create mode 100644 core/src/com/unciv/logic/IdChecker.kt delete mode 100644 core/src/com/unciv/logic/IdHelper.kt rename core/src/com/unciv/models/simulation/{Utils.kt => MutableInt.kt} (100%) rename core/src/com/unciv/ui/screens/overviewscreen/{CityOverviewTable.kt => CityOverviewTab.kt} (100%) rename core/src/com/unciv/ui/screens/overviewscreen/{ReligionOverviewTable.kt => ReligionOverviewTab.kt} (100%) rename core/src/com/unciv/ui/screens/overviewscreen/{ResourcesOverviewTable.kt => ResourcesOverviewTab.kt} (100%) rename core/src/com/unciv/ui/screens/overviewscreen/{StatsOverviewTable.kt => StatsOverviewTab.kt} (100%) rename core/src/com/unciv/ui/screens/overviewscreen/{TradesOverviewTable.kt => TradesOverviewTab.kt} (94%) rename core/src/com/unciv/ui/screens/overviewscreen/{UnitOverviewTable.kt => UnitOverviewTab.kt} (100%) rename core/src/com/unciv/ui/screens/overviewscreen/{WonderOverviewTable.kt => WonderOverviewTab.kt} (99%) rename core/src/com/unciv/utils/{Debug.kt => DebugUtils.kt} (100%) rename tests/src/com/unciv/ui/screens/victoryscreen/{RankingTypeTest.kt => RankingTypeTests.kt} (100%) diff --git a/android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt b/android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt index 67cead5dcf..e33b8b317a 100644 --- a/android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt +++ b/android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt @@ -202,7 +202,7 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame gameIds[count] = gamePreview.gameId gameNames[count] = gameFile.name() count++ - } catch (ex: Throwable) { + } catch (_: Throwable) { //only loadGamePreviewFromFile can throw an exception //nothing will be added to the arrays if it fails //just skip one file diff --git a/buildSrc/src/main/kotlin/AndroidImagePacker.kt b/buildSrc/src/main/kotlin/AndroidImagePacker.kt index ff0920f46e..8a4f0b9d39 100644 --- a/buildSrc/src/main/kotlin/AndroidImagePacker.kt +++ b/buildSrc/src/main/kotlin/AndroidImagePacker.kt @@ -1,3 +1,4 @@ +@file:Suppress("InvalidPackageDeclaration") package com.unciv.build import com.badlogic.gdx.graphics.Texture @@ -62,14 +63,15 @@ object AndroidImagePacker { // pack for mods val modDirectory = File("mods") - if (modDirectory.exists()) { - for (mod in modDirectory.listFiles()!!) { - if (!mod.isHidden) { - try { - packImagesPerMod(mod.path, mod.path, defaultSettings) - } catch (ex: Throwable) { - } - } + if (!modDirectory.exists()) + return + for (mod in modDirectory.listFiles()!!) { + if (mod.isHidden) + continue + try { + packImagesPerMod(mod.path, mod.path, defaultSettings) + } catch (ex: Throwable) { + ex.printStackTrace() } } } diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt index c1065bd65b..1defdbb95c 100644 --- a/buildSrc/src/main/kotlin/BuildConfig.kt +++ b/buildSrc/src/main/kotlin/BuildConfig.kt @@ -1,3 +1,4 @@ +@file:Suppress("InvalidPackageDeclaration") package com.unciv.build object BuildConfig { diff --git a/core/src/com/unciv/UncivGame.kt b/core/src/com/unciv/UncivGame.kt index df17fd2ab9..591cb72ce4 100644 --- a/core/src/com/unciv/UncivGame.kt +++ b/core/src/com/unciv/UncivGame.kt @@ -501,7 +501,7 @@ open class UncivGame(val isConsoleMode: Boolean = false) : Game(), PlatformSpeci PrintWriter(files.fileWriter("lasterror.txt")).use { ex.printStackTrace(it) } - } catch (ex: Exception) { + } catch (_: Exception) { // ignore } Gdx.app.postRunnable { diff --git a/core/src/com/unciv/logic/BackwardCompatibility.kt b/core/src/com/unciv/logic/BackwardCompatibility.kt index b3c52ae97a..3578754b59 100644 --- a/core/src/com/unciv/logic/BackwardCompatibility.kt +++ b/core/src/com/unciv/logic/BackwardCompatibility.kt @@ -156,9 +156,8 @@ object BackwardCompatibility { } /** Move max XP from barbarians to new home */ - @Suppress("DEPRECATION") - fun ModOptions.updateDeprecations() { - } + @Suppress("DEPRECATION", "EmptyFunctionBlock") + fun ModOptions.updateDeprecations() { } /** Convert from Fortify X to Fortify and save off X */ fun GameInfo.convertFortify() { diff --git a/core/src/com/unciv/logic/GameStarter.kt b/core/src/com/unciv/logic/GameStarter.kt index d9ef67761d..780d10fd73 100644 --- a/core/src/com/unciv/logic/GameStarter.kt +++ b/core/src/com/unciv/logic/GameStarter.kt @@ -204,12 +204,13 @@ object GameStarter { val policyName = unique.params[0] // check if the policy is in the ruleset and not already adopted - if (ruleset.policies.containsKey(policyName) && !civInfo.policies.isAdopted(policyName)) { - val policyToAdopt = ruleset.policies[policyName]!! - civInfo.policies.run { - freePolicies++ - adopt(policyToAdopt) - } + if (!ruleset.policies.containsKey(policyName) || civInfo.policies.isAdopted(policyName)) + continue + + val policyToAdopt = ruleset.policies[policyName]!! + civInfo.policies.run { + freePolicies++ + adopt(policyToAdopt) } } } @@ -503,47 +504,65 @@ object GameStarter { startScores: HashMap ): HashMap { - val civsOrderedByAvailableLocations = civs.shuffled() // Order should be random since it determines who gets best start - .sortedBy { civ -> - when { - civ.civName in tileMap.startingLocationsByNation -> 1 // harshest requirements - civ.nation.startBias.any { it in tileMap.naturalWonders } && !gameSetupInfo.gameParameters.noStartBias -> 2 - civ.nation.startBias.contains(Constants.tundra) && !gameSetupInfo.gameParameters.noStartBias -> 3 // Tundra starts are hard to find, so let's do them first - civ.nation.startBias.isNotEmpty() && !gameSetupInfo.gameParameters.noStartBias -> 4 // less harsh - else -> 5 // no requirements - } - }.sortedByDescending { it.isHuman() } // More important for humans to get their start biases! + val civsOrderedByAvailableLocations = getCivsOrderedByAvailableLocations(civs, tileMap) for (minimumDistanceBetweenStartingLocations in tileMap.tileMatrix.size / 6 downTo 0) { - val freeTiles = landTilesInBigEnoughGroup.asSequence() - .filter { - HexMath.getDistanceFromEdge(it.key.position, tileMap.mapParameters) >= - (minimumDistanceBetweenStartingLocations * 2) / 3 - }.sortedBy { it.value } - .map { it.key } - .toMutableList() + val freeTiles = getFreeTiles(tileMap, landTilesInBigEnoughGroup, minimumDistanceBetweenStartingLocations) - val startingLocations = HashMap() - for (civ in civsOrderedByAvailableLocations) { - val distanceToNext = minimumDistanceBetweenStartingLocations / - (if (civ.isCityState()) 2 else 1) // We allow city states to squeeze in tighter - val presetStartingLocation = tileMap.startingLocationsByNation[civ.civName]?.randomOrNull() - val startingLocation = if (presetStartingLocation != null) presetStartingLocation - else { - if (freeTiles.isEmpty()) break // we failed to get all the starting tiles with this minimum distance - getOneStartingLocation(civ, tileMap, freeTiles, startScores) - } - startingLocations[civ] = startingLocation - freeTiles.removeAll(tileMap.getTilesInDistance(startingLocation.position, distanceToNext) - .toSet()) - } - if (startingLocations.size < civs.size) continue // let's try again with less minimum distance! - - return startingLocations + val startingLocations = getStartingLocationsForCivs(civsOrderedByAvailableLocations, tileMap, freeTiles, startScores, minimumDistanceBetweenStartingLocations) + if (startingLocations != null) return startingLocations } throw Exception("Didn't manage to get starting tiles even with distance of 1?") } + private fun getCivsOrderedByAvailableLocations(civs: List, tileMap: TileMap): List { + return civs.shuffled() // Order should be random since it determines who gets best start + .sortedBy { civ -> + when { + civ.civName in tileMap.startingLocationsByNation -> 1 // harshest requirements + civ.nation.startBias.any { it in tileMap.naturalWonders } && !gameSetupInfo.gameParameters.noStartBias -> 2 + civ.nation.startBias.contains(Constants.tundra) && !gameSetupInfo.gameParameters.noStartBias -> 3 // Tundra starts are hard to find, so let's do them first + civ.nation.startBias.isNotEmpty() && !gameSetupInfo.gameParameters.noStartBias -> 4 // less harsh + else -> 5 // no requirements + } + }.sortedByDescending { it.isHuman() } // More important for humans to get their start biases! + } + + private fun getFreeTiles(tileMap: TileMap, landTilesInBigEnoughGroup: Map, minimumDistanceBetweenStartingLocations: Int): MutableList { + return landTilesInBigEnoughGroup.asSequence() + .filter { + HexMath.getDistanceFromEdge(it.key.position, tileMap.mapParameters) >= + (minimumDistanceBetweenStartingLocations * 2) / 3 + }.sortedBy { it.value } + .map { it.key } + .toMutableList() + } + + private fun getStartingLocationsForCivs( + civsOrderedByAvailableLocations: List, + tileMap: TileMap, + freeTiles: MutableList, + startScores: HashMap, + minimumDistanceBetweenStartingLocations: Int + ): HashMap? { + val startingLocations = HashMap() + for (civ in civsOrderedByAvailableLocations) { + val distanceToNext = minimumDistanceBetweenStartingLocations / + (if (civ.isCityState()) 2 else 1) // We allow city states to squeeze in tighter + val presetStartingLocation = tileMap.startingLocationsByNation[civ.civName]?.randomOrNull() + val startingLocation = if (presetStartingLocation != null) presetStartingLocation + else { + if (freeTiles.isEmpty()) break // we failed to get all the starting tiles with this minimum distance + getOneStartingLocation(civ, tileMap, freeTiles, startScores) + } + startingLocations[civ] = startingLocation + freeTiles.removeAll(tileMap.getTilesInDistance(startingLocation.position, distanceToNext) + .toSet()) + } + return if (startingLocations.size < civsOrderedByAvailableLocations.size) null else startingLocations + } + + private fun getOneStartingLocation( civ: Civilization, tileMap: TileMap, diff --git a/core/src/com/unciv/logic/IdChecker.kt b/core/src/com/unciv/logic/IdChecker.kt new file mode 100644 index 0000000000..2b9d85e041 --- /dev/null +++ b/core/src/com/unciv/logic/IdChecker.kt @@ -0,0 +1,114 @@ +package com.unciv.logic + +import java.util.Locale +import kotlin.math.abs + +/** + * This class checks whether a Game- or Player-ID matches the old or new format. + * If old format is used, checks are skipped and input is returned. + * If new format is detected, prefix and checkDigit are checked and UUID returned. + * + * All input is returned trimmed. + * + * New format: + * G-UUID-CheckDigit for Game IDs + * P-UUID-CheckDigit for Player IDs + * + * Example: + * 2ddb3a34-0699-4126-b7a5-38603e665928 + * Same ID in proposed new Player-ID format: + * P-2ddb3a34-0699-4126-b7a5-38603e665928-5 + * Same ID in proposed new Game-ID format: + * G-2ddb3a34-0699-4126-b7a5-38603e665928-5 + */ +object IdChecker { + + fun checkAndReturnPlayerUuid(playerId: String): String { + return checkAndReturnUuiId(playerId, "P") + } + + fun checkAndReturnGameUuid(gameId: String): String { + return checkAndReturnUuiId(gameId, "G") + } + + private fun checkAndReturnUuiId(id: String, prefix: String): String { + val trimmedPlayerId = id.trim() + if (trimmedPlayerId.length == 40) { // length of a UUID (36) with pre- and postfix + require(trimmedPlayerId.startsWith(prefix, true)) { "Not a valid ID. Does not start with prefix $prefix" } + + val checkDigit = trimmedPlayerId.substring(trimmedPlayerId.lastIndex, trimmedPlayerId.lastIndex +1) + // remember, the format is: P-9e37e983-a676-4ecc-800e-ef8ec721a9b9-5 + val shortenedPlayerId = trimmedPlayerId.substring(2, 38) + val calculatedCheckDigit = getCheckDigit(shortenedPlayerId).toString() + require(calculatedCheckDigit == checkDigit) { + "Not a valid ID. Checkdigit invalid." + } + return shortenedPlayerId + } else if (trimmedPlayerId.length == 36) { + return trimmedPlayerId + } + throw IllegalArgumentException("Not a valid ID. Wrong length.") + } + + + /** + * Adapted from https://wiki.openmrs.org/display/docs/Check+Digit+Algorithm + */ + fun getCheckDigit(uuid: String): Int { + // allowable characters within identifier + @Suppress("SpellCheckingInspection") + val validChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVYWXZ-" + var idWithoutCheckdigit = uuid + // remove leading or trailing whitespace, convert to uppercase + idWithoutCheckdigit = idWithoutCheckdigit.trim().uppercase(Locale.ENGLISH) + + // this will be a running total + var sum = 0 + + // loop through digits from right to left + for (i in idWithoutCheckdigit.indices) { + + //set ch to "current" character to be processed + val ch = idWithoutCheckdigit[idWithoutCheckdigit.length - i - 1] + + // throw exception for invalid characters + require(validChars.indexOf(ch) != -1) { + "$ch is an invalid character" + } + + // our "digit" is calculated using ASCII value - 48 + val digit = ch.code - 48 + + // weight will be the current digit's contribution to + // the running total + var weight: Int + if (i % 2 == 0) { + + // for alternating digits starting with the rightmost, we + // use our formula this is the same as multiplying x 2 and + // adding digits together for values 0 to 9. Using the + // following formula allows us to gracefully calculate a + // weight for non-numeric "digits" as well (from their + // ASCII value - 48). + weight = (2 * digit) - (digit / 5) * 9 + + } else { + + // even-positioned digits just contribute their ascii + // value minus 48 + weight = digit + + } + // keep a running total of weights + sum += weight + + } + // avoid sum less than 10 (if characters below "0" allowed, + // this could happen) + sum = abs(sum) + 10 + + // check digit is amount needed to reach next number + // divisible by ten + return (10 - (sum % 10)) % 10 + } +} diff --git a/core/src/com/unciv/logic/IdHelper.kt b/core/src/com/unciv/logic/IdHelper.kt deleted file mode 100644 index de27932415..0000000000 --- a/core/src/com/unciv/logic/IdHelper.kt +++ /dev/null @@ -1,114 +0,0 @@ -package com.unciv.logic - -import java.util.Locale -import kotlin.math.abs - -/** - * This class checks whether a Game- or Player-ID matches the old or new format. - * If old format is used, checks are skipped and input is returned. - * If new format is detected, prefix and checkDigit are checked and UUID returned. - * - * All input is returned trimmed. - * - * New format: - * G-UUID-CheckDigit for Game IDs - * P-UUID-CheckDigit for Player IDs - * - * Example: - * 2ddb3a34-0699-4126-b7a5-38603e665928 - * Same ID in proposed new Player-ID format: - * P-2ddb3a34-0699-4126-b7a5-38603e665928-5 - * Same ID in proposed new Game-ID format: - * G-2ddb3a34-0699-4126-b7a5-38603e665928-5 - */ -object IdChecker { - - fun checkAndReturnPlayerUuid(playerId: String): String { - return checkAndReturnUuiId(playerId, "P") - } - - fun checkAndReturnGameUuid(gameId: String): String { - return checkAndReturnUuiId(gameId, "G") - } - - private fun checkAndReturnUuiId(id: String, prefix: String): String { - val trimmedPlayerId = id.trim() - if (trimmedPlayerId.length == 40) { // length of a UUID (36) with pre- and postfix - if (!trimmedPlayerId.startsWith(prefix, true)) { - throw IllegalArgumentException("Not a valid ID. Does not start with prefix $prefix") - } - val checkDigit = trimmedPlayerId.substring(trimmedPlayerId.lastIndex, trimmedPlayerId.lastIndex +1) - // remember, the format is: P-9e37e983-a676-4ecc-800e-ef8ec721a9b9-5 - val shortenedPlayerId = trimmedPlayerId.substring(2, 38) - val calculatedCheckDigit = getCheckDigit(shortenedPlayerId).toString() - if (calculatedCheckDigit != checkDigit) { - throw IllegalArgumentException("Not a valid ID. Checkdigit invalid.") - } - return shortenedPlayerId - } else if (trimmedPlayerId.length == 36) { - return trimmedPlayerId - } - throw IllegalArgumentException("Not a valid ID. Wrong length.") - } - - - /** - * Adapted from https://wiki.openmrs.org/display/docs/Check+Digit+Algorithm - */ - fun getCheckDigit(uuid: String): Int { - // allowable characters within identifier - @Suppress("SpellCheckingInspection") - val validChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVYWXZ-" - var idWithoutCheckdigit = uuid - // remove leading or trailing whitespace, convert to uppercase - idWithoutCheckdigit = idWithoutCheckdigit.trim().uppercase(Locale.ENGLISH) - - // this will be a running total - var sum = 0 - - // loop through digits from right to left - for (i in idWithoutCheckdigit.indices) { - - //set ch to "current" character to be processed - val ch = idWithoutCheckdigit[idWithoutCheckdigit.length - i - 1] - - // throw exception for invalid characters - if (validChars.indexOf(ch) == -1) - throw IllegalArgumentException("$ch is an invalid character") - - // our "digit" is calculated using ASCII value - 48 - val digit = ch.code - 48 - - // weight will be the current digit's contribution to - // the running total - var weight: Int - if (i % 2 == 0) { - - // for alternating digits starting with the rightmost, we - // use our formula this is the same as multiplying x 2 and - // adding digits together for values 0 to 9. Using the - // following formula allows us to gracefully calculate a - // weight for non-numeric "digits" as well (from their - // ASCII value - 48). - weight = (2 * digit) - (digit / 5) * 9 - - } else { - - // even-positioned digits just contribute their ascii - // value minus 48 - weight = digit - - } - // keep a running total of weights - sum += weight - - } - // avoid sum less than 10 (if characters below "0" allowed, - // this could happen) - sum = abs(sum) + 10 - - // check digit is amount needed to reach next number - // divisible by ten - return (10 - (sum % 10)) % 10 - } -} diff --git a/core/src/com/unciv/logic/automation/ai/TacticalAnalysisMap.kt b/core/src/com/unciv/logic/automation/ai/TacticalAnalysisMap.kt index 1e7e3d2b2f..6e2f5d3ea2 100644 --- a/core/src/com/unciv/logic/automation/ai/TacticalAnalysisMap.kt +++ b/core/src/com/unciv/logic/automation/ai/TacticalAnalysisMap.kt @@ -220,6 +220,10 @@ class TacticalAnalysisMap { // Ensure that continents sizes are calculated game.tileMap.assignContinents(TileMap.AssignContinentsMode.Ensure) + groupRemainingNonCityTiles(nonCityTiles) + } + + private fun groupRemainingNonCityTiles(nonCityTiles: ArrayList) { while (nonCityTiles.isNotEmpty()) { var count = maxZoneSize @@ -249,8 +253,8 @@ class TacticalAnalysisMap { val neighborContinentSize = neighbor.tileMap.continentSizes[neighbor.getContinent()] ?: Int.MAX_VALUE val isSameZone = neighbor.getContinent() == tile.getContinent() - || isLake || (isMountain && neighbor.isLand) - || neighborContinentSize < 4 || tileContinentSize < 4 + || isLake || (isMountain && neighbor.isLand) + || neighborContinentSize < 4 || tileContinentSize < 4 if (isSameZone && nonCityTiles.contains(neighbor) && count > 0) { nonCityTiles.remove(neighbor) diff --git a/core/src/com/unciv/logic/automation/city/ConstructionAutomation.kt b/core/src/com/unciv/logic/automation/city/ConstructionAutomation.kt index dde71e5a5a..5822e22d1f 100644 --- a/core/src/com/unciv/logic/automation/city/ConstructionAutomation.kt +++ b/core/src/com/unciv/logic/automation/city/ConstructionAutomation.kt @@ -161,7 +161,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){ val bfs = BFS(cityInfo.getCenterTile()) { (it.isWater || it.isCityCenter()) && it.isFriendlyTerritory(civInfo) } - for (i in 1..10) bfs.nextStep() + repeat(10) { bfs.nextStep() } if (!bfs.getReachedTiles() .any { tile -> tile.hasViewableResource(civInfo) && tile.improvement == null && tile.getOwner() == civInfo diff --git a/core/src/com/unciv/logic/automation/civilization/NextTurnAutomation.kt b/core/src/com/unciv/logic/automation/civilization/NextTurnAutomation.kt index 7ec5408430..39c53f35af 100644 --- a/core/src/com/unciv/logic/automation/civilization/NextTurnAutomation.kt +++ b/core/src/com/unciv/logic/automation/civilization/NextTurnAutomation.kt @@ -688,10 +688,11 @@ object NextTurnAutomation { // not have used a great prophet to found/enhance our religion. for (belief in BeliefType.values()) { if (belief == BeliefType.None) continue - for (counter in 0 until (beliefsToChoose[belief] ?: 0)) + repeat((beliefsToChoose[belief] ?: 0) - 1) { chosenBeliefs.add( - chooseBeliefOfType(civInfo, belief, chosenBeliefs) ?: continue + chooseBeliefOfType(civInfo, belief, chosenBeliefs) ?: return@repeat ) + } } return chosenBeliefs } diff --git a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt index 3cbc5a41a3..2af9d00089 100644 --- a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt @@ -141,8 +141,7 @@ object UnitAutomation { } fun automateUnitMoves(unit: MapUnit) { - if (unit.civ.isBarbarian()) - throw IllegalStateException("Barbarians is not allowed here.") + check(!unit.civ.isBarbarian()) { "Barbarians is not allowed here." } // Might die next turn - move! if (unit.health <= unit.getDamageFromTerrain() && tryHealUnit(unit)) return @@ -345,7 +344,7 @@ object UnitAutomation { /** @return true only if the unit has 0 movement left */ private fun tryAttacking(unit: MapUnit): Boolean { - for (attackNumber in unit.attacksThisTurn until unit.maxAttacksPerTurn()) { + repeat(unit.maxAttacksPerTurn() - unit.attacksThisTurn) { if (BattleHelper.tryAttackNearbyEnemy(unit)) return true } return false diff --git a/core/src/com/unciv/logic/battle/Battle.kt b/core/src/com/unciv/logic/battle/Battle.kt index d97cde2f9b..69cda57cbd 100644 --- a/core/src/com/unciv/logic/battle/Battle.kt +++ b/core/src/com/unciv/logic/battle/Battle.kt @@ -640,8 +640,8 @@ object Battle { * @throws IllegalArgumentException if the [attacker] and [defender] belong to the same civ. */ fun captureCivilianUnit(attacker: ICombatant, defender: MapUnitCombatant, checkDefeat: Boolean = true) { - if (attacker.getCivInfo() == defender.getCivInfo()) { - throw IllegalArgumentException("Can't capture our own unit!") + require(attacker.getCivInfo() != defender.getCivInfo()) { + "Can't capture our own unit!" } // need to save this because if the unit is captured its owner wil be overwritten diff --git a/core/src/com/unciv/logic/city/managers/CityPopulationManager.kt b/core/src/com/unciv/logic/city/managers/CityPopulationManager.kt index 5d05f114f1..c9a636e856 100644 --- a/core/src/com/unciv/logic/city/managers/CityPopulationManager.kt +++ b/core/src/com/unciv/logic/city/managers/CityPopulationManager.kt @@ -160,7 +160,7 @@ class CityPopulationManager : IsPartOfGameInfoSerialization { .filter { it.getOwner() == currentCiv && !it.isBlockaded() }.toList().asSequence() val localUniqueCache = LocalUniqueCache() - for (i in 1..getFreePopulation()) { + repeat(getFreePopulation() - 1) { //evaluate tiles val (bestTile, valueBestTile) = tilesToEvaluate .filterNot { it.providesYield() } diff --git a/core/src/com/unciv/logic/civilization/ExploredRegion.kt b/core/src/com/unciv/logic/civilization/ExploredRegion.kt index 79e7e4571f..4e9743803f 100644 --- a/core/src/com/unciv/logic/civilization/ExploredRegion.kt +++ b/core/src/com/unciv/logic/civilization/ExploredRegion.kt @@ -12,7 +12,7 @@ import com.unciv.ui.components.tilegroups.TileGroupMap import kotlin.math.abs import kotlin.math.sqrt -class ExploredRegion () : IsPartOfGameInfoSerialization { +class ExploredRegion : IsPartOfGameInfoSerialization { @Transient private var worldWrap = false diff --git a/core/src/com/unciv/logic/files/MapSaver.kt b/core/src/com/unciv/logic/files/MapSaver.kt index 69f236b3e2..b3e807cac0 100644 --- a/core/src/com/unciv/logic/files/MapSaver.kt +++ b/core/src/com/unciv/logic/files/MapSaver.kt @@ -6,6 +6,7 @@ import com.unciv.json.json import com.unciv.logic.map.MapParameters import com.unciv.logic.map.TileMap import com.unciv.ui.screens.savescreens.Gzip +import com.unciv.utils.Log object MapSaver { @@ -17,7 +18,7 @@ object MapSaver { fun mapFromSavedString(mapString: String): TileMap { val unzippedJson = try { Gzip.unzip(mapString.trim()) - } catch (ex: Exception) { + } catch (_: Exception) { mapString } return mapFromJson(unzippedJson) @@ -53,7 +54,7 @@ object MapSaver { fun mapParametersFromSavedString(mapString: String): MapParameters { val unzippedJson = try { Gzip.unzip(mapString.trim()) - } catch (ex: Exception) { + } catch (_: Exception) { mapString } return json().fromJson(TileMapPreview::class.java, unzippedJson).mapParameters diff --git a/core/src/com/unciv/logic/files/UncivFiles.kt b/core/src/com/unciv/logic/files/UncivFiles.kt index 3ea2a8c5cb..047dad58fa 100644 --- a/core/src/com/unciv/logic/files/UncivFiles.kt +++ b/core/src/com/unciv/logic/files/UncivFiles.kt @@ -338,7 +338,7 @@ class UncivFiles( fun gameInfoFromString(gameData: String): GameInfo { val unzippedJson = try { Gzip.unzip(gameData.trim()) - } catch (ex: Exception) { + } catch (_: Exception) { gameData.trim() } val gameInfo = try { @@ -433,14 +433,14 @@ class UncivFiles( } fun loadLatestAutosave(): GameInfo { - try { - return loadGameByName(AUTOSAVE_FILE_NAME) - } catch (ex: Exception) { + return try { + loadGameByName(AUTOSAVE_FILE_NAME) + } catch (_: Exception) { // silent fail if we can't read the autosave for any reason - try to load the last autosave by turn number first val autosaves = getSaves().filter { it.name() != AUTOSAVE_FILE_NAME && it.name().startsWith( AUTOSAVE_FILE_NAME ) } - return loadGameFromFile(autosaves.maxByOrNull { it.lastModified() }!!) + loadGameFromFile(autosaves.maxByOrNull { it.lastModified() }!!) } } diff --git a/core/src/com/unciv/logic/map/TileMap.kt b/core/src/com/unciv/logic/map/TileMap.kt index 773414540c..92be1ab1db 100644 --- a/core/src/com/unciv/logic/map/TileMap.kt +++ b/core/src/com/unciv/logic/map/TileMap.kt @@ -387,7 +387,7 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization { // All the rest is to find missing nations try { // This can fail if the map contains a resource that isn't in the ruleset, in Tile.tileResource setTransients(ruleset) - } catch (ex: Exception) { + } catch (_: Exception) { return rulesetIncompatibilities } setStartingLocationsTransients() @@ -415,7 +415,7 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization { */ fun setTransients(ruleset: Ruleset? = null, setUnitCivTransients: Boolean = true) { if (ruleset != null) this.ruleset = ruleset - if (this.ruleset == null) throw(IllegalStateException("TileMap.setTransients called without ruleset")) + check(this.ruleset != null) { "TileMap.setTransients called without ruleset" } if (tileMatrix.isEmpty()) { val topY = tileList.asSequence().map { it.position.y.toInt() }.maxOrNull()!! @@ -434,8 +434,9 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization { } else { // Yes the map generator calls this repeatedly, and we don't want to end up with an oversized tileMatrix // rightX is -leftX or -leftX + 1 or -leftX + 2 - if (tileMatrix.size !in (1 - 2 * leftX)..(3 - 2 * leftX)) - throw(IllegalStateException("TileMap.setTransients called on existing tileMatrix of different size")) + check(tileMatrix.size in (1 - 2 * leftX)..(3 - 2 * leftX)) { + "TileMap.setTransients called on existing tileMatrix of different size" + } } for (tileInfo in values) { diff --git a/core/src/com/unciv/logic/map/mapgenerator/MapRegions.kt b/core/src/com/unciv/logic/map/mapgenerator/MapRegions.kt index d120de88db..a486a510f9 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/MapRegions.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/MapRegions.kt @@ -117,7 +117,7 @@ class MapRegions (val ruleset: Ruleset){ } // Assign regions to the best continents, giving half value for region #2 etc - for (regionToAssign in 1..numRegions) { + repeat(numRegions) { val bestContinent = continents .maxByOrNull { continentFertility[it]!! / (1 + (civsAddedToContinent[it] ?: 0)) }!! civsAddedToContinent[bestContinent] = (civsAddedToContinent[bestContinent] ?: 0) + 1 @@ -949,12 +949,12 @@ class MapRegions (val ruleset: Ruleset){ } // Assign luxuries to City States - for (i in 1..targetCityStateLuxuries) { + repeat(targetCityStateLuxuries) { val candidateLuxuries = assignableLuxuries.filter { amountRegionsWithLuxury[it.name] == 0 && - (fallbackWeightings || it.hasUnique(UniqueType.LuxuryWeightingForCityStates)) + (fallbackWeightings || it.hasUnique(UniqueType.LuxuryWeightingForCityStates)) } - if (candidateLuxuries.isEmpty()) continue + if (candidateLuxuries.isEmpty()) return@repeat val weights = candidateLuxuries.map { val weightingUnique = it.getMatchingUniques(UniqueType.LuxuryWeightingForCityStates).firstOrNull() diff --git a/core/src/com/unciv/logic/map/mapgenerator/Perlin.kt b/core/src/com/unciv/logic/map/mapgenerator/Perlin.kt index 69697cb06b..a65b24024a 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/Perlin.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/Perlin.kt @@ -46,7 +46,7 @@ object Perlin { var amp = 1.0 var max = 0.0 var total = 0.0 - for (i in 0 until nOctaves) { + repeat(nOctaves - 1) { total += amp * noise(x * freq / scale, y * freq / scale, z * freq / scale) max += amp freq *= lacunarity @@ -64,7 +64,7 @@ object Perlin { var amp = 1.0 var max = 0.0 var total = 0.0 - for (i in 0 until nOctaves) { + repeat(nOctaves) { var value = noise( x * freq / scale, y * freq / scale, diff --git a/core/src/com/unciv/logic/map/mapgenerator/RiverGenerator.kt b/core/src/com/unciv/logic/map/mapgenerator/RiverGenerator.kt index a5d434130b..a1e1464bb1 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/RiverGenerator.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/RiverGenerator.kt @@ -54,7 +54,7 @@ class RiverGenerator( private fun spawnRiver(initialPosition: Tile) { val endPosition = getClosestWaterTile(initialPosition) - ?: throw IllegalStateException("No water found for river destination") + ?: error("No water found for river destination") spawnRiver(initialPosition, endPosition) } @@ -64,7 +64,7 @@ class RiverGenerator( var riverCoordinate = RiverCoordinate(initialPosition.position, RiverCoordinate.BottomRightOrLeft.values().random(randomness.RNG)) - for (step in 1..maxRiverLength) { // Arbitrary max on river length, otherwise this will go in circles - rarely + repeat(maxRiverLength) { // Arbitrary max on river length, otherwise this will go in circles - rarely val riverCoordinateTile = tileMap[riverCoordinate.position] resultingTiles?.add(riverCoordinateTile) if (riverCoordinate.getAdjacentTiles(tileMap).any { it.isWater }) return diff --git a/core/src/com/unciv/logic/multiplayer/FriendList.kt b/core/src/com/unciv/logic/multiplayer/FriendList.kt index e50f5deb48..07a05b3f72 100644 --- a/core/src/com/unciv/logic/multiplayer/FriendList.kt +++ b/core/src/com/unciv/logic/multiplayer/FriendList.kt @@ -4,7 +4,7 @@ import com.unciv.UncivGame class FriendList { private val settings = UncivGame.Current.settings - var friendList = settings.multiplayer.friendList + var listOfFriends = settings.multiplayer.friendList enum class ErrorType { NOERROR, @@ -21,10 +21,10 @@ class FriendList { } fun add(friendName: String, playerID: String): ErrorType { - for (index in friendList.indices) { - if (friendList[index].name == friendName) { + for (index in listOfFriends.indices) { + if (listOfFriends[index].name == friendName) { return ErrorType.NAME - } else if (friendList[index].playerID == playerID) { + } else if (listOfFriends[index].playerID == playerID) { return ErrorType.ID } } @@ -35,27 +35,27 @@ class FriendList { } else if (playerID == UncivGame.Current.settings.multiplayer.userId) { return ErrorType.YOURSELF } - friendList.add(Friend(friendName, playerID)) + listOfFriends.add(Friend(friendName, playerID)) settings.save() return ErrorType.NOERROR } fun edit(friend: Friend, name: String, playerID: String) { - friendList.remove(friend) + listOfFriends.remove(friend) val editedFriend = Friend(name,playerID) - friendList.add(editedFriend) + listOfFriends.add(editedFriend) settings.save() } fun delete(friend: Friend) { - friendList.remove(friend) + listOfFriends.remove(friend) settings.save() } - fun getFriendsList() = friendList + fun getFriendsList() = listOfFriends fun isFriendNameInFriendList(name: String): ErrorType { - return if (friendList.firstOrNull { it.name == name } != null ) { + return if (listOfFriends.firstOrNull { it.name == name } != null ) { ErrorType.ALREADYINLIST } else { ErrorType.NOERROR @@ -63,14 +63,14 @@ class FriendList { } fun isFriendIDInFriendList(id: String): ErrorType { - return if (friendList.firstOrNull { it.playerID == id } != null ) { + return if (listOfFriends.firstOrNull { it.playerID == id } != null ) { ErrorType.ALREADYINLIST } else { ErrorType.NOERROR } } - fun getFriendById(id: String) = friendList.firstOrNull { it.playerID == id } + fun getFriendById(id: String) = listOfFriends.firstOrNull { it.playerID == id } - fun getFriendByName(name: String) = friendList.firstOrNull { it.name == name } + fun getFriendByName(name: String) = listOfFriends.firstOrNull { it.name == name } } diff --git a/core/src/com/unciv/logic/multiplayer/OnlineMultiplayer.kt b/core/src/com/unciv/logic/multiplayer/OnlineMultiplayer.kt index f139620e0c..fc54c598d6 100644 --- a/core/src/com/unciv/logic/multiplayer/OnlineMultiplayer.kt +++ b/core/src/com/unciv/logic/multiplayer/OnlineMultiplayer.kt @@ -135,11 +135,11 @@ class OnlineMultiplayer { suspend fun addGame(gameId: String, gameName: String? = null) { val saveFileName = if (gameName.isNullOrBlank()) gameId else gameName var gamePreview: GameInfoPreview - try { - gamePreview = multiplayerServer.tryDownloadGamePreview(gameId) - } catch (ex: MultiplayerFileNotFoundException) { + gamePreview = try { + multiplayerServer.tryDownloadGamePreview(gameId) + } catch (_: MultiplayerFileNotFoundException) { // Game is so old that a preview could not be found on dropbox lets try the real gameInfo instead - gamePreview = multiplayerServer.tryDownloadGame(gameId).asPreview() + multiplayerServer.tryDownloadGame(gameId).asPreview() } addGame(gamePreview, saveFileName) } diff --git a/core/src/com/unciv/logic/multiplayer/OnlineMultiplayerGame.kt b/core/src/com/unciv/logic/multiplayer/OnlineMultiplayerGame.kt index e7ffc6994a..664bbb7e6a 100644 --- a/core/src/com/unciv/logic/multiplayer/OnlineMultiplayerGame.kt +++ b/core/src/com/unciv/logic/multiplayer/OnlineMultiplayerGame.kt @@ -97,7 +97,7 @@ class OnlineMultiplayerGame( error = null MultiplayerGameUpdateUnchanged(name, updateResult.status) } - else -> throw IllegalStateException("Unknown update event") + else -> error("Unknown update event") } launchOnGLThread { EventBus.send(updateEvent) diff --git a/core/src/com/unciv/logic/trade/TradeOffer.kt b/core/src/com/unciv/logic/trade/TradeOffer.kt index 01d58ae813..8fd043e797 100644 --- a/core/src/com/unciv/logic/trade/TradeOffer.kt +++ b/core/src/com/unciv/logic/trade/TradeOffer.kt @@ -25,7 +25,7 @@ data class TradeOffer(val name: String, val type: TradeType, var amount: Int = 1 constructor() : this("", TradeType.Gold, duration = -1) // so that the json deserializer can work - @Suppress("CovariantEquals") // This is an overload, not an override of the built-in equals(Any?) + @Suppress("CovariantEquals", "WrongEqualsTypeParameter") // This is an overload, not an override of the built-in equals(Any?) fun equals(offer: TradeOffer): Boolean { return offer.name == name && offer.type == type diff --git a/core/src/com/unciv/models/metadata/GameParameters.kt b/core/src/com/unciv/models/metadata/GameParameters.kt index 7785799686..188618fb81 100644 --- a/core/src/com/unciv/models/metadata/GameParameters.kt +++ b/core/src/com/unciv/models/metadata/GameParameters.kt @@ -20,7 +20,7 @@ class GameParameters : IsPartOfGameInfoSerialization { // Default values are the var maxNumberOfPlayers = 3 var players = ArrayList().apply { add(Player(playerType = PlayerType.Human)) - for (i in 1..3) add(Player()) + repeat(3) { add(Player()) } } var randomNumberOfCityStates = false var minNumberOfCityStates = 6 diff --git a/core/src/com/unciv/models/metadata/GameSettings.kt b/core/src/com/unciv/models/metadata/GameSettings.kt index eafb8e4f88..0ee3b98062 100644 --- a/core/src/com/unciv/models/metadata/GameSettings.kt +++ b/core/src/com/unciv/models/metadata/GameSettings.kt @@ -154,7 +154,7 @@ class GameSettings { locale = try { val code = LocaleCode.valueOf(languageName) Locale(code.language, code.country) - } catch (e: Exception) { + } catch (_: Exception) { Locale.getDefault() } } diff --git a/core/src/com/unciv/models/ruleset/TextSimilarity.kt b/core/src/com/unciv/models/ruleset/TextSimilarity.kt index 24c085f965..6bcbd90bbe 100644 --- a/core/src/com/unciv/models/ruleset/TextSimilarity.kt +++ b/core/src/com/unciv/models/ruleset/TextSimilarity.kt @@ -63,7 +63,7 @@ fun getTextDistance(text1: String, text2: String): Int { i1++ i2 = firstMatchIndex2 + 1 } - else -> throw IllegalStateException("Can't compare Strings:\n\t${text1}\n\t${text2}") + else -> error("Can't compare Strings:\n\t${text1}\n\t${text2}") } } } diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt b/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt index 29389c6f1c..08306e1fab 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt @@ -93,7 +93,7 @@ object UniqueTriggerActivation { if (actualAmount <= 0) return false val tilesUnitsWerePlacedOn: MutableList = mutableListOf() - for (i in 1..actualAmount) { + repeat(actualAmount) { val placedUnit = civInfo.units.addUnit(unitName, chosenCity) if (placedUnit != null) tilesUnitsWerePlacedOn.add(placedUnit.getTile().position) diff --git a/core/src/com/unciv/models/simulation/Utils.kt b/core/src/com/unciv/models/simulation/MutableInt.kt similarity index 100% rename from core/src/com/unciv/models/simulation/Utils.kt rename to core/src/com/unciv/models/simulation/MutableInt.kt diff --git a/core/src/com/unciv/models/simulation/Simulation.kt b/core/src/com/unciv/models/simulation/Simulation.kt index 7f9dceb75f..194f808bd2 100644 --- a/core/src/com/unciv/models/simulation/Simulation.kt +++ b/core/src/com/unciv/models/simulation/Simulation.kt @@ -50,7 +50,7 @@ class Simulation( val jobs: ArrayList = ArrayList() for (threadId in 1..threadsNumber) { jobs.add(launch(CoroutineName("simulation-${threadId}")) { - for (i in 1..simulationsPerThread) { + repeat(simulationsPerThread) { val gameInfo = GameStarter.startNewGame(GameSetupInfo(newGameInfo)) gameInfo.simulateMaxTurns = maxTurns gameInfo.simulateUntilWin = true diff --git a/core/src/com/unciv/models/stats/Stats.kt b/core/src/com/unciv/models/stats/Stats.kt index e438cd0bbc..78d3fb21e4 100644 --- a/core/src/com/unciv/models/stats/Stats.kt +++ b/core/src/com/unciv/models/stats/Stats.kt @@ -45,7 +45,7 @@ open class Stats( /** Compares two instances. Not callable via `==`. */ // This is an overload, not an override conforming to the kotlin conventions of `equals(Any?)`, // so do not rely on it to be called for the `==` operator! A tad more efficient, though. - @Suppress("CovariantEquals") // historical reasons to keep this function signature + @Suppress("CovariantEquals", "WrongEqualsTypeParameter") // historical reasons to keep this function signature fun equals(otherStats: Stats): Boolean { return production == otherStats.production && food == otherStats.food diff --git a/core/src/com/unciv/ui/audio/MusicTrackController.kt b/core/src/com/unciv/ui/audio/MusicTrackController.kt index e513d2b3a7..2fad3ec847 100644 --- a/core/src/com/unciv/ui/audio/MusicTrackController.kt +++ b/core/src/com/unciv/ui/audio/MusicTrackController.kt @@ -47,8 +47,8 @@ internal class MusicTrackController(private var volume: Float) { onError: ((MusicTrackController)->Unit)? = null, onSuccess: ((MusicTrackController)->Unit)? = null ) { - if (state != State.None || music != null) - throw IllegalStateException("MusicTrackController.load should only be called once") + check(state == State.None && music == null) { "MusicTrackController.load should only be called once" } + state = State.Loading try { music = Gdx.audio.newMusic(file) @@ -105,9 +105,8 @@ internal class MusicTrackController(private var volume: Float) { * @throws IllegalStateException if called on uninitialized instance */ fun play(): Boolean { - if (!state.canPlay || music == null) { - throw IllegalStateException("MusicTrackController.play called on uninitialized instance") - } + check(state.canPlay && music != null) { "MusicTrackController.play called on uninitialized instance" } + // Unexplained observed exception: Gdx.Music.play fails with // "Unable to allocate audio buffers. AL Error: 40964" (AL_INVALID_OPERATION) // Approach: This track dies, parent controller will enter state Silence thus retry after a while. diff --git a/core/src/com/unciv/ui/components/Fonts.kt b/core/src/com/unciv/ui/components/Fonts.kt index dba73282fd..5151c81a35 100644 --- a/core/src/com/unciv/ui/components/Fonts.kt +++ b/core/src/com/unciv/ui/components/Fonts.kt @@ -165,7 +165,7 @@ class NativeBitmapFontData( try { // This sometimes fails with a "Frame buffer couldn't be constructed: incomplete attachment" error, unclear why Fonts.getPixmapFromActor(Fonts.charToRulesetImageActor[ch]!!) - } catch (ex: Exception) { + } catch (_: Exception) { Pixmap(0,0, Pixmap.Format.RGBA8888) // Empty space } else -> fontImplementation.getCharPixmap(ch) diff --git a/core/src/com/unciv/ui/components/TabbedPager.kt b/core/src/com/unciv/ui/components/TabbedPager.kt index a8bfbfcbe2..48f154b71c 100644 --- a/core/src/com/unciv/ui/components/TabbedPager.kt +++ b/core/src/com/unciv/ui/components/TabbedPager.kt @@ -119,8 +119,10 @@ open class TabbedPager( for (table in tables) table.packIfNeeded() val columns = tables.first().columns - if (tables.any { it.columns < columns }) - throw IllegalStateException("IPageExtensions.equalizeColumns needs all tables to have at least the same number of columns as the first one") + check(tables.all { it.columns >= columns }) { + "IPageExtensions.equalizeColumns needs all tables to have at least the same number of columns as the first one" + } + val widths = (0 until columns) .mapTo(ArrayList(columns)) { column -> tables.maxOf { it.getColumnWidth(column) } @@ -353,7 +355,7 @@ open class TabbedPager( override fun getPrefWidth() = dimW.pref fun setPrefWidth(width: Float) { if (dimW.growMax && width > dimW.max) dimW.max = width - if (width !in dimW.min..dimW.max) throw IllegalArgumentException("Width is not in the required range") + require(width in dimW.min..dimW.max) { "Width is not in the required range" } dimW.pref = width invalidateHierarchy() } @@ -361,7 +363,7 @@ open class TabbedPager( fun setPrefHeight(height: Float) { val contentHeight = (height - headerHeight).coerceIn(0f..dimH.limit) if (dimH.growMax && contentHeight > dimH.max) dimH.max = contentHeight - if (contentHeight !in dimH.min..dimH.max) throw IllegalArgumentException("Content height is not in the required range") + require(contentHeight in dimH.min..dimH.max) { "Content height is not in the required range" } dimH.pref = contentHeight invalidateHierarchy() } diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerBorders.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerBorders.kt index 7764ae7960..2d2eef4643 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerBorders.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerBorders.kt @@ -106,7 +106,7 @@ class TileLayerBorders(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, !borderSegment.isLeftConcave && !borderSegment.isRightConcave -> "Convex" !borderSegment.isLeftConcave && borderSegment.isRightConcave -> "ConvexConcave" borderSegment.isLeftConcave && !borderSegment.isRightConcave -> "ConcaveConvex" - else -> throw IllegalStateException("This shouldn't happen?") + else -> error("This shouldn't happen?") } val relativeWorldPosition = tile.tileMap.getNeighborTilePositionAsWorldCoords(tile, neighbor) diff --git a/core/src/com/unciv/ui/images/Portrait.kt b/core/src/com/unciv/ui/images/Portrait.kt index ef84ea2bdb..a6ebb2527b 100644 --- a/core/src/com/unciv/ui/images/Portrait.kt +++ b/core/src/com/unciv/ui/images/Portrait.kt @@ -256,8 +256,9 @@ class PortraitPromotion(name: String, size: Float) : Portrait(Type.Promotion, na if (level > 0) { val padding = if (level == 3) 0.5f else 2f val starTable = Table().apply { defaults().pad(padding) } - for (i in 1..level) + repeat(level) { starTable.add(ImageGetter.getImage("OtherIcons/Star")).size(size / 4f) + } starTable.centerX(this) starTable.y = size / 6f addActor(starTable) diff --git a/core/src/com/unciv/ui/popups/AuthPopup.kt b/core/src/com/unciv/ui/popups/AuthPopup.kt index 706bdab565..607d800390 100644 --- a/core/src/com/unciv/ui/popups/AuthPopup.kt +++ b/core/src/com/unciv/ui/popups/AuthPopup.kt @@ -23,7 +23,7 @@ class AuthPopup(stage: Stage, authSuccessful: ((Boolean) -> Unit)? = null) UncivGame.Current.onlineMultiplayer.multiplayerServer.authenticate(passwordField.text) authSuccessful?.invoke(true) close() - } catch (ex: Exception) { + } catch (_: Exception) { innerTable.clear() addGoodSizedLabel("Authentication failed").colspan(2).row() add(passwordField).colspan(2).growX().pad(16f, 0f, 16f, 0f).row() diff --git a/core/src/com/unciv/ui/popups/options/AdvancedTab.kt b/core/src/com/unciv/ui/popups/options/AdvancedTab.kt index 50c5399438..504ad29e26 100644 --- a/core/src/com/unciv/ui/popups/options/AdvancedTab.kt +++ b/core/src/com/unciv/ui/popups/options/AdvancedTab.kt @@ -334,7 +334,7 @@ private fun addSetUserId(table: Table, settings: GameSettings) { idSetLabel.setFontColor(Color.WHITE).setText("ID successfully set!".tr()) }.open(true) idSetLabel.isVisible = true - } catch (ex: Exception) { + } catch (_: Exception) { idSetLabel.isVisible = true idSetLabel.setFontColor(Color.RED).setText("Invalid ID!".tr()) } diff --git a/core/src/com/unciv/ui/popups/options/SoundTab.kt b/core/src/com/unciv/ui/popups/options/SoundTab.kt index be5552fb28..e0b25b0f5a 100644 --- a/core/src/com/unciv/ui/popups/options/SoundTab.kt +++ b/core/src/com/unciv/ui/popups/options/SoundTab.kt @@ -59,7 +59,7 @@ private fun addDownloadMusic(table: Table, optionsPopup: OptionsPopup) { optionsPopup.tabs.replacePage("Sound", soundTab(optionsPopup)) UncivGame.Current.musicController.chooseTrack(flags = MusicTrackChooserFlags.setPlayDefault) } - } catch (ex: Exception) { + } catch (_: Exception) { launchOnGLThread { errorTable.clear() errorTable.add("Could not download music!".toLabel(Color.RED)) diff --git a/core/src/com/unciv/ui/screens/cityscreen/CityStatsTable.kt b/core/src/com/unciv/ui/screens/cityscreen/CityStatsTable.kt index a9b0f52d09..e5febfb940 100644 --- a/core/src/com/unciv/ui/screens/cityscreen/CityStatsTable.kt +++ b/core/src/com/unciv/ui/screens/cityscreen/CityStatsTable.kt @@ -287,7 +287,7 @@ class CityStatsTable(val cityScreen: CityScreen): Table() { for ((specialistName, amount) in building.newSpecialists()) { val specialist = cityInfo.getRuleset().specialists[specialistName] ?: continue // probably a mod that doesn't have the specialist defined yet - for (i in 0 until amount) { + repeat(amount) { if (assignedSpec[specialistName]!! > 0) { specialistIcons.add(ImageGetter.getSpecialistIcon(specialist.colorObject)) .size(20f) diff --git a/core/src/com/unciv/ui/screens/mainmenuscreen/MainMenuScreen.kt b/core/src/com/unciv/ui/screens/mainmenuscreen/MainMenuScreen.kt index 346ae89508..f353616e5e 100644 --- a/core/src/com/unciv/ui/screens/mainmenuscreen/MainMenuScreen.kt +++ b/core/src/com/unciv/ui/screens/mainmenuscreen/MainMenuScreen.kt @@ -307,7 +307,7 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize { val (message) = LoadGameScreen.getLoadExceptionMessage(notAPlayer) launchOnGLThread { ToastPopup(message, this@MainMenuScreen) } return@run - } catch (ex: Exception) { + } catch (_: Exception) { launchOnGLThread { ToastPopup(errorText, this@MainMenuScreen) } return@run } @@ -315,7 +315,7 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize { // ...or when loading the game try { game.loadGame(newGame) - } catch (outOfMemory: OutOfMemoryError) { + } catch (_: OutOfMemoryError) { launchOnGLThread { ToastPopup("Not enough memory on phone to load game!", this@MainMenuScreen) } @@ -324,7 +324,7 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize { launchOnGLThread { ToastPopup(message, this@MainMenuScreen) } - } catch (ex: Exception) { + } catch (_: Exception) { launchOnGLThread { ToastPopup(errorText, this@MainMenuScreen) } diff --git a/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorLoadTab.kt b/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorLoadTab.kt index 5dc654861e..b8b6059349 100644 --- a/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorLoadTab.kt +++ b/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorLoadTab.kt @@ -158,6 +158,8 @@ class MapEditorLoadTab( Gdx.app.postRunnable { popup?.close() Log.error("Error loading map \"$chosenMap\"", ex) + + @Suppress("InstanceOfCheckForException") // looks cleaner like this than having 2 catch statements ToastPopup("{Error loading map!}" + (if (ex is UncivShowableException) "\n{${ex.message}}" else ""), editorScreen) } diff --git a/core/src/com/unciv/ui/screens/multiplayerscreens/AddFriendScreen.kt b/core/src/com/unciv/ui/screens/multiplayerscreens/AddFriendScreen.kt index 10ca57775b..c1d555ba9b 100644 --- a/core/src/com/unciv/ui/screens/multiplayerscreens/AddFriendScreen.kt +++ b/core/src/com/unciv/ui/screens/multiplayerscreens/AddFriendScreen.kt @@ -47,7 +47,7 @@ class AddFriendScreen : PickerScreen() { rightSideButton.onClick { try { UUID.fromString(IdChecker.checkAndReturnPlayerUuid(playerIDTextField.text)) - } catch (ex: Exception) { + } catch (_: Exception) { ToastPopup("Player ID is incorrect", this) return@onClick } diff --git a/core/src/com/unciv/ui/screens/multiplayerscreens/AddMultiplayerGameScreen.kt b/core/src/com/unciv/ui/screens/multiplayerscreens/AddMultiplayerGameScreen.kt index 232a497a56..96772cce53 100644 --- a/core/src/com/unciv/ui/screens/multiplayerscreens/AddMultiplayerGameScreen.kt +++ b/core/src/com/unciv/ui/screens/multiplayerscreens/AddMultiplayerGameScreen.kt @@ -47,7 +47,7 @@ class AddMultiplayerGameScreen : PickerScreen() { rightSideButton.onClick { try { UUID.fromString(IdChecker.checkAndReturnGameUuid(gameIDTextField.text)) - } catch (ex: Exception) { + } catch (_: Exception) { ToastPopup("Invalid game ID!", this) return@onClick } diff --git a/core/src/com/unciv/ui/screens/multiplayerscreens/EditFriendScreen.kt b/core/src/com/unciv/ui/screens/multiplayerscreens/EditFriendScreen.kt index 7b913a1e21..40987bac1c 100644 --- a/core/src/com/unciv/ui/screens/multiplayerscreens/EditFriendScreen.kt +++ b/core/src/com/unciv/ui/screens/multiplayerscreens/EditFriendScreen.kt @@ -77,7 +77,7 @@ class EditFriendScreen(selectedFriend: FriendList.Friend) : PickerScreen() { } try { UUID.fromString(IdChecker.checkAndReturnPlayerUuid(playerIDTextField.text)) - } catch (ex: Exception) { + } catch (_: Exception) { ToastPopup("Player ID is incorrect", this) return@onClick } diff --git a/core/src/com/unciv/ui/screens/multiplayerscreens/EditMultiplayerGameInfoScreen.kt b/core/src/com/unciv/ui/screens/multiplayerscreens/EditMultiplayerGameInfoScreen.kt index c4ec3aa104..37e7af26e5 100644 --- a/core/src/com/unciv/ui/screens/multiplayerscreens/EditMultiplayerGameInfoScreen.kt +++ b/core/src/com/unciv/ui/screens/multiplayerscreens/EditMultiplayerGameInfoScreen.kt @@ -120,20 +120,24 @@ class EditMultiplayerGameInfoScreen(val multiplayerGame: OnlineMultiplayerGame) } } } catch (ex: Exception) { - if (ex is MultiplayerAuthException) { - launchOnGLThread { - AuthPopup(this@EditMultiplayerGameInfoScreen) { - success -> if (success) resign(multiplayerGame) - }.open(true) + val (message) = LoadGameScreen.getLoadExceptionMessage(ex) + + when (ex) { + is MultiplayerAuthException -> { + launchOnGLThread { + AuthPopup(this@EditMultiplayerGameInfoScreen) { success -> + if (success) resign(multiplayerGame) + }.open(true) + } + return@runOnNonDaemonThreadPool } - return@runOnNonDaemonThreadPool } - val (message) = LoadGameScreen.getLoadExceptionMessage(ex) launchOnGLThread { popup.reuseWith(message, true) } } + } } } diff --git a/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt index 25f4e14988..c4ec40d939 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt @@ -354,7 +354,7 @@ class MapParametersTable( seedTextField.onChange { mapParameters.seed = try { seedTextField.text.toLong() - } catch (e: Exception) { + } catch (_: Exception) { 0L } } diff --git a/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt b/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt index 4c5d304b54..3099898700 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt @@ -125,7 +125,7 @@ class NewGameScreen( for (player in gameSetupInfo.gameParameters.players.filter { it.playerType == PlayerType.Human }) { try { UUID.fromString(IdChecker.checkAndReturnPlayerUuid(player.playerId)) - } catch (ex: Exception) { + } catch (_: Exception) { val invalidPlayerIdPopup = Popup(this) invalidPlayerIdPopup.addGoodSizedLabel("Invalid player ID!".tr()).row() invalidPlayerIdPopup.addCloseButton() @@ -272,7 +272,7 @@ class NewGameScreen( con.connect() true - } catch(ex: Throwable) { + } catch(_: Throwable) { false } } diff --git a/core/src/com/unciv/ui/screens/newgamescreen/PlayerPickerTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/PlayerPickerTable.kt index 47eb72f4b0..f8c58a011b 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/PlayerPickerTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/PlayerPickerTable.kt @@ -235,7 +235,7 @@ class PlayerPickerTable( UUID.fromString(IdChecker.checkAndReturnPlayerUuid(playerIdTextField.text)) player.playerId = playerIdTextField.text.trim() errorLabel.apply { setText("✔");setFontColor(Color.GREEN) } - } catch (ex: Exception) { + } catch (_: Exception) { errorLabel.apply { setText("✘");setFontColor(Color.RED) } } } @@ -258,7 +258,7 @@ class PlayerPickerTable( add(copyFromClipboardButton).right().colspan(3).fillX().pad(5f).row() //check if friends list is empty before adding the select friend button - if (friendList.friendList.isNotEmpty()) { + if (friendList.listOfFriends.isNotEmpty()) { val selectPlayerFromFriendsList = "Player ID from friends list".toTextButton() selectPlayerFromFriendsList.onClick { popupFriendPicker(player) @@ -328,7 +328,7 @@ class PlayerPickerTable( * @return [Sequence] of available [FriendList.Friend]s */ internal fun getAvailableFriends(): Sequence { - val friendListWithRemovedFriends = friendList.friendList.toMutableList() + val friendListWithRemovedFriends = friendList.listOfFriends.toMutableList() for (index in gameParameters.players.indices) { val currentFriendId = previousScreen.gameSetupInfo.gameParameters.players[index].playerId friendListWithRemovedFriends.remove(friendList.getFriendById(currentFriendId)) diff --git a/core/src/com/unciv/ui/screens/overviewscreen/CityOverviewTable.kt b/core/src/com/unciv/ui/screens/overviewscreen/CityOverviewTab.kt similarity index 100% rename from core/src/com/unciv/ui/screens/overviewscreen/CityOverviewTable.kt rename to core/src/com/unciv/ui/screens/overviewscreen/CityOverviewTab.kt diff --git a/core/src/com/unciv/ui/screens/overviewscreen/ReligionOverviewTable.kt b/core/src/com/unciv/ui/screens/overviewscreen/ReligionOverviewTab.kt similarity index 100% rename from core/src/com/unciv/ui/screens/overviewscreen/ReligionOverviewTable.kt rename to core/src/com/unciv/ui/screens/overviewscreen/ReligionOverviewTab.kt diff --git a/core/src/com/unciv/ui/screens/overviewscreen/ResourcesOverviewTable.kt b/core/src/com/unciv/ui/screens/overviewscreen/ResourcesOverviewTab.kt similarity index 100% rename from core/src/com/unciv/ui/screens/overviewscreen/ResourcesOverviewTable.kt rename to core/src/com/unciv/ui/screens/overviewscreen/ResourcesOverviewTab.kt diff --git a/core/src/com/unciv/ui/screens/overviewscreen/StatsOverviewTable.kt b/core/src/com/unciv/ui/screens/overviewscreen/StatsOverviewTab.kt similarity index 100% rename from core/src/com/unciv/ui/screens/overviewscreen/StatsOverviewTable.kt rename to core/src/com/unciv/ui/screens/overviewscreen/StatsOverviewTab.kt diff --git a/core/src/com/unciv/ui/screens/overviewscreen/TradesOverviewTable.kt b/core/src/com/unciv/ui/screens/overviewscreen/TradesOverviewTab.kt similarity index 94% rename from core/src/com/unciv/ui/screens/overviewscreen/TradesOverviewTable.kt rename to core/src/com/unciv/ui/screens/overviewscreen/TradesOverviewTab.kt index 917fd9c8a1..50eda69024 100644 --- a/core/src/com/unciv/ui/screens/overviewscreen/TradesOverviewTable.kt +++ b/core/src/com/unciv/ui/screens/overviewscreen/TradesOverviewTab.kt @@ -65,8 +65,10 @@ class TradesOverviewTab( if (!offerText.contains("\n")) offerText += "\n" table.add(offerText.toLabel(civ.nation.getInnerColor())).row() } - for (i in 1..numberOfOtherSidesOffers - offersList.size) - table.add("\n".toLabel()).row() // we want both sides of the general table to have the same number of rows + repeat(numberOfOtherSidesOffers - offersList.size) { + table.add("\n".toLabel()) + .row() // we want both sides of the general table to have the same number of rows + } return table } } diff --git a/core/src/com/unciv/ui/screens/overviewscreen/UnitOverviewTable.kt b/core/src/com/unciv/ui/screens/overviewscreen/UnitOverviewTab.kt similarity index 100% rename from core/src/com/unciv/ui/screens/overviewscreen/UnitOverviewTable.kt rename to core/src/com/unciv/ui/screens/overviewscreen/UnitOverviewTab.kt diff --git a/core/src/com/unciv/ui/screens/overviewscreen/WonderOverviewTable.kt b/core/src/com/unciv/ui/screens/overviewscreen/WonderOverviewTab.kt similarity index 99% rename from core/src/com/unciv/ui/screens/overviewscreen/WonderOverviewTable.kt rename to core/src/com/unciv/ui/screens/overviewscreen/WonderOverviewTab.kt index 6d4862debc..fe16757f85 100644 --- a/core/src/com/unciv/ui/screens/overviewscreen/WonderOverviewTable.kt +++ b/core/src/com/unciv/ui/screens/overviewscreen/WonderOverviewTab.kt @@ -44,8 +44,9 @@ class WonderOverviewTab( top() defaults().pad(10f).align(Align.center) - for (i in 1..5) + repeat(5) { add() // dummies so equalizeColumns can work because the first grid cell is colspan(5) + } row() createGrid() diff --git a/core/src/com/unciv/ui/screens/pickerscreens/GitHub.kt b/core/src/com/unciv/ui/screens/pickerscreens/GitHub.kt index d5940461cf..3423f99e70 100644 --- a/core/src/com/unciv/ui/screens/pickerscreens/GitHub.kt +++ b/core/src/com/unciv/ui/screens/pickerscreens/GitHub.kt @@ -270,6 +270,7 @@ object Github { } var url: String = "" + @Suppress("MemberNameEqualsClassName") var tree = ArrayList() } diff --git a/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt b/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt index 236ecef951..5806987e53 100644 --- a/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt +++ b/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt @@ -387,7 +387,7 @@ class ModManagementScreen( private fun addModInfoToActionTable( modName: String, repoUrl: String, - default_branch: String, + defaultBranch: String, updatedAt: String, author: String, modSize: Int @@ -401,7 +401,7 @@ class ModManagementScreen( if (repoUrl.isEmpty()) addLocalPreviewImage(imageHolder, modName) else - addPreviewImage(imageHolder, repoUrl, default_branch) + addPreviewImage(imageHolder, repoUrl, defaultBranch) modActionTable.add(imageHolder).row() @@ -442,7 +442,7 @@ class ModManagementScreen( private fun addPreviewImage( imageHolder: Table, repoUrl: String, - default_branch: String + defaultBranch: String ) { if (!repoUrl.startsWith("http")) return // invalid url @@ -454,7 +454,7 @@ class ModManagementScreen( } Concurrency.run { - val imagePixmap = Github.tryGetPreviewImage(repoUrl, default_branch) + val imagePixmap = Github.tryGetPreviewImage(repoUrl, defaultBranch) if (imagePixmap == null) { repoUrlToPreviewImage[repoUrl] = null diff --git a/core/src/com/unciv/ui/screens/savescreens/LoadOrSaveScreen.kt b/core/src/com/unciv/ui/screens/savescreens/LoadOrSaveScreen.kt index 919de08ef2..63aa65a887 100644 --- a/core/src/com/unciv/ui/screens/savescreens/LoadOrSaveScreen.kt +++ b/core/src/com/unciv/ui/screens/savescreens/LoadOrSaveScreen.kt @@ -89,9 +89,9 @@ abstract class LoadOrSaveScreen( } else { "Failed to delete [$name]." } - } catch (ex: SecurityException) { + } catch (_: SecurityException) { "Insufficient permissions to delete [$name]." - } catch (ex: Throwable) { + } catch (_: Throwable) { "Failed to delete [$name]." } descriptionLabel.setText(result.tr()) @@ -126,7 +126,7 @@ abstract class LoadOrSaveScreen( "${saveGameFile.name()}\n{Saved at}: ${savedAt.formatDate()}\n" + "$playerCivNames, ${game.difficulty.tr()}, ${Fonts.turn}${game.turns}\n" + "{Base ruleset:} ${game.gameParameters.baseRuleset}$mods" - } catch (ex: Exception) { + } catch (_: Exception) { "\n{Could not load game}!" } diff --git a/core/src/com/unciv/ui/screens/savescreens/QuickSave.kt b/core/src/com/unciv/ui/screens/savescreens/QuickSave.kt index 6d55df2236..f7848e4f84 100644 --- a/core/src/com/unciv/ui/screens/savescreens/QuickSave.kt +++ b/core/src/com/unciv/ui/screens/savescreens/QuickSave.kt @@ -70,7 +70,7 @@ object QuickSave { val savedGame: GameInfo try { savedGame = screen.game.files.loadLatestAutosave() - } catch (oom: OutOfMemoryError) { + } catch (_: OutOfMemoryError) { outOfMemory() return@run } catch (ex: Exception) { @@ -89,7 +89,7 @@ object QuickSave { if (savedGame.gameParameters.isOnlineMultiplayer) { try { screen.game.onlineMultiplayer.loadGame(savedGame) - } catch (oom: OutOfMemoryError) { + } catch (_: OutOfMemoryError) { outOfMemory() } catch (notAPlayer: UncivShowableException) { val (message) = LoadGameScreen.getLoadExceptionMessage(notAPlayer) @@ -108,7 +108,7 @@ object QuickSave { } else { try { screen.game.loadGame(savedGame) - } catch (oom: OutOfMemoryError) { + } catch (_: OutOfMemoryError) { outOfMemory() } catch (ex: Exception) { launchOnGLThread { diff --git a/core/src/com/unciv/ui/screens/victoryscreen/ReplayMap.kt b/core/src/com/unciv/ui/screens/victoryscreen/ReplayMap.kt index 5a49ec4aa5..bd75e5fe71 100644 --- a/core/src/com/unciv/ui/screens/victoryscreen/ReplayMap.kt +++ b/core/src/com/unciv/ui/screens/victoryscreen/ReplayMap.kt @@ -47,6 +47,7 @@ abstract class IndependentMiniMap( protected open fun includeTileFilter(tile: Tile): Boolean = true private fun createReplayMap(tileSize: Float): List { + @Suppress("EmptyFunctionBlock") val doNothing = fun(){} val tiles = ArrayList(tileMap.values.size) for (tile in tileMap.values.filter(::includeTileFilter) ) { diff --git a/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt b/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt index 64ed335332..719c12b088 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt @@ -271,13 +271,20 @@ class WorldMapHolder( try { tileToMoveTo = selectedUnit.movement.getTileToMoveToThisTurn(targetTile) } catch (ex: Exception) { - // This is normal e.g. when selecting an air unit then right-clicking on an empty tile - // Or telling a ship to run onto a coastal land tile. - if (ex !is UnitMovement.UnreachableDestinationException) - Log.error("Exception in getTileToMoveToThisTurn", ex) + when (ex) { + is UnitMovement.UnreachableDestinationException -> { + // This is normal e.g. when selecting an air unit then right-clicking on an empty tile + // Or telling a ship to run onto a coastal land tile. + // Do nothing + } + else -> { + Log.error("Exception in getTileToMoveToThisTurn", ex) + } + } return@run // can't move here } + worldScreen.preActionGameInfo = worldScreen.gameInfo.clone() launchOnGLThread { diff --git a/core/src/com/unciv/ui/screens/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/screens/worldscreen/WorldScreen.kt index 96897afe69..afb37003f2 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/WorldScreen.kt @@ -571,23 +571,32 @@ class WorldScreen( if (originalGameInfo.gameParameters.isOnlineMultiplayer) { try { game.onlineMultiplayer.updateGame(gameInfoClone) - } catch (ex: Exception) { - if (ex is MultiplayerAuthException) { - launchOnGLThread { - AuthPopup(this@WorldScreen) { - success -> if (success) nextTurn() - }.open(true) + }catch (ex: Exception) { + when (ex) { + is MultiplayerAuthException -> { + launchOnGLThread { + AuthPopup(this@WorldScreen) { + success -> if (success) nextTurn() + }.open(true) + } } - } else { - val message = when (ex) { - is FileStorageRateLimitReached -> "Server limit reached! Please wait for [${ex.limitRemainingSeconds}] seconds" - else -> "Could not upload game!" + is FileStorageRateLimitReached -> { + val message = "Server limit reached! Please wait for [${ex.limitRemainingSeconds}] seconds" + launchOnGLThread { + val cantUploadNewGamePopup = Popup(this@WorldScreen) + cantUploadNewGamePopup.addGoodSizedLabel(message).row() + cantUploadNewGamePopup.addCloseButton() + cantUploadNewGamePopup.open() + } } - launchOnGLThread { // Since we're changing the UI, that should be done on the main thread - val cantUploadNewGamePopup = Popup(this@WorldScreen) - cantUploadNewGamePopup.addGoodSizedLabel(message).row() - cantUploadNewGamePopup.addCloseButton() - cantUploadNewGamePopup.open() + else -> { + val message = "Could not upload game!" + launchOnGLThread { + val cantUploadNewGamePopup = Popup(this@WorldScreen) + cantUploadNewGamePopup.addGoodSizedLabel(message).row() + cantUploadNewGamePopup.addCloseButton() + cantUploadNewGamePopup.open() + } } } @@ -595,6 +604,7 @@ class WorldScreen( this@WorldScreen.shouldUpdate = true return@runOnNonDaemonThreadPool } + } if (game.gameInfo != originalGameInfo) // while this was turning we loaded another game @@ -757,7 +767,7 @@ private fun startNewScreenJob(gameInfo: GameInfo, autosaveDisabled:Boolean = fal ToastPopup(message, mainMenu) } return@run - } catch (oom: OutOfMemoryError) { + } catch (_: OutOfMemoryError) { withGLContext { val mainMenu = UncivGame.Current.goToMainMenu() ToastPopup("Not enough memory on phone to load game!", mainMenu) diff --git a/core/src/com/unciv/utils/Debug.kt b/core/src/com/unciv/utils/DebugUtils.kt similarity index 100% rename from core/src/com/unciv/utils/Debug.kt rename to core/src/com/unciv/utils/DebugUtils.kt diff --git a/core/src/com/unciv/utils/Log.kt b/core/src/com/unciv/utils/Log.kt index ea584a98bd..883895d67a 100644 --- a/core/src/com/unciv/utils/Log.kt +++ b/core/src/com/unciv/utils/Log.kt @@ -232,6 +232,7 @@ private fun replaceLambdasWithValues(params: Array): Array { private fun getTag(): Tag { + @Suppress("ThrowingExceptionsWithoutMessageOrCause") val firstOutsideStacktrace = Throwable().stackTrace.filter { "com.unciv.utils.Log" !in it.className }.first() val simpleClassName = firstOutsideStacktrace.className.substringAfterLast('.') return Tag(removeAnonymousSuffix(simpleClassName)) diff --git a/desktop/src/com/unciv/app/desktop/DesktopFont.kt b/desktop/src/com/unciv/app/desktop/DesktopFont.kt index 19a15d41b9..438a8735a0 100644 --- a/desktop/src/com/unciv/app/desktop/DesktopFont.kt +++ b/desktop/src/com/unciv/app/desktop/DesktopFont.kt @@ -48,7 +48,7 @@ class DesktopFont : FontImplementation { font = Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(size.toFloat()) ge.registerFont(font) } - catch (e: Exception) + catch (_: Exception) { // Fallback to default, if failed. font = Font(Fonts.DEFAULT_FONT_FAMILY, Font.PLAIN, size) diff --git a/desktop/src/com/unciv/app/desktop/DiscordUpdater.kt b/desktop/src/com/unciv/app/desktop/DiscordUpdater.kt index d383f5d046..8583934fc5 100644 --- a/desktop/src/com/unciv/app/desktop/DiscordUpdater.kt +++ b/desktop/src/com/unciv/app/desktop/DiscordUpdater.kt @@ -43,7 +43,7 @@ class DiscordUpdater { debug("Exception while updating Discord Rich Presence", ex) } } - } catch (ex: Throwable) { + } catch (_: Throwable) { // This needs to be a Throwable because if we can't find the discord_rpc library, we'll get a UnsatisfiedLinkError, which is NOT an exception. debug("Could not initialize Discord") } diff --git a/desktop/src/com/unciv/app/desktop/SystemUtils.kt b/desktop/src/com/unciv/app/desktop/SystemUtils.kt index 5da201f6c4..4fde41f678 100644 --- a/desktop/src/com/unciv/app/desktop/SystemUtils.kt +++ b/desktop/src/com/unciv/app/desktop/SystemUtils.kt @@ -33,7 +33,7 @@ object SystemUtils { // Java VM memory limit as set by -Xmx val maxMemory = try { Runtime.getRuntime().maxMemory() / 1024 / 1024 - } catch (ex: Throwable) { -1L } + } catch (_: Throwable) { -1L } if (maxMemory > 0) { builder.append('\t') builder.appendLine("Max Memory: $maxMemory MB") @@ -69,7 +69,7 @@ object SystemUtils { goodLines.map { it.split("REG_SZ") } .filter { it.size == 2 } .associate { it[0].trim() to it[1].trim() } - } catch (ex: Throwable) { mapOf() } + } catch (_: Throwable) { mapOf() } if ("ProductName" !in entries) return "" @@ -89,7 +89,7 @@ object SystemUtils { .map { it.split('=') } .filter { it.size == 2 } .associate { it[0] to it[1].removeSuffix("\"").removePrefix("\"") } - } catch (ex: Throwable) { mapOf() } + } catch (_: Throwable) { mapOf() } if ("NAME" !in osRelease) return "" return osRelease["PRETTY_NAME"] ?: "${osRelease["NAME"]} ${osRelease["VERSION"]}" } diff --git a/detekt/config/detekt-warnings.yml b/detekt/config/detekt-warnings.yml index 92d3ce7ff9..be1cf9b7d4 100644 --- a/detekt/config/detekt-warnings.yml +++ b/detekt/config/detekt-warnings.yml @@ -283,7 +283,7 @@ exceptions: ThrowingNewInstanceOfSameException: active: true TooGenericExceptionCaught: - active: true + active: false excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] exceptionNames: - 'ArrayIndexOutOfBoundsException' @@ -296,7 +296,7 @@ exceptions: - 'Throwable' allowedExceptionNameRegex: '_|(ignore|expected).*' TooGenericExceptionThrown: - active: true + active: false exceptionNames: - 'Error' - 'Exception' @@ -390,7 +390,7 @@ performance: active: true excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] SpreadOperator: - active: true + active: false # not considered a performance issue as of Kotlin 1.1.60 and 1.2-Beta2 excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] UnnecessaryPartOfBinaryExpression: active: false @@ -569,7 +569,7 @@ style: - reason: 'Kotlin does not support @Inherited annotation, see https://youtrack.jetbrains.com/issue/KT-22265' value: 'java.lang.annotation.Inherited' ForbiddenComment: - active: true + active: false values: - 'FIXME:' - 'STOPSHIP:' diff --git a/tests/src/com/unciv/dev/FasterUIDevelopment.kt b/tests/src/com/unciv/dev/FasterUIDevelopment.kt index c756328ede..30b9fa2812 100644 --- a/tests/src/com/unciv/dev/FasterUIDevelopment.kt +++ b/tests/src/com/unciv/dev/FasterUIDevelopment.kt @@ -41,6 +41,7 @@ object FasterUIDevelopment { actor = "This could be your UI element in development!".toLabel() } + @Suppress("EmptyFunctionBlock") fun afterAdd() { } } diff --git a/tests/src/com/unciv/testing/BasicTests.kt b/tests/src/com/unciv/testing/BasicTests.kt index 00ac049d19..bed615928d 100644 --- a/tests/src/com/unciv/testing/BasicTests.kt +++ b/tests/src/com/unciv/testing/BasicTests.kt @@ -329,7 +329,7 @@ class BasicTests { val statCount = Stat.values().size val stats = Stats() - for (i in 0 until iterations) { + repeat(iterations) { val value: Float = random.nextDouble(-10.0, 10.0).toFloat() stats.add( Stats(gold = value) ) stats.forEach { diff --git a/tests/src/com/unciv/testing/SerializationTests.kt b/tests/src/com/unciv/testing/SerializationTests.kt index 1bd624f402..d2e09aefba 100644 --- a/tests/src/com/unciv/testing/SerializationTests.kt +++ b/tests/src/com/unciv/testing/SerializationTests.kt @@ -89,7 +89,7 @@ class SerializationTests { fun canSerializeGame() { val json = try { json().toJson(game) - } catch (ex: Exception) { + } catch (_: Exception) { "" } Assert.assertTrue("This test will only pass when a game can be serialized", json.isNotEmpty()) diff --git a/tests/src/com/unciv/ui/screens/victoryscreen/RankingTypeTest.kt b/tests/src/com/unciv/ui/screens/victoryscreen/RankingTypeTests.kt similarity index 100% rename from tests/src/com/unciv/ui/screens/victoryscreen/RankingTypeTest.kt rename to tests/src/com/unciv/ui/screens/victoryscreen/RankingTypeTests.kt