From 1122195e14b29a07a67ae4bef5b1d5029be81e72 Mon Sep 17 00:00:00 2001 From: yairm210 Date: Mon, 29 Jul 2024 11:57:20 +0300 Subject: [PATCH] Improvement Unique converted to trigger - "Gain control over [tileFilter] tiles in a [amount]-tile radius" --- .../TileImprovements.json | 2 +- .../Civ V - Vanilla/TileImprovements.json | 2 +- .../ruleset/unique/UniqueTriggerActivation.kt | 46 ++++++++++++++++++- .../unciv/models/ruleset/unique/UniqueType.kt | 9 +++- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/android/assets/jsons/Civ V - Gods & Kings/TileImprovements.json b/android/assets/jsons/Civ V - Gods & Kings/TileImprovements.json index d927dc61a9..309078987b 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/TileImprovements.json +++ b/android/assets/jsons/Civ V - Gods & Kings/TileImprovements.json @@ -233,7 +233,7 @@ "Gives a defensive bonus of [100]%", "Adjacent enemy units ending their turn take [30] damage", "Can be built just outside your borders", - "Constructing it will take over the tiles around it and assign them to your closest city", + "Gain control over [all] tiles in a [1]-tile radius", "Removes removable features when built", "Will not be replaced by automated units" ] diff --git a/android/assets/jsons/Civ V - Vanilla/TileImprovements.json b/android/assets/jsons/Civ V - Vanilla/TileImprovements.json index 16516ff622..103a2ff98f 100644 --- a/android/assets/jsons/Civ V - Vanilla/TileImprovements.json +++ b/android/assets/jsons/Civ V - Vanilla/TileImprovements.json @@ -232,7 +232,7 @@ "Gives a defensive bonus of [100]%", "Adjacent enemy units ending their turn take [30] damage", "Can be built just outside your borders", - "Constructing it will take over the tiles around it and assign them to your closest city", + "Gain control over [all] tiles in a [1]-tile radius", "Removes removable features when built", "Will not be replaced by automated units" ] diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt b/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt index 114c09806d..7ad30c15a0 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt @@ -16,6 +16,7 @@ import com.unciv.logic.civilization.NotificationIcon import com.unciv.logic.civilization.PolicyAction import com.unciv.logic.civilization.PopupAlert import com.unciv.logic.civilization.TechAction +import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers import com.unciv.logic.civilization.managers.ReligionState import com.unciv.logic.map.mapgenerator.NaturalWonderGenerator import com.unciv.logic.map.mapgenerator.RiverGenerator @@ -932,7 +933,7 @@ object UniqueTriggerActivation { } } - UniqueType.SellBuilding -> { + UniqueType.OneTimeSellBuilding -> { val applicableCities = if (unique.params[1] == "in this city") sequenceOf(relevantCity!!) else civInfo.cities.asSequence().filter { it.matchesFilter(unique.params[1]) } @@ -1048,6 +1049,49 @@ object UniqueTriggerActivation { } } + UniqueType.OneTimeTakeOverTilesInRadius -> { + if (tile == null) return null + if (civInfo.cities.isEmpty()) return null + val tileFilter = unique.params[0] + val radius = unique.params[1].toInt() + if (radius < 0) return null + val tilesToTakeOver = tile.getTilesInDistance(radius) + .filter { !it.isCityCenter() && it.matchesFilter(tileFilter) }.toList() + if (tilesToTakeOver.none()) return null + + /** Lower is better */ + fun cityPriority(city: City) = city.getCenterTile().aerialDistanceTo(tile) + (if (city.isBeingRazed) 5 else 0) + + val citiesWithAdjacentTiles = tilesToTakeOver.asSequence() + .flatMap { it.neighbors + it } + .map { it.owningCity } + .filterNotNull() + .filter { it.civ == civInfo } + .toSet() + + val cityToAddTo = citiesWithAdjacentTiles.minByOrNull { cityPriority(it) } + ?: civInfo.cities.minBy { cityPriority(it) } + + return { + val civsToNotify = mutableSetOf() + for (tileToTakeOver in tilesToTakeOver) { + val otherCiv = tileToTakeOver.getOwner() + if (otherCiv != null) { + // decrease relations for -10 pt/tile + otherCiv.getDiplomacyManagerOrMeet(civInfo).addModifier(DiplomaticModifiers.StealingTerritory, -10f) + civsToNotify.add(otherCiv) + } + cityToAddTo.expansion.takeOwnership(tileToTakeOver) + } + + for (otherCiv in civsToNotify) + otherCiv.addNotification("Your territory has been stolen by [$civInfo]!", + tile.position, NotificationCategory.Cities, civInfo.civName, NotificationIcon.War) + + true + } + } + else -> 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 506aef809b..40b8713148 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -138,7 +138,7 @@ enum class UniqueType( GainFreeBuildings("Gain a free [buildingName] [cityFilter]", UniqueTarget.Global, UniqueTarget.Triggerable), BuildingMaintenance("[relativeAmount]% maintenance cost for buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief), RemoveBuilding("Remove [buildingFilter] [cityFilter]", UniqueTarget.Global, UniqueTarget.Triggerable), - SellBuilding("Sell [buildingFilter] buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.Triggerable), + OneTimeSellBuilding("Sell [buildingFilter] buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.Triggerable), /// Border growth BorderGrowthPercentage("[relativeAmount]% Culture cost of natural border growth [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief), @@ -632,7 +632,6 @@ enum class UniqueType( GreatImprovement("Great Improvement", UniqueTarget.Improvement), IsAncientRuinsEquivalent("Provides a random bonus when entered", UniqueTarget.Improvement), - TakesOverAdjacentTiles("Constructing it will take over the tiles around it and assign them to your closest city", UniqueTarget.Improvement), Unpillagable("Unpillagable", UniqueTarget.Improvement), PillageYieldRandom("Pillaging this improvement yields approximately [stats]", UniqueTarget.Improvement), @@ -820,6 +819,11 @@ enum class UniqueType( OneTimeGainStatRange("Gain [amount]-[amount] [stat]", UniqueTarget.Triggerable), OneTimeGainPantheon("Gain enough Faith for a Pantheon", UniqueTarget.Triggerable), OneTimeGainProphet("Gain enough Faith for [amount]% of a Great Prophet", UniqueTarget.Triggerable), + + @Deprecated("As of 4.12.15", ReplaceWith("Gain control over [all] tiles in a [1]-tile radius")) + TakesOverAdjacentTiles("Constructing it will take over the tiles around it and assign them to your closest city", UniqueTarget.Improvement), + OneTimeTakeOverTilesInRadius("Gain control over [tileFilter] tiles in a [amount]-tile radius", UniqueTarget.Triggerable), + // todo: The "up to [All]" used in vanilla json is not nice to read. Split? // Or just reword it without the 'up to', so it reads "Reveal [amount/'all'] [tileFilter] tiles within [amount] tiles" OneTimeRevealSpecificMapTiles("Reveal up to [positiveAmount/'all'] [tileFilter] within a [positiveAmount] tile radius", UniqueTarget.Triggerable), @@ -843,6 +847,7 @@ enum class UniqueType( OneTimeChangeTerrain("Turn this tile into a [terrainName] tile", UniqueTarget.Triggerable), + UnitsGainPromotion("[mapUnitFilter] units gain the [promotion] promotion", UniqueTarget.Triggerable, docDescription = "Works only with promotions that are valid for the unit's type - or for promotions that do not specify any."), // Not used in Vanilla FreeStatBuildings("Provides the cheapest [stat] building in your first [positiveAmount] cities for free", UniqueTarget.Triggerable), // used in Policy