diff --git a/android/assets/jsons/Civ V - Vanilla/Nations.json b/android/assets/jsons/Civ V - Vanilla/Nations.json index 2f77b668..574a42ca 100644 --- a/android/assets/jsons/Civ V - Vanilla/Nations.json +++ b/android/assets/jsons/Civ V - Vanilla/Nations.json @@ -30,6 +30,7 @@ "outerColor": [27,53,63], "innerColor": [213,249,255], "unique": "INGENUITY", + "uniques": ["Receive free [Great Scientist] when you discover [Writing]", "Earn Great Scientists 50% faster"] "cities": ["Babylon","Akkad","Dur-Kurigalzu","Nippur","Borsippa","Sippar","Opis","Mari","Shushan","Eshnunna", "Ellasar","Erech","Kutha","Sirpurla","Neribtum","Ashur","Ninveh","Nimrud","Arbela","Nuzi", "Arrapkha","Tutub","Shaduppum","Rapiqum","Mashkan Shapir","Tuttul","Ramad","Ana","Haradum","Agrab", diff --git a/android/assets/jsons/Civ V - Vanilla/Policies.json b/android/assets/jsons/Civ V - Vanilla/Policies.json index af77c06b..4eacb73b 100644 --- a/android/assets/jsons/Civ V - Vanilla/Policies.json +++ b/android/assets/jsons/Civ V - Vanilla/Policies.json @@ -72,7 +72,7 @@ { "name": "Republic", "effect": "+1 production in every city, +5% production when constructing buildings", - "uniques": ["[+1 Production] in all cities", "+5% production when constructing buildings"], + "uniques": ["[+1 Production] in all cities", "+[5]% Production when constructing [Buildings]"], "requires": ["Collective Rule"], "row": 2, "column": 1 diff --git a/android/assets/jsons/Civ V - Vanilla/Units.json b/android/assets/jsons/Civ V - Vanilla/Units.json index a716320e..f2904b81 100644 --- a/android/assets/jsons/Civ V - Vanilla/Units.json +++ b/android/assets/jsons/Civ V - Vanilla/Units.json @@ -1290,32 +1290,33 @@ { "name": "Great Artist", "unitType": "Civilian", - "uniques": ["Can start an 8-turn golden age", "Can construct [Landmark]", "Unbuildable"], + "uniques": ["Can start an 8-turn golden age", "Can construct [Landmark]", "Great Person", "Unbuildable"], "movement": 2 }, { "name": "Great Scientist", "unitType": "Civilian", - "uniques": ["Can hurry technology research", "Can construct [Academy]", "Unbuildable"], + "uniques": ["Can hurry technology research", "Can construct [Academy]", "Great Person", "Unbuildable"], "movement": 2 }, { "name": "Great Merchant", "unitType": "Civilian", "uniques": ["Can undertake a trade mission with City-State, giving a large sum of gold and [30] Influence", - "Can construct [Customs house]", "Unbuildable"], + "Can construct [Customs house]", "Great Person", "Unbuildable"], "movement": 2 }, { "name": "Great Engineer", "unitType": "Civilian", - "uniques": ["Can speed up construction of a wonder", "Can construct [Manufactory]", "Unbuildable"], + "uniques": ["Can speed up construction of a wonder", "Can construct [Manufactory]", "Great Person", "Unbuildable"], "movement": 2 }, { "name": "Great General", "unitType": "Civilian", - "uniques": ["Can start an 8-turn golden age", "Bonus for units in 2 tile radius 15%", "Can construct [Citadel]", "Unbuildable"], + "uniques": ["Can start an 8-turn golden age", "Bonus for units in 2 tile radius 15%", "Can construct [Citadel]", + "Great Person", "Unbuildable"], "movement": 2 }, { @@ -1323,8 +1324,8 @@ "unitType": "Civilian", "uniqueTo": "Mongolia", "replaces": "Great General", - "uniques": ["Can start an 8-turn golden age","Bonus for units in 2 tile radius 15%", "Unbuildable", - "Heal adjacent units for an additional 15 HP per turn", "Can construct [Citadel]"], + "uniques": ["Can start an 8-turn golden age","Bonus for units in 2 tile radius 15%", + "Heal adjacent units for an additional 15 HP per turn", "Can construct [Citadel]", "Great Person", "Unbuildable"], "movement": 5 } ] diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index 329f26fc..c3965735 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -676,6 +676,8 @@ Policies = Base happiness = Occupied City = Buildings = +# For the "when constructing [military units]" translation +military units = Wonders = Base values = Bonuses = diff --git a/changelog.md b/changelog.md index 912a3f9a..cf39ee23 100644 --- a/changelog.md +++ b/changelog.md @@ -16,13 +16,10 @@ Resolved #2907 - University unique registers properly Added civ-wide per-building stat bonus -By lishaoxia1985: +New Diplomacy Overview UI - By lishaoxia1985 -- New Diplomacy Overview UI +Fog of war implementation - By alkorolyov -By alkorolyov: - -- Fog of war implementation ## 3.9.16 diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 6f6ffa41..a4fb3083 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -330,15 +330,13 @@ class CityStats { return stats } - private fun getStatPercentBonusesFromPolicies(policies: HashSet, cityConstructions: CityConstructions): Stats { + private fun getStatPercentBonusesFromPolicies(cityConstructions: CityConstructions): Stats { val stats = Stats() val currentConstruction = cityConstructions.getCurrentConstruction() - if (policies.contains("Collective Rule") && cityInfo.isCapital() - && currentConstruction.name == Constants.settler) + if (currentConstruction.name == Constants.settler && cityInfo.isCapital() + && cityInfo.civInfo.hasUnique("Training of settlers increased +50% in capital")) stats.production += 50f - if (policies.contains("Republic") && currentConstruction is Building) - stats.production += 5f if (cityInfo.civInfo.hasUnique("+20% production when training melee units") && currentConstruction is BaseUnit && currentConstruction.unitType.isMelee()) stats.production += 20 @@ -355,7 +353,8 @@ class CityStats { val placeholderParams = unique.getPlaceholderParameters() val filter = placeholderParams[1] if (currentConstruction.name == filter - || (filter=="military units" && currentConstruction is BaseUnit && !currentConstruction.unitType.isCivilian())) + || (filter=="military units" && currentConstruction is BaseUnit && !currentConstruction.unitType.isCivilian()) + || (filter=="Buildings" && currentConstruction is Building && !currentConstruction.isWonder)) stats.production += placeholderParams[0].toInt() } @@ -407,7 +406,7 @@ class CityStats { fun updateStatPercentBonusList() { val newStatPercentBonusList = LinkedHashMap() newStatPercentBonusList["Golden Age"] = getStatPercentBonusesFromGoldenAge(cityInfo.civInfo.goldenAges.isGoldenAge()) - newStatPercentBonusList["Policies"] = getStatPercentBonusesFromPolicies(cityInfo.civInfo.policies.adoptedPolicies, cityInfo.cityConstructions) + newStatPercentBonusList["Policies"] = getStatPercentBonusesFromPolicies(cityInfo.cityConstructions) newStatPercentBonusList["Buildings"] = getStatPercentBonusesFromBuildings() newStatPercentBonusList["Railroad"] = getStatPercentBonusesFromRailroad() newStatPercentBonusList["Marble"] = getStatPercentBonusesFromMarble() diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index a89f1ba4..9ce16c23 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -178,9 +178,9 @@ class CivilizationInfo { fun hasResource(resourceName:String): Boolean = getCivResourcesByName()[resourceName]!!>0 - private fun getCivUniques() = policies.policyEffects.asSequence() + cities.asSequence().flatMap { it.getBuildingUniques() } + private fun getCivUniques() = nation.uniques.asSequence() + policies.policyEffects.asSequence() + + cities.asSequence().flatMap { it.getBuildingUniques() } - // This is fun hasUnique(unique:String) = getCivUniques().contains(unique) fun getMatchingUniques(uniqueTemplate: String) = @@ -407,7 +407,7 @@ class CivilizationInfo { // so they won't be generated out in the open and vulnerable to enemy attacks before you can control them if (cities.isNotEmpty()) { //if no city available, addGreatPerson will throw exception val greatPerson = greatPeople.getNewGreatPerson() - if (greatPerson != null) addGreatPerson(greatPerson) + if (greatPerson != null) addUnit(greatPerson) } updateViewableTiles() // adds explored tiles so that the units will be able to perform automated actions better @@ -492,15 +492,13 @@ class CivilizationInfo { notifications.add(Notification(text, color, action)) } - fun addGreatPerson(greatPerson: String){ - if(cities.isEmpty()) return - addGreatPerson(greatPerson, cities.random()) - } - - fun addGreatPerson(greatPerson: String, city:CityInfo) { - val greatPersonName = getEquivalentUnit(greatPerson).name - placeUnitNearTile(city.location, greatPersonName) - addNotification("A [$greatPersonName] has been born in [${city.name}]!", city.location, Color.GOLD) + fun addUnit(unitName:String, city: CityInfo?=null) { + if (cities.isEmpty()) return + val cityToAddTo = city ?: cities.random() + val unit = getEquivalentUnit(unitName) + placeUnitNearTile(cityToAddTo.location, unit.name) + if ("Great Person" in unit.uniques) + addNotification("A [${unit.name}] has been born in [${cityToAddTo.name}]!", cityToAddTo.location, Color.GOLD) } fun placeUnitNearTile(location: Vector2, unitName: String): MapUnit? { diff --git a/core/src/com/unciv/logic/civilization/PolicyManager.kt b/core/src/com/unciv/logic/civilization/PolicyManager.kt index 42bd8f73..17336b34 100644 --- a/core/src/com/unciv/logic/civilization/PolicyManager.kt +++ b/core/src/com/unciv/logic/civilization/PolicyManager.kt @@ -148,7 +148,7 @@ class PolicyManager { VictoryType.Domination, VictoryType.Neutral -> civInfo.gameInfo.ruleSet.units.keys.filter { it.startsWith("Great") }.random() } - civInfo.addGreatPerson(greatPerson) + civInfo.addUnit(greatPerson) } } "Quantity of strategic resources produced by the empire increased by 100%" -> civInfo.updateDetailedCivResources() diff --git a/core/src/com/unciv/logic/civilization/TechManager.kt b/core/src/com/unciv/logic/civilization/TechManager.kt index cd0addcd..cd1ea0c1 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.UniqueAbility import com.unciv.logic.map.MapSize import com.unciv.logic.map.RoadStatus import com.unciv.models.ruleset.tech.Technology +import com.unciv.models.translations.getPlaceholderParameters import com.unciv.ui.utils.withItem import java.util.* import kotlin.collections.ArrayList @@ -271,9 +272,11 @@ class TechManager { } } - if (techName == "Writing" && civInfo.nation.unique == UniqueAbility.INGENUITY - && civInfo.cities.any()) - civInfo.addGreatPerson("Great Scientist") + for(unique in civInfo.getMatchingUniques("Receive free [] when you discover []")){ + val params = unique.getPlaceholderParameters() + if(params[1]!=techName) continue + civInfo.addUnit(params[0]) + } } fun setTransients() { diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index 48ee7cb6..409fd31f 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -361,24 +361,24 @@ class Building : NamedStats(), IConstruction{ if ("Empire enters golden age" in uniques) civInfo.goldenAges.enterGoldenAge() for(unique in uniques) if(unique.equalsPlaceholderText("Free [] appears")){ val unitName = unique.getPlaceholderParameters()[0] - civInfo.addGreatPerson(unitName, cityConstructions.cityInfo) + civInfo.addUnit(unitName, cityConstructions.cityInfo) } if ("2 free Great Artists appear" in uniques) { - civInfo.addGreatPerson("Great Artist", cityConstructions.cityInfo) - civInfo.addGreatPerson("Great Artist", cityConstructions.cityInfo) + civInfo.addUnit("Great Artist", cityConstructions.cityInfo) + civInfo.addUnit("Great Artist", cityConstructions.cityInfo) } if ("2 free great scientists appear" in uniques) { - civInfo.addGreatPerson("Great Scientist", cityConstructions.cityInfo) - civInfo.addGreatPerson("Great Scientist", cityConstructions.cityInfo) + civInfo.addUnit("Great Scientist", cityConstructions.cityInfo) + civInfo.addUnit("Great Scientist", cityConstructions.cityInfo) } if ("Provides 2 free workers" in uniques) { - civInfo.placeUnitNearTile(cityConstructions.cityInfo.location, Constants.worker) - civInfo.placeUnitNearTile(cityConstructions.cityInfo.location, Constants.worker) + civInfo.addUnit(Constants.worker, cityConstructions.cityInfo) + civInfo.addUnit(Constants.worker, cityConstructions.cityInfo) } if ("Free Social Policy" in uniques) civInfo.policies.freePolicies++ if ("Free Great Person" in uniques) { if (civInfo.isPlayerCivilization()) civInfo.greatPeople.freeGreatPeople++ - else civInfo.addGreatPerson(civInfo.gameInfo.ruleSet.units.keys.filter { it.startsWith("Great") }.random()) + else civInfo.addUnit(civInfo.gameInfo.ruleSet.units.keys.filter { it.startsWith("Great") }.random()) } if ("+1 population in each city" in uniques) { for(city in civInfo.cities){ diff --git a/core/src/com/unciv/models/ruleset/Nation.kt b/core/src/com/unciv/models/ruleset/Nation.kt index 008d4c38..5788d9db 100644 --- a/core/src/com/unciv/models/ruleset/Nation.kt +++ b/core/src/com/unciv/models/ruleset/Nation.kt @@ -36,6 +36,7 @@ class Nation : INamed { lateinit var outerColor: List var unique: UniqueAbility? = null + val uniques = ArrayList() var innerColor: List? = null var startBias = ArrayList() diff --git a/core/src/com/unciv/models/ruleset/Policy.kt b/core/src/com/unciv/models/ruleset/Policy.kt index 011094ef..0d21079b 100644 --- a/core/src/com/unciv/models/ruleset/Policy.kt +++ b/core/src/com/unciv/models/ruleset/Policy.kt @@ -12,8 +12,6 @@ open class Policy : INamed { var column: Int = 0 var requires: ArrayList? = null - override fun toString(): String { - return name - } + override fun toString() = name } diff --git a/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt b/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt index 7eec52aa..4dc4b20e 100644 --- a/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt @@ -93,14 +93,18 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo rightSideButton.enable() } pickedPolicy = policy - var policyText = policy.name.tr() + "\r\n" + policy.effect.tr() + "\r\n" - if (!policy.name.endsWith("Complete")){ - if(policy.requires!!.isNotEmpty()) + val policyText = mutableListOf() + policyText += policy.name +// policyText += policy.effect + policyText += policy.uniques + + if (!policy.name.endsWith("Complete")) { + if (policy.requires!!.isNotEmpty()) policyText += "{Requires} ".tr() + policy.requires!!.joinToString { it.tr() } else - policyText += ("{Unlocked at} {"+ policy.branch.era+"}").tr() + policyText += ("{Unlocked at} {" + policy.branch.era + "}").tr() } - descriptionLabel.setText(policyText) + descriptionLabel.setText(policyText.joinToString("\r\n") { it.tr() }) } private fun getPolicyButton(policy: Policy, image: Boolean): Button {