mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-31 15:19:29 +07:00
More power to improvement uniques (resourceTerrainAllow-be-gone) (#4024)
* More flexibility for modding improvements (tileFilter), deprecate resourceTerrainAllow * More tileFilter and improvement uniques - Translations * Update template.properties * More tileFilter and improvement uniques - Revert and/or inside unique parameter
This commit is contained in:
@ -227,7 +227,7 @@ class WorkerAutomation(val unit: MapUnit) {
|
||||
?: return false
|
||||
val resourceImprovement = civInfo.gameInfo.ruleSet.tileImprovements[resourceImprovementName]
|
||||
?: return false
|
||||
return tile.terrainFeatures.any { resourceImprovement.resourceTerrainAllow.contains(it) }
|
||||
return tile.terrainFeatures.any { resourceImprovement.isAllowedOnFeature(it) }
|
||||
}
|
||||
|
||||
private fun isAcceptableTileForFort(tile: TileInfo, civInfo: CivilizationInfo): Boolean {
|
||||
|
@ -356,6 +356,9 @@ open class TileInfo {
|
||||
isCityCenter() -> false
|
||||
"Cannot be built on bonus resource" in improvement.uniques && resource != null
|
||||
&& getTileResource().resourceType == ResourceType.Bonus -> false
|
||||
improvement.uniqueObjects.filter { it.placeholderText == "Cannot be built on [] tiles" }.any {
|
||||
unique -> matchesUniqueFilter(unique.params[0])
|
||||
} -> false
|
||||
|
||||
// Road improvements can change on tiles with irremovable improvements - nothing else can, though.
|
||||
improvement.name != RoadStatus.Railroad.name && improvement.name != RoadStatus.Railroad.name
|
||||
@ -376,22 +379,33 @@ open class TileInfo {
|
||||
improvement.name == "Railroad" && this.roadStatus != RoadStatus.Railroad && !isWater -> true
|
||||
improvement.name == "Remove Road" && this.roadStatus == RoadStatus.Road -> true
|
||||
improvement.name == "Remove Railroad" && this.roadStatus == RoadStatus.Railroad -> true
|
||||
topTerrain.unbuildable && (topTerrain.name !in improvement.resourceTerrainAllow) -> false
|
||||
topTerrain.unbuildable && !improvement.isAllowedOnFeature(topTerrain.name) -> false
|
||||
// DO NOT reverse this &&. isAdjacentToFreshwater() is a lazy which calls a function, and reversing it breaks the tests.
|
||||
improvement.hasUnique("Can also be built on tiles adjacent to fresh water") && isAdjacentToFreshwater -> true
|
||||
"Can only be built on Coastal tiles" in improvement.uniques && isCoastalTile() -> true
|
||||
improvement.uniqueObjects.filter { it.placeholderText == "Can only be built on [] tiles" }.any {
|
||||
unique -> !matchesUniqueFilter(unique.params[0])
|
||||
} -> false
|
||||
else -> resourceIsVisible && getTileResource().improvement == improvement.name
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of _`tileFilter`_
|
||||
* @see <a href="https://github.com/yairm210/Unciv/wiki/uniques#user-content-tilefilter">tileFilter</a>
|
||||
*/
|
||||
fun matchesUniqueFilter(filter: String, civInfo: CivilizationInfo? = null): Boolean {
|
||||
return filter == baseTerrain
|
||||
return filter == "All"
|
||||
|| filter == baseTerrain
|
||||
|| filter == "River" && isAdjacentToRiver()
|
||||
|| terrainFeatures.contains(filter)
|
||||
|| baseTerrainObject.uniques.contains(filter)
|
||||
|| improvement == filter
|
||||
|| resource == filter
|
||||
|| (resource != null && getTileResource().resourceType.name + " resource" == filter)
|
||||
|| filter == "Water" && isWater
|
||||
|| filter == "Land" && isLand
|
||||
|| filter == "Coastal" && isCoastalTile()
|
||||
|| filter == naturalWonder
|
||||
|| terrainFeatures.isNotEmpty() && getTerrainFeatures().last().uniques.contains(filter)
|
||||
|| civInfo != null && hasViewableResource(civInfo) && resource == filter
|
||||
|
@ -23,7 +23,7 @@ class Terrain : NamedStats() {
|
||||
/** Used by Natural Wonders: it is the baseTerrain on top of which the Natural Wonder is placed */
|
||||
val turnsInto: String? = null
|
||||
|
||||
/** Uniques (currently used only for Natural Wonders) */
|
||||
/** Uniques (Properties such as Temp/humidity, Fresh water, elevation, rough, defense, Natural Wonder specials) */
|
||||
val uniques = ArrayList<String>()
|
||||
val uniqueObjects: List<Unique> by lazy { uniques.map { Unique(it) } }
|
||||
|
||||
|
@ -14,6 +14,7 @@ class TileImprovement : NamedStats() {
|
||||
|
||||
// Used only for Camp - but avoid hardcoded comparison and *allow modding*
|
||||
// Terrain Features that need not be cleared if the improvement enables a resource
|
||||
@Deprecated("As of 3.14.15")
|
||||
var resourceTerrainAllow: Collection<String> = ArrayList()
|
||||
|
||||
var techRequired: String? = null
|
||||
@ -68,5 +69,24 @@ class TileImprovement : NamedStats() {
|
||||
|
||||
fun hasUnique(unique: String) = uniques.contains(unique)
|
||||
fun isGreatImprovement() = hasUnique("Great Improvement")
|
||||
|
||||
/**
|
||||
* Check: Is this improvement allowed on a [given][name] terrain feature?
|
||||
*
|
||||
* Uses both _legacy_ [resourceTerrainAllow] and unique "Does not need removal of []"
|
||||
*
|
||||
* Background: This not used for e.g. a lumbermill - it derives the right to be placed on forest
|
||||
* from [terrainsCanBeBuiltOn]. Other improvements may be candidates without fulfilling the
|
||||
* [terrainsCanBeBuiltOn] check - e.g. they are listed by a resource as 'their' improvement.
|
||||
* I such cases, the 'unbuildable' property of the Terrain feature might prevent the improvement,
|
||||
* so this check is done in conjunction - for the user, success means he does not need to remove
|
||||
* a terrain feature, thus the unique name.
|
||||
*/
|
||||
fun isAllowedOnFeature(name: String): Boolean {
|
||||
if (name in resourceTerrainAllow) return true
|
||||
return uniqueObjects.filter { it.placeholderText == "Does not need removal of []"
|
||||
&& it.params[0] == name
|
||||
}.any()
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user