diff --git a/android/assets/jsons/Civ V - Gods & Kings/Buildings.json b/android/assets/jsons/Civ V - Gods & Kings/Buildings.json index 3ad858d156..e2cfe1e587 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/Buildings.json +++ b/android/assets/jsons/Civ V - Gods & Kings/Buildings.json @@ -406,7 +406,7 @@ "culture": 3, "greatPersonPoints": {"Great Engineer": 1}, "isWonder": true, - "uniques": ["Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)", + "uniques": ["Enemy [Land] units must spend [1] extra movement points when inside your territory ", "Gain a free [Walls] [in this city]"], "requiredTech": "Engineering", "quote": "'The art of war teaches us to rely not on the likelihood of the enemy's not attacking, but rather on the fact that we have made our position unassailable.' - Sun Tzu" diff --git a/android/assets/jsons/Civ V - Vanilla/Buildings.json b/android/assets/jsons/Civ V - Vanilla/Buildings.json index 8e03c962fd..6d8eb34ee9 100644 --- a/android/assets/jsons/Civ V - Vanilla/Buildings.json +++ b/android/assets/jsons/Civ V - Vanilla/Buildings.json @@ -253,7 +253,7 @@ "culture": 3, "greatPersonPoints": {"Great Engineer": 1}, "isWonder": true, - "uniques": ["Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)", + "uniques": ["Enemy [Land] units must spend [1] extra movement points when inside your territory ", "Gain a free [Walls] [in this city]"], "requiredTech": "Construction", "quote": "'The art of war teaches us to rely not on the likelihood of the enemy's not attacking, but rather on the fact that we have made our position unassailable.' - Sun Tzu" diff --git a/core/src/com/unciv/logic/civilization/CivInfoTransientUpdater.kt b/core/src/com/unciv/logic/civilization/CivInfoTransientUpdater.kt index 0691f8aa2a..321674f481 100644 --- a/core/src/com/unciv/logic/civilization/CivInfoTransientUpdater.kt +++ b/core/src/com/unciv/logic/civilization/CivInfoTransientUpdater.kt @@ -145,9 +145,12 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) { } } - fun updateHasActiveGreatWall() { - civInfo.hasActiveGreatWall = !civInfo.tech.isResearched("Dynamite") && - civInfo.hasUnique(UniqueType.EnemyLandUnitsSpendExtraMovement) + fun updateHasActiveEnemyMovementPenalty() { + civInfo.hasActiveEnemyMovementPenalty = (!civInfo.tech.isResearched("Dynamite") && civInfo.hasUnique(UniqueType.EnemyLandUnitsSpendExtraMovementDepreciated)) + || civInfo.hasUnique(UniqueType.EnemyLandUnitsSpendExtraMovement) + civInfo.enemyMovementPenaltyUniques = + civInfo.getMatchingUniques(UniqueType.EnemyLandUnitsSpendExtraMovement) + + civInfo.getMatchingUniques(UniqueType.EnemyLandUnitsSpendExtraMovementDepreciated) } fun updateCitiesConnectedToCapital(initialSetup: Boolean = false) { diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 8b6ae67197..e0d226b8e4 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -33,6 +33,7 @@ import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.tile.TileResource import com.unciv.models.ruleset.unique.StateForConditionals import com.unciv.models.ruleset.unique.TemporaryUnique +import com.unciv.models.ruleset.unique.Unique import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.stats.Stat @@ -105,7 +106,11 @@ class CivilizationInfo : IsPartOfGameInfoSerialization { /** This is for performance since every movement calculation depends on this, see MapUnit comment */ @Transient - var hasActiveGreatWall = false + var hasActiveEnemyMovementPenalty = false + + /** Same as above variable */ + @Transient + var enemyMovementPenaltyUniques: Sequence? = null @Transient var statsForNextTurn = Stats() @@ -673,6 +678,27 @@ class CivilizationInfo : IsPartOfGameInfoSerialization { return diplomacyManager.hasOpenBorders } + fun getEnemyMovementPenalty(enemyUnit: MapUnit, toMoveTo: TileInfo): Float { + if (enemyMovementPenaltyUniques != null && enemyMovementPenaltyUniques!!.any()) { + return enemyMovementPenaltyUniques!!.sumOf { + when (it.type!!) { + UniqueType.EnemyLandUnitsSpendExtraMovement -> { + if (enemyUnit.matchesFilter(it.params[0])) + it.params[1].toInt() + else 0 // doesn't match + } + UniqueType.EnemyLandUnitsSpendExtraMovementDepreciated -> { + if (toMoveTo.isLand) { + 1 // depreciated unique only works on land tiles + } else 0 + } + else -> 0 + } + }.toFloat() + } + return 0f // should not reach this point + } + /** * Returns a civilization caption suitable for greetings including player type info: * Like "Milan" if the nation is a city state, "Caesar of Rome" otherwise, with an added @@ -869,7 +895,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization { fun updateSightAndResources() { updateViewableTiles() - updateHasActiveGreatWall() + updateHasActiveEnemyMovementPenalty() updateDetailedCivResources() } @@ -879,7 +905,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization { // implementation in a separate class, to not clog up CivInfo fun initialSetCitiesConnectedToCapitalTransients() = transients().updateCitiesConnectedToCapital(true) - fun updateHasActiveGreatWall() = transients().updateHasActiveGreatWall() + fun updateHasActiveEnemyMovementPenalty() = transients().updateHasActiveEnemyMovementPenalty() fun updateViewableTiles() = transients().updateViewableTiles() fun updateDetailedCivResources() = transients().updateCivResources() @@ -982,7 +1008,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization { goldenAges.endTurn(getHappiness()) getCivUnits().forEach { it.endTurn() } // This is the most expensive part of endTurn diplomacy.values.toList().forEach { it.nextTurn() } // we copy the diplomacy values so if it changes in-loop we won't crash - updateHasActiveGreatWall() + updateHasActiveEnemyMovementPenalty() cachedMilitaryMight = -1 // Reset so we don't use a value from a previous turn } diff --git a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt index 2bcd25fe3b..f1bff8cad8 100644 --- a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt +++ b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt @@ -34,10 +34,9 @@ class UnitMovementAlgorithms(val unit: MapUnit) { val toOwner = to.getOwner() val extraCost = if ( toOwner != null && - to.isLand && - toOwner.hasActiveGreatWall && + toOwner.hasActiveEnemyMovementPenalty && civInfo.isAtWarWith(toOwner) - ) 1f else 0f + ) toOwner.getEnemyMovementPenalty(unit, to) else 0f if (from.roadStatus == RoadStatus.Railroad && to.roadStatus == RoadStatus.Railroad) return RoadStatus.Railroad.movement + extraCost diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index 06de4ae184..f8da0f638a 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -666,8 +666,9 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { for (unique in uniqueObjects) UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo, cityConstructions.cityInfo) - if ("Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)" in uniques) - civInfo.updateHasActiveGreatWall() + if (hasUnique(UniqueType.EnemyLandUnitsSpendExtraMovement) + || hasUnique(UniqueType.EnemyLandUnitsSpendExtraMovementDepreciated)) + civInfo.updateHasActiveEnemyMovementPenalty() // Korean unique - apparently gives the same as the research agreement if (science > 0 && civInfo.hasUnique(UniqueType.TechBoostWhenScientificBuildingsBuiltInCapital)) diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index 9fa5c4b993..78ef0f687e 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -215,7 +215,9 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: DoubleHappinessFromNaturalWonders("Double Happiness from Natural Wonders", UniqueTarget.Global), EnablesConstructionOfSpaceshipParts("Enables construction of Spaceship parts", UniqueTarget.Global), - EnemyLandUnitsSpendExtraMovement("Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)", UniqueTarget.Global), + EnemyLandUnitsSpendExtraMovement("Enemy [mapUnitFilter] units must spend [amount] extra movement points when inside your territory", UniqueTarget.Global), + @Deprecated("As of 4.2.4", ReplaceWith("Enemy [Land] units must spend [1] extra movement points when inside your territory ")) + EnemyLandUnitsSpendExtraMovementDepreciated("Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)", UniqueTarget.Global), @Deprecated("s of 4.1.14", ReplaceWith("Production to [Science] conversion in cities changed by [33]%")) ProductionToScienceConversionBonus("Production to science conversion in cities increased by 33%", UniqueTarget.Global),