Constructed units that can't be placed are put on hold till the next turn

This commit is contained in:
Yair Morgenstern 2023-03-29 23:19:55 +03:00
parent c4a0f49af3
commit 6fa1d61f4f
2 changed files with 22 additions and 10 deletions

View File

@ -29,6 +29,7 @@ import com.unciv.ui.screens.civilopediascreen.CivilopediaCategories
import com.unciv.ui.screens.civilopediascreen.FormattedLine
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActions
import kotlin.math.ceil
import kotlin.math.min
import kotlin.math.roundToInt
@ -314,13 +315,17 @@ class CityConstructions : IsPartOfGameInfoSerialization {
val productionCost = (construction as INonPerpetualConstruction).getProductionCost(city.civ)
if (inProgressConstructions.containsKey(currentConstructionFromQueue)
&& inProgressConstructions[currentConstructionFromQueue]!! >= productionCost) {
productionOverflow = inProgressConstructions[currentConstructionFromQueue]!! - productionCost
// See the URL below for explanation for this cap
// https://forums.civfanatics.com/threads/hammer-overflow.419352/
val maxOverflow = maxOf(productionCost, city.cityStats.currentCityStats.production.roundToInt())
if (productionOverflow > maxOverflow)
productionOverflow = maxOverflow
constructionComplete(construction)
val potentialOverflow = inProgressConstructions[currentConstructionFromQueue]!! - productionCost
if (constructionComplete(construction)){
// See the URL below for explanation for this cap
// https://forums.civfanatics.com/threads/hammer-overflow.419352/
val maxOverflow = maxOf(productionCost, city.cityStats.currentCityStats.production.roundToInt())
productionOverflow = min(maxOverflow, potentialOverflow)
}
else {
city.civ.addNotification("No space available to place [${construction.name}] near [${city.name}]",
city.location, NotificationCategory.Production, construction.name)
}
}
}
}
@ -405,8 +410,11 @@ class CityConstructions : IsPartOfGameInfoSerialization {
}
}
private fun constructionComplete(construction: INonPerpetualConstruction) {
construction.postBuildEvent(this)
/** Returns false if we tried to construct a unit but it has nowhere to go */
private fun constructionComplete(construction: INonPerpetualConstruction): Boolean {
val managedToConstruct = construction.postBuildEvent(this)
if (!managedToConstruct) return false
if (construction.name in inProgressConstructions)
inProgressConstructions.remove(construction.name)
if (construction.name == currentConstructionFromQueue)
@ -426,7 +434,8 @@ class CityConstructions : IsPartOfGameInfoSerialization {
}
} else {
val icon = if (construction is Building) buildingIcon else construction.name // could be a unit, in which case take the unit name.
city.civ.addNotification("[${construction.name}] has been built in [" + city.name + "]",
city.civ.addNotification(
"[${construction.name}] has been built in [${city.name}]",
city.location, NotificationCategory.Production, NotificationIcon.Construction, icon)
}
@ -442,6 +451,7 @@ class CityConstructions : IsPartOfGameInfoSerialization {
NotificationCategory.General, NotificationIcon.Construction, buildingIcon)
}
}
return true
}
fun addBuilding(buildingName: String) {

View File

@ -26,6 +26,8 @@ interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques {
fun getProductionCost(civInfo: Civilization): Int
fun getStatBuyCost(city: City, stat: Stat): Int?
fun getRejectionReasons(cityConstructions: CityConstructions): Sequence<RejectionReason>
/** Returns whether was successful - can fail for units if we can't place them */
fun postBuildEvent(cityConstructions: CityConstructions, boughtWith: Stat? = null): Boolean // Yes I'm hilarious.
/** Only checks if it has the unique to be bought with this stat, not whether it is purchasable at all */