From c7d79ad179719bcbc8c309506d299d6364444690 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Tue, 22 Dec 2020 23:31:29 +0200 Subject: [PATCH] Replaced hardcoded Settler references with unique Tech uniques now saved in tech object for less regex parsing per turn --- .../assets/jsons/Civ V - Vanilla/Units.json | 2 +- core/src/com/unciv/logic/city/CityStats.kt | 41 +++++++++++-------- .../logic/civilization/CivilizationInfo.kt | 2 +- .../unciv/logic/civilization/TechManager.kt | 10 ++--- .../unciv/models/ruleset/tech/Technology.kt | 2 + .../com/unciv/ui/cityscreen/CityStatsTable.kt | 4 +- 6 files changed, 35 insertions(+), 26 deletions(-) diff --git a/android/assets/jsons/Civ V - Vanilla/Units.json b/android/assets/jsons/Civ V - Vanilla/Units.json index beb2b0b6a1..965a5dce8f 100644 --- a/android/assets/jsons/Civ V - Vanilla/Units.json +++ b/android/assets/jsons/Civ V - Vanilla/Units.json @@ -15,7 +15,7 @@ "unitType": "Civilian", "movement": 2, "cost": 106, - "uniques": ["Founds a new city"], + "uniques": ["Founds a new city", "Excess Food converted to Production when under construction"], "hurryCostModifier": 20 }, { diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index e90ce20507..dc69a15abb 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -18,6 +18,7 @@ class CityStats { @Transient var baseStatList = LinkedHashMap() + @Transient var statPercentBonusList = LinkedHashMap() @@ -27,11 +28,13 @@ class CityStats { @Transient var happinessList = LinkedHashMap() + @Transient var foodEaten = 0f @Transient var currentCityStats: Stats = Stats() // This is so we won't have to calculate this multiple times - takes a lot of time, especially on phones + @Transient lateinit var cityInfo: CityInfo @@ -67,7 +70,7 @@ class CityStats { } fun getScienceConversionRate(): Float { - var conversionRate = 1/4f + var conversionRate = 1 / 4f if (cityInfo.civInfo.hasUnique("Production to science conversion in cities increased by 33%")) conversionRate *= 1.33f return conversionRate @@ -176,11 +179,11 @@ class CityStats { if (cityInfo.civInfo.hasUnique("+15% growth in all cities")) bonus += 15f - for(unique in cityInfo.civInfo.getMatchingUniques("+[]% growth in all cities")) + for (unique in cityInfo.civInfo.getMatchingUniques("+[]% growth in all cities")) bonus += unique.params[0].toFloat() - if (cityInfo.isCapital()) for(unique in cityInfo.civInfo.getMatchingUniques("+[]% growth in capital")) + if (cityInfo.isCapital()) for (unique in cityInfo.civInfo.getMatchingUniques("+[]% growth in capital")) bonus += unique.params[0].toFloat() - return bonus/100 + return bonus / 100 } // needs to be a separate function because we need to know the global happiness state @@ -207,8 +210,8 @@ class CityStats { else if (hasExtraAnnexUnhappiness()) unhappinessFromCitizens *= 2f - for(unique in civInfo.getMatchingUniques("Unhappiness from population decreased by []%")) - unhappinessFromCitizens *= (1-unique.params[0].toFloat()/100) + for (unique in civInfo.getMatchingUniques("Unhappiness from population decreased by []%")) + unhappinessFromCitizens *= (1 - unique.params[0].toFloat() / 100) newHappinessList["Population"] = -unhappinessFromCitizens * unhappinessModifier @@ -227,7 +230,7 @@ class CityStats { if (hasExtraAnnexUnhappiness()) newHappinessList["Occupied City"] = -2f //annexed city val happinessFromSpecialists = getStatsFromSpecialists(cityInfo.population.getNewSpecialists()).happiness.toInt().toFloat() - if (happinessFromSpecialists>0) newHappinessList["Specialists"] = happinessFromSpecialists + if (happinessFromSpecialists > 0) newHappinessList["Specialists"] = happinessFromSpecialists val happinessFromBuildings = cityInfo.cityConstructions.getStats().happiness.toInt().toFloat() newHappinessList["Buildings"] = happinessFromBuildings @@ -244,7 +247,7 @@ class CityStats { } - private fun hasExtraAnnexUnhappiness() : Boolean { + private fun hasExtraAnnexUnhappiness(): Boolean { if (cityInfo.civInfo.civName == cityInfo.foundingCiv || cityInfo.foundingCiv == "" || cityInfo.isPuppet) return false return !cityInfo.containsBuildingUnique("Remove extra unhappiness from annexed cities") } @@ -254,13 +257,13 @@ class CityStats { if (stat == Stat.Culture || stat == Stat.Science) stats.add(stat, 3f) else stats.add(stat, 2f) // science and gold specialists - for(unique in cityInfo.civInfo.getMatchingUniques("[] from every specialist")) + for (unique in cityInfo.civInfo.getMatchingUniques("[] from every specialist")) stats.add(unique.stats) return stats } - fun getStatsOfSpecialist(specialistName:String): Stats { + fun getStatsOfSpecialist(specialistName: String): Stats { val specialist = cityInfo.getRuleset().specialists[specialistName] if (specialist == null) return Stats() val stats = specialist.clone() @@ -276,7 +279,7 @@ class CityStats { return stats } - private fun getStatsFromUniques(uniques: Sequence):Stats { + private fun getStatsFromUniques(uniques: Sequence): Stats { val stats = Stats() for (unique in uniques) { @@ -308,7 +311,7 @@ class CityStats { } private fun getStatPercentBonusesFromBuildings(): Stats { - val stats = cityInfo.cityConstructions.getStatPercentBonuses() + val stats = cityInfo.cityConstructions.getStatPercentBonuses() val currentConstruction = cityInfo.cityConstructions.getCurrentConstruction() // This is to be deprecated and converted to "+[]% production when building [] in this city" - keeping it here to that mods with this can still work for now @@ -373,7 +376,7 @@ class CityStats { return stats } - fun constructionMatchesFilter(construction:IConstruction, filter:String): Boolean { + fun constructionMatchesFilter(construction: IConstruction, filter: String): Boolean { return construction.name == filter // All of these are deprecated as of 3.11.20 in favor of "+[]% Production when constructing [] units" || filter == "land units" && construction is BaseUnit && construction.unitType.isLandUnit() @@ -446,9 +449,9 @@ class CityStats { updateStatPercentBonusList() updateFinalStatList() // again, we don't edit the existing currentCityStats directly, in order to avoid concurrency exceptions - + val newCurrentCityStats = Stats() - for(stat in finalStatList.values) newCurrentCityStats.add(stat) + for (stat in finalStatList.values) newCurrentCityStats.add(stat) currentCityStats = newCurrentCityStats cityInfo.civInfo.updateStatsForNextTurn() @@ -527,7 +530,9 @@ class CityStats { newFinalStatList["Maintenance"] = Stats().apply { gold -= buildingsMaintenance.toInt() } - if (cityInfo.cityConstructions.currentConstructionFromQueue == Constants.settler && totalFood > 0) { + val currentconstruction = cityInfo.cityConstructions.currentConstructionFromQueue + if (totalFood > 0 && cityInfo.getRuleset().units[currentconstruction] + .let { it != null && it.uniques.contains("Excess Food converted to Production when under construction") }) { newFinalStatList["Excess food to production"] = Stats().apply { production = totalFood; food = -totalFood } } @@ -541,9 +546,9 @@ class CityStats { } private fun updateFoodEaten() { - foodEaten = (cityInfo.population.population * 2).toFloat() + foodEaten = cityInfo.population.population.toFloat() * 2 if (cityInfo.civInfo.hasUnique("-50% food consumption by specialists")) foodEaten -= cityInfo.population.getNumberOfSpecialists() } -} +} \ No newline at end of file diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 8adbc686c3..b25e494a55 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -230,7 +230,7 @@ class CivilizationInfo { return nation.uniqueObjects.asSequence().filter { it.placeholderText == uniqueTemplate } + cities.asSequence().flatMap { it.cityConstructions.builtBuildingUniqueMap.getUniques(uniqueTemplate).asSequence() } + policies.policyUniques.getUniques(uniqueTemplate) + - tech.getTechUniques() + tech.getTechUniques().filter { it.placeholderText == uniqueTemplate } } //region Units diff --git a/core/src/com/unciv/logic/civilization/TechManager.kt b/core/src/com/unciv/logic/civilization/TechManager.kt index 7745b52a9a..a183c74b90 100644 --- a/core/src/com/unciv/logic/civilization/TechManager.kt +++ b/core/src/com/unciv/logic/civilization/TechManager.kt @@ -122,7 +122,7 @@ class TechManager { return tech.prerequisites.all { isResearched(it) } } - fun getTechUniques() = researchedTechUniques + fun getTechUniques() = researchedTechUniques.asSequence() //endregion @@ -231,9 +231,9 @@ class TechManager { if (!newTech.isContinuallyResearchable()) techsToResearch.remove(techName) researchedTechnologies = researchedTechnologies.withItem(newTech) - for (unique in newTech.uniques) { - researchedTechUniques = researchedTechUniques.withItem(Unique(unique)) - UniqueTriggerActivation.triggerCivwideUnique(Unique(unique), civInfo) + for (unique in newTech.uniqueObjects) { + researchedTechUniques = researchedTechUniques.withItem(unique) + UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo) } updateTransientBooleans() @@ -296,7 +296,7 @@ class TechManager { fun setTransients() { researchedTechnologies.addAll(techsResearched.map { getRuleset().technologies[it]!! }) - researchedTechUniques.addAll(researchedTechnologies.asSequence().flatMap { it.uniques.asSequence() }.map { Unique(it) }) + researchedTechUniques.addAll(researchedTechnologies.asSequence().flatMap { it.uniqueObjects.asSequence() }) updateTransientBooleans() } diff --git a/core/src/com/unciv/models/ruleset/tech/Technology.kt b/core/src/com/unciv/models/ruleset/tech/Technology.kt index 201da7bb92..ffe322c4a0 100644 --- a/core/src/com/unciv/models/ruleset/tech/Technology.kt +++ b/core/src/com/unciv/models/ruleset/tech/Technology.kt @@ -4,6 +4,7 @@ import com.unciv.UncivGame import com.unciv.logic.civilization.CivilizationInfo import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Ruleset +import com.unciv.models.ruleset.Unique import com.unciv.models.translations.tr import com.unciv.models.ruleset.unit.BaseUnit import java.util.* @@ -15,6 +16,7 @@ class Technology { var cost: Int = 0 var prerequisites = HashSet() var uniques = ArrayList() + val uniqueObjects: List by lazy { uniques.map { Unique(it) } } var column: TechColumn? = null // The column that this tech is in the tech tree var row: Int = 0 diff --git a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt index 071521dfd9..f08ff04423 100644 --- a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt @@ -67,7 +67,9 @@ class CityStatsTable(val cityScreen: CityScreen): Table() { when { cityInfo.isGrowing() -> "[${cityInfo.getNumTurnsToNewPopulation()}] turns to new population".tr() cityInfo.isStarving() -> "[${cityInfo.getNumTurnsToStarvation()}] turns to lose population".tr() - cityInfo.cityConstructions.currentConstructionFromQueue == Constants.settler -> "Food converts to production".tr() + cityInfo.getRuleset().units[cityInfo.cityConstructions.currentConstructionFromQueue] + .let { it != null && it.uniques.contains("Excess Food converted to Production when under construction") } + -> "Food converts to production".tr() else -> "Stopped population growth".tr() } turnsToPopString += " (" + cityInfo.population.foodStored + "/" + cityInfo.population.getFoodToNextPopulation() + ")"