diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt index 907c6309d0..1512ea1a54 100644 --- a/buildSrc/src/main/kotlin/BuildConfig.kt +++ b/buildSrc/src/main/kotlin/BuildConfig.kt @@ -3,8 +3,8 @@ package com.unciv.build object BuildConfig { const val kotlinVersion = "1.4.30" const val appName = "Unciv" - const val appCodeNumber = 571 - const val appVersion = "3.14.12" + const val appCodeNumber = 572 + const val appVersion = "3.14.13" const val gdxVersion = "1.10.0" const val roboVMVersion = "2.3.1" diff --git a/core/src/com/unciv/logic/automation/Automation.kt b/core/src/com/unciv/logic/automation/Automation.kt index d1ac8fa804..8417ed41ba 100644 --- a/core/src/com/unciv/logic/automation/Automation.kt +++ b/core/src/com/unciv/logic/automation/Automation.kt @@ -14,7 +14,7 @@ import kotlin.math.sqrt object Automation { - fun rankTileForCityWork(tile:TileInfo, city: CityInfo, foodWeight: Float = 1f): Float { + fun rankTileForCityWork(tile: TileInfo, city: CityInfo, foodWeight: Float = 1f): Float { val stats = tile.getTileStats(city, city.civInfo) return rankStatsForCityWork(stats, city, foodWeight) } @@ -29,7 +29,7 @@ object Automation { rank += stats.culture / 2 rank += stats.gold / 5 // it's barely worth anything at this point } else { - if (stats.food <= 2 || city.civInfo.getHappiness() > 5) rank += stats.food * 1.2f * foodWeight //food get more value to keep city growing + if (stats.food <= 2 || city.civInfo.getHappiness() > 5) rank += stats.food * 1.2f * foodWeight // food get more value to keep city growing else rank += (2.4f + (stats.food - 2) / 2) * foodWeight // 1.2 point for each food up to 2, from there on half a point if (city.civInfo.gold < 0 && city.civInfo.statsForNextTurn.gold <= 0) @@ -57,9 +57,11 @@ object Automation { city.cityConstructions.currentConstructionFromQueue = chosenUnitName } - fun chooseMilitaryUnit(city: CityInfo) : String? { - var militaryUnits = city.cityConstructions.getConstructableUnits().filter { !it.unitType.isCivilian() } - if (militaryUnits.map { it.name }.contains(city.cityConstructions.currentConstructionFromQueue)) + fun chooseMilitaryUnit(city: CityInfo): String? { + var militaryUnits = + city.cityConstructions.getConstructableUnits().filter { !it.unitType.isCivilian() } + if (militaryUnits.map { it.name } + .contains(city.cityConstructions.currentConstructionFromQueue)) return city.cityConstructions.currentConstructionFromQueue // This is so that the AI doesn't use all its aluminum on units and have none left for spaceship parts @@ -67,41 +69,49 @@ object Automation { if (aluminum != null && aluminum < 2) // mods may have no aluminum militaryUnits.filter { !it.getResourceRequirements().containsKey("Aluminum") } - val findWaterConnectedCitiesAndEnemies = BFS(city.getCenterTile()) { it.isWater || it.isCityCenter() } + val findWaterConnectedCitiesAndEnemies = + BFS(city.getCenterTile()) { it.isWater || it.isCityCenter() } findWaterConnectedCitiesAndEnemies.stepToEnd() if (findWaterConnectedCitiesAndEnemies.tilesReached.keys.none { - (it.isCityCenter() && it.getOwner() != city.civInfo) - || (it.militaryUnit != null && it.militaryUnit!!.civInfo != city.civInfo) - }) // there is absolutely no reason for you to make water units on this body of water. - militaryUnits = militaryUnits.filter { it.unitType.isLandUnit() || it.unitType.isAirUnit() } + (it.isCityCenter() && it.getOwner() != city.civInfo) + || (it.militaryUnit != null && it.militaryUnit!!.civInfo != city.civInfo) + }) // there is absolutely no reason for you to make water units on this body of water. + militaryUnits = + militaryUnits.filter { it.unitType.isLandUnit() || it.unitType.isAirUnit() } val chosenUnit: BaseUnit if (!city.civInfo.isAtWar() && city.civInfo.cities.any { it.getCenterTile().militaryUnit == null } - && militaryUnits.any { it.unitType == UnitType.Ranged }) // this is for city defence so get an archery unit if we can - chosenUnit = militaryUnits.filter { it.unitType == UnitType.Ranged }.maxBy { it.cost }!! + && militaryUnits.any { it.unitType == UnitType.Ranged }) // this is for city defence so get an archery unit if we can + chosenUnit = militaryUnits.filter { it.unitType == UnitType.Ranged } + .maxByOrNull { it.cost }!! else { // randomize type of unit and take the most expensive of its kind - val availableTypes = militaryUnits.map { it.unitType }.distinct().filterNot { it == UnitType.Scout }.toList() + val availableTypes = + militaryUnits.map { it.unitType }.distinct().filterNot { it == UnitType.Scout } + .toList() if (availableTypes.isEmpty()) return null val randomType = availableTypes.random() - chosenUnit = militaryUnits.filter { it.unitType == randomType }.maxBy { it.cost }!! + chosenUnit = militaryUnits.filter { it.unitType == randomType } + .maxByOrNull { it.cost }!! } return chosenUnit.name } - fun evaluteCombatStrength(civInfo: CivilizationInfo): Int { + fun evaluateCombatStrength(civInfo: CivilizationInfo): Int { // Since units become exponentially stronger per combat strength increase, we square em all - fun square(x:Int) = x*x - val unitStrength = civInfo.getCivUnits().map { square(max(it.baseUnit().strength, it.baseUnit().rangedStrength)) }.sum() + fun square(x: Int) = x * x + val unitStrength = civInfo.getCivUnits() + .map { square(max(it.baseUnit().strength, it.baseUnit().rangedStrength)) }.sum() return sqrt(unitStrength.toDouble()).toInt() + 1 //avoid 0, because we divide by the result } - fun threatAssessment(assessor:CivilizationInfo, assessed: CivilizationInfo): ThreatLevel { - val powerLevelComparison = evaluteCombatStrength(assessed)/evaluteCombatStrength(assessor).toFloat() + fun threatAssessment(assessor: CivilizationInfo, assessed: CivilizationInfo): ThreatLevel { + val powerLevelComparison = + evaluateCombatStrength(assessed) / evaluateCombatStrength(assessor).toFloat() return when { - powerLevelComparison>2 -> ThreatLevel.VeryHigh - powerLevelComparison>1.5f -> ThreatLevel.High - powerLevelComparison<(1/1.5f) -> ThreatLevel.Low - powerLevelComparison<0.5f -> ThreatLevel.VeryLow + powerLevelComparison > 2 -> ThreatLevel.VeryHigh + powerLevelComparison > 1.5f -> ThreatLevel.High + powerLevelComparison < (1 / 1.5f) -> ThreatLevel.Low + powerLevelComparison < 0.5f -> ThreatLevel.VeryLow else -> ThreatLevel.Medium } } @@ -142,5 +152,4 @@ enum class ThreatLevel{ Medium, High, VeryHigh -} - +} \ No newline at end of file diff --git a/core/src/com/unciv/logic/automation/ConstructionAutomation.kt b/core/src/com/unciv/logic/automation/ConstructionAutomation.kt index 2abe477c3b..0f23dd392c 100644 --- a/core/src/com/unciv/logic/automation/ConstructionAutomation.kt +++ b/core/src/com/unciv/logic/automation/ConstructionAutomation.kt @@ -21,7 +21,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){ val buildableNotWonders = cityConstructions.getBuildableBuildings() .filterNot { it.isWonder || it.isNationalWonder } - val buildableWonders = cityConstructions.getBuildableBuildings() + private val buildableWonders = cityConstructions.getBuildableBuildings() .filter { it.isWonder || it.isNationalWonder } val civUnits = civInfo.getCivUnits() @@ -33,7 +33,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){ val isAtWar = civInfo.isAtWar() val preferredVictoryType = civInfo.victoryType() - val averageProduction = civInfo.cities.map { it.cityStats.currentCityStats.production }.average() + private val averageProduction = civInfo.cities.map { it.cityStats.currentCityStats.production }.average() val cityIsOverAverageProduction = cityInfo.cityStats.currentCityStats.production >= averageProduction val relativeCostEffectiveness = ArrayList() @@ -205,7 +205,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){ if (!buildableWonders.any()) return val highestPriorityWonder = buildableWonders - .maxBy { getWonderPriority(it) }!! + .maxByOrNull { getWonderPriority(it) }!! val citiesBuildingWonders = civInfo.cities .count { it.cityConstructions.isBuildingWonder() } diff --git a/core/src/com/unciv/logic/automation/NextTurnAutomation.kt b/core/src/com/unciv/logic/automation/NextTurnAutomation.kt index e58fad6401..9eeab29b4c 100644 --- a/core/src/com/unciv/logic/automation/NextTurnAutomation.kt +++ b/core/src/com/unciv/logic/automation/NextTurnAutomation.kt @@ -360,12 +360,12 @@ object NextTurnAutomation { } private fun motivationToAttack(civInfo: CivilizationInfo, otherCiv: CivilizationInfo): Int { - val ourCombatStrength = Automation.evaluteCombatStrength(civInfo).toFloat() - var theirCombatStrength = Automation.evaluteCombatStrength(otherCiv) + val ourCombatStrength = Automation.evaluateCombatStrength(civInfo).toFloat() + var theirCombatStrength = Automation.evaluateCombatStrength(otherCiv) //for city-states, also consider there protectors if(otherCiv.isCityState() and otherCiv.getProtectorCivs().isNotEmpty()) { - theirCombatStrength += otherCiv.getProtectorCivs().sumOf{Automation.evaluteCombatStrength(it)} + theirCombatStrength += otherCiv.getProtectorCivs().sumOf{Automation.evaluateCombatStrength(it)} } if (theirCombatStrength > ourCombatStrength) return 0 diff --git a/core/src/com/unciv/logic/battle/BattleDamage.kt b/core/src/com/unciv/logic/battle/BattleDamage.kt index 48c7c38f8f..9e34432bc5 100644 --- a/core/src/com/unciv/logic/battle/BattleDamage.kt +++ b/core/src/com/unciv/logic/battle/BattleDamage.kt @@ -118,7 +118,6 @@ object BattleDamage { fun getAttackModifiers( attacker: ICombatant, - tileToAttackFrom: TileInfo?, defender: ICombatant ): Counter { val modifiers = getGeneralModifiers(attacker, defender) @@ -280,7 +279,7 @@ object BattleDamage { defender: ICombatant ): Float { val attackModifier = - modifiersToMultiplicationBonus(getAttackModifiers(attacker, tileToAttackFrom, defender)) + modifiersToMultiplicationBonus(getAttackModifiers(attacker, defender)) return attacker.getAttackingStrength() * attackModifier } diff --git a/core/src/com/unciv/logic/city/IConstruction.kt b/core/src/com/unciv/logic/city/IConstruction.kt index 71fe1c1108..5101a79bae 100644 --- a/core/src/com/unciv/logic/city/IConstruction.kt +++ b/core/src/com/unciv/logic/city/IConstruction.kt @@ -10,7 +10,7 @@ interface IConstruction : INamed { fun getGoldCost(civInfo: CivilizationInfo): Int fun isBuildable(cityConstructions: CityConstructions): Boolean fun shouldBeDisplayed(cityConstructions: CityConstructions): Boolean - fun postBuildEvent(construction: CityConstructions, wasBought: Boolean = false): Boolean // Yes I'm hilarious. + fun postBuildEvent(cityConstructions: CityConstructions, wasBought: Boolean = false): Boolean // Yes I'm hilarious. fun getResourceRequirements(): HashMap fun canBePurchased(): Boolean } @@ -59,7 +59,7 @@ open class PerpetualConstruction(override var name: String, val description: Str override fun isBuildable(cityConstructions: CityConstructions): Boolean = throw Exception("Impossible!") - override fun postBuildEvent(construction: CityConstructions, wasBought: Boolean) = + override fun postBuildEvent(cityConstructions: CityConstructions, wasBought: Boolean) = throw Exception("Impossible!") override fun getResourceRequirements(): HashMap = hashMapOf() diff --git a/core/src/com/unciv/logic/civilization/QuestManager.kt b/core/src/com/unciv/logic/civilization/QuestManager.kt index f4e4e8edca..214b8a3ba1 100644 --- a/core/src/com/unciv/logic/civilization/QuestManager.kt +++ b/core/src/com/unciv/logic/civilization/QuestManager.kt @@ -51,7 +51,7 @@ class QuestManager { /** Number of turns left before this city state can start a new individual quest */ private var individualQuestCountdown: HashMap = HashMap() - /** Returns [true] if [civInfo] have active quests for [challenger] */ + /** Returns true if [civInfo] have active quests for [challenger] */ fun haveQuestsFor(challenger: CivilizationInfo): Boolean = assignedQuests.any { it.assignee == challenger.civName } fun clone(): QuestManager { @@ -195,7 +195,7 @@ class QuestManager { if (quests.isEmpty()) return - val topScore = quests.map { getScoreForQuest(it) }.max()!! + val topScore = quests.map { getScoreForQuest(it) }.maxOrNull()!! for (quest in quests) { if (getScoreForQuest(quest) >= topScore) @@ -218,7 +218,7 @@ class QuestManager { } /** If quest is complete, it gives the influence reward to the player. - * Returns [true] if the quest can be removed (is either complete, obsolete or expired) */ + * Returns true if the quest can be removed (is either complete, obsolete or expired) */ private fun handleIndividualQuest(assignedQuest: AssignedQuest): Boolean { val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee) @@ -251,7 +251,7 @@ class QuestManager { when (quest.name) { QuestName.ClearBarbarianCamp.value -> { - val camp = getBarbarianEncampmentForQuest(assignee)!! + val camp = getBarbarianEncampmentForQuest()!! data1 = camp.position.x.toInt().toString() data2 = camp.position.y.toInt().toString() } @@ -281,13 +281,13 @@ class QuestManager { } } - /** Returns [true] if [civInfo] can assign a quest to [challenger] */ + /** Returns true if [civInfo] can assign a quest to [challenger] */ private fun canAssignAQuestTo(challenger: CivilizationInfo): Boolean { return !challenger.isDefeated() && challenger.isMajorCiv() && civInfo.knows(challenger) && !civInfo.isAtWarWith(challenger) } - /** Returns [true] if the [quest] can be assigned to [challenger] */ + /** Returns true if the [quest] can be assigned to [challenger] */ private fun isQuestValid(quest: Quest, challenger: CivilizationInfo): Boolean { if (!canAssignAQuestTo(challenger)) return false @@ -295,7 +295,7 @@ class QuestManager { return false return when (quest.name) { - QuestName.ClearBarbarianCamp.value -> getBarbarianEncampmentForQuest(challenger) != null + QuestName.ClearBarbarianCamp.value -> getBarbarianEncampmentForQuest() != null QuestName.Route.value -> { if (challenger.cities.none() || !civInfo.hasEverBeenFriendWith(challenger) || civInfo.isCapitalConnectedToCity(challenger.getCapital())) return false @@ -313,7 +313,7 @@ class QuestManager { } } - /** Returns [true] if the [assignedQuest] is successfully completed */ + /** Returns true if the [assignedQuest] is successfully completed */ private fun isComplete(assignedQuest: AssignedQuest): Boolean { val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee) return when (assignedQuest.questName) { @@ -327,7 +327,7 @@ class QuestManager { } } - /** Returns [true] if the [assignedQuest] request cannot be fulfilled anymore */ + /** Returns true if the [assignedQuest] request cannot be fulfilled anymore */ private fun isObsolete(assignedQuest: AssignedQuest): Boolean { val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee) return when (assignedQuest.questName) { @@ -441,7 +441,7 @@ class QuestManager { * Returns a random [TileInfo] containing a Barbarian encampment within 8 tiles of [civInfo] * to be destroyed */ - private fun getBarbarianEncampmentForQuest(challenger: CivilizationInfo): TileInfo? { + private fun getBarbarianEncampmentForQuest(): TileInfo? { val encampments = civInfo.getCapital().getCenterTile().getTilesInDistance(8) .filter { it.improvement == Constants.barbarianEncampment }.toList() @@ -492,7 +492,7 @@ class QuestManager { } /** - * Returns a random [NaturalWonder] not yet discovered by [challenger]. + * Returns a random Natural Wonder not yet discovered by [challenger]. */ private fun getNaturalWonderToFindForQuest(challenger: CivilizationInfo): String? { val naturalWondersToFind = civInfo.gameInfo.tileMap.naturalWonders.subtract(challenger.naturalWonders) diff --git a/core/src/com/unciv/logic/map/mapgenerator/MapLandmassGenerator.kt b/core/src/com/unciv/logic/map/mapgenerator/MapLandmassGenerator.kt index 619331c12e..3e9a2282bb 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/MapLandmassGenerator.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/MapLandmassGenerator.kt @@ -132,8 +132,6 @@ class MapLandmassGenerator(val randomness: MapGenerationRandomness) { // region Cellular automata private fun generateLandCellularAutomata(tileMap: TileMap) { - val mapRadius = tileMap.mapParameters.mapSize.radius - val mapType = tileMap.mapParameters.type val numSmooth = 4 // init diff --git a/core/src/com/unciv/logic/map/mapgenerator/RiverGenerator.kt b/core/src/com/unciv/logic/map/mapgenerator/RiverGenerator.kt index 24348dd1e4..5a32e17b74 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/RiverGenerator.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/RiverGenerator.kt @@ -55,11 +55,11 @@ class RiverGenerator(val randomness: MapGenerationRandomness) { .filter { map.contains(it.position) } if (possibleCoordinates.none()) return // end of the line val newCoordinate = possibleCoordinates - .groupBy { - getAdjacentTiles(it, map).map { it.aerialDistanceTo(endPosition) } - .minOrNull()!! - } - .minBy { it.key }!! + .groupBy { + getAdjacentTiles(it, map).map { it.aerialDistanceTo(endPosition) } + .minOrNull()!! + } + .minByOrNull { it.key }!! .component2().random(randomness.RNG) // set new rivers in place diff --git a/core/src/com/unciv/logic/trade/TradeEvaluation.kt b/core/src/com/unciv/logic/trade/TradeEvaluation.kt index 0e14e69674..af6c2649eb 100644 --- a/core/src/com/unciv/logic/trade/TradeEvaluation.kt +++ b/core/src/com/unciv/logic/trade/TradeEvaluation.kt @@ -237,8 +237,8 @@ class TradeEvaluation { } fun evaluatePeaceCostForThem(ourCivilization: CivilizationInfo, otherCivilization: CivilizationInfo): Int { - val ourCombatStrength = Automation.evaluteCombatStrength(ourCivilization) - val theirCombatStrength = Automation.evaluteCombatStrength(otherCivilization) + val ourCombatStrength = Automation.evaluateCombatStrength(ourCivilization) + val theirCombatStrength = Automation.evaluateCombatStrength(otherCivilization) if (ourCombatStrength*1.5f >= theirCombatStrength && theirCombatStrength * 1.5f >= ourCombatStrength) return 0 // we're roughly equal, there's no huge power imbalance if (ourCombatStrength == 0) return -1000 diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index 5df8a11a8d..6331e14713 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -75,7 +75,7 @@ class Building : NamedStats(), IConstruction { val str = getStats(null).toString() if (str.isNotEmpty()) infoList += str for (stat in getStatPercentageBonuses(null).toHashMap()) - if (stat.value != 0f) infoList += "+${stat.value.toInt()}% ${stat.key.toString().tr()}" + if (stat.value != 0f) infoList += "+${stat.value.toInt()}% ${stat.key.name.tr()}" val improvedResources = ruleset.tileResources.values.asSequence().filter { it.building == name }.map { it.name.tr() } if (improvedResources.any()) { diff --git a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt index 958f5ee5c6..2954bdd6dc 100644 --- a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt @@ -184,9 +184,9 @@ class BaseUnit : INamed, IConstruction { return getRejectionReason(cityConstructions) == "" } - override fun postBuildEvent(construction: CityConstructions, wasBought: Boolean): Boolean { - val civInfo = construction.cityInfo.civInfo - val unit = civInfo.placeUnitNearTile(construction.cityInfo.location, name) + override fun postBuildEvent(cityConstructions: CityConstructions, wasBought: Boolean): Boolean { + val civInfo = cityConstructions.cityInfo.civInfo + val unit = civInfo.placeUnitNearTile(cityConstructions.cityInfo.location, name) if (unit == null) return false // couldn't place the unit, so there's actually no unit =( //movement penalty @@ -195,10 +195,10 @@ class BaseUnit : INamed, IConstruction { if (this.unitType.isCivilian()) return true // tiny optimization makes save files a few bytes smaller - var XP = construction.getBuiltBuildings().sumBy { it.xpForNewUnits } + var XP = cityConstructions.getBuiltBuildings().sumBy { it.xpForNewUnits } - for (unique in construction.cityInfo.cityConstructions.builtBuildingUniqueMap + for (unique in cityConstructions.cityInfo.cityConstructions.builtBuildingUniqueMap .getUniques("New [] units start with [] Experience in this city") + civInfo.getMatchingUniques("New [] units start with [] Experience")) { if (unit.matchesFilter(unique.params[0])) @@ -206,7 +206,7 @@ class BaseUnit : INamed, IConstruction { } unit.promotions.XP = XP - for (unique in construction.cityInfo.cityConstructions.builtBuildingUniqueMap + for (unique in cityConstructions.cityInfo.cityConstructions.builtBuildingUniqueMap .getUniques("All newly-trained [] units in this city receive the [] promotion")) { val filter = unique.params[0] val promotion = unique.params[1] diff --git a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt index 9d96c654a1..851c8109eb 100644 --- a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt +++ b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt @@ -119,7 +119,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() { add(defender.getDefendingStrength().toString()+Fonts.strength).row() val attackerModifiers = - BattleDamage.getAttackModifiers(attacker,null,defender).map { + BattleDamage.getAttackModifiers(attacker, defender).map { val description = if(it.key.startsWith("vs ")) ("vs ["+it.key.replace("vs ","")+"]").tr() else it.key.tr() val percentage = (if(it.value>0)"+" else "")+ it.value +"%" "$description: $percentage"