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()
This commit is contained in:
itanasi 2024-02-17 11:42:23 -08:00 committed by GitHub
parent 88df2c26e6
commit c8a7cf29b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 24 additions and 8 deletions

View File

@ -47,6 +47,7 @@ object Automation {
val cityAIFocus = city.getCityFocus() val cityAIFocus = city.getCityFocus()
val yieldStats = stats.clone() val yieldStats = stats.clone()
val civPersonality = city.civ.getPersonality() val civPersonality = city.civ.getPersonality()
val cityStatsObj = city.cityStats
if (specialist) { if (specialist) {
// If you have the Food Bonus, count as 1 extra food production (base is 2food) // 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] 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 // Apply base weights
yieldStats.applyRankingWeights() yieldStats.applyRankingWeights()

View File

@ -577,10 +577,7 @@ class CityStats(val city: City) {
val buildingsMaintenance = getBuildingMaintenanceCosts() // this is AFTER the bonus calculation! val buildingsMaintenance = getBuildingMaintenanceCosts() // this is AFTER the bonus calculation!
newFinalStatList["Maintenance"] = Stats(gold = -buildingsMaintenance.toInt().toFloat()) newFinalStatList["Maintenance"] = Stats(gold = -buildingsMaintenance.toInt().toFloat())
if (totalFood > 0 if (canConvertFoodToProduction(totalFood, currentConstruction)) {
&& currentConstruction is INonPerpetualConstruction
&& currentConstruction.hasUnique(UniqueType.ConvertFoodToProductionWhenConstructed)
) {
newFinalStatList["Excess food to production"] = newFinalStatList["Excess food to production"] =
Stats(production = getProductionFromExcessiveFood(totalFood), food = -totalFood) Stats(production = getProductionFromExcessiveFood(totalFood), food = -totalFood)
} }
@ -603,9 +600,15 @@ class CityStats(val city: City) {
finalStatList = newFinalStatList 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 // calculate the conversion of the excessive food to the production
// See for details: https://civilization.fandom.com/wiki/Settler_(Civ5) // 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() return if (food >= 4.0f ) 2.0f + (food / 4.0f).toInt()
else if (food >= 2.0f ) 2.0f else if (food >= 2.0f ) 2.0f
else if (food >= 1.0f ) 1.0f else if (food >= 1.0f ) 1.0f

View File

@ -368,6 +368,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
if (cityScreen.canCityBeChanged()) if (cityScreen.canCityBeChanged())
table.onRightClick { selectQueueEntry { table.onRightClick { selectQueueEntry {
CityScreenConstructionMenu(cityScreen.stage, table, cityScreen.city, construction) { CityScreenConstructionMenu(cityScreen.stage, table, cityScreen.city, construction) {
cityScreen.city.reassignPopulation()
cityScreen.update() cityScreen.update()
} }
} } } }
@ -487,6 +488,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
cityScreen.updateWithoutConstructionAndMap() cityScreen.updateWithoutConstructionAndMap()
} }
CityScreenConstructionMenu(cityScreen.stage, pickConstructionButton, cityScreen.city, construction) { CityScreenConstructionMenu(cityScreen.stage, pickConstructionButton, cityScreen.city, construction) {
cityScreen.city.reassignPopulation()
cityScreen.update() cityScreen.update()
} }
} }
@ -554,6 +556,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
cityConstructions.removeFromQueue(selectedQueueEntry, false) cityConstructions.removeFromQueue(selectedQueueEntry, false)
cityScreen.clearSelection() cityScreen.clearSelection()
selectedQueueEntry = -1 selectedQueueEntry = -1
cityScreen.city.reassignPopulation()
cityScreen.update() cityScreen.update()
} }
if (city.isPuppet) if (city.isPuppet)
@ -591,6 +594,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
cityConstructions.addToQueue(construction.name) cityConstructions.addToQueue(construction.name)
if (!construction.shouldBeDisplayed(cityConstructions)) // For buildings - unlike units which can be queued multiple times if (!construction.shouldBeDisplayed(cityConstructions)) // For buildings - unlike units which can be queued multiple times
cityScreen.clearSelection() cityScreen.clearSelection()
cityScreen.city.reassignPopulation()
cityScreen.update() cityScreen.update()
cityScreen.game.settings.addCompletedTutorialTask("Pick construction") cityScreen.game.settings.addCompletedTutorialTask("Pick construction")
} }
@ -762,6 +766,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
cityScreen.selectConstruction(newConstruction) cityScreen.selectConstruction(newConstruction)
} }
} }
cityScreen.city.reassignPopulation()
cityScreen.update() cityScreen.update()
} }
@ -779,11 +784,11 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
button.onActivation { button.onActivation {
button.touchable = Touchable.disabled button.touchable = Touchable.disabled
selectedQueueEntry = movePriority(constructionQueueIndex) 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. // Selection display may need to update as I can click the button of a non-selected entry.
cityScreen.selectConstruction(name) cityScreen.selectConstruction(name)
cityScreen.updateWithoutConstructionAndMap() cityScreen.city.reassignPopulation()
cityScreen.update()
//cityScreen.updateWithoutConstructionAndMap()
updateQueueAndButtons(cityScreen.selectedConstruction) updateQueueAndButtons(cityScreen.selectedConstruction)
ensureQueueEntryVisible() // Not passing current button info - already outdated, our parent is already removed from the stage hierarchy and replaced 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 tab.touchable = Touchable.disabled
city.cityConstructions.removeFromQueue(constructionQueueIndex, false) city.cityConstructions.removeFromQueue(constructionQueueIndex, false)
cityScreen.clearSelection() cityScreen.clearSelection()
cityScreen.city.reassignPopulation()
cityScreen.update() cityScreen.update()
} }
return tab return tab