From 51ecb0e99d3aee975f59dc14390f0cdaca1d1784 Mon Sep 17 00:00:00 2001 From: r3versi Date: Sat, 11 Jan 2020 21:52:58 +0100 Subject: [PATCH] Legalism grants Culture Buildings asap (#1658) * Legalism grants Culture Buildings asap * Buildings granted by Legalism cost no maintenance --- .../com/unciv/logic/city/CityConstructions.kt | 44 ++++++++++---- .../logic/civilization/CivilizationInfo.kt | 3 +- .../unciv/logic/civilization/PolicyManager.kt | 60 ++++++++++++------- .../ui/worldscreen/NotificationsScroll.kt | 2 +- 4 files changed, 74 insertions(+), 35 deletions(-) diff --git a/core/src/com/unciv/logic/city/CityConstructions.kt b/core/src/com/unciv/logic/city/CityConstructions.kt index cbd5780400..53d5eed61e 100644 --- a/core/src/com/unciv/logic/city/CityConstructions.kt +++ b/core/src/com/unciv/logic/city/CityConstructions.kt @@ -62,7 +62,15 @@ class CityConstructions { /** * @return Maintenance cost of all built buildings */ - fun getMaintenanceCosts(): Int = getBuiltBuildings().sumBy { it.maintenance } + fun getMaintenanceCosts(): Int { + var maintenanceCost = getBuiltBuildings().sumBy { it.maintenance } + val policyManager = cityInfo.civInfo.policies + if (policyManager.isAdopted("Legalism") && cityInfo.id in policyManager.legalismState) { + val buildingName = policyManager.legalismState[cityInfo.id] + maintenanceCost -= cityInfo.getRuleset().buildings[buildingName]!!.maintenance + } + return maintenanceCost + } /** * @return Bonus (%) [Stats] provided by all built buildings in city @@ -194,6 +202,7 @@ class CityConstructions { if (inProgressConstructions.containsKey(currentConstruction) && inProgressConstructions[currentConstruction]!! >= productionCost) { constructionComplete(construction) + cancelCurrentConstruction() } } } @@ -232,20 +241,19 @@ class CityConstructions { private fun constructionComplete(construction: IConstruction) { construction.postBuildEvent(this) - inProgressConstructions.remove(currentConstruction) + if (construction.name in inProgressConstructions) + inProgressConstructions.remove(construction.name) if (construction is Building && construction.isWonder) { cityInfo.civInfo.popupAlerts.add(PopupAlert(AlertType.WonderBuilt, construction.name)) for (civ in cityInfo.civInfo.gameInfo.civilizations) { if (civ.exploredTiles.contains(cityInfo.location)) - civ.addNotification("[$currentConstruction] has been built in [${cityInfo.name}]", cityInfo.location, Color.BROWN) + civ.addNotification("[${construction.name}] has been built in [${cityInfo.name}]", cityInfo.location, Color.BROWN) else - civ.addNotification("[$currentConstruction] has been built in a faraway land",null,Color.BROWN) + civ.addNotification("[${construction.name}] has been built in a faraway land",null,Color.BROWN) } } else - cityInfo.civInfo.addNotification("[$currentConstruction] has been built in [" + cityInfo.name + "]", cityInfo.location, Color.BROWN) - - cancelCurrentConstruction() + cityInfo.civInfo.addNotification("[${construction.name}] has been built in [" + cityInfo.name + "]", cityInfo.location, Color.BROWN) } fun addBuilding(buildingName:String){ @@ -270,18 +278,32 @@ class CityConstructions { cityInfo.civInfo.updateDetailedCivResources() // this building/unit could be a resource-requiring one } - fun addCultureBuilding() { + fun hasBuildableCultureBuilding(): Boolean { + val basicCultureBuildings = listOf("Monument", "Temple", "Opera House", "Museum") + .map { cityInfo.civInfo.getEquivalentBuilding(it) } + + return basicCultureBuildings + .filter { it.isBuildable(this) || it.name == currentConstruction} + .any() + } + + fun addCultureBuilding(): String? { val basicCultureBuildings = listOf("Monument", "Temple", "Opera House", "Museum") .map { cityInfo.civInfo.getEquivalentBuilding(it) } val buildableCultureBuildings = basicCultureBuildings - .filter { it.isBuildable(this)} + .filter { it.isBuildable(this) || it.name == currentConstruction } + + if (buildableCultureBuildings.isEmpty()) + return null - if (buildableCultureBuildings.isEmpty()) return val cultureBuildingToBuild = buildableCultureBuildings.minBy { it.cost }!!.name - addBuilding(cultureBuildingToBuild) + constructionComplete(getConstruction(cultureBuildingToBuild)) + if (currentConstruction == cultureBuildingToBuild) cancelCurrentConstruction() + + return cultureBuildingToBuild } private fun cancelCurrentConstruction() { diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 73b9dea146..a5a4ed4570 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -358,7 +358,8 @@ class CivilizationInfo { fun updateViewableTiles() = transients().updateViewableTiles() fun updateDetailedCivResources() = transients().updateDetailedCivResources() - fun startTurn(){ + fun startTurn() { + policies.startTurn() updateStatsForNextTurn() // for things that change when turn passes e.g. golden age, city state influence // Generate great people at the start of the turn, diff --git a/core/src/com/unciv/logic/civilization/PolicyManager.kt b/core/src/com/unciv/logic/civilization/PolicyManager.kt index 3f90f19153..f97c860688 100644 --- a/core/src/com/unciv/logic/civilization/PolicyManager.kt +++ b/core/src/com/unciv/logic/civilization/PolicyManager.kt @@ -10,8 +10,7 @@ import kotlin.math.roundToInt class PolicyManager { - @Transient - lateinit var civInfo: CivilizationInfo + @Transient lateinit var civInfo: CivilizationInfo var freePolicies = 0 var storedCulture = 0 @@ -19,6 +18,30 @@ class PolicyManager { var numberOfAdoptedPolicies = 0 var shouldOpenPolicyPicker = false get() = field && canAdoptPolicy() + var legalismState = HashMap() + + fun clone(): PolicyManager { + val toReturn = PolicyManager() + toReturn.numberOfAdoptedPolicies = numberOfAdoptedPolicies + toReturn.adoptedPolicies.addAll(adoptedPolicies) + toReturn.freePolicies = freePolicies + toReturn.shouldOpenPolicyPicker = shouldOpenPolicyPicker + toReturn.storedCulture = storedCulture + toReturn.legalismState.putAll(legalismState) + return toReturn + } + + fun startTurn() { + if (isAdopted("Legalism") && legalismState.size < 4) + tryAddLegalismBuildings() + } + + fun endTurn(culture: Int) { + val couldAdoptPolicyBefore = canAdoptPolicy() + storedCulture += culture + if (!couldAdoptPolicyBefore && canAdoptPolicy()) + shouldOpenPolicyPicker = true + } // from https://forums.civfanatics.com/threads/the-number-crunching-thread.389702/ // round down to nearest 5 @@ -88,9 +111,7 @@ class PolicyManager { "Citizenship" -> if(hasCapital) civInfo.placeUnitNearTile(civInfo.getCapital().location, Constants.worker) "Representation", "Reformation" -> civInfo.goldenAges.enterGoldenAge() "Scientific Revolution" -> civInfo.tech.freeTechs += 2 - "Legalism" -> - for (city in civInfo.cities.subList(0, min(4, civInfo.cities.size))) - city.cityConstructions.addCultureBuilding() + "Legalism" -> tryAddLegalismBuildings() "Free Religion" -> freePolicies++ "Liberty Complete" -> { if (civInfo.isPlayerCivilization()) civInfo.greatPeople.freeGreatPeople++ @@ -107,27 +128,22 @@ class PolicyManager { } } + // This ALSO has the side-effect of updating the CivInfo statForNextTurn so we don't need to call it explicitly for (cityInfo in civInfo.cities) - cityInfo.cityStats.update() // This ALSO has the side-effect of updating the CivInfo startForNextTurn so we don't need to call it explicitly + cityInfo.cityStats.update() if(!canAdoptPolicy()) shouldOpenPolicyPicker=false } - fun endTurn(culture: Int) { - val couldAdoptPolicyBefore = canAdoptPolicy() - storedCulture += culture - if (!couldAdoptPolicyBefore && canAdoptPolicy()) - shouldOpenPolicyPicker = true + private fun tryAddLegalismBuildings() { + val candidateCities = civInfo.cities + .sortedBy { it.turnAcquired } + .subList(0, min(4, civInfo.cities.size)) + .filter { it.id !in legalismState + && it.cityConstructions.hasBuildableCultureBuilding() } + for (city in candidateCities) { + val builtBuilding = city.cityConstructions.addCultureBuilding() + legalismState[city.id] = builtBuilding!! + } } - - fun clone(): PolicyManager { - val toReturn = PolicyManager() - toReturn.numberOfAdoptedPolicies=numberOfAdoptedPolicies - toReturn.adoptedPolicies.addAll(adoptedPolicies) - toReturn.freePolicies=freePolicies - toReturn.shouldOpenPolicyPicker=shouldOpenPolicyPicker - toReturn.storedCulture=storedCulture - return toReturn - } - } \ No newline at end of file diff --git a/core/src/com/unciv/ui/worldscreen/NotificationsScroll.kt b/core/src/com/unciv/ui/worldscreen/NotificationsScroll.kt index ef6aa4c726..8312bf2380 100644 --- a/core/src/com/unciv/ui/worldscreen/NotificationsScroll.kt +++ b/core/src/com/unciv/ui/worldscreen/NotificationsScroll.kt @@ -29,7 +29,7 @@ class NotificationsScroll(internal val worldScreen: WorldScreen) : ScrollPane(nu notificationsHash = notifications.hashCode() notificationsTable.clearChildren() - for (notification in notifications.toList()) { // toList to avoid concurrency problems + for (notification in notifications.toList().reversed()) { // toList to avoid concurrency problems val label = notification.text.toLabel(Color.BLACK,14) val listItem = Table()