diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index 08132ba84e..7b760ae02f 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -392,6 +392,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: RemoveAnnexUnhappiness("Remove extra unhappiness from annexed cities", UniqueTarget.Building), + ConnectTradeRoutes("Connects trade routes over water", UniqueTarget.Building), //endregion @@ -400,6 +401,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: FoundCity("Founds a new city", UniqueTarget.Unit), ConstructImprovementConsumingUnit("Can construct [improvementName]", UniqueTarget.Unit), + CanConstructIfNoOtherActions("Can construct [improvementName] if it hasn't used other actions yet", UniqueTarget.Unit), BuildImprovements("Can build [improvementFilter/terrainFilter] improvements on tiles", UniqueTarget.Unit), CreateWaterImprovements("May create improvements on water resources", UniqueTarget.Unit), @@ -426,6 +428,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: SelfDestructs("Self-destructs when attacking", UniqueTarget.Unit), BlastRadius("Blast radius [amount]", UniqueTarget.Unit), IndirectFire("Ranged attacks may be performed over obstacles", UniqueTarget.Unit), + NuclearWeapon("Nuclear weapon of Strength [amount]", UniqueTarget.Unit), NoDefensiveTerrainBonus("No defensive terrain bonus", UniqueTarget.Unit, UniqueTarget.Global), NoDefensiveTerrainPenalty("No defensive terrain penalty", UniqueTarget.Unit, UniqueTarget.Global), @@ -437,6 +440,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: NoMovementToPillage("No movement cost to pillage", UniqueTarget.Unit, UniqueTarget.Global), CanMoveAfterAttacking("Can move after attacking", UniqueTarget.Unit), MoveImmediatelyOnceBought("Can move immediately once bought", UniqueTarget.Unit), + MayParadrop("May Paradrop up to [amount] tiles from inside friendly territory", UniqueTarget.Unit), HealsOutsideFriendlyTerritory("May heal outside of friendly territory", UniqueTarget.Unit, UniqueTarget.Global), HealingEffectsDoubled("All healing effects doubled", UniqueTarget.Unit, UniqueTarget.Global), @@ -462,6 +466,8 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: CarryAirUnits("Can carry [amount] [mapUnitFilter] units", UniqueTarget.Unit), CarryExtraAirUnits("Can carry [amount] extra [mapUnitFilter] units", UniqueTarget.Unit), CannotBeCarriedBy("Cannot be carried by [mapUnitFilter] units", UniqueTarget.Unit), + ChanceInterceptAirAttacks("[relativeAmount]% chance to intercept air attacks", UniqueTarget.Unit), + DamageFromInterceptionReduced("Damage taken from interception reduced by [relativeAmount]%", UniqueTarget.Unit), UnitMaintenanceDiscount("[relativeAmount]% maintenance costs", UniqueTarget.Unit, UniqueTarget.Global), UnitUpgradeCost("[relativeAmount]% Gold cost of upgrading", UniqueTarget.Unit, UniqueTarget.Global), @@ -504,6 +510,22 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: SpaceshipPart("Spaceship part", UniqueTarget.Unit, UniqueTarget.Building), // Should be deprecated in the near future AddInCapital("Can be added to [comment] in the Capital", UniqueTarget.Unit), + StartGoldenAge("Can start an [amount]-turn golden age", UniqueTarget.Unit), + GreatPerson("Great Person - [comment]", UniqueTarget.Unit), + + PreventSpreadingReligion("Prevents spreading of religion to the city it is next to", UniqueTarget.Unit), + TakeReligionOverBirthCity("Takes your religion over the one in their birth city", UniqueTarget.Unit), + RemoveOtherReligions("Removes other religions when spreading religion", UniqueTarget.Unit), + + CanActionSeveralTimes("Can [action] [amount] times", UniqueTarget.Unit), + // TODO needs to be more general + BonusForUnitsInRadius("Bonus for units in 2 tile radius 15%", UniqueTarget.Unit), + + CanSpeedupConstruction("Can speed up construction of a building", UniqueTarget.Unit), + CanHurryResearch("Can hurry technology research", UniqueTarget.Unit), + CanTradeWithCityStateForGoldAndInfluence("Can undertake a trade mission with City-State, giving a large sum of gold and [amount] Influence", UniqueTarget.Unit), + + //endregion diff --git a/docs/Modders/uniques.md b/docs/Modders/uniques.md index d0033d001a..39ade1e0db 100644 --- a/docs/Modders/uniques.md +++ b/docs/Modders/uniques.md @@ -942,6 +942,9 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl ??? example "Remove extra unhappiness from annexed cities" Applicable to: Building +??? example "Connects trade routes over water" + Applicable to: Building + ??? example "Spaceship part" Applicable to: Building, Unit @@ -962,6 +965,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl Applicable to: Unit +??? example "Can construct [improvementName] if it hasn't used other actions yet" + Example: "Can construct [Trading Post] if it hasn't used other actions yet" + + Applicable to: Unit + ??? example "Can build [improvementFilter/terrainFilter] improvements on tiles" Example: "Can build [All Road] improvements on tiles" @@ -1003,6 +1011,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl ??? example "Ranged attacks may be performed over obstacles" Applicable to: Unit +??? example "Nuclear weapon of Strength [amount]" + Example: "Nuclear weapon of Strength [3]" + + Applicable to: Unit + ??? example "Uncapturable" Applicable to: Unit @@ -1020,6 +1033,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl ??? example "Can move immediately once bought" Applicable to: Unit +??? example "May Paradrop up to [amount] tiles from inside friendly territory" + Example: "May Paradrop up to [3] tiles from inside friendly territory" + + Applicable to: Unit + ??? example "Unit will heal every turn, even if it performs an action" Applicable to: Unit @@ -1055,6 +1073,16 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl Applicable to: Unit +??? example "[relativeAmount]% chance to intercept air attacks" + Example: "[+20]% chance to intercept air attacks" + + Applicable to: Unit + +??? example "Damage taken from interception reduced by [relativeAmount]%" + Example: "Damage taken from interception reduced by [+20]%" + + Applicable to: Unit + ??? example "May capture killed [mapUnitFilter] units" Example: "May capture killed [Wounded] units" @@ -1121,6 +1149,44 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl Applicable to: Unit +??? example "Can start an [amount]-turn golden age" + Example: "Can start an [3]-turn golden age" + + Applicable to: Unit + +??? example "Great Person - [comment]" + Example: "Great Person - [comment]" + + Applicable to: Unit + +??? example "Prevents spreading of religion to the city it is next to" + Applicable to: Unit + +??? example "Takes your religion over the one in their birth city" + Applicable to: Unit + +??? example "Removes other religions when spreading religion" + Applicable to: Unit + +??? example "Can [action] [amount] times" + Example: "Can [Spread Religion] [3] times" + + Applicable to: Unit + +??? example "Bonus for units in 2 tile radius 15%" + Applicable to: Unit + +??? example "Can speed up construction of a building" + Applicable to: Unit + +??? example "Can hurry technology research" + Applicable to: Unit + +??? example "Can undertake a trade mission with City-State, giving a large sum of gold and [amount] Influence" + Example: "Can undertake a trade mission with City-State, giving a large sum of gold and [3] Influence" + + Applicable to: Unit + ## Promotion uniques ??? example "Heal this unit by [amount] HP" Example: "Heal this unit by [3] HP" diff --git a/tests/src/com/unciv/testing/BasicTests.kt b/tests/src/com/unciv/testing/BasicTests.kt index 3d394728b7..629ab61d57 100644 --- a/tests/src/com/unciv/testing/BasicTests.kt +++ b/tests/src/com/unciv/testing/BasicTests.kt @@ -9,6 +9,7 @@ import com.unciv.models.metadata.BaseRuleset import com.unciv.models.metadata.GameSettings import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.RulesetCache +import com.unciv.models.ruleset.RulesetStatsObject import com.unciv.models.ruleset.unique.Unique import com.unciv.models.ruleset.unique.UniqueParameterType import com.unciv.models.ruleset.unique.UniqueType @@ -16,6 +17,7 @@ import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.stats.Stat import com.unciv.models.stats.Stats import com.unciv.models.translations.getPlaceholderParameters +import com.unciv.models.translations.getPlaceholderText import org.junit.Assert import org.junit.Before import org.junit.Test @@ -125,6 +127,54 @@ class BasicTests { Assert.assertTrue("This test succeeds only if all UniqueTypes have at least one UniqueTarget", allOK) } + @Test + fun allUnitsUniquesHaveTheirUniqueTypes() { + val units: Collection = ruleset.units.values + var allOK = true + for (unit in units) { + for (unique in unit.uniques) { + if (!UniqueType.values().any { it.placeholderText == unique.getPlaceholderText() }) { + println("${unit.name}: $unique") + allOK = false + } + } + } + Assert.assertTrue("This test succeeds only if all uniques of units are presented in UniqueType.values()", allOK) + } + + @Test + fun allBuildingsUniquesHaveTheirUniqueTypes() { + val buildings = ruleset.buildings.values + var allOK = true + for (building in buildings) { + for (unique in building.uniques) { + if (!UniqueType.values().any { it.placeholderText == unique.getPlaceholderText() }) { + println("${building.name}: $unique") + allOK = false + } + } + } + Assert.assertTrue("This test succeeds only if all uniques of buildings are presented in UniqueType.values()", allOK) + } + + @Test + fun allTerrainRelatedUniquesHaveTheirUniqueTypes() { + val objects : MutableCollection = mutableListOf() + objects.addAll(ruleset.tileImprovements.values) + objects.addAll(ruleset.tileResources.values) + objects.addAll(ruleset.terrains.values) + var allOK = true + for (obj in objects) { + for (unique in obj.uniques) { + if (!UniqueType.values().any { it.placeholderText == unique.getPlaceholderText() }) { + println("${obj.name}: $unique") + allOK = false + } + } + } + Assert.assertTrue("This test succeeds only if all uniques are presented in UniqueType.values()", allOK) + } + @Test fun allDeprecatedUniqueTypesHaveReplacewithThatMatchesOtherType() { var allOK = true