From aa2486c896c70edfdcc56f4ce994d9286b763bbf Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Wed, 30 Sep 2020 20:18:52 +0300 Subject: [PATCH] Great person points come from the json! The only things that still happen directly to the specialists stats is the assign/unassign, this is as close as we'll get without changing the rest of it! --- .../jsons/Civ V - Vanilla/Specialists.json | 4 + core/src/com/unciv/logic/GameInfo.kt | 135 ++++++++++-------- core/src/com/unciv/logic/city/CityInfo.kt | 12 +- core/src/com/unciv/logic/city/CityStats.kt | 5 +- .../com/unciv/logic/city/PopulationManager.kt | 2 + core/src/com/unciv/models/ruleset/Building.kt | 2 +- core/src/com/unciv/models/ruleset/Ruleset.kt | 1 + core/src/com/unciv/models/stats/Stats.kt | 4 + 8 files changed, 95 insertions(+), 70 deletions(-) diff --git a/android/assets/jsons/Civ V - Vanilla/Specialists.json b/android/assets/jsons/Civ V - Vanilla/Specialists.json index c1b28c4b9d..11773f2cb6 100644 --- a/android/assets/jsons/Civ V - Vanilla/Specialists.json +++ b/android/assets/jsons/Civ V - Vanilla/Specialists.json @@ -2,21 +2,25 @@ { "name":"Scientist", "science":3, + "greatPersonPoints": {"science":3} "color": [0,0,255] }, { "name":"Merchant", "gold":3, + "greatPersonPoints": {"gold":3} "color": [255,215,0] }, { "name":"Artist", "culture":2, + "greatPersonPoints": {"culture":3} "color": [160,32,240] }, { "name":"Engineer", "production":2, + "greatPersonPoints": {"production":3} "color": [139,69,19] } ] diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 2110890275..70b98a2d89 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -253,16 +253,17 @@ class GameInfo { throw UncivShowableException("Missing mods: [$missingMods]") } + // TODO: Scheduled for removal 3.10.14 // Renames as of version 3.1.8, because of translation conflicts with the property "Range" and the difficulty "Immortal" // Needs to be BEFORE tileMap.setTransients, because the units' setTransients is called from there - for (tile in tileMap.values) - for (unit in tile.getUnits()) { - if (unit.name == "Immortal") unit.name = "Persian Immortal" - if (unit.promotions.promotions.contains("Range")) { - unit.promotions.promotions.remove("Range") - unit.promotions.promotions.add("Extended Range") - } - } +// for (tile in tileMap.values) +// for (unit in tile.getUnits()) { +// if (unit.name == "Immortal") unit.name = "Persian Immortal" +// if (unit.promotions.promotions.contains("Range")) { +// unit.promotions.promotions.remove("Range") +// unit.promotions.promotions.add("Extended Range") +// } +// } tileMap.setTransients(ruleSet) @@ -285,67 +286,72 @@ class GameInfo { civInfo.policies.adoptedPolicies.remove("Facism") civInfo.policies.adoptedPolicies.add("Fascism") } + } + // This doesn't HAVE to go here, but why not. // As of version 3.1.3, trade offers of "Declare war on X" and "Introduction to X" were changed to X, // with the extra text being added only on UI display (solved a couple of problems). - for (trade in civInfo.tradeRequests.map { it.trade }) { - for (offer in trade.theirOffers.union(trade.ourOffers)) { - offer.name = offer.name.removePrefix("Declare war on ") - offer.name = offer.name.removePrefix("Introduction to ") - } - } + // TODO: Scheduled for removal 3.10.14 +// for (trade in civInfo.tradeRequests.map { it.trade }) { +// for (offer in trade.theirOffers.union(trade.ourOffers)) { +// offer.name = offer.name.removePrefix("Declare war on ") +// offer.name = offer.name.removePrefix("Introduction to ") +// } +// } + // TODO: Scheduled for removal 3.10.14 // As of 3.4.9 cities are referenced by id, not by name // So try to update every tradeRequest (if there are no conflicting names) - for (tradeRequest in civInfo.tradeRequests) { - val trade = tradeRequest.trade - val toRemove = ArrayList() - for (offer in trade.ourOffers) { - if (offer.type == TradeType.City) { - val countNames = civInfo.cities.count { it.name == offer.name } - - if (countNames == 1) - offer.name = civInfo.cities.first { it.name == offer.name }.id - // There are conflicting names: we can't guess what city was being offered - else if (countNames > 1) - toRemove.add(offer) - } - } - - trade.ourOffers.removeAll(toRemove) - toRemove.clear() - - val themCivInfo = getCivilization(tradeRequest.requestingCiv) - for (offer in trade.theirOffers) { - if (offer.type == TradeType.City) { - val countNames = themCivInfo.cities.count { it.name == offer.name } - - if (countNames == 1) - offer.name = themCivInfo.cities.first { it.name == offer.name }.id - // There are conflicting names: we can't guess what city was being offered - else if (countNames > 1) - toRemove.add(offer) - } - } - - trade.theirOffers.removeAll(toRemove) - } +// for (tradeRequest in civInfo.tradeRequests) { +// val trade = tradeRequest.trade +// val toRemove = ArrayList() +// for (offer in trade.ourOffers) { +// if (offer.type == TradeType.City) { +// val countNames = civInfo.cities.count { it.name == offer.name } +// +// if (countNames == 1) +// offer.name = civInfo.cities.first { it.name == offer.name }.id +// // There are conflicting names: we can't guess what city was being offered +// else if (countNames > 1) +// toRemove.add(offer) +// } +// } +// +// trade.ourOffers.removeAll(toRemove) +// toRemove.clear() +// +// val themCivInfo = getCivilization(tradeRequest.requestingCiv) +// for (offer in trade.theirOffers) { +// if (offer.type == TradeType.City) { +// val countNames = themCivInfo.cities.count { it.name == offer.name } +// +// if (countNames == 1) +// offer.name = themCivInfo.cities.first { it.name == offer.name }.id +// // There are conflicting names: we can't guess what city was being offered +// else if (countNames > 1) +// toRemove.add(offer) +// } +// } +// +// trade.theirOffers.removeAll(toRemove) +// } + // TODO: Scheduled for removal 3.10.14 // As of 3.4.9 cities are referenced by id, not by name - val toRemove = ArrayList() - for (popupAlert in civInfo.popupAlerts.filter { it.type == AlertType.CityConquered }) { - val countNames = getCities().count { it.name == popupAlert.value } - - if (countNames == 1) - popupAlert.value = getCities().first { it.name == popupAlert.value }.id - else if (countNames > 1) { - // Sorry again, conflicting names: who knows what city you conquered? - toRemove.add(popupAlert) - } - } - civInfo.popupAlerts.removeAll(toRemove) - } +// val toRemove = ArrayList() +// for (popupAlert in civInfo.popupAlerts.filter { it.type == AlertType.CityConquered }) { +// val countNames = getCities().count { it.name == popupAlert.value } +// +// if (countNames == 1) +// popupAlert.value = getCities().first { it.name == popupAlert.value }.id +// else if (countNames > 1) { +// // Sorry again, conflicting names: who knows what city you conquered? +// toRemove.add(popupAlert) +// } +// } +// civInfo.popupAlerts.removeAll(toRemove) +// } for (civInfo in civilizations) civInfo.setNationTransient() for (civInfo in civilizations) civInfo.setTransients() @@ -364,7 +370,7 @@ class GameInfo { for (cityInfo in civInfo.cities) cityInfo.cityStats.updateCityHappiness() for (cityInfo in civInfo.cities) { - if(cityInfo.cityConstructions.currentConstruction!="") { // move it to the top of the queue + if (cityInfo.cityConstructions.currentConstruction != "") { // move it to the top of the queue val constructionQueue = cityInfo.cityConstructions.constructionQueue val itemsInQueue = constructionQueue.toList() constructionQueue.clear() @@ -372,6 +378,13 @@ class GameInfo { constructionQueue.addAll(itemsInQueue) cityInfo.cityConstructions.currentConstruction = "" } + + // As of 3.10.14, specialists are saved by name not by stat +// for((key, value) in cityInfo.population.specialists.toHashMap()) +// cityInfo.population.specialistAllocations.add( +// cityInfo.population.specialistNameByStat(key), value.toInt()) +// cityInfo.population.specialists.clear() + cityInfo.cityStats.update() } } diff --git a/core/src/com/unciv/logic/city/CityInfo.kt b/core/src/com/unciv/logic/city/CityInfo.kt index c01b6b6930..2f0f74ef6f 100644 --- a/core/src/com/unciv/logic/city/CityInfo.kt +++ b/core/src/com/unciv/logic/city/CityInfo.kt @@ -19,12 +19,12 @@ import com.unciv.models.ruleset.tile.ResourceSupplyList import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.stats.Stat +import com.unciv.models.stats.StatMap import com.unciv.models.stats.Stats import com.unciv.models.translations.equalsPlaceholderText import com.unciv.models.translations.getPlaceholderParameters import com.unciv.ui.utils.withoutItem import java.util.* -import kotlin.collections.HashMap import kotlin.collections.HashSet import kotlin.math.ceil import kotlin.math.max @@ -243,16 +243,16 @@ class CityInfo { fun containsBuildingUnique(unique:String) = cityConstructions.getBuiltBuildings().any { it.uniques.contains(unique) } - fun getGreatPersonMap():HashMap { - val stats = HashMap() - if (population.specialists.toString() != "") - stats["Specialists"] = population.specialists.times(3f) + fun getGreatPersonMap():StatMap { + val stats = StatMap() + for((specialist, amount) in population.getNewSpecialists()) + stats.add("Specialists", getRuleset().specialists[specialist]!!.greatPersonPoints.times(amount)) val buildingStats = Stats() for (building in cityConstructions.getBuiltBuildings()) if (building.greatPersonPoints != null) buildingStats.add(building.greatPersonPoints!!) - if (buildingStats.toString() != "") + if (!buildingStats.isEmpty()) stats["Buildings"] = buildingStats for (entry in stats) { diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 78f22fe648..a3f7b43efc 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -5,6 +5,7 @@ import com.unciv.UncivGame import com.unciv.logic.civilization.CityStateType import com.unciv.logic.civilization.diplomacy.RelationshipLevel import com.unciv.logic.map.RoadStatus +import com.unciv.models.Counter import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Unique import com.unciv.models.ruleset.unit.BaseUnit @@ -260,10 +261,10 @@ class CityStats { return stats } - private fun getStatsFromSpecialists(specialists: HashMap): Stats { + private fun getStatsFromSpecialists(specialists: Counter): Stats { val stats = Stats() for (entry in specialists.filter { it.value > 0 }) - stats.add(getStatsOfSpecialist(entry.key) * entry.value.toFloat()) + stats.add(getStatsOfSpecialist(entry.key) * entry.value) return stats } diff --git a/core/src/com/unciv/logic/city/PopulationManager.kt b/core/src/com/unciv/logic/city/PopulationManager.kt index 03bfa0890e..d05a5e71da 100644 --- a/core/src/com/unciv/logic/city/PopulationManager.kt +++ b/core/src/com/unciv/logic/city/PopulationManager.kt @@ -20,6 +20,8 @@ class PopulationManager { // Being deprecated out val specialists = Stats() + // In favor of this bad boy + val specialistAllocations = Counter() fun getNewSpecialists() = convertStatsToSpecialistHashmap(specialists) diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index 1bdf041730..ae64416871 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -85,7 +85,7 @@ class Building : NamedStats(), IConstruction { if (providesFreeBuilding != null) stringBuilder.appendln("Provides a free [$providesFreeBuilding] in the city".tr()) if(uniques.isNotEmpty()) stringBuilder.appendln(uniques.asSequence().map { it.tr() }.joinToString("\n")) - if (stats.toString() != "") + if (!stats.isEmpty()) stringBuilder.appendln(stats) val percentStats = getStatPercentageBonuses(civInfo) diff --git a/core/src/com/unciv/models/ruleset/Ruleset.kt b/core/src/com/unciv/models/ruleset/Ruleset.kt index d9da2765a0..2ec9ce906c 100644 --- a/core/src/com/unciv/models/ruleset/Ruleset.kt +++ b/core/src/com/unciv/models/ruleset/Ruleset.kt @@ -317,4 +317,5 @@ object RulesetCache :HashMap() { class Specialist: NamedStats() { var color = ArrayList() val colorObject by lazy { colorFromRGB(color) } + var greatPersonPoints= Stats() } \ No newline at end of file diff --git a/core/src/com/unciv/models/stats/Stats.kt b/core/src/com/unciv/models/stats/Stats.kt index 61dcbc5576..df0511baab 100644 --- a/core/src/com/unciv/models/stats/Stats.kt +++ b/core/src/com/unciv/models/stats/Stats.kt @@ -57,12 +57,16 @@ open class Stats() { return stats } + operator fun times(number: Int) = times(number.toFloat()) + operator fun times(number: Float): Stats { val hashMap = toHashMap() for (stat in Stat.values()) hashMap[stat] = number * hashMap[stat]!! return Stats(hashMap) } + fun isEmpty() = equals(Stats()) + override fun toString(): String { return toHashMap().filter { it.value != 0f } .map { (if (it.value > 0) "+" else "") + it.value.toInt() + " " + it.key.toString().tr() }.joinToString()