From 1df49749f2aac13adde3e2ac61f29f0c9edc493e Mon Sep 17 00:00:00 2001 From: Xander Lenstra <71121390+xlenstra@users.noreply.github.com> Date: Mon, 21 Mar 2022 20:03:33 +0100 Subject: [PATCH] Split 6 tiles visible unique into its parts, making it more moddable (#6389) * Split sight unique into its parts, making it more moddable * Standardized unique ordering --- .../jsons/Civ V - Gods & Kings/UnitTypes.json | 2 +- .../jsons/Civ V - Gods & Kings/Units.json | 2 +- .../jsons/Civ V - Vanilla/UnitTypes.json | 2 +- .../assets/jsons/Civ V - Vanilla/Units.json | 2 +- core/src/com/unciv/logic/map/MapUnit.kt | 18 +++++------ core/src/com/unciv/logic/map/TileInfo.kt | 4 +++ .../unciv/models/ruleset/unique/UniqueType.kt | 3 ++ .../ui/worldscreen/mainmenu/OptionsPopup.kt | 31 ++++++++++++------- docs/Modders/uniques.md | 5 ++- 9 files changed, 42 insertions(+), 27 deletions(-) diff --git a/android/assets/jsons/Civ V - Gods & Kings/UnitTypes.json b/android/assets/jsons/Civ V - Gods & Kings/UnitTypes.json index 31a3db20d1..5a34da36c0 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/UnitTypes.json +++ b/android/assets/jsons/Civ V - Gods & Kings/UnitTypes.json @@ -59,7 +59,7 @@ { "name": "Fighter", "movementType": "Air", - "uniques": ["Aircraft", "6 tiles in every direction always visible"] + "uniques": ["Aircraft", "[+4] Sight", "Can see over obstacles"] }, { "name": "Bomber", diff --git a/android/assets/jsons/Civ V - Gods & Kings/Units.json b/android/assets/jsons/Civ V - Gods & Kings/Units.json index 4abf96692e..a6373d9731 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/Units.json +++ b/android/assets/jsons/Civ V - Gods & Kings/Units.json @@ -1589,7 +1589,7 @@ "cost": 425, "requiredTech": "Stealth", "requiredResource": "Aluminum", - "uniques": ["Damage taken from interception reduced by [100]%", "Cannot be carried by [Carrier] units", "6 tiles in every direction always visible"], + "uniques": ["Damage taken from interception reduced by [100]%", "Cannot be carried by [Carrier] units", "[+4] Sight", "Can see over obstacles"], "attackSound": "bombing" }, diff --git a/android/assets/jsons/Civ V - Vanilla/UnitTypes.json b/android/assets/jsons/Civ V - Vanilla/UnitTypes.json index 31a3db20d1..5a34da36c0 100644 --- a/android/assets/jsons/Civ V - Vanilla/UnitTypes.json +++ b/android/assets/jsons/Civ V - Vanilla/UnitTypes.json @@ -59,7 +59,7 @@ { "name": "Fighter", "movementType": "Air", - "uniques": ["Aircraft", "6 tiles in every direction always visible"] + "uniques": ["Aircraft", "[+4] Sight", "Can see over obstacles"] }, { "name": "Bomber", diff --git a/android/assets/jsons/Civ V - Vanilla/Units.json b/android/assets/jsons/Civ V - Vanilla/Units.json index 0fa031c916..e0d7149c90 100644 --- a/android/assets/jsons/Civ V - Vanilla/Units.json +++ b/android/assets/jsons/Civ V - Vanilla/Units.json @@ -1265,7 +1265,7 @@ "cost": 425, "requiredTech": "Stealth", "requiredResource": "Aluminum", - "uniques": ["Damage taken from interception reduced by [100]%", "Cannot be carried by [Carrier] units", "6 tiles in every direction always visible"], + "uniques": ["Damage taken from interception reduced by [100]%", "Cannot be carried by [Carrier] units", "[+4] Sight", "Can see over obstacles"], "attackSound": "bombing" }, diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index e6a3a95959..801a8cd1c5 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -376,16 +376,14 @@ class MapUnit { val conditionalState = StateForConditionals(civInfo = civInfo, unit = this) - if (isEmbarked() && !hasUnique(UniqueType.NormalVisionWhenEmbarked, conditionalState) - && !civInfo.hasUnique(UniqueType.NormalVisionWhenEmbarked, conditionalState)) { + if (isEmbarked() && !hasUnique(UniqueType.NormalVisionWhenEmbarked, conditionalState, checkCivInfoUniques = true)) { return 1 } visibilityRange += getMatchingUniques(UniqueType.Sight, conditionalState, checkCivInfoUniques = true) .sumOf { it.params[0].toInt() } - visibilityRange += getTile().getAllTerrains() - .flatMap { it.getMatchingUniques(UniqueType.Sight, conditionalState) } + visibilityRange += getTile().getMatchingUniques(UniqueType.Sight, conditionalState) .sumOf { it.params[0].toInt() } if (visibilityRange < 1) visibilityRange = 1 @@ -399,13 +397,13 @@ class MapUnit { fun updateVisibleTiles(updateCivViewableTiles:Boolean = true) { val oldViewableTiles = viewableTiles - if (baseUnit.isAirUnit()) { - viewableTiles = if (hasUnique(UniqueType.SixTilesAlwaysVisible)) - getTile().getTilesInDistance(6).toHashSet() // it's that simple - else HashSet(0) // bomber units don't do recon - } else { - viewableTiles = getTile().getViewableTilesList(getVisibilityRange()).toHashSet() + viewableTiles = when { + hasUnique(UniqueType.NoSight) -> hashSetOf() + hasUnique(UniqueType.CanSeeOverObstacles) -> + getTile().getTilesInDistance(getVisibilityRange()).toHashSet() // it's that simple + else -> getTile().getViewableTilesList(getVisibilityRange()).toHashSet() } + // Set equality automatically determines if anything changed - https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-abstract-set/equals.html if (updateCivViewableTiles && oldViewableTiles != viewableTiles) civInfo.updateViewableTiles() // for the civ diff --git a/core/src/com/unciv/logic/map/TileInfo.kt b/core/src/com/unciv/logic/map/TileInfo.kt index 08e724cff6..37b8a15571 100644 --- a/core/src/com/unciv/logic/map/TileInfo.kt +++ b/core/src/com/unciv/logic/map/TileInfo.kt @@ -11,6 +11,7 @@ import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.tile.* import com.unciv.models.ruleset.unique.StateForConditionals +import com.unciv.models.ruleset.unique.Unique import com.unciv.models.stats.Stats import com.unciv.models.translations.tr import com.unciv.ui.civilopedia.FormattedLine @@ -242,6 +243,9 @@ open class TileInfo { fun isRoughTerrain() = getAllTerrains().any{ it.isRough() } fun hasUnique(uniqueType: UniqueType) = getAllTerrains().any { it.hasUnique(uniqueType) } + fun getMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(tile=this) ): Sequence { + return getAllTerrains().flatMap { it.getMatchingUniques(uniqueType, stateForConditionals) } + } fun getWorkingCity(): CityInfo? { val civInfo = getOwner() ?: return null diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index eb22185e53..a694fae9eb 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -436,6 +436,9 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: AttackFromSea("Eliminates combat penalty for attacking from the sea", UniqueTarget.Unit), AttackAcrossCoast("Eliminates combat penalty for attacking across a coast", UniqueTarget.Unit), + NoSight("No Sight", UniqueTarget.Unit), + CanSeeOverObstacles("Can see over obstacles", UniqueTarget.Unit), + @Deprecated("as of 3.19.19", ReplaceWith("[+4] Sight\", \"Can see over obstacles")) SixTilesAlwaysVisible("6 tiles in every direction always visible", UniqueTarget.Unit), CarryAirUnits("Can carry [amount] [mapUnitFilter] units", UniqueTarget.Unit), diff --git a/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt b/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt index 0fdc38133d..6642ad8280 100644 --- a/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt +++ b/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt @@ -377,14 +377,16 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { private fun getDeprecatedReplaceableUniques(mod:Ruleset): HashMap { val objectsToCheck = sequenceOf( - mod.units, + mod.beliefs, + mod.buildings, + mod.nations, + mod.policies, + mod.technologies, + mod.terrains, mod.tileImprovements, mod.unitPromotions, - mod.buildings, - mod.policies, - mod.nations, - mod.beliefs, - mod.technologies, + mod.unitTypes, + mod.units, ) val allDeprecatedUniques = HashSet() val deprecatedUniquesToReplacementText = HashMap() @@ -442,15 +444,20 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) { private fun autoUpdateUniques(mod: Ruleset, replaceableUniques: HashMap, ) { + if (mod.name.contains("mod")) + println("mod") + val filesToReplace = listOf( - "Units.json", + "Beliefs.json", + "Buildings.json", + "Nations.json", + "Policies.json", + "Techs.json", + "Terrains.json", "TileImprovements.json", "UnitPromotions.json", - "Buildings.json", - "Policies.json", - "Nations.json", - "Beliefs.json", - "Techs.json", + "UnitTypes.json", + "Units.json", ) val jsonFolder = mod.folderLocation!!.child("jsons") diff --git a/docs/Modders/uniques.md b/docs/Modders/uniques.md index 2a388351b2..2862c54d26 100644 --- a/docs/Modders/uniques.md +++ b/docs/Modders/uniques.md @@ -1017,7 +1017,10 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl ??? example "Eliminates combat penalty for attacking across a coast" Applicable to: Unit -??? example "6 tiles in every direction always visible" +??? example "No Sight" + Applicable to: Unit + +??? example "Can see over obstacles" Applicable to: Unit ??? example "Can carry [amount] [mapUnitFilter] units"