mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-29 06:51:30 -04:00
Units & buildings requiring resources or other needs are now displayed, but not selectable, from the city screen as constructions
This commit is contained in:
parent
a5e1978a71
commit
9eb9176b2a
@ -21,8 +21,8 @@ android {
|
|||||||
applicationId "com.unciv.app"
|
applicationId "com.unciv.app"
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode 220
|
versionCode 221
|
||||||
versionName "2.14.1.patch1"
|
versionName "2.14.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Had to add this crap for Travis to build, it wanted to sign the app
|
// Had to add this crap for Travis to build, it wanted to sign the app
|
||||||
|
@ -7,6 +7,7 @@ interface IConstruction : INamed, ICivilopedia {
|
|||||||
fun getProductionCost(adoptedPolicies: HashSet<String>): Int
|
fun getProductionCost(adoptedPolicies: HashSet<String>): Int
|
||||||
fun getGoldCost(adoptedPolicies: HashSet<String>): Int
|
fun getGoldCost(adoptedPolicies: HashSet<String>): Int
|
||||||
fun isBuildable(construction: CityConstructions): Boolean
|
fun isBuildable(construction: CityConstructions): Boolean
|
||||||
|
fun shouldBeDisplayed(construction: CityConstructions): Boolean
|
||||||
fun postBuildEvent(construction: CityConstructions) // Yes I'm hilarious.
|
fun postBuildEvent(construction: CityConstructions) // Yes I'm hilarious.
|
||||||
fun canBePurchased(): Boolean
|
fun canBePurchased(): Boolean
|
||||||
}
|
}
|
||||||
@ -14,6 +15,9 @@ interface IConstruction : INamed, ICivilopedia {
|
|||||||
|
|
||||||
|
|
||||||
open class SpecialConstruction(override var name: String, override val description: String) : IConstruction{
|
open class SpecialConstruction(override var name: String, override val description: String) : IConstruction{
|
||||||
|
override fun shouldBeDisplayed(construction: CityConstructions): Boolean {
|
||||||
|
return isBuildable(construction)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getSpecialConstructions(): List<SpecialConstruction> {
|
fun getSpecialConstructions(): List<SpecialConstruction> {
|
||||||
|
@ -8,6 +8,7 @@ import com.unciv.models.stats.Stats
|
|||||||
import com.unciv.ui.utils.getRandom
|
import com.unciv.ui.utils.getRandom
|
||||||
|
|
||||||
class Building : NamedStats(), IConstruction{
|
class Building : NamedStats(), IConstruction{
|
||||||
|
|
||||||
override val description: String
|
override val description: String
|
||||||
get() = getDescription(false, hashSetOf())
|
get() = getDescription(false, hashSetOf())
|
||||||
|
|
||||||
@ -167,43 +168,63 @@ class Building : NamedStats(), IConstruction{
|
|||||||
return (cost / 10).toInt() * 10
|
return (cost / 10).toInt() * 10
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isBuildable(construction: CityConstructions): Boolean {
|
|
||||||
if (construction.isBuilt(name)) return false
|
override fun shouldBeDisplayed(construction: CityConstructions): Boolean {
|
||||||
|
val rejectionReason = getRejectionReason(construction)
|
||||||
|
return rejectionReason==""
|
||||||
|
|| rejectionReason.startsWith("Requires")
|
||||||
|
|| rejectionReason == "Wonder is being built elsewhere"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRejectionReason(construction: CityConstructions):String{
|
||||||
|
if (construction.isBuilt(name)) return "Already built"
|
||||||
|
|
||||||
val civInfo = construction.cityInfo.civInfo
|
val civInfo = construction.cityInfo.civInfo
|
||||||
if (uniqueTo!=null && uniqueTo!=civInfo.civName) return false
|
if (uniqueTo!=null && uniqueTo!=civInfo.civName) return "Unique to $uniqueTo"
|
||||||
if (GameBasics.Buildings.values.any { it.uniqueTo==civInfo.civName && it.replaces==name }) return false
|
if (GameBasics.Buildings.values.any { it.uniqueTo==civInfo.civName && it.replaces==name }) return "Our unique building replaces this"
|
||||||
if (requiredTech != null && !civInfo.tech.isResearched(requiredTech!!)) return false
|
if (requiredTech != null && !civInfo.tech.isResearched(requiredTech!!)) return "$requiredTech not researched"
|
||||||
|
|
||||||
|
// Regular wonders
|
||||||
if (isWonder && requiredBuildingInAllCities==null){
|
if (isWonder && requiredBuildingInAllCities==null){
|
||||||
if(civInfo.gameInfo.civilizations.flatMap { it.cities }
|
if(civInfo.gameInfo.civilizations.flatMap { it.cities }
|
||||||
.any {it.cityConstructions.isBuilt(name)})
|
.any {it.cityConstructions.isBuilt(name)})
|
||||||
return false
|
return "Wonder is already built"
|
||||||
|
|
||||||
if(civInfo.cities.any { it!=construction.cityInfo && it.cityConstructions.isBeingConstructed(name) })
|
if(civInfo.cities.any { it!=construction.cityInfo && it.cityConstructions.isBeingConstructed(name) })
|
||||||
return false
|
return "Wonder is being built elsewhere"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requiredBuilding != null && !construction.containsBuildingOrEquivalent(requiredBuilding!!)) return false
|
|
||||||
if (requiredBuildingInAllCities != null && civInfo.cities.any { !it.cityConstructions.containsBuildingOrEquivalent(requiredBuildingInAllCities!!) })
|
|
||||||
return false
|
|
||||||
if(requiredBuildingInAllCities!=null && civInfo.cities.any {
|
|
||||||
it.cityConstructions.isBeingConstructed(name) || it.cityConstructions.isBuilt(name)
|
|
||||||
})
|
|
||||||
return false
|
|
||||||
|
|
||||||
if (cannotBeBuiltWith != null && construction.isBuilt(cannotBeBuiltWith!!)) return false
|
// National wonders
|
||||||
|
if(requiredBuildingInAllCities!=null) {
|
||||||
|
if (civInfo.cities.any { !it.cityConstructions.containsBuildingOrEquivalent(requiredBuildingInAllCities!!) })
|
||||||
|
return "Requires a $requiredBuildingInAllCities in all cities"
|
||||||
|
|
||||||
|
if (civInfo.cities.any {it.cityConstructions.isBuilt(name) })
|
||||||
|
return "Wonder is already built"
|
||||||
|
if (civInfo.cities.any {it.cityConstructions.isBeingConstructed(name) })
|
||||||
|
return "Wonder is being built elsewhere"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requiredBuilding != null && !construction.containsBuildingOrEquivalent(requiredBuilding!!))
|
||||||
|
return "Requires a $requiredBuilding in this city"
|
||||||
|
if (cannotBeBuiltWith != null && construction.isBuilt(cannotBeBuiltWith!!))
|
||||||
|
return "Cannot be built with $cannotBeBuiltWith"
|
||||||
|
|
||||||
if ("Must be next to desert" in uniques
|
if ("Must be next to desert" in uniques
|
||||||
&& !construction.cityInfo.getCenterTile().getTilesInDistance(1).any { it.baseTerrain == "Desert" })
|
&& !construction.cityInfo.getCenterTile().getTilesInDistance(1).any { it.baseTerrain == "Desert" })
|
||||||
return false
|
return "Must be next to desert"
|
||||||
|
|
||||||
if ("Must be next to mountain" in uniques
|
if ("Must be next to mountain" in uniques
|
||||||
&& !construction.cityInfo.getCenterTile().getTilesInDistance(1).any { it.baseTerrain == "Mountain" })
|
&& !construction.cityInfo.getCenterTile().getTilesInDistance(1).any { it.baseTerrain == "Mountain" })
|
||||||
return false
|
return "Must be next to mountain"
|
||||||
|
|
||||||
if("Can only be built in coastal cities" in uniques
|
if("Can only be built in coastal cities" in uniques
|
||||||
&& construction.cityInfo.getCenterTile().neighbors.none { it.baseTerrain=="Coast" })
|
&& construction.cityInfo.getCenterTile().neighbors.none { it.baseTerrain=="Coast" })
|
||||||
return false
|
return "Can only be built in coastal cities"
|
||||||
if (requiredResource != null && !civInfo.hasResource(requiredResource!!))
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
if (requiredResource != null && !civInfo.hasResource(requiredResource!!))
|
||||||
|
return "Requires $requiredResource"
|
||||||
|
|
||||||
if (requiredNearbyImprovedResources != null) {
|
if (requiredNearbyImprovedResources != null) {
|
||||||
val containsResourceWithImprovement = construction.cityInfo.getTilesInRange()
|
val containsResourceWithImprovement = construction.cityInfo.getTilesInRange()
|
||||||
@ -213,14 +234,18 @@ class Building : NamedStats(), IConstruction{
|
|||||||
&& it.getTileResource().improvement == it.improvement
|
&& it.getTileResource().improvement == it.improvement
|
||||||
&& it.getOwner() == civInfo
|
&& it.getOwner() == civInfo
|
||||||
}
|
}
|
||||||
if (!containsResourceWithImprovement) return false
|
if (!containsResourceWithImprovement) return "Nearby $requiredNearbyImprovedResources required"
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("Spaceship part" in uniques) {
|
if ("Spaceship part" in uniques) {
|
||||||
if (!civInfo.getBuildingUniques().contains("Enables construction of Spaceship parts")) return false
|
if (!civInfo.getBuildingUniques().contains("Enables construction of Spaceship parts")) return "Apollo project not built!"
|
||||||
if (civInfo.victoryManager.unconstructedSpaceshipParts()[name] == 0) return false // Don't need to build any more of these!
|
if (civInfo.victoryManager.unconstructedSpaceshipParts()[name] == 0) return "Don't need to build any more of these!"
|
||||||
}
|
}
|
||||||
return true
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isBuildable(construction: CityConstructions): Boolean {
|
||||||
|
return getRejectionReason(construction)==""
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun postBuildEvent(construction: CityConstructions) {
|
override fun postBuildEvent(construction: CityConstructions) {
|
||||||
|
@ -108,22 +108,33 @@ class BaseUnit : INamed, IConstruction, ICivilopedia {
|
|||||||
|
|
||||||
fun getDisbandGold() = getBaseGoldCost().toInt()/20
|
fun getDisbandGold() = getBaseGoldCost().toInt()/20
|
||||||
|
|
||||||
fun isBuildable(civInfo:CivilizationInfo): Boolean {
|
override fun shouldBeDisplayed(construction: CityConstructions): Boolean {
|
||||||
if (unbuildable) return false
|
val rejectionReason = getRejectionReason(construction)
|
||||||
if (requiredTech!=null && !civInfo.tech.isResearched(requiredTech!!)) return false
|
return rejectionReason=="" || rejectionReason.startsWith("Requires")
|
||||||
if (obsoleteTech!=null && civInfo.tech.isResearched(obsoleteTech!!)) return false
|
|
||||||
if (uniqueTo!=null && uniqueTo!=civInfo.civName) return false
|
|
||||||
if (GameBasics.Units.values.any { it.uniqueTo==civInfo.civName && it.replaces==name }) return false
|
|
||||||
if (requiredResource!=null && !civInfo.hasResource(requiredResource!!)) return false
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isBuildable(construction: CityConstructions): Boolean {
|
fun getRejectionReason(construction: CityConstructions): String {
|
||||||
if(!isBuildable(construction.cityInfo.civInfo)) return false
|
val civRejectionReason = getRejectionReason(construction.cityInfo.civInfo)
|
||||||
|
if(civRejectionReason!="") return civRejectionReason
|
||||||
if(unitType.isWaterUnit() && construction.cityInfo.getCenterTile().neighbors.none { it.baseTerrain=="Coast" })
|
if(unitType.isWaterUnit() && construction.cityInfo.getCenterTile().neighbors.none { it.baseTerrain=="Coast" })
|
||||||
return false
|
return "Can't build water units by the coast"
|
||||||
return true
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRejectionReason(civInfo: CivilizationInfo): String {
|
||||||
|
if (unbuildable) return "Unbuildable"
|
||||||
|
if (requiredTech!=null && !civInfo.tech.isResearched(requiredTech!!)) return "$requiredTech not researched"
|
||||||
|
if (obsoleteTech!=null && civInfo.tech.isResearched(obsoleteTech!!)) return "Obsolete by $obsoleteTech"
|
||||||
|
if (uniqueTo!=null && uniqueTo!=civInfo.civName) return "Unique to $uniqueTo"
|
||||||
|
if (GameBasics.Units.values.any { it.uniqueTo==civInfo.civName && it.replaces==name }) return "Our unique unit replaces this"
|
||||||
|
if (requiredResource!=null && !civInfo.hasResource(requiredResource!!)) return "Requires $requiredResource"
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isBuildable(civInfo: CivilizationInfo) = getRejectionReason(civInfo)==""
|
||||||
|
|
||||||
|
override fun isBuildable(construction: CityConstructions): Boolean {
|
||||||
|
return getRejectionReason(construction) == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun postBuildEvent(construction: CityConstructions) {
|
override fun postBuildEvent(construction: CityConstructions) {
|
||||||
|
@ -19,7 +19,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
|
|
||||||
var constructionScrollPane:ScrollPane?=null
|
var constructionScrollPane:ScrollPane?=null
|
||||||
|
|
||||||
private fun getProductionButton(construction: String, buttonText: String): Table {
|
private fun getProductionButton(construction: String, buttonText: String, rejectionReason: String=""): Table {
|
||||||
val pickProductionButton = Table()
|
val pickProductionButton = Table()
|
||||||
pickProductionButton.touchable = Touchable.enabled
|
pickProductionButton.touchable = Touchable.enabled
|
||||||
pickProductionButton.align(Align.left)
|
pickProductionButton.align(Align.left)
|
||||||
@ -32,11 +32,20 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
|
|
||||||
pickProductionButton.add(ImageGetter.getConstructionImage(construction).surroundWithCircle(40f)).padRight(10f)
|
pickProductionButton.add(ImageGetter.getConstructionImage(construction).surroundWithCircle(40f)).padRight(10f)
|
||||||
pickProductionButton.add(buttonText.toLabel().setFontColor(Color.WHITE))
|
pickProductionButton.add(buttonText.toLabel().setFontColor(Color.WHITE))
|
||||||
|
|
||||||
|
if(rejectionReason=="") {
|
||||||
pickProductionButton.onClick {
|
pickProductionButton.onClick {
|
||||||
cityScreen.city.cityConstructions.currentConstruction = construction
|
cityScreen.city.cityConstructions.currentConstruction = construction
|
||||||
cityScreen.city.cityStats.update()
|
cityScreen.city.cityStats.update()
|
||||||
cityScreen.update()
|
cityScreen.update()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pickProductionButton.color = Color.GRAY
|
||||||
|
pickProductionButton.row()
|
||||||
|
pickProductionButton.add(rejectionReason.toLabel().setFontColor(Color.RED))
|
||||||
|
}
|
||||||
|
|
||||||
if(construction==cityScreen.city.cityConstructions.currentConstruction)
|
if(construction==cityScreen.city.cityConstructions.currentConstruction)
|
||||||
pickProductionButton.color= Color.GREEN
|
pickProductionButton.color= Color.GREEN
|
||||||
return pickProductionButton
|
return pickProductionButton
|
||||||
@ -77,18 +86,21 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
constructionPickerTable.background = ImageGetter.getBackground(Color.BLACK)
|
constructionPickerTable.background = ImageGetter.getBackground(Color.BLACK)
|
||||||
|
|
||||||
val units = ArrayList<Table>()
|
val units = ArrayList<Table>()
|
||||||
for (unit in GameBasics.Units.values.filter { it.isBuildable(cityConstructions) })
|
for (unit in GameBasics.Units.values.filter { it.shouldBeDisplayed(cityConstructions) })
|
||||||
units += getProductionButton(unit.name,
|
units += getProductionButton(unit.name,
|
||||||
unit.name.tr() + "\r\n" + cityConstructions.turnsToConstruction(unit.name) + " {turns}".tr())
|
unit.name.tr() + "\r\n" + cityConstructions.turnsToConstruction(unit.name) + " {turns}".tr(),
|
||||||
|
unit.getRejectionReason(cityConstructions))
|
||||||
|
|
||||||
constructionPickerTable.addCategory("Units",units)
|
constructionPickerTable.addCategory("Units",units)
|
||||||
|
|
||||||
val buildableWonders = ArrayList<Table>()
|
val buildableWonders = ArrayList<Table>()
|
||||||
val buildableBuildings = ArrayList<Table>()
|
val buildableBuildings = ArrayList<Table>()
|
||||||
for (building in GameBasics.Buildings.values) {
|
for (building in GameBasics.Buildings.values) {
|
||||||
if (!building.isBuildable(cityConstructions) && building.name != cityConstructions.currentConstruction) continue
|
if (!building.shouldBeDisplayed(cityConstructions) && building.name != cityConstructions.currentConstruction) continue
|
||||||
val productionTextButton = getProductionButton(building.name,
|
val productionTextButton = getProductionButton(building.name,
|
||||||
building.name + "\r\n" + cityConstructions.turnsToConstruction(building.name) + " {turns}".tr())
|
building.name + "\r\n" + cityConstructions.turnsToConstruction(building.name) + " {turns}".tr(),
|
||||||
|
building.getRejectionReason(cityConstructions)
|
||||||
|
)
|
||||||
if (building.isWonder)
|
if (building.isWonder)
|
||||||
buildableWonders += productionTextButton
|
buildableWonders += productionTextButton
|
||||||
else
|
else
|
||||||
@ -99,7 +111,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
constructionPickerTable.addCategory("Buildings",buildableBuildings)
|
constructionPickerTable.addCategory("Buildings",buildableBuildings)
|
||||||
|
|
||||||
val specialConstructions = ArrayList<Table>()
|
val specialConstructions = ArrayList<Table>()
|
||||||
for (specialConstruction in SpecialConstruction.getSpecialConstructions().filter { it.isBuildable(cityConstructions) }) {
|
for (specialConstruction in SpecialConstruction.getSpecialConstructions().filter { it.shouldBeDisplayed(cityConstructions) }) {
|
||||||
specialConstructions += getProductionButton(specialConstruction.name,
|
specialConstructions += getProductionButton(specialConstruction.name,
|
||||||
"Produce [${specialConstruction.name}]".tr())
|
"Produce [${specialConstruction.name}]".tr())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user