From 853a3258764523d5b027d25f0a58db8c04a84b50 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Mon, 17 Jun 2019 11:20:15 +0300 Subject: [PATCH] Added German nation - #703 --- android/assets/jsons/Buildings.json | 1 + android/assets/jsons/Nations.json | 16 ++--- .../jsons/Translations/Notifications.json | 67 ++++++++++--------- android/assets/jsons/Units.json | 4 -- core/src/com/unciv/logic/battle/Battle.kt | 12 ++++ .../com/unciv/logic/city/CityConstructions.kt | 4 +- core/src/com/unciv/logic/city/CityInfo.kt | 3 +- core/src/com/unciv/logic/city/CityStats.kt | 6 +- .../unciv/logic/civilization/CityStateType.kt | 7 ++ .../logic/civilization/CivilizationInfo.kt | 37 +++++----- .../unciv/logic/civilization/PlayerType.kt | 6 ++ core/src/com/unciv/logic/trade/Trade.kt | 7 +- .../com/unciv/models/gamebasics/Building.kt | 50 +++++++++----- core/src/com/unciv/ui/NationTable.kt | 3 + core/src/com/unciv/ui/NewGameScreen.kt | 14 ++-- .../src/com/unciv/ui/tilegroups/CityButton.kt | 3 +- 16 files changed, 140 insertions(+), 100 deletions(-) create mode 100644 core/src/com/unciv/logic/civilization/CityStateType.kt create mode 100644 core/src/com/unciv/logic/civilization/PlayerType.kt diff --git a/android/assets/jsons/Buildings.json b/android/assets/jsons/Buildings.json index 37776d29a9..9db78b3d36 100644 --- a/android/assets/jsons/Buildings.json +++ b/android/assets/jsons/Buildings.json @@ -508,6 +508,7 @@ specialistSlots:{gold:1}, hurryCostModifier:15, percentStatBonus:{gold:25}, + uniques:["+5% Production for every Trade Route with a City-State in the empire"] requiredBuilding:"Market", requiredTech:"Banking" }, diff --git a/android/assets/jsons/Nations.json b/android/assets/jsons/Nations.json index 1c26066f66..3cd833d3e6 100644 --- a/android/assets/jsons/Nations.json +++ b/android/assets/jsons/Nations.json @@ -430,8 +430,7 @@ "Kolhapur","Prayaga","Ayodhya","Indraprastha","Mathura","Ujjain","Gulbarga","Jaunpur","Rajagriha","Sravasti","Tiruchirapalli","Thanjavur", "Bodhgaya","Kushinagar","Amaravati","Gaur","Gwalior","Jaipur","Karachi"] }, - /* - { // REQUIRES BARBARIAN CAMPS + { name:"Germany", leaderName:"Otto von Bismark", adjective:["German"], @@ -440,10 +439,10 @@ startIntroPart1: "Hail mighty Bismark, first canchellor of Germany and her empire! Germany is an upstart nation, fashioned from the ruins of the Holy Roman Empire and finally unified in 1871, a little more than a century ago. The German people have proven themselves to be creative, industrious a ferocious warriors. Despite enduring great catastrophes in the first half of the 20th century, Germany remains a worldwide economic, artistic and technological leader." startIntroPart2: "Great Prince Bismark, the German people look up too you to lead them to greater days of glory. Their determination is strong, and now they turn to you, their beloved iron chancellor, to guide them once more. Will you rile and conquer through blood and iron, or foster the Germanic arts and industry? Can you build a civilization that will stand the test of time?" - declaringWar:"I cannot wait until ye grow even mightier. Therefore, prepare for war!" - attacked:"Corrupted villain! We will bring you into the ground!" - defeated:"Germany has been destroyed. I weep for the future generations." - introduction:"Guten tag. In the name of the great German people, I bid you welcome." + declaringWar: "I cannot wait until ye grow even mightier. Therefore, prepare for war!" + attacked: "Corrupted villain! We will bring you into the ground!" + defeated: "Germany has been destroyed. I weep for the future generations." + introduction: "Guten tag. In the name of the great German people, I bid you welcome." neutralHello:"What now?" neutralLetsHearIt:["What do ye say?","Yes?","Ja?"] @@ -458,8 +457,8 @@ afterPeace:"What do ye think about calling it a draw?" tradeRequest:"It would be in your best interest, to carefully consider this proposal." - mainColor:[224,224,224], - secondaryColor:[64,64,64], + mainColor:[150,150,150], + secondaryColor:[60,60,60], uniqueName:"Furor Teutonicus" unique:"67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment, -25% land units maintenance.", cities:["Berlin","Hamburg","Munich","Cologne","Frankfurt","Essen","Dortmund","Stuttgart","Dusseldorf","Bremen", @@ -470,6 +469,7 @@ "Recklinghausen","Gצttingen","Wolfsburg","Koblenz","Hildesheim","Erlangen"] }, + /* { // REQUIRES RIVERS name:"Aztecs", leaderName:"Montezuma I", diff --git a/android/assets/jsons/Translations/Notifications.json b/android/assets/jsons/Translations/Notifications.json index 40116715e9..8390729b77 100644 --- a/android/assets/jsons/Translations/Notifications.json +++ b/android/assets/jsons/Translations/Notifications.json @@ -133,11 +133,11 @@ Portuguese:"o(a) [construction] foi construirdo em [cityName]" Japanese:"[construction]は[cityName]に建てられました" } - - "[wonder] has been built in a faraway land":{ - Italian:"La Meraviglia [wonder] è stata costruita in una terra lontana" - French:"[wonder] a été construit(e) dans un lointain pays" - } + + "[wonder] has been built in a faraway land":{ + Italian:"La Meraviglia [wonder] è stata costruita in una terra lontana" + French:"[wonder] a été construit(e) dans un lointain pays" + } "Work has started on [construction]":{ Italian:"Sono iniziati i lavori per [construction]" @@ -159,7 +159,7 @@ "One of our trades with [nation] has ended": { Italian:"Un nostro accordo con [nation] è terminato." - French:"Un de nos échanges avec [nation] a pris fin" + French:"Un de nos échanges avec [nation] a pris fin" }, "[cityname] has expanded its borders!":{ @@ -229,10 +229,10 @@ Japanese:"敵[unit]が私たちの[ourUnit]を攻撃しました" } - "Enemy city [cityName] has attacked our [ourUnit]":{ - Italian:"La città nemica [cityName] ha attaccato [ourUnit]" - French:"La cité ennemie [cityName] a attaqué notre [ourUnit]" - } + "Enemy city [cityName] has attacked our [ourUnit]":{ + Italian:"La città nemica [cityName] ha attaccato [ourUnit]" + French:"La cité ennemie [cityName] a attaqué notre [ourUnit]" + } "An enemy [unit] has captured [cityname]":{ Italian:"Un'unità nemica [unit] ha conquistato [cityname]" @@ -273,10 +273,10 @@ Japanese:"敵[unit]が私たちの[ourUnit]を破壊しました" } - "Enemy city [cityName] has destroyed our [ourUnit]":{ - Italian:"La città nemica [cityName] ha distrutto [ourUnit]" - French:"La cité ennemie [cityName] a détruit notre [ourUnit]" - } + "Enemy city [cityName] has destroyed our [ourUnit]":{ + Italian:"La città nemica [cityName] ha distrutto [ourUnit]" + French:"La cité ennemie [cityName] a détruit notre [ourUnit]" + } "An enemy [unit] was destroyed while attacking [cityname]":{ Italian:"Un'unità nemica [unit] è stata distrutta mentre attaccava [cityname]" @@ -334,14 +334,14 @@ Italian:"Abbiamo avvistato [amount] unità nemiche vicino ai nostri confini!" German:"[amount] feindliche Einheiten wurden nahe unserer Grenzen entdeckt" Simplified_Chinese:"在我们的领土附近发现了[amount]个敌方单位" - French:"[amount] unités ennemies ont été repérées proche de notre territoire" + French:"[amount] unités ennemies ont été repérées proche de notre territoire" } "[amount] enemy units were spotted in our territory": { Italian:"Abbiamo avvistato [amount] unità nemiche nel nostro territorio!" German:"[amount] feindliche Einheiten wurden in unseren Grenzen entdeckt" Simplified_Chinese:"在我们的领土内发现了[amount]个敌方单位" - French:"[amount] unités ennemies ont été repérées sur notre territoire" + French:"[amount] unités ennemies ont été repérées sur notre territoire" } "The civilization of [civName] has been destroyed!":{ @@ -356,11 +356,14 @@ Portuguese:"A civilização de [civName] foi destruida!" Japanese:"[civName]の文明は破壊されました!" } + + "We have captured a barbarian encampment and recovered [goldAmount] gold!":{ //shouldn't it be "we have destroyed ..." ? + Italian:"Nella cattura di un accampamento barbaro, abbiamo recuperato [goldAmount] Oro!" + French:"Nous avons capturé un campement barbare et pillé [goldAmount] ors" + } - "We have captured a barbarian encampment and recovered [goldAmount] gold!":{ //shouldn't it be "we have destroyed ..." ? - Italian:"Nella cattura di un accampamento barbaro, abbiamo recuperato [goldAmount] Oro!" - French:"Nous avons capturé un campement barbare et pillé [goldAmount] ors" - } + "A barbarian [unitType] has joined us!":{ + } ///////////////// ruins @@ -440,19 +443,19 @@ French:"[unit] n'a rien à faire" } - "You're losing control of [name].":{ //When you're about to lose your friendship with a City-State - Italian:"Stai perdendo il controllo di [name]." - } + "You're losing control of [name].":{ //When you're about to lose your friendship with a City-State + Italian:"Stai perdendo il controllo di [name]." + } - "You and [name] are no longer friends!":{ // When you lose friendship with a City-State (Relationship fall less than 30) - Italian:"Non sei più amico di [name]!" - } + "You and [name] are no longer friends!":{ // When you lose friendship with a City-State (Relationship fall less than 30) + Italian:"Non sei più amico di [name]!" + } - "Your alliance with [name] is faltering.":{ //When you're about to lose your alliance with a City-State - Italian:"L'alleanza con [name] si sta sfaldando." - } + "Your alliance with [name] is faltering.":{ //When you're about to lose your alliance with a City-State + Italian:"L'alleanza con [name] si sta sfaldando." + } - "You and [name] are no longer allies!":{ // When you lose alliance with a City-State (Relationship fall less than 60) - Italian:"Non sei più alleato con [name]!" - } + "You and [name] are no longer allies!":{ // When you lose alliance with a City-State (Relationship fall less than 60) + Italian:"Non sei più alleato con [name]!" + } } diff --git a/android/assets/jsons/Units.json b/android/assets/jsons/Units.json index 28cb68e717..e618ec73eb 100644 --- a/android/assets/jsons/Units.json +++ b/android/assets/jsons/Units.json @@ -516,7 +516,6 @@ attackSound:"metalhit" //Pikeman should upgrade not only to Musketman but also to Lancer }, - /* { name:"Landsknecht", replaces:"Pikeman", @@ -532,7 +531,6 @@ hurryCostModifier:20, attackSound:"metalhit" }, - */ { name:"Galleass", unitType:"WaterRanged", @@ -1014,7 +1012,6 @@ uniques:["Can move after attacking","No defensive terrain bonus"] hurryCostModifier:20, }, - /* { name:"Panzer", unitType:"Armor", @@ -1029,7 +1026,6 @@ hurryCostModifier:20, //German unique unit, stronger than Tank }, - */ { name:"Anti-Tank Gun", unitType:"Melee", diff --git a/core/src/com/unciv/logic/battle/Battle.kt b/core/src/com/unciv/logic/battle/Battle.kt index dab5c92a67..adcab685bd 100644 --- a/core/src/com/unciv/logic/battle/Battle.kt +++ b/core/src/com/unciv/logic/battle/Battle.kt @@ -85,6 +85,16 @@ class Battle(val gameInfo:GameInfo) { conquerCity(defender.city, attacker) } + + // German unique - needs to be checked before we try to move to the enemy tile, since the encampment disappears after we move in + if(defender.isDefeated() && defender.getCivInfo().isBarbarianCivilization() && attackedTile.improvement==Constants.barbarianEncampment + && attacker.getCivInfo().getNation().unique== "67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment, -25% land units maintenance." + && Random().nextDouble() > 0.67){ + attacker.getCivInfo().placeUnitNearTile(attackedTile.position, defender.getName()) + attacker.getCivInfo().gold += 25 + attacker.getCivInfo().addNotification("A barbarian [${defender.getName()}] has joined us!",attackedTile.position, Color.RED) + } + // we're a melee unit and we destroyed\captured an enemy unit else if (attacker.isMelee() && (defender.isDefeated() || defender.getCivInfo()==attacker.getCivInfo()) @@ -96,6 +106,7 @@ class Battle(val gameInfo:GameInfo) { attacker.unit.moveToTile(attackedTile) } + if(attacker is MapUnitCombatant) { val unit = attacker.unit if (unit.hasUnique("Can move after attacking") @@ -141,6 +152,7 @@ class Battle(val gameInfo:GameInfo) { addXp(defender,2,attacker) } + // Add culture when defeating a barbarian when Honor policy is adopted (can be either attacker or defender!) fun tryGetCultureFromHonor(civUnit:ICombatant, barbarianUnit:ICombatant){ if(barbarianUnit.isDefeated() && barbarianUnit is MapUnitCombatant diff --git a/core/src/com/unciv/logic/city/CityConstructions.kt b/core/src/com/unciv/logic/city/CityConstructions.kt index 1c02b011fe..079b6b3e6f 100644 --- a/core/src/com/unciv/logic/city/CityConstructions.kt +++ b/core/src/com/unciv/logic/city/CityConstructions.kt @@ -49,8 +49,8 @@ class CityConstructions { fun getStatPercentBonuses(): Stats { val stats = Stats() - for (building in getBuiltBuildings().filter { it.percentStatBonus != null }) - stats.add(building.percentStatBonus!!) + for (building in getBuiltBuildings()) + stats.add(building.getStatPercentageBonuses(cityInfo.civInfo)) return stats } diff --git a/core/src/com/unciv/logic/city/CityInfo.kt b/core/src/com/unciv/logic/city/CityInfo.kt index 5fc33eb6c0..d73be63936 100644 --- a/core/src/com/unciv/logic/city/CityInfo.kt +++ b/core/src/com/unciv/logic/city/CityInfo.kt @@ -17,7 +17,6 @@ import kotlin.math.min class CityInfo { @Transient lateinit var civInfo: CivilizationInfo - @Transient var isConnectedToCapital = false @Transient lateinit var ccenterTile:TileInfo // cached for better performance @Transient val range = 2 @Transient lateinit var tileMap: TileMap @@ -95,7 +94,6 @@ class CityInfo { toReturn.tiles = tiles toReturn.workedTiles = workedTiles toReturn.isBeingRazed=isBeingRazed - toReturn.isConnectedToCapital = isConnectedToCapital toReturn.attackedThisTurn = attackedThisTurn toReturn.resistanceCounter = resistanceCounter return toReturn @@ -178,6 +176,7 @@ class CityInfo { } fun isCapital() = cityConstructions.isBuilt("Palace") + fun isConnectedToCapital() = civInfo.citiesConnectedToCapital.contains(this) internal fun getMaxHealth(): Int { return 200 + cityConstructions.getBuiltBuildings().sumBy { it.cityHealth } diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index c076657308..f14038428e 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -34,7 +34,7 @@ class CityStats { private fun getStatsFromTradeRoute(): Stats { val stats = Stats() - if (!cityInfo.isCapital() && isConnectedToCapital(RoadStatus.Road)) { + if (!cityInfo.isCapital() && cityInfo.isConnectedToCapital()) { val civInfo = cityInfo.civInfo var goldFromTradeRoute = civInfo.getCapital().population.population * 0.15 + cityInfo.population.population * 1.1 - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5) if(civInfo.getNation().unique=="+1 Gold from each Trade Route, Oil resources provide double quantity") goldFromTradeRoute += 1 @@ -196,7 +196,7 @@ class CityStats { happinessFromPolicies += (cityInfo.population.population / 10).toFloat() if (civInfo.policies.isAdopted("Monarchy") && cityInfo.isCapital()) happinessFromPolicies += (cityInfo.population.population / 2).toFloat() - if (civInfo.policies.isAdopted("Meritocracy") && isConnectedToCapital(RoadStatus.Road)) + if (civInfo.policies.isAdopted("Meritocracy") && cityInfo.isConnectedToCapital()) happinessFromPolicies += 1f if(civInfo.policies.isAdopted("Military Caste") && cityInfo.getCenterTile().militaryUnit!=null) happinessFromPolicies+=1 @@ -320,7 +320,7 @@ class CityStats { fun isConnectedToCapital(roadType: RoadStatus): Boolean { if (cityInfo.civInfo.cities.count() < 2) return false// first city! - if(roadType==RoadStatus.Road) return cityInfo.isConnectedToCapital // this transient is not applicable to connection via railroad. + if(roadType==RoadStatus.Road) return cityInfo.isConnectedToCapital() // this transient is not applicable to connection via railroad. val capitalTile = cityInfo.civInfo.getCapital().getCenterTile() val bfs = BFS(capitalTile){it.roadStatus == roadType} diff --git a/core/src/com/unciv/logic/civilization/CityStateType.kt b/core/src/com/unciv/logic/civilization/CityStateType.kt new file mode 100644 index 0000000000..8c1440e91c --- /dev/null +++ b/core/src/com/unciv/logic/civilization/CityStateType.kt @@ -0,0 +1,7 @@ +package com.unciv.logic.civilization + +enum class CityStateType{ + Cultured, + Maritime, + Mercantile +} \ 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 5bbb9e8cc5..1e2d4e9e0e 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -14,7 +14,7 @@ import com.unciv.logic.map.BFS import com.unciv.logic.map.MapUnit import com.unciv.logic.map.RoadStatus import com.unciv.logic.map.TileInfo -import com.unciv.logic.trade.Trade +import com.unciv.logic.trade.TradeRequest import com.unciv.models.gamebasics.* import com.unciv.models.gamebasics.tech.TechEra import com.unciv.models.gamebasics.tile.ResourceSupplyList @@ -25,24 +25,10 @@ import java.util.* import kotlin.collections.ArrayList import kotlin.collections.HashMap import kotlin.math.max +import kotlin.math.min import kotlin.math.pow import kotlin.math.roundToInt -enum class PlayerType{ - AI, - Human -} - -enum class CityStateType{ - Cultured, - Maritime, - Mercantile -} - -class TradeRequest(val requestingCiv:String, - /** Their offers are what they offer us, and our offers are what they want in return */ - val trade: Trade) - class CivilizationInfo { @Transient lateinit var gameInfo: GameInfo /** @@ -53,6 +39,8 @@ class CivilizationInfo { @Transient private var units=listOf() @Transient var viewableTiles = setOf() @Transient var viewableInvisibleUnitsTiles = setOf() + /** Contains cities from ALL civilizations connected by trade routes to the capital */ + @Transient var citiesConnectedToCapital = listOf() /** This is for performance since every movement calculation depends on this, see MapUnit comment */ @Transient var hasActiveGreatWall = false @@ -203,9 +191,16 @@ class CivilizationInfo { val freeUnits = 3 var unitsToPayFor = getCivUnits() if(policies.isAdopted("Oligarchy")) unitsToPayFor = unitsToPayFor.filterNot { it.getTile().isCityCenter() } - val totalPaidUnits = max(0,unitsToPayFor.count()-freeUnits) + + var numberOfUnitsToPayFor = max(0f, unitsToPayFor.count().toFloat() - freeUnits) + if(getNation().unique=="67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment, -25% land units maintenance."){ + val numberOfUnitsWithDiscount = min(numberOfUnitsToPayFor, unitsToPayFor.count { it.type.isLandUnit() }.toFloat()) + numberOfUnitsToPayFor -= 0.25f * numberOfUnitsWithDiscount + } + + val gameProgress = gameInfo.turns/400f // as game progresses Maintenance cost rises - var cost = baseUnitCost*totalPaidUnits*(1+gameProgress) + var cost = baseUnitCost*numberOfUnitsToPayFor*(1+gameProgress) cost = cost.pow(1+gameProgress/3) // Why 3? To spread 1 to 1.33 if(!isPlayerCivilization()) cost *= gameInfo.getDifficulty().aiUnitMaintenanceModifier @@ -544,6 +539,7 @@ class CivilizationInfo { val citiesReachedToMediums = HashMap>() var citiesToCheck = mutableListOf(getCapital()) citiesReachedToMediums[getCapital()] = arrayListOf("Start") + while(citiesToCheck.isNotEmpty() && citiesReachedToMediums.size() for(cityToConnectFrom in citiesToCheck){ @@ -551,6 +547,7 @@ class CivilizationInfo { // This is copypasta and can be cleaned up if(!reachedMediums.contains("Road")){ + val roadBfs = BFS(cityToConnectFrom.getCenterTile()){it.roadStatus!=RoadStatus.None} roadBfs.stepToEnd() val reachedCities = cities.filter { roadBfs.tilesReached.containsKey(it.getCenterTile())} @@ -586,9 +583,7 @@ class CivilizationInfo { citiesToCheck = newCitiesToCheck } - for(city in cities){ - city.isConnectedToCapital = citiesReachedToMediums.containsKey(city) - } + citiesConnectedToCapital = citiesReachedToMediums.keys.toList() } fun destroy(){ diff --git a/core/src/com/unciv/logic/civilization/PlayerType.kt b/core/src/com/unciv/logic/civilization/PlayerType.kt new file mode 100644 index 0000000000..5d5a4790a9 --- /dev/null +++ b/core/src/com/unciv/logic/civilization/PlayerType.kt @@ -0,0 +1,6 @@ +package com.unciv.logic.civilization + +enum class PlayerType{ + AI, + Human +} \ No newline at end of file diff --git a/core/src/com/unciv/logic/trade/Trade.kt b/core/src/com/unciv/logic/trade/Trade.kt index bd471584e7..308ee216a4 100644 --- a/core/src/com/unciv/logic/trade/Trade.kt +++ b/core/src/com/unciv/logic/trade/Trade.kt @@ -38,4 +38,9 @@ class Trade{ theirOffers.clear() theirOffers.addAll(trade.theirOffers) } -} \ No newline at end of file +} + + +class TradeRequest(val requestingCiv:String, + /** Their offers are what they offer us, and our offers are what they want in return */ + val trade: Trade) \ No newline at end of file diff --git a/core/src/com/unciv/models/gamebasics/Building.kt b/core/src/com/unciv/models/gamebasics/Building.kt index fd64b92b5f..31709d4fae 100644 --- a/core/src/com/unciv/models/gamebasics/Building.kt +++ b/core/src/com/unciv/models/gamebasics/Building.kt @@ -55,10 +55,9 @@ class Building : NamedStats(), IConstruction{ val infoList= mutableListOf() val str = getStats(null).toString() if(str.isNotEmpty()) infoList += str - if(percentStatBonus!=null){ - for(stat in percentStatBonus!!.toHashMap()) - if(stat.value!=0f) infoList+="+${stat.value.toInt()}% ${stat.key.toString().tr()}" - } + for(stat in getStatPercentageBonuses(null).toHashMap()) + if(stat.value!=0f) infoList+="+${stat.value.toInt()}% ${stat.key.toString().tr()}" + val improvedResources = GameBasics.TileResources.values.filter { it.building==name }.map { it.name.tr() } if(improvedResources.isNotEmpty()){ // buildings that improve resources @@ -93,13 +92,14 @@ class Building : NamedStats(), IConstruction{ if(uniques.isNotEmpty()) stringBuilder.appendln(uniques.asSequence().map { it.tr() }.joinToString("\n")) if (stats.toString() != "") stringBuilder.appendln(stats) - if (this.percentStatBonus != null) { - if (this.percentStatBonus!!.production != 0f) stringBuilder.append("+" + this.percentStatBonus!!.production.toInt() + "% {Production}\n".tr()) - if (this.percentStatBonus!!.gold != 0f) stringBuilder.append("+" + this.percentStatBonus!!.gold.toInt() + "% {Gold}\n".tr()) - if (this.percentStatBonus!!.science != 0f) stringBuilder.append("+" + this.percentStatBonus!!.science.toInt() + "% {Science}\r\n".tr()) - if (this.percentStatBonus!!.food != 0f) stringBuilder.append("+" + this.percentStatBonus!!.food.toInt() + "% {Food}\n".tr()) - if (this.percentStatBonus!!.culture != 0f) stringBuilder.append("+" + this.percentStatBonus!!.culture.toInt() + "% {Culture}\r\n".tr()) - } + + val percentStats = getStatPercentageBonuses(civInfo) + if (percentStats.production != 0f) stringBuilder.append("+" + percentStats.production.toInt() + "% {Production}\n".tr()) + if (percentStats.gold != 0f) stringBuilder.append("+" + percentStats.gold.toInt() + "% {Gold}\n".tr()) + if (percentStats.science != 0f) stringBuilder.append("+" + percentStats.science.toInt() + "% {Science}\r\n".tr()) + if (percentStats.food != 0f) stringBuilder.append("+" + percentStats.food.toInt() + "% {Food}\n".tr()) + if (percentStats.culture != 0f) stringBuilder.append("+" + percentStats.culture.toInt() + "% {Culture}\r\n".tr()) + if (this.greatPersonPoints != null) { val gpp = this.greatPersonPoints!! if (gpp.production != 0f) stringBuilder.appendln("+" + gpp.production.toInt()+" " + "[Great Engineer] points".tr()) @@ -143,12 +143,6 @@ class Building : NamedStats(), IConstruction{ if (adoptedPolicies.contains("Humanism") && hashSetOf("University", "Observatory", "Public School").contains(baseBuildingName )) stats.happiness += 1f - if (adoptedPolicies.contains("Theocracy") && baseBuildingName == "Temple") - percentStatBonus = Stats().apply { gold = 10f } - - if (adoptedPolicies.contains("Free Thought") && baseBuildingName == "University") - percentStatBonus!!.science = 50f - if (adoptedPolicies.contains("Rationalism Complete") && !isWonder && stats.science > 0) stats.gold += 1f @@ -168,6 +162,26 @@ class Building : NamedStats(), IConstruction{ return stats } + fun getStatPercentageBonuses(civInfo: CivilizationInfo?): Stats { + val stats = percentStatBonus + if(stats==null) return Stats() // empty + if(civInfo==null) return stats // initial stats + + val adoptedPolicies = civInfo.policies.adoptedPolicies + val baseBuildingName = getBaseBuilding().name + + if (adoptedPolicies.contains("Theocracy") && baseBuildingName == "Temple") + stats.gold = 10f + + if (adoptedPolicies.contains("Free Thought") && baseBuildingName == "University") + stats.science = 50f + + if(uniques.contains("+5% Production for every Trade Route with a City-State in the empire")) + stats.production += 5*civInfo.citiesConnectedToCapital.count { it.civInfo.isCityState() } + + return stats + } + override fun canBePurchased(): Boolean { return !isWonder && !isNationalWonder } @@ -331,7 +345,7 @@ class Building : NamedStats(), IConstruction{ fun isStatRelated(stat: Stat): Boolean { if (get(stat) > 0) return true - if (percentStatBonus!=null && percentStatBonus!!.get(stat)>0) return true + if (getStatPercentageBonuses(null).get(stat)>0) return true if (specialistSlots!=null && specialistSlots!!.get(stat)>0) return true return false } diff --git a/core/src/com/unciv/ui/NationTable.kt b/core/src/com/unciv/ui/NationTable.kt index 6f60e774ef..70e4a7a5e5 100644 --- a/core/src/com/unciv/ui/NationTable.kt +++ b/core/src/com/unciv/ui/NationTable.kt @@ -56,6 +56,7 @@ class NationTable(val nation: Nation, val newGameParameters: GameParameters, ski for (stat in building.toHashMap()) if (stat.value != originalBuildingStatMap[stat.key]) textList += " "+stat.key.toString().tr() +" "+stat.value.toInt() + " vs " + originalBuildingStatMap[stat.key]!!.toInt() + for(unique in building.uniques.filter { it !in originalBuilding.uniques }) textList += " "+unique.tr() if (building.maintenance != originalBuilding.maintenance) @@ -74,6 +75,8 @@ class NationTable(val nation: Nation, val newGameParameters: GameParameters, ski val originalUnit = GameBasics.Units[unit.replaces!!]!! textList += unit.name.tr() + " - {replaces} " + originalUnit.name.tr() + if(unit.cost != originalUnit.cost) + textList += " {Cost} " + unit.cost + " vs " + originalUnit.cost if (unit.strength != originalUnit.strength) textList += " {Strength} " + unit.strength + " vs " + originalUnit.strength if (unit.rangedStrength!= originalUnit.rangedStrength) diff --git a/core/src/com/unciv/ui/NewGameScreen.kt b/core/src/com/unciv/ui/NewGameScreen.kt index 62cc880aa4..9f38fa6762 100644 --- a/core/src/com/unciv/ui/NewGameScreen.kt +++ b/core/src/com/unciv/ui/NewGameScreen.kt @@ -234,17 +234,17 @@ class NewGameScreen: PickerScreen(){ newGameOptionsTable.add("{Victory conditions}:".tr()).colspan(2).row() // Create a checkbox for each VictoryType existing - var i=0 + var i = 0 val victoryConditionsTable = Table().apply { defaults().pad(10f) } for (victoryType in VictoryType.values()) { - if(victoryType==VictoryType.Neutral) continue - val victoryCheckbox = CheckBox(victoryType.name.tr(),skin) - victoryCheckbox.name=victoryType.name - victoryCheckbox.isChecked=newGameParameters.victoryTypes.contains(victoryType) + if (victoryType == VictoryType.Neutral) continue + val victoryCheckbox = CheckBox(victoryType.name.tr(), skin) + victoryCheckbox.name = victoryType.name + victoryCheckbox.isChecked = newGameParameters.victoryTypes.contains(victoryType) victoryCheckbox.addListener(object : ChangeListener() { override fun changed(event: ChangeEvent?, actor: Actor?) { // If the checkbox is checked, adds the victoryTypes else remove it - if(victoryCheckbox.isChecked){ + if (victoryCheckbox.isChecked) { newGameParameters.victoryTypes.add(victoryType) } else { newGameParameters.victoryTypes.remove(victoryType) @@ -252,7 +252,7 @@ class NewGameScreen: PickerScreen(){ } }) victoryConditionsTable.add(victoryCheckbox) - if(++i%2==0) victoryConditionsTable.row() + if (++i % 2 == 0) victoryConditionsTable.row() } newGameOptionsTable.add(victoryConditionsTable).colspan(2).row() } diff --git a/core/src/com/unciv/ui/tilegroups/CityButton.kt b/core/src/com/unciv/ui/tilegroups/CityButton.kt index 6ebf349f3c..58e5856ca9 100644 --- a/core/src/com/unciv/ui/tilegroups/CityButton.kt +++ b/core/src/com/unciv/ui/tilegroups/CityButton.kt @@ -12,7 +12,6 @@ import com.unciv.UnCivGame import com.unciv.logic.city.CityConstructions import com.unciv.logic.city.CityInfo import com.unciv.logic.city.SpecialConstruction -import com.unciv.logic.map.RoadStatus import com.unciv.ui.cityscreen.CityScreen import com.unciv.ui.utils.* @@ -87,7 +86,7 @@ class CityButton(val city: CityInfo, internal val tileGroup: WorldTileGroup, ski val starImage = ImageGetter.getImage("OtherIcons/Star.png").apply { color = Color.LIGHT_GRAY } iconTable.add(starImage).size(20f).pad(2f).padLeft(10f) } - } else if (city.civInfo.isCurrentPlayer() && city.cityStats.isConnectedToCapital(RoadStatus.Road)) { + } else if (city.civInfo.isCurrentPlayer() && city.isConnectedToCapital()) { val connectionImage = ImageGetter.getStatIcon("CityConnection") iconTable.add(connectionImage).size(20f).pad(2f).padLeft(10f) }