From c8a7cf29b6486664ab6c434666a45fcdf316110d Mon Sep 17 00:00:00 2001 From: itanasi <44038014+itanasi@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:42:23 -0800 Subject: [PATCH] AutoAssign Population with Food Converts to Production (#11141) * Properly Calculate Population based on Food Conversion to Prod Trigger properly when Queue is changed * Remove triggers * Missed a trigger * Add triggers in CityConstructionsTable so we can call cityScreen.update() * Properly Calculate Population based on Food Conversion to Prod Trigger properly when Queue is changed * Remove triggers * Missed a trigger * Add triggers in CityConstructionsTable so we can call cityScreen.update() --- core/src/com/unciv/logic/automation/Automation.kt | 7 +++++++ core/src/com/unciv/logic/city/CityStats.kt | 13 ++++++++----- .../ui/screens/cityscreen/CityConstructionsTable.kt | 12 +++++++++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/core/src/com/unciv/logic/automation/Automation.kt b/core/src/com/unciv/logic/automation/Automation.kt index 2916eb40c5..8684eac43e 100644 --- a/core/src/com/unciv/logic/automation/Automation.kt +++ b/core/src/com/unciv/logic/automation/Automation.kt @@ -47,6 +47,7 @@ object Automation { val cityAIFocus = city.getCityFocus() val yieldStats = stats.clone() val civPersonality = city.civ.getPersonality() + val cityStatsObj = city.cityStats if (specialist) { // If you have the Food Bonus, count as 1 extra food production (base is 2food) @@ -61,6 +62,12 @@ object Automation { } val surplusFood = cityStats[Stat.Food] + // If current Production converts Food into Production, then calculate increased Production Yield + if(cityStatsObj.canConvertFoodToProduction(surplusFood, city.cityConstructions.getCurrentConstruction())) { + // calculate delta increase of food->prod. This isn't linear + yieldStats.production += cityStatsObj.getProductionFromExcessiveFood(surplusFood+yieldStats.food) - cityStatsObj.getProductionFromExcessiveFood(surplusFood) + yieldStats.food = 0f // all food goes to 0 + } // Apply base weights yieldStats.applyRankingWeights() diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 29195eafcd..c45b82f5ab 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -577,10 +577,7 @@ class CityStats(val city: City) { val buildingsMaintenance = getBuildingMaintenanceCosts() // this is AFTER the bonus calculation! newFinalStatList["Maintenance"] = Stats(gold = -buildingsMaintenance.toInt().toFloat()) - if (totalFood > 0 - && currentConstruction is INonPerpetualConstruction - && currentConstruction.hasUnique(UniqueType.ConvertFoodToProductionWhenConstructed) - ) { + if (canConvertFoodToProduction(totalFood, currentConstruction)) { newFinalStatList["Excess food to production"] = Stats(production = getProductionFromExcessiveFood(totalFood), food = -totalFood) } @@ -603,9 +600,15 @@ class CityStats(val city: City) { finalStatList = newFinalStatList } + fun canConvertFoodToProduction(food: Float, currentConstruction: IConstruction): Boolean { + return (food > 0 + && currentConstruction is INonPerpetualConstruction + && currentConstruction.hasUnique(UniqueType.ConvertFoodToProductionWhenConstructed)) + } + // calculate the conversion of the excessive food to the production // See for details: https://civilization.fandom.com/wiki/Settler_(Civ5) - private fun getProductionFromExcessiveFood(food : Float): Float { + fun getProductionFromExcessiveFood(food : Float): Float { return if (food >= 4.0f ) 2.0f + (food / 4.0f).toInt() else if (food >= 2.0f ) 2.0f else if (food >= 1.0f ) 1.0f diff --git a/core/src/com/unciv/ui/screens/cityscreen/CityConstructionsTable.kt b/core/src/com/unciv/ui/screens/cityscreen/CityConstructionsTable.kt index a5eb74a84b..18ec9a055d 100644 --- a/core/src/com/unciv/ui/screens/cityscreen/CityConstructionsTable.kt +++ b/core/src/com/unciv/ui/screens/cityscreen/CityConstructionsTable.kt @@ -368,6 +368,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) { if (cityScreen.canCityBeChanged()) table.onRightClick { selectQueueEntry { CityScreenConstructionMenu(cityScreen.stage, table, cityScreen.city, construction) { + cityScreen.city.reassignPopulation() cityScreen.update() } } } @@ -487,6 +488,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) { cityScreen.updateWithoutConstructionAndMap() } CityScreenConstructionMenu(cityScreen.stage, pickConstructionButton, cityScreen.city, construction) { + cityScreen.city.reassignPopulation() cityScreen.update() } } @@ -554,6 +556,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) { cityConstructions.removeFromQueue(selectedQueueEntry, false) cityScreen.clearSelection() selectedQueueEntry = -1 + cityScreen.city.reassignPopulation() cityScreen.update() } if (city.isPuppet) @@ -591,6 +594,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) { cityConstructions.addToQueue(construction.name) if (!construction.shouldBeDisplayed(cityConstructions)) // For buildings - unlike units which can be queued multiple times cityScreen.clearSelection() + cityScreen.city.reassignPopulation() cityScreen.update() cityScreen.game.settings.addCompletedTutorialTask("Pick construction") } @@ -762,6 +766,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) { cityScreen.selectConstruction(newConstruction) } } + cityScreen.city.reassignPopulation() cityScreen.update() } @@ -779,11 +784,11 @@ class CityConstructionsTable(private val cityScreen: CityScreen) { button.onActivation { button.touchable = Touchable.disabled selectedQueueEntry = movePriority(constructionQueueIndex) - // No need to call entire cityScreen.update() as reordering doesn't influence Stat or Map, - // nor does it need an expensive rebuild of the available constructions. // Selection display may need to update as I can click the button of a non-selected entry. cityScreen.selectConstruction(name) - cityScreen.updateWithoutConstructionAndMap() + cityScreen.city.reassignPopulation() + cityScreen.update() + //cityScreen.updateWithoutConstructionAndMap() updateQueueAndButtons(cityScreen.selectedConstruction) ensureQueueEntryVisible() // Not passing current button info - already outdated, our parent is already removed from the stage hierarchy and replaced } @@ -808,6 +813,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) { tab.touchable = Touchable.disabled city.cityConstructions.removeFromQueue(constructionQueueIndex, false) cityScreen.clearSelection() + cityScreen.city.reassignPopulation() cityScreen.update() } return tab