diff --git a/core/src/com/unciv/logic/battle/BattleDamage.kt b/core/src/com/unciv/logic/battle/BattleDamage.kt index 9a5301a9b2..cb9669e64c 100644 --- a/core/src/com/unciv/logic/battle/BattleDamage.kt +++ b/core/src/com/unciv/logic/battle/BattleDamage.kt @@ -2,6 +2,7 @@ package com.unciv.logic.battle import com.unciv.logic.map.TileInfo import com.unciv.models.Counter +import com.unciv.ui.utils.toPercent import java.util.* import kotlin.collections.set import kotlin.math.max @@ -264,7 +265,7 @@ object BattleDamage { private fun modifiersToMultiplicationBonus(modifiers: Counter): Float { var finalModifier = 1f - for (modifierValue in modifiers.values) finalModifier *= (1 + modifierValue / 100f) // so 25 will result in *= 1.25 + for (modifierValue in modifiers.values) finalModifier *= modifierValue.toPercent() return finalModifier } diff --git a/core/src/com/unciv/logic/city/CityExpansionManager.kt b/core/src/com/unciv/logic/city/CityExpansionManager.kt index 1e2e17fee1..6041b412cf 100644 --- a/core/src/com/unciv/logic/city/CityExpansionManager.kt +++ b/core/src/com/unciv/logic/city/CityExpansionManager.kt @@ -5,6 +5,7 @@ import com.unciv.logic.automation.Automation import com.unciv.logic.civilization.LocationAction import com.unciv.logic.civilization.NotificationIcon import com.unciv.logic.map.TileInfo +import com.unciv.ui.utils.toPercent import com.unciv.ui.utils.withItem import com.unciv.ui.utils.withoutItem import kotlin.math.max @@ -41,11 +42,11 @@ class CityExpansionManager { for (unique in cityInfo.getMatchingUniques("-[]% Culture cost of acquiring tiles []")) { if (cityInfo.matchesFilter(unique.params[1])) - cultureToNextTile *= (100 - unique.params[0].toFloat()) / 100 + cultureToNextTile /= unique.params[0].toPercent() } for (unique in cityInfo.getMatchingUniques("[]% cost of natural border growth")) - cultureToNextTile *= 1 + unique.params[0].toFloat() / 100f + cultureToNextTile *= unique.params[0].toPercent() // Unique deprecated since 3.15.10 (seems unused, and should be replaced by the unique above) if (cityInfo.civInfo.hasUnique("Increased rate of border expansion")) cultureToNextTile *= 0.75 diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 1d07e98f68..5ee0cb9f1d 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -13,6 +13,7 @@ import com.unciv.models.stats.Stat import com.unciv.models.stats.Stats import com.unciv.models.translations.getPlaceholderParameters import com.unciv.models.translations.getPlaceholderText +import com.unciv.ui.utils.toPercent import kotlin.math.min @@ -475,7 +476,7 @@ class CityStats { for (bonus in statPercentBonusList.values) statPercentBonusesSum.add(bonus) for (entry in newFinalStatList.values) - entry.production *= 1 + statPercentBonusesSum.production / 100 + entry.production *= statPercentBonusesSum.production.toPercent() val statsFromProduction = getStatsFromProduction(newFinalStatList.values.map { it.production }.sum()) baseStatList = LinkedHashMap(baseStatList).apply { put("Construction", statsFromProduction) } // concurrency-safe addition @@ -483,9 +484,9 @@ class CityStats { val isUnhappy = cityInfo.civInfo.getHappiness() < 0 for (entry in newFinalStatList.values) { - entry.gold *= 1 + statPercentBonusesSum.gold / 100 - entry.culture *= 1 + statPercentBonusesSum.culture / 100 - entry.food *= 1 + statPercentBonusesSum.food / 100 + entry.gold *= statPercentBonusesSum.gold.toPercent() + entry.culture *= statPercentBonusesSum.culture.toPercent() + entry.food *= statPercentBonusesSum.food.toPercent() } // AFTER we've gotten all the gold stats figured out, only THEN do we plonk that gold into Science @@ -496,7 +497,7 @@ class CityStats { newFinalStatList["Gold -> Science"] = Stats().apply { science = amountConverted; gold = -amountConverted } } for (entry in newFinalStatList.values) { - entry.science *= 1 + statPercentBonusesSum.science / 100 + entry.science *= statPercentBonusesSum.science.toPercent() } diff --git a/core/src/com/unciv/logic/city/IConstruction.kt b/core/src/com/unciv/logic/city/IConstruction.kt index 83477d4f76..f251530ed4 100644 --- a/core/src/com/unciv/logic/city/IConstruction.kt +++ b/core/src/com/unciv/logic/city/IConstruction.kt @@ -6,6 +6,7 @@ import com.unciv.models.ruleset.Unique import com.unciv.models.stats.INamed import com.unciv.models.stats.Stat import com.unciv.ui.utils.Fonts +import com.unciv.ui.utils.toPercent import kotlin.math.pow import kotlin.math.roundToInt @@ -55,7 +56,7 @@ interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques { fun getBaseGoldCost(civInfo: CivilizationInfo): Double { // https://forums.civfanatics.com/threads/rush-buying-formula.393892/ - return (30.0 * getProductionCost(civInfo)).pow(0.75) * (1 + hurryCostModifier / 100f) + return (30.0 * getProductionCost(civInfo)).pow(0.75) * hurryCostModifier.toPercent() } fun getBaseBuyCost(cityInfo: CityInfo, stat: Stat): Int? { diff --git a/core/src/com/unciv/logic/civilization/GoldenAgeManager.kt b/core/src/com/unciv/logic/civilization/GoldenAgeManager.kt index 8657fb7050..17729c1bf0 100644 --- a/core/src/com/unciv/logic/civilization/GoldenAgeManager.kt +++ b/core/src/com/unciv/logic/civilization/GoldenAgeManager.kt @@ -1,5 +1,7 @@ package com.unciv.logic.civilization +import com.unciv.ui.utils.toPercent + class GoldenAgeManager { @Transient lateinit var civInfo: CivilizationInfo @@ -19,13 +21,13 @@ class GoldenAgeManager { fun isGoldenAge(): Boolean = turnsLeftForCurrentGoldenAge > 0 fun happinessRequiredForNextGoldenAge(): Int { - return ((500 + numberOfGoldenAges * 250) * (1 + civInfo.cities.size / 100.0)).toInt() //https://forums.civfanatics.com/resources/complete-guide-to-happiness-vanilla.25584/ + return ((500 + numberOfGoldenAges * 250) * civInfo.cities.size.toPercent()).toInt() //https://forums.civfanatics.com/resources/complete-guide-to-happiness-vanilla.25584/ } fun enterGoldenAge(unmodifiedNumberOfTurns: Int = 10) { var turnsToGoldenAge = unmodifiedNumberOfTurns.toFloat() for (unique in civInfo.getMatchingUniques("Golden Age length increased by []%")) - turnsToGoldenAge *= (unique.params[0].toFloat() / 100 + 1) + turnsToGoldenAge *= unique.params[0].toPercent() turnsToGoldenAge *= civInfo.gameInfo.gameParameters.gameSpeed.modifier turnsLeftForCurrentGoldenAge += turnsToGoldenAge.toInt() civInfo.addNotification("You have entered a Golden Age!", "StatIcons/Happiness") diff --git a/core/src/com/unciv/logic/civilization/TechManager.kt b/core/src/com/unciv/logic/civilization/TechManager.kt index e6758956fc..31e2a89819 100644 --- a/core/src/com/unciv/logic/civilization/TechManager.kt +++ b/core/src/com/unciv/logic/civilization/TechManager.kt @@ -8,6 +8,7 @@ import com.unciv.models.ruleset.UniqueMap import com.unciv.models.ruleset.UniqueTriggerActivation import com.unciv.models.ruleset.tech.Technology import com.unciv.models.ruleset.unit.BaseUnit +import com.unciv.ui.utils.toPercent import com.unciv.ui.utils.withItem import java.util.* import kotlin.collections.ArrayList @@ -163,7 +164,7 @@ class TechManager { civInfo.cities.forEach { it -> val totalBaseScience = it.cityStats.baseStatList.values.map { it.science }.sum() val totalBonusPercents = it.cityStats.statPercentBonusList.filter { it.key != "Policies" }.values.map { it.science }.sum() - allCitiesScience += totalBaseScience * (1 + totalBonusPercents / 100) + allCitiesScience += totalBaseScience * totalBonusPercents.toPercent() } scienceOfLast8Turns[civInfo.gameInfo.turns % 8] = allCitiesScience.toInt() } diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index bba420990d..7a988e7634 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -16,6 +16,7 @@ import com.unciv.models.translations.tr import com.unciv.ui.civilopedia.FormattedLine import com.unciv.ui.civilopedia.ICivilopediaText import com.unciv.ui.utils.Fonts +import com.unciv.ui.utils.toPercent import java.util.* import kotlin.collections.ArrayList import kotlin.collections.HashMap @@ -407,11 +408,11 @@ class Building : NamedStats(), INonPerpetualConstruction, ICivilopediaText { for (unique in cityInfo.getMatchingUniques("[] cost of purchasing items in cities []%")) if (stat.name == unique.params[0]) - cost *= 1 + (unique.params[1].toFloat() / 100) + cost *= unique.params[1].toPercent() for (unique in cityInfo.getMatchingUniques("[] cost of purchasing [] buildings []%")) { if (stat.name == unique.params[0] && matchesFilter(unique.params[1])) - cost *= 1 + (unique.params[2].toFloat() / 100) + cost *= unique.params[2].toPercent() } return (cost / 10f).toInt() * 10 diff --git a/core/src/com/unciv/models/ruleset/tile/TileImprovement.kt b/core/src/com/unciv/models/ruleset/tile/TileImprovement.kt index 364c8dbbbc..67998f8d28 100644 --- a/core/src/com/unciv/models/ruleset/tile/TileImprovement.kt +++ b/core/src/com/unciv/models/ruleset/tile/TileImprovement.kt @@ -13,6 +13,7 @@ import com.unciv.models.stats.NamedStats import com.unciv.models.translations.tr import com.unciv.ui.civilopedia.FormattedLine import com.unciv.ui.civilopedia.ICivilopediaText +import com.unciv.ui.utils.toPercent import java.util.* import kotlin.math.roundToInt @@ -32,7 +33,7 @@ class TileImprovement : NamedStats(), ICivilopediaText, IHasUniques { fun getTurnsToBuild(civInfo: CivilizationInfo): Int { var realTurnsToBuild = turnsToBuild.toFloat() * civInfo.gameInfo.gameParameters.gameSpeed.modifier for (unique in civInfo.getMatchingUniques("[]% tile improvement construction time")) { - realTurnsToBuild *= 1 + unique.params[0].toFloat() / 100f + realTurnsToBuild *= unique.params[0].toPercent() } // Deprecated since 3.14.17 if (civInfo.hasUnique("Worker construction increased 25%")) diff --git a/core/src/com/unciv/ui/utils/ExtensionFunctions.kt b/core/src/com/unciv/ui/utils/ExtensionFunctions.kt index 8b57b7eebb..e7b6f3f139 100644 --- a/core/src/com/unciv/ui/utils/ExtensionFunctions.kt +++ b/core/src/com/unciv/ui/utils/ExtensionFunctions.kt @@ -172,6 +172,15 @@ fun HashSet.withoutItem(item:T): HashSet { return newHashSet } +/** Translate a percentage number - e.g. 25 - to the multiplication value - e.g. 1.25f */ +fun String.toPercent() = toFloat().toPercent() + +/** Translate a percentage number - e.g. 25 - to the multiplication value - e.g. 1.25f */ +fun Int.toPercent() = toFloat().toPercent() + +/** Translate a percentage number - e.g. 25 - to the multiplication value - e.g. 1.25f */ +fun Float.toPercent() = 1 + this/100 + /** Translate a [String] and make a [TextButton] widget from it */ fun String.toTextButton() = TextButton(this.tr(), CameraStageBaseScreen.skin)