This commit is contained in:
Yair Morgenstern
2020-04-16 11:06:58 +03:00
8 changed files with 39 additions and 12 deletions

View File

@ -39,6 +39,7 @@
// Resource-specific // Resource-specific
{ {
"name": "Camp", "name": "Camp",
"resourceTerrainAllow": ["Forest"],
"turnsToBuild": 7, "turnsToBuild": 7,
"techRequired": "Trapping", "techRequired": "Trapping",
"improvingTech": "Economics", "improvingTech": "Economics",

View File

@ -177,10 +177,10 @@ class WorkerAutomation(val unit: MapUnit) {
private fun chooseImprovement(tile: TileInfo, civInfo: CivilizationInfo): TileImprovement? { private fun chooseImprovement(tile: TileInfo, civInfo: CivilizationInfo): TileImprovement? {
val improvementStringForResource : String ?= when { val improvementStringForResource : String ?= when {
tile.resource == null || !tile.hasViewableResource(civInfo) -> null tile.resource == null || !tile.hasViewableResource(civInfo) -> null
tile.terrainFeature == "Marsh" -> "Remove Marsh" tile.terrainFeature == "Marsh" && !isImprovementOnFeatureAllowed(tile,civInfo) -> "Remove Marsh"
tile.terrainFeature == "Fallout" -> "Remove Fallout" tile.terrainFeature == "Fallout" && !isImprovementOnFeatureAllowed(tile,civInfo) -> "Remove Fallout" // for really mad modders
tile.terrainFeature == Constants.jungle -> "Remove Jungle" tile.terrainFeature == Constants.jungle && !isImprovementOnFeatureAllowed(tile,civInfo) -> "Remove Jungle"
tile.terrainFeature == Constants.forest && tile.getTileResource().improvement!="Camp" -> "Remove Forest" tile.terrainFeature == Constants.forest && !isImprovementOnFeatureAllowed(tile,civInfo) -> "Remove Forest"
else -> tile.getTileResource().improvement else -> tile.getTileResource().improvement
} }
@ -211,6 +211,17 @@ class WorkerAutomation(val unit: MapUnit) {
if (improvementString == null) return null if (improvementString == null) return null
return unit.civInfo.gameInfo.ruleSet.tileImprovements[improvementString]!! return unit.civInfo.gameInfo.ruleSet.tileImprovements[improvementString]!!
} }
private fun isImprovementOnFeatureAllowed(tile: TileInfo, civInfo: CivilizationInfo): Boolean {
// Old hardcoded logic amounts to:
//return tile.terrainFeature == Constants.forest && tile.getTileResource().improvement == "Camp"
// routine assumes the caller ensured that terrainFeature and resource are both present
val resourceImprovementName = tile.getTileResource().improvement
?: return false
val resourceImprovement = civInfo.gameInfo.ruleSet.tileImprovements[resourceImprovementName]
?: return false
return resourceImprovement.resourceTerrainAllow.contains(tile.terrainFeature!!)
}
private fun isAcceptableTileForFort(tile: TileInfo, civInfo: CivilizationInfo): Boolean private fun isAcceptableTileForFort(tile: TileInfo, civInfo: CivilizationInfo): Boolean
{ {

View File

@ -56,6 +56,10 @@ class CityInfo {
var attackedThisTurn = false var attackedThisTurn = false
var hasSoldBuildingThisTurn = false var hasSoldBuildingThisTurn = false
var isPuppet = false var isPuppet = false
/** The very first found city is the _original_ capital,
* while the _current_ capital can be any other city after the original one is captured.
* It is important to distinct them since the original cannot be razed and defines the Domination Victory. */
var isOriginalCapital = false
constructor() // for json parsing, we need to have a default constructor constructor() // for json parsing, we need to have a default constructor
constructor(civInfo: CivilizationInfo, cityLocation: Vector2) { // new city! constructor(civInfo: CivilizationInfo, cityLocation: Vector2) { // new city!
@ -76,6 +80,7 @@ class CityInfo {
name = cityNamePrefix + cityName name = cityNamePrefix + cityName
isOriginalCapital = civInfo.citiesCreated == 0
civInfo.citiesCreated++ civInfo.citiesCreated++
civInfo.cities = civInfo.cities.toMutableList().apply { add(this@CityInfo) } civInfo.cities = civInfo.cities.toMutableList().apply { add(this@CityInfo) }
@ -125,6 +130,7 @@ class CityInfo {
toReturn.foundingCiv = foundingCiv toReturn.foundingCiv = foundingCiv
toReturn.turnAcquired = turnAcquired toReturn.turnAcquired = turnAcquired
toReturn.isPuppet = isPuppet toReturn.isPuppet = isPuppet
toReturn.isOriginalCapital = isOriginalCapital
return toReturn return toReturn
} }

View File

@ -262,8 +262,8 @@ class CivilizationInfo {
override fun toString(): String {return civName} // for debug override fun toString(): String {return civName} // for debug
/** Returns true if the civ was fully initialized and has no cities or settlers remaining */ /** Returns true if the civ was fully initialized and has no cities remaining */
fun isDefeated()= cities.isEmpty() fun isDefeated()= cities.isEmpty() // No cities
&& exploredTiles.isNotEmpty() // Dirty hack: exploredTiles are empty only before starting units are placed && exploredTiles.isNotEmpty() // Dirty hack: exploredTiles are empty only before starting units are placed
&& !isBarbarian() // Barbarians can be never defeated && !isBarbarian() // Barbarians can be never defeated
&& (citiesCreated > 0 || !getCivUnits().any { it.name == Constants.settler }) && (citiesCreated > 0 || !getCivUnits().any { it.name == Constants.settler })

View File

@ -281,7 +281,7 @@ open class TileInfo {
improvement.name == "Remove Road" && this.roadStatus == RoadStatus.Road -> true improvement.name == "Remove Road" && this.roadStatus == RoadStatus.Road -> true
improvement.name == "Remove Railroad" && this.roadStatus == RoadStatus.Railroad -> true improvement.name == "Remove Railroad" && this.roadStatus == RoadStatus.Railroad -> true
improvement.name == Constants.cancelImprovementOrder && this.improvementInProgress != null -> true improvement.name == Constants.cancelImprovementOrder && this.improvementInProgress != null -> true
topTerrain.unbuildable && !(topTerrain.name == Constants.forest && improvement.name == "Camp") -> false topTerrain.unbuildable && (topTerrain.name !in improvement.resourceTerrainAllow) -> false
"Can only be built on Coastal tiles" in improvement.uniques && isCoastalTile() -> true "Can only be built on Coastal tiles" in improvement.uniques && isCoastalTile() -> true
else -> hasViewableResource(civInfo) && getTileResource().improvement == improvement.name else -> hasViewableResource(civInfo) && getTileResource().improvement == improvement.name
} }

View File

@ -11,6 +11,11 @@ import kotlin.math.roundToInt
class TileImprovement : NamedStats() { class TileImprovement : NamedStats() {
var terrainsCanBeBuiltOn: Collection<String> = ArrayList() var terrainsCanBeBuiltOn: Collection<String> = ArrayList()
// Used only for Camp - but avoid hardcoded comparison and *allow modding*
// Terrain Features that need not be cleared if the improvement enables a resource
var resourceTerrainAllow: Collection<String> = ArrayList()
var techRequired: String? = null var techRequired: String? = null
var improvingTech: String? = null var improvingTech: String? = null

View File

@ -125,7 +125,9 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() {
val razeCityButton = "Raze city".toTextButton() val razeCityButton = "Raze city".toTextButton()
razeCityButton.labelCell.pad(10f) razeCityButton.labelCell.pad(10f)
razeCityButton.onClick { city.isBeingRazed=true; update() } razeCityButton.onClick { city.isBeingRazed=true; update() }
if(!UncivGame.Current.worldScreen.isPlayersTurn) razeCityButton.disable() if(!UncivGame.Current.worldScreen.isPlayersTurn || city.isOriginalCapital)
razeCityButton.disable()
razeCityButtonHolder.add(razeCityButton).colspan(cityPickerTable.columns) razeCityButtonHolder.add(razeCityButton).colspan(cityPickerTable.columns)
} else { } else {
val stopRazingCityButton = "Stop razing city".toTextButton() val stopRazingCityButton = "Stop razing city".toTextButton()

View File

@ -99,13 +99,15 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu
addSeparator() addSeparator()
add("Raze".toTextButton().onClick { add("Raze".toTextButton().apply {
if (city.isOriginalCapital) disable()
else onClick {
city.puppetCity(conqueringCiv) city.puppetCity(conqueringCiv)
city.annexCity() city.annexCity()
city.isBeingRazed = true city.isBeingRazed = true
worldScreen.shouldUpdate=true worldScreen.shouldUpdate=true
close() close()
}).row() }}).row()
addGoodSizedLabel("Razing the city annexes it, and starts razing the city to the ground.").row() addGoodSizedLabel("Razing the city annexes it, and starts razing the city to the ground.").row()
addGoodSizedLabel("The population will gradually dwindle until the city is destroyed.").row() addGoodSizedLabel("The population will gradually dwindle until the city is destroyed.").row()
} else { } else {