Fix city construction side effects (#2448)

This commit is contained in:
SomeTroglodyte
2020-04-18 20:01:26 +02:00
committed by GitHub
parent 0de947d1b9
commit 0397cd7126
3 changed files with 24 additions and 17 deletions

View File

@ -116,7 +116,7 @@ object NextTurnAutomation{
val construction = city.cityConstructions.getCurrentConstruction() val construction = city.cityConstructions.getCurrentConstruction()
if (construction.canBePurchased() if (construction.canBePurchased()
&& city.civInfo.gold / 3 >= construction.getGoldCost(civInfo)) { && city.civInfo.gold / 3 >= construction.getGoldCost(civInfo)) {
city.cityConstructions.purchaseConstruction(construction.name) city.cityConstructions.purchaseConstruction(construction.name, 0, true)
} }
} }
} }

View File

@ -309,13 +309,26 @@ class CityConstructions {
builtBuildings.remove(buildingName) builtBuildings.remove(buildingName)
} }
fun purchaseConstruction(constructionName: String): Boolean { /**
* Purchase a construction for gold
* called from NextTurnAutomation and the City UI
* Build / place the new item, deduct cost, and maintain queue.
*
* @param constructionName What to buy (needed since buying something not queued is allowed)
* @param queuePosition Position in the queue or -1 if not from queue
* Note: -1 does not guarantee queue will remain unchanged (validation)
* @param automatic Flag whether automation should try to choose what next to build (not coming from UI)
* Note: settings.autoAssignCityProduction is handled later
* @return Success (false e.g. unit cannot be placed
*/
fun purchaseConstruction(constructionName: String, queuePosition: Int, automatic: Boolean): Boolean {
if (!getConstruction(constructionName).postBuildEvent(this, true)) if (!getConstruction(constructionName).postBuildEvent(this, true))
return false // nothing built - no pay return false // nothing built - no pay
cityInfo.civInfo.gold -= getConstruction(constructionName).getGoldCost(cityInfo.civInfo) cityInfo.civInfo.gold -= getConstruction(constructionName).getGoldCost(cityInfo.civInfo)
if (currentConstructionFromQueue == constructionName)
removeCurrentConstruction() if (queuePosition in 0 until constructionQueue.size)
removeFromQueue(queuePosition, automatic)
validateConstructionQueue() validateConstructionQueue()
return true return true

View File

@ -17,8 +17,8 @@ import com.unciv.ui.cityscreen.ConstructionInfoTable.Companion.turnOrTurns
import com.unciv.ui.utils.* import com.unciv.ui.utils.*
class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScreen.skin) { class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScreen.skin) {
/* -2 = Nothing, -1 = current construction, >= 0 queue entry */ /* -1 = Nothing, >= 0 queue entry (0 = current construction) */
private var selectedQueueEntry = -2 // None private var selectedQueueEntry = -1 // None
private val showCityInfoTableButton: TextButton private val showCityInfoTableButton: TextButton
private val constructionsQueueScrollPane: ScrollPane private val constructionsQueueScrollPane: ScrollPane
@ -252,14 +252,14 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
pickProductionButton.onClick { pickProductionButton.onClick {
cityScreen.selectedConstruction = construction cityScreen.selectedConstruction = construction
cityScreen.selectedTile = null cityScreen.selectedTile = null
selectedQueueEntry = -2 selectedQueueEntry = -1
cityScreen.update() cityScreen.update()
} }
return pickProductionButton return pickProductionButton
} }
private fun isSelectedQueueEntry(): Boolean = selectedQueueEntry > -2 private fun isSelectedQueueEntry(): Boolean = selectedQueueEntry >= 0
private fun getQueueButton(construction: IConstruction?): TextButton { private fun getQueueButton(construction: IConstruction?): TextButton {
val city = cityScreen.city val city = cityScreen.city
@ -273,7 +273,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
button.onClick { button.onClick {
cityConstructions.removeFromQueue(selectedQueueEntry,false) cityConstructions.removeFromQueue(selectedQueueEntry,false)
cityScreen.selectedConstruction = null cityScreen.selectedConstruction = null
selectedQueueEntry = -2 selectedQueueEntry = -1
cityScreen.update() cityScreen.update()
} }
} }
@ -303,12 +303,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
fun purchaseConstruction(construction: IConstruction) { fun purchaseConstruction(construction: IConstruction) {
val city = cityScreen.city val city = cityScreen.city
val cityConstructions = city.cityConstructions if (!city.cityConstructions.purchaseConstruction(construction.name, selectedQueueEntry, false)) {
// We can't trust the isSelectedQueueEntry because that fails when we have the same unit as both the current construction and in the queue,
// and then we purchase the unit from the queue - see #2157
val constructionIsCurrentConstruction = construction.name==cityConstructions.currentConstructionFromQueue
if (!cityConstructions.purchaseConstruction(construction.name)) {
Popup(cityScreen).apply { Popup(cityScreen).apply {
add("No space available to place [${construction.name}] near [${city.name}]".tr()).row() add("No space available to place [${construction.name}] near [${city.name}]".tr()).row()
addCloseButton() addCloseButton()
@ -317,10 +312,9 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
return return
} }
if (isSelectedQueueEntry()) { if (isSelectedQueueEntry()) {
selectedQueueEntry = -2 selectedQueueEntry = -1
cityScreen.selectedConstruction = null cityScreen.selectedConstruction = null
} }
if (!construction.shouldBeDisplayed(cityConstructions)) cityScreen.selectedConstruction = null
cityScreen.update() cityScreen.update()
} }