mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 15:27:50 +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:
@ -42,10 +42,9 @@
|
|||||||
// Resource-specific
|
// Resource-specific
|
||||||
{
|
{
|
||||||
"name": "Camp",
|
"name": "Camp",
|
||||||
"resourceTerrainAllow": ["Forest"],
|
|
||||||
"turnsToBuild": 7,
|
"turnsToBuild": 7,
|
||||||
"techRequired": "Trapping",
|
"techRequired": "Trapping",
|
||||||
"uniques": ["[+1 Gold] once [Economics] is discovered"],
|
"uniques": ["Does not need removal of [Forest]","[+1 Gold] once [Economics] is discovered"],
|
||||||
"shortcutKey": "C"
|
"shortcutKey": "C"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -680,6 +680,10 @@ Water resource = Wasser-Ressource
|
|||||||
River = Fluss
|
River = Fluss
|
||||||
Fresh water = Frischwasser
|
Fresh water = Frischwasser
|
||||||
non-fresh water = nicht frisches Wasser
|
non-fresh water = nicht frisches Wasser
|
||||||
|
Coastal = Küsten
|
||||||
|
Bonus resource = Bonus-ressource
|
||||||
|
Strategic resource = Strategische Ressource
|
||||||
|
Luxury resource = Luxus-ressource
|
||||||
|
|
||||||
Wonders = Wunder
|
Wonders = Wunder
|
||||||
Base values = Grundwerte
|
Base values = Grundwerte
|
||||||
@ -988,6 +992,9 @@ Must be on [terrain] = Muss sich auf [terrain] befinden
|
|||||||
+[amount]% vs [unitType] = +[amount]% vs [unitType]
|
+[amount]% vs [unitType] = +[amount]% vs [unitType]
|
||||||
+[amount] Movement for all [unitType] units = +[amount] Bewegung für alle "[unitType]"-Einheiten
|
+[amount] Movement for all [unitType] units = +[amount] Bewegung für alle "[unitType]"-Einheiten
|
||||||
+[amount]% Production when constructing [param] = +[amount]% Produktion, für alle Bauten vom Typ: [param]
|
+[amount]% Production when constructing [param] = +[amount]% Produktion, für alle Bauten vom Typ: [param]
|
||||||
|
Can only be built on [tileFilter] tiles = Kann nur auf [tileFilter]-Feldern gebaut werden
|
||||||
|
Cannot be built on [tileFilter] tiles = Kann nicht auf [tileFilter]-Feldern gebaut werden
|
||||||
|
Does not need removal of [feature] = Hierfür muß [feature] nicht entfernt werden
|
||||||
|
|
||||||
# City filters
|
# City filters
|
||||||
in this city = in dieser Stadt
|
in this city = in dieser Stadt
|
||||||
@ -3151,6 +3158,7 @@ Can be built just outside your borders = Kann, auch ein Feld weit, außerhalb De
|
|||||||
Citadel = Zitadelle
|
Citadel = Zitadelle
|
||||||
|
|
||||||
Can only be built on Coastal tiles = Kann nur entlang der Küstenlinie gebaut werden
|
Can only be built on Coastal tiles = Kann nur entlang der Küstenlinie gebaut werden
|
||||||
|
|
||||||
Moai = Moai
|
Moai = Moai
|
||||||
|
|
||||||
Cannot be built on bonus resource = Darf nicht auf Bonus-Ressourcen gebaut werden
|
Cannot be built on bonus resource = Darf nicht auf Bonus-Ressourcen gebaut werden
|
||||||
|
@ -674,6 +674,10 @@ Water resource =
|
|||||||
River =
|
River =
|
||||||
Fresh water =
|
Fresh water =
|
||||||
non-fresh water =
|
non-fresh water =
|
||||||
|
Coastal =
|
||||||
|
Bonus resource =
|
||||||
|
Strategic resource =
|
||||||
|
Luxury resource =
|
||||||
|
|
||||||
Wonders =
|
Wonders =
|
||||||
Base values =
|
Base values =
|
||||||
@ -979,6 +983,9 @@ Must be on [terrain] =
|
|||||||
+[amount]% vs [unitType] =
|
+[amount]% vs [unitType] =
|
||||||
+[amount] Movement for all [unitType] units =
|
+[amount] Movement for all [unitType] units =
|
||||||
+[amount]% Production when constructing [param] =
|
+[amount]% Production when constructing [param] =
|
||||||
|
Can only be built on [tileFilter] tiles =
|
||||||
|
Cannot be built on [tileFilter] tiles =
|
||||||
|
Does not need removal of [feature] =
|
||||||
|
|
||||||
# City filters
|
# City filters
|
||||||
in this city =
|
in this city =
|
||||||
|
@ -227,7 +227,7 @@ class WorkerAutomation(val unit: MapUnit) {
|
|||||||
?: return false
|
?: return false
|
||||||
val resourceImprovement = civInfo.gameInfo.ruleSet.tileImprovements[resourceImprovementName]
|
val resourceImprovement = civInfo.gameInfo.ruleSet.tileImprovements[resourceImprovementName]
|
||||||
?: return false
|
?: 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 {
|
private fun isAcceptableTileForFort(tile: TileInfo, civInfo: CivilizationInfo): Boolean {
|
||||||
|
@ -356,6 +356,9 @@ open class TileInfo {
|
|||||||
isCityCenter() -> false
|
isCityCenter() -> false
|
||||||
"Cannot be built on bonus resource" in improvement.uniques && resource != null
|
"Cannot be built on bonus resource" in improvement.uniques && resource != null
|
||||||
&& getTileResource().resourceType == ResourceType.Bonus -> false
|
&& 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.
|
// Road improvements can change on tiles with irremovable improvements - nothing else can, though.
|
||||||
improvement.name != RoadStatus.Railroad.name && improvement.name != RoadStatus.Railroad.name
|
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 == "Railroad" && this.roadStatus != RoadStatus.Railroad && !isWater -> true
|
||||||
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
|
||||||
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.
|
// 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
|
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
|
"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
|
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 {
|
fun matchesUniqueFilter(filter: String, civInfo: CivilizationInfo? = null): Boolean {
|
||||||
return filter == baseTerrain
|
return filter == "All"
|
||||||
|
|| filter == baseTerrain
|
||||||
|| filter == "River" && isAdjacentToRiver()
|
|| filter == "River" && isAdjacentToRiver()
|
||||||
|| terrainFeatures.contains(filter)
|
|| terrainFeatures.contains(filter)
|
||||||
|| baseTerrainObject.uniques.contains(filter)
|
|| baseTerrainObject.uniques.contains(filter)
|
||||||
|| improvement == filter
|
|| improvement == filter
|
||||||
|
|| resource == filter
|
||||||
|
|| (resource != null && getTileResource().resourceType.name + " resource" == filter)
|
||||||
|| filter == "Water" && isWater
|
|| filter == "Water" && isWater
|
||||||
|| filter == "Land" && isLand
|
|| filter == "Land" && isLand
|
||||||
|
|| filter == "Coastal" && isCoastalTile()
|
||||||
|| filter == naturalWonder
|
|| filter == naturalWonder
|
||||||
|| terrainFeatures.isNotEmpty() && getTerrainFeatures().last().uniques.contains(filter)
|
|| terrainFeatures.isNotEmpty() && getTerrainFeatures().last().uniques.contains(filter)
|
||||||
|| civInfo != null && hasViewableResource(civInfo) && resource == 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 */
|
/** Used by Natural Wonders: it is the baseTerrain on top of which the Natural Wonder is placed */
|
||||||
val turnsInto: String? = null
|
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 uniques = ArrayList<String>()
|
||||||
val uniqueObjects: List<Unique> by lazy { uniques.map { Unique(it) } }
|
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*
|
// Used only for Camp - but avoid hardcoded comparison and *allow modding*
|
||||||
// Terrain Features that need not be cleared if the improvement enables a resource
|
// 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 resourceTerrainAllow: Collection<String> = ArrayList()
|
||||||
|
|
||||||
var techRequired: String? = null
|
var techRequired: String? = null
|
||||||
@ -68,5 +69,24 @@ class TileImprovement : NamedStats() {
|
|||||||
|
|
||||||
fun hasUnique(unique: String) = uniques.contains(unique)
|
fun hasUnique(unique: String) = uniques.contains(unique)
|
||||||
fun isGreatImprovement() = hasUnique("Great Improvement")
|
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