diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index 808aa0c66f..ac8cd611e6 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -452,12 +452,13 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { rejectionReasons.add(RejectionReason.Unbuildable) for (unique in uniqueObjects) { - when (unique.placeholderText) { // TODO: Lots of typification… - UniqueType.OnlyAvailableWhen.placeholderText-> + @Suppress("NON_EXHAUSTIVE_WHEN") + when (unique.type) { // TODO: Lots of typification… + UniqueType.OnlyAvailableWhen-> if (!unique.conditionalsApply(civInfo, cityConstructions.cityInfo)) rejectionReasons.add(RejectionReason.ShouldNotBeDisplayed) - UniqueType.NotDisplayedWithout.placeholderText -> + UniqueType.NotDisplayedWithout -> if (unique.params[0] in ruleSet.tileResources && !civInfo.hasResource(unique.params[0]) || unique.params[0] in ruleSet.buildings && !cityConstructions.containsBuildingOrEquivalent(unique.params[0]) || unique.params[0] in ruleSet.technologies && !civInfo.tech.isResearched(unique.params[0]) @@ -465,34 +466,33 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { ) rejectionReasons.add(RejectionReason.ShouldNotBeDisplayed) - // Shouldn't this be "Enables nuclear weapon_s_"? - "Enables nuclear weapon" -> if (!cityConstructions.cityInfo.civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled) + UniqueType.EnablesNuclearWeapons -> if (!cityConstructions.cityInfo.civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled) rejectionReasons.add(RejectionReason.DisabledBySetting) - UniqueType.MustBeOn.placeholderText -> + UniqueType.MustBeOn -> if (!cityCenter.matchesTerrainFilter(unique.params[0], civInfo)) rejectionReasons.add(RejectionReason.MustBeOnTile.apply { errorMessage = unique.text }) - UniqueType.MustNotBeOn.placeholderText -> + UniqueType.MustNotBeOn -> if (cityCenter.matchesTerrainFilter(unique.params[0], civInfo)) rejectionReasons.add(RejectionReason.MustNotBeOnTile.apply { errorMessage = unique.text }) - UniqueType.MustBeNextTo.placeholderText -> + UniqueType.MustBeNextTo -> if (!cityCenter.isAdjacentTo(unique.params[0])) rejectionReasons.add(RejectionReason.MustBeNextToTile.apply { errorMessage = unique.text }) - UniqueType.MustNotBeNextTo.placeholderText -> + UniqueType.MustNotBeNextTo -> if (cityCenter.getTilesInDistance(1).any { it.matchesFilter(unique.params[0], civInfo) }) rejectionReasons.add(RejectionReason.MustNotBeNextToTile.apply { errorMessage = unique.text }) - "Must have an owned [] within [] tiles" -> + UniqueType.MustHaveOwnedWithinTiles -> if (cityCenter.getTilesInDistance(unique.params[1].toInt()) .none { it.matchesFilter(unique.params[0], civInfo) && it.getOwner() == cityConstructions.cityInfo.civInfo } ) rejectionReasons.add(RejectionReason.MustOwnTile.apply { errorMessage = unique.text }) // Deprecated since 3.16.11 - "Can only be built in annexed cities" -> + UniqueType.CanOnlyBeBuiltInAnnexedCities -> if ( cityConstructions.cityInfo.isPuppet || cityConstructions.cityInfo.civInfo.civName == cityConstructions.cityInfo.foundingCiv @@ -500,24 +500,24 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { rejectionReasons.add(RejectionReason.CanOnlyBeBuiltInSpecificCities.apply { errorMessage = unique.text }) // - "Can only be built []" -> + UniqueType.CanOnlyBeBuiltInCertainCities -> if (!cityConstructions.cityInfo.matchesFilter(unique.params[0])) rejectionReasons.add(RejectionReason.CanOnlyBeBuiltInSpecificCities.apply { errorMessage = unique.text }) - UniqueType.ObsoleteWith.placeholderText -> + UniqueType.ObsoleteWith -> if (civInfo.tech.isResearched(unique.params[0])) rejectionReasons.add(RejectionReason.Obsoleted.apply { errorMessage = unique.text }) - UniqueType.HiddenWithoutReligion.text -> + UniqueType.HiddenWithoutReligion -> if (!civInfo.gameInfo.isReligionEnabled()) rejectionReasons.add(RejectionReason.DisabledBySetting) - UniqueType.MaxNumberBuildable.placeholderText -> + UniqueType.MaxNumberBuildable -> if (civInfo.civConstructions.countConstructedObjects(this) >= unique.params[0].toInt()) rejectionReasons.add(RejectionReason.MaxNumberBuildable) // This should be deprecated and replaced with the already-existing "only available when" unique, see above - UniqueType.UnlockedWith.placeholderText, UniqueType.Requires.placeholderText -> { + UniqueType.UnlockedWith, UniqueType.Requires -> { val filter = unique.params[0] when { ruleSet.technologies.contains(filter) -> @@ -535,14 +535,14 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { } } - UniqueType.SpaceshipPart.placeholderText -> { + UniqueType.SpaceshipPart -> { if (!civInfo.hasUnique(UniqueType.EnablesConstructionOfSpaceshipParts)) rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.apply { errorMessage = "Apollo project not built!" }) if (civInfo.victoryManager.unconstructedSpaceshipParts()[name] == 0) rejectionReasons.add(RejectionReason.ReachedBuildCap) } - UniqueType.RequiresAnotherBuilding.placeholderText -> { + UniqueType.RequiresAnotherBuilding -> { val filter = unique.params[0] if (civInfo.gameInfo.ruleSet.buildings.containsKey(filter) && !cityConstructions.containsBuildingOrEquivalent(filter)) rejectionReasons.add( @@ -551,7 +551,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { ) } - UniqueType.RequiresBuildingInSomeCities.placeholderText -> { + UniqueType.RequiresBuildingInSomeCities -> { val buildingName = unique.params[0] val numberOfCitiesRequired = unique.params[1].toInt() val numberOfCitiesWithBuilding = civInfo.cities.count { @@ -569,7 +569,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { } } - UniqueType.RequiresBuildingInAllCities.placeholderText -> { + UniqueType.RequiresBuildingInAllCities -> { val filter = unique.params[0] if (civInfo.gameInfo.ruleSet.buildings.containsKey(filter) && civInfo.cities.any { @@ -585,12 +585,12 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { } } - UniqueType.HiddenBeforeAmountPolicies.placeholderText -> { + UniqueType.HiddenBeforeAmountPolicies -> { if (cityConstructions.cityInfo.civInfo.getCompletedPolicyBranchesCount() < unique.params[0].toInt()) rejectionReasons.add(RejectionReason.MorePolicyBranches.apply { errorMessage = unique.text }) } - UniqueType.HiddenWithoutVictoryType.placeholderText -> { + UniqueType.HiddenWithoutVictoryType -> { if (!civInfo.gameInfo.gameParameters.victoryTypes.contains(VictoryType.valueOf(unique.params[0]))) rejectionReasons.add(RejectionReason.HiddenWithoutVictory.apply { errorMessage = unique.text }) } diff --git a/core/src/com/unciv/models/ruleset/tech/Technology.kt b/core/src/com/unciv/models/ruleset/tech/Technology.kt index cf73da781d..61e6ee86d8 100644 --- a/core/src/com/unciv/models/ruleset/tech/Technology.kt +++ b/core/src/com/unciv/models/ruleset/tech/Technology.kt @@ -119,7 +119,7 @@ class Technology: RulesetObject() { .filter { predicate(it) // expected to be the most selective, thus tested first && (it.uniqueTo == civInfo.civName || it.uniqueTo==null && civInfo.getEquivalentBuilding(it) == it) - && (nuclearWeaponsEnabled || "Enables nuclear weapon" !in it.uniques) + && (nuclearWeaponsEnabled || it.hasUnique(UniqueType.EnablesNuclearWeapons)) && (religionEnabled || !it.hasUnique(UniqueType.HiddenWithoutReligion)) && !it.hasUnique(UniqueType.HiddenFromCivilopedia) } diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index 2d63f4332c..1e1cbdc8e0 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -348,10 +348,19 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: RequiresAnotherBuilding("Requires a [buildingName] in this city", UniqueTarget.Building), RequiresBuildingInAllCities("Requires a [buildingName] in all cities", UniqueTarget.Building), RequiresBuildingInSomeCities("Requires a [buildingName] in at least [amount] cities", UniqueTarget.Building), + CanOnlyBeBuiltInCertainCities("Can only be built [cityFilter]", UniqueTarget.Building), + @Deprecated("as of 3.19.16", ReplaceWith("Can only be built [in annexed cities]")) + CanOnlyBeBuiltInAnnexedCities("Can only be built in annexed cities", UniqueTarget.Building), + + MustHaveOwnedWithinTiles("Must have an owned [tileFilter] within [amount] tiles", UniqueTarget.Building), @Deprecated("as of 3.19.7", ReplaceWith("[stats] ")) StatsWithResource("[stats] with [resource]", UniqueTarget.Building), + // Todo nuclear weapon and spaceship enabling requires a rethink. + // This doesn't actually directly affect anything, the "Only available " of the nuclear weapons does that. + EnablesNuclearWeapons("Enables nuclear weapon", UniqueTarget.Building), + MustBeOn("Must be on [terrainFilter]", UniqueTarget.Building), MustNotBeOn("Must not be on [terrainFilter]", UniqueTarget.Building), diff --git a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt index f595f4fb03..d0f147d8ad 100644 --- a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt @@ -352,18 +352,19 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { rejectionReasons.add(RejectionReason.WaterUnitsInCoastalCities) val civInfo = cityConstructions.cityInfo.civInfo for (unique in uniqueObjects) { - when (unique.placeholderText) { - UniqueType.OnlyAvailableWhen.placeholderText -> if (!unique.conditionalsApply(civInfo, cityConstructions.cityInfo)) + @Suppress("NON_EXHAUSTIVE_WHEN") + when (unique.type) { + UniqueType.OnlyAvailableWhen -> if (!unique.conditionalsApply(civInfo, cityConstructions.cityInfo)) rejectionReasons.add(RejectionReason.ShouldNotBeDisplayed) - UniqueType.NotDisplayedWithout.placeholderText -> { + UniqueType.NotDisplayedWithout -> { val filter = unique.params[0] if (filter in civInfo.gameInfo.ruleSet.tileResources && !civInfo.hasResource(filter) || filter in civInfo.gameInfo.ruleSet.buildings && !cityConstructions.containsBuildingOrEquivalent(filter)) rejectionReasons.add(RejectionReason.ShouldNotBeDisplayed) } - UniqueType.RequiresPopulation.placeholderText -> if (unique.params[0].toInt() > cityConstructions.cityInfo.population.population) + UniqueType.RequiresPopulation -> if (unique.params[0].toInt() > cityConstructions.cityInfo.population.population) rejectionReasons.add(RejectionReason.PopulationRequirement.apply { errorMessage = unique.text }) } } @@ -393,12 +394,12 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { rejectionReasons.add(RejectionReason.DisabledBySetting) for (unique in uniqueObjects) { - when (unique.placeholderText) { - UniqueType.Unbuildable.placeholderText -> + when (unique.type) { + UniqueType.Unbuildable -> rejectionReasons.add(RejectionReason.Unbuildable) // This should be deprecated and replaced with the already-existing "only available when" unique, see above - UniqueType.UnlockedWith.placeholderText, UniqueType.Requires.placeholderText -> { + UniqueType.UnlockedWith, UniqueType.Requires -> { val filter = unique.params[0] when { ruleSet.technologies.contains(filter) -> @@ -416,10 +417,10 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { } } - UniqueType.FoundCity.placeholderText-> if (civInfo.isCityState() || civInfo.isOneCityChallenger()) + UniqueType.FoundCity -> if (civInfo.isCityState() || civInfo.isOneCityChallenger()) rejectionReasons.add(RejectionReason.NoSettlerForOneCityPlayers) - UniqueType.MaxNumberBuildable.placeholderText -> if (civInfo.civConstructions.countConstructedObjects(this) >= unique.params[0].toInt()) + UniqueType.MaxNumberBuildable -> if (civInfo.civConstructions.countConstructedObjects(this) >= unique.params[0].toInt()) rejectionReasons.add(RejectionReason.MaxNumberBuildable) } }