From 1c03133fdcbb75093a28dd9175099583f3a32544 Mon Sep 17 00:00:00 2001 From: EmperorPinguin <99119424+EmperorPinguin@users.noreply.github.com> Date: Tue, 25 Mar 2025 10:37:31 +0100 Subject: [PATCH] Forest chopping moddability (#13072) * Update ModConstants.kt * Update UniqueType.kt * Update TileImprovementFunctions.kt * Update Terrains.json * Update Terrains.json * Update TileImprovementFunctions.kt * Update TileImprovementFunctions.kt * Update TileImprovementFunctions.kt * Update Terrains.json * Update Terrains.json * Update UniqueType.kt * Update TileImprovementFunctions.kt * Update TileImprovementFunctions.kt * Update TileImprovementFunctions.kt * Update TileImprovementFunctions.kt * Update TileImprovementFunctions.kt * Update TileImprovementFunctions.kt * Game speed modifier * Add meta modifier (WIP) * Update * Update UniqueType.kt * Rename * Float * Revert modifier * Update Unique.kt * Update TileImprovementFunctions.kt * Update TileImprovementFunctions.kt --- .../jsons/Civ V - Gods & Kings/Terrains.json | 2 +- .../jsons/Civ V - Vanilla/Terrains.json | 2 +- .../map/tile/TileImprovementFunctions.kt | 21 ++++++++++++------- .../unciv/models/ruleset/unique/UniqueType.kt | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/android/assets/jsons/Civ V - Gods & Kings/Terrains.json b/android/assets/jsons/Civ V - Gods & Kings/Terrains.json index cd8582efd8..09a30928aa 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/Terrains.json +++ b/android/assets/jsons/Civ V - Gods & Kings/Terrains.json @@ -188,7 +188,7 @@ "defenceBonus": 0.25, "occursOn": ["Tundra","Plains","Grassland","Hill"], "uniques": ["Rough terrain", "Vegetation", - "Provides a one-time Production bonus to the closest city when cut down", + "Provides a one-time bonus of [+30 Production] to the closest city when cut down <(modified by game speed)>", "Blocks line-of-sight from tiles at same elevation", "[25]% Chance to be destroyed by nukes", "A Region is formed with at least [30]% [Forest] tiles, with priority [3]", diff --git a/android/assets/jsons/Civ V - Vanilla/Terrains.json b/android/assets/jsons/Civ V - Vanilla/Terrains.json index cee007555c..df16301300 100644 --- a/android/assets/jsons/Civ V - Vanilla/Terrains.json +++ b/android/assets/jsons/Civ V - Vanilla/Terrains.json @@ -188,7 +188,7 @@ "occursOn": ["Tundra","Plains","Grassland","Hill"], "uniques": [ "Rough terrain", "Vegetation", - "Provides a one-time Production bonus to the closest city when cut down", + "Provides a one-time bonus of [+30 Production] to the closest city when cut down <(modified by game speed)>", "Blocks line-of-sight from tiles at same elevation", "[25]% Chance to be destroyed by nukes", "A Region is formed with at least [30]% [Forest] tiles, with priority [3]", diff --git a/core/src/com/unciv/logic/map/tile/TileImprovementFunctions.kt b/core/src/com/unciv/logic/map/tile/TileImprovementFunctions.kt index 672220ae58..b62d2a1571 100644 --- a/core/src/com/unciv/logic/map/tile/TileImprovementFunctions.kt +++ b/core/src/com/unciv/logic/map/tile/TileImprovementFunctions.kt @@ -10,6 +10,7 @@ import com.unciv.models.ruleset.tile.TileImprovement import com.unciv.models.ruleset.unique.StateForConditionals import com.unciv.models.ruleset.unique.UniqueTriggerActivation import com.unciv.models.ruleset.unique.UniqueType +import com.unciv.models.stats.Stats /** Reason why an Improvement cannot be built by a given civ */ @@ -312,20 +313,26 @@ class TileImprovementFunctions(val tile: Tile) { val closestCity = civ.cities.minByOrNull { it.getCenterTile().aerialDistanceTo(tile) } ?: return val distance = closestCity.getCenterTile().aerialDistanceTo(tile) - var productionPointsToAdd = if (distance == 1) 20 else 20 - (distance - 2) * 5 - if (tile.owningCity == null || tile.owningCity!!.civ != civ) productionPointsToAdd = - productionPointsToAdd * 2 / 3 - if (productionPointsToAdd > 0) { - closestCity.cityConstructions.addProductionPoints(productionPointsToAdd) + if (distance > 5) return + var stats = Stats() + for (unique in tile.getTerrainMatchingUniques(UniqueType.ProductionBonusWhenRemoved)) { + if (unique.isModifiedByGameSpeed()) + stats.add(unique.stats * civ.gameInfo.speed.modifier) + else stats.add(unique.stats) + } + if (stats.isEmpty()) return + if (distance != 1) stats *= (6 - distance) / 4f + if (tile.owningCity == null || tile.owningCity!!.civ != civ) stats *= 2 / 3f + for ((stat, value) in stats) { + closestCity.addStat(stat, value.toInt()) val locations = LocationAction(tile.position, closestCity.location) civ.addNotification( - "Clearing a [$removedTerrainFeature] has created [$productionPointsToAdd] Production for [${closestCity.name}]", + "Clearing a [$removedTerrainFeature] has created [${stats.toStringForNotifications()}] for [${closestCity.name}]", locations, NotificationCategory.Production, NotificationIcon.Construction ) } } - /** Marks tile as target tile for a building with a [UniqueType.CreatesOneImprovement] unique */ fun markForCreatesOneImprovement(improvement: String) { tile.stopWorkingOnImprovement() diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index 06773c1a97..5da38f6c1b 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -562,7 +562,7 @@ enum class UniqueType( DamagesContainingUnits("Units ending their turn on this terrain take [amount] damage", UniqueTarget.Terrain), TerrainGrantsPromotion("Grants [promotion] ([comment]) to adjacent [mapUnitFilter] units for the rest of the game", UniqueTarget.Terrain), GrantsCityStrength("[amount] Strength for cities built on this terrain", UniqueTarget.Terrain), - ProductionBonusWhenRemoved("Provides a one-time Production bonus to the closest city when cut down", UniqueTarget.Terrain), + ProductionBonusWhenRemoved("Provides a one-time bonus of [stats] to the closest city when cut down", UniqueTarget.Terrain, flags = setOf(UniqueFlag.AcceptsSpeedModifier)), Vegetation("Vegetation", UniqueTarget.Terrain, UniqueTarget.Improvement, flags = UniqueFlag.setOfHiddenToUsers), // Improvement included because use as tileFilter works