From ea2b26370aec08a898cbad48d49dc6ce7b469302 Mon Sep 17 00:00:00 2001 From: lishaoxia1985 <49801619+lishaoxia1985@users.noreply.github.com> Date: Tue, 8 Mar 2022 20:18:15 +0800 Subject: [PATCH] Some edits for fun getRejectionReasons in class building/unit and fun checkMod (#6165) --- .../src/com/unciv/logic/city/IConstruction.kt | 1 - core/src/com/unciv/models/ruleset/Building.kt | 180 ++++++++---------- .../com/unciv/models/ruleset/unit/BaseUnit.kt | 87 ++++----- 3 files changed, 126 insertions(+), 142 deletions(-) diff --git a/core/src/com/unciv/logic/city/IConstruction.kt b/core/src/com/unciv/logic/city/IConstruction.kt index 84d1741209..bb1f5f57cd 100644 --- a/core/src/com/unciv/logic/city/IConstruction.kt +++ b/core/src/com/unciv/logic/city/IConstruction.kt @@ -158,7 +158,6 @@ enum class RejectionReason(val shouldShow: Boolean, var errorMessage: String) { MorePolicyBranches(false, "Hidden until more policy branches are fully adopted"), RequiresNearbyResource(false, "Requires a certain resource being exploited nearby"), - InvalidRequiredBuilding(false, "Required building does not exist in ruleSet!"), CannotBeBuiltWith(false, "Cannot be built at the same time as another building already built"), RequiresBuildingInThisCity(true, "Requires a specific building in this city!"), diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index cca9db3eba..f1b8074c22 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -110,8 +110,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { if (isNationalWonder) lines += "National Wonder" if (!isFree) { for ((resource, amount) in getResourceRequirements()) { - lines += if (amount == 1) "Consumes 1 [$resource]" // For now, to keep the existing translations - else "Consumes [$amount] [$resource]" + lines += "Consumes [$amount] [$resource]" } } @@ -525,6 +524,85 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { UniqueType.MaxNumberBuildable.placeholderText -> 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 -> { + val filter = unique.params[0] + when { + ruleSet.technologies.contains(filter) -> + if (!civInfo.tech.isResearched(filter)) + rejectionReasons.add(RejectionReason.RequiresTech.apply { errorMessage = unique.text }) + ruleSet.policies.contains(filter) -> + if (!civInfo.policies.isAdopted(filter)) + rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text }) + ruleSet.eras.contains(filter) -> + if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber) + rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text }) + ruleSet.buildings.contains(filter) -> + if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) }) + rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.apply { errorMessage = unique.text }) + } + } + + UniqueType.SpaceshipPart.placeholderText -> { + 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 -> { + val filter = unique.params[0] + if (civInfo.gameInfo.ruleSet.buildings.containsKey(filter) && !cityConstructions.containsBuildingOrEquivalent(filter)) + rejectionReasons.add( + // replace with civ-specific building for user + RejectionReason.RequiresBuildingInThisCity.apply { errorMessage = "Requires a [${civInfo.getEquivalentBuilding(filter)}] in this city" } + ) + } + + UniqueType.RequiresBuildingInSomeCities.placeholderText -> { + val buildingName = unique.params[0] + val numberOfCitiesRequired = unique.params[1].toInt() + val numberOfCitiesWithBuilding = civInfo.cities.count { + it.cityConstructions.containsBuildingOrEquivalent(buildingName) + } + if (numberOfCitiesWithBuilding < numberOfCitiesRequired) { + val equivalentBuildingName = civInfo.getEquivalentBuilding(buildingName).name + rejectionReasons.add( + // replace with civ-specific building for user + RejectionReason.RequiresBuildingInAllCities.apply { + errorMessage = unique.text.fillPlaceholders(equivalentBuildingName, numberOfCitiesRequired.toString()) + + " ($numberOfCitiesWithBuilding/$numberOfCitiesRequired)" + } + ) + } + } + + UniqueType.RequiresBuildingInAllCities.placeholderText -> { + val filter = unique.params[0] + if (civInfo.gameInfo.ruleSet.buildings.containsKey(filter) + && civInfo.cities.any { + !it.isPuppet && !it.cityConstructions.containsBuildingOrEquivalent(unique.params[0]) + } + ) { + rejectionReasons.add( + // replace with civ-specific building for user + RejectionReason.RequiresBuildingInAllCities.apply { + errorMessage = "Requires a [${civInfo.getEquivalentBuilding(unique.params[0])}] in all cities" + } + ) + } + } + + UniqueType.HiddenBeforeAmountPolicies.placeholderText -> { + if (cityConstructions.cityInfo.civInfo.getCompletedPolicyBranchesCount() < unique.params[0].toInt()) + rejectionReasons.add(RejectionReason.MorePolicyBranches.apply { errorMessage = unique.text }) + } + + UniqueType.HiddenWithoutVictoryType.placeholderText -> { + if (!civInfo.gameInfo.gameParameters.victoryTypes.contains(VictoryType.valueOf(unique.params[0]))) + rejectionReasons.add(RejectionReason.HiddenWithoutVictory.apply { errorMessage = unique.text }) + } } } @@ -537,25 +615,6 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { if (requiredTech != null && !civInfo.tech.isResearched(requiredTech!!)) rejectionReasons.add(RejectionReason.RequiresTech.apply { "$requiredTech not researched!"}) - for (unique in uniqueObjects) { - if (unique.type != UniqueType.UnlockedWith && unique.type != UniqueType.Requires) continue - val filter = unique.params[0] - when { - ruleSet.technologies.contains(filter) -> - if (!civInfo.tech.isResearched(filter)) - rejectionReasons.add(RejectionReason.RequiresTech.apply { errorMessage = unique.text }) - ruleSet.policies.contains(filter) -> - if (!civInfo.policies.isAdopted(filter)) - rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text }) - ruleSet.eras.contains(filter) -> - if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber) - rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text }) - ruleSet.buildings.contains(filter) -> - if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) }) - rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.apply { errorMessage = unique.text }) - } - } - // Regular wonders if (isWonder) { if (civInfo.gameInfo.getCities().any { it.cityConstructions.isBuilt(name) }) @@ -572,7 +631,6 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { rejectionReasons.add(RejectionReason.WonderDisabledEra) } - // National wonders if (isNationalWonder) { if (civInfo.cities.any { it.cityConstructions.isBuilt(name) }) @@ -585,84 +643,10 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { rejectionReasons.add(RejectionReason.CityStateNationalWonder) } - if (hasUnique(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) - } - - for (unique in uniqueObjects) when (unique.type) { - UniqueType.RequiresAnotherBuilding -> { - val filter = unique.params[0] - if (civInfo.gameInfo.ruleSet.buildings.containsKey(filter) && !cityConstructions.containsBuildingOrEquivalent(filter)) - rejectionReasons.add( - // replace with civ-specific building for user - RejectionReason.RequiresBuildingInThisCity.apply { errorMessage = "Requires a [${civInfo.getEquivalentBuilding(filter)}] in this city" } - ) - } - - - UniqueType.RequiresBuildingInSomeCities -> { - val buildingName = unique.params[0] - val numberOfCitiesRequired = unique.params[1].toInt() - if (!civInfo.gameInfo.ruleSet.buildings.containsKey(buildingName)) continue - val numberOfCitiesWithBuilding = civInfo.cities.count { - it.cityConstructions.containsBuildingOrEquivalent(buildingName) - } - if (numberOfCitiesWithBuilding < numberOfCitiesRequired) { - val equivalentBuildingName = civInfo.getEquivalentBuilding(buildingName).name - rejectionReasons.add( - // replace with civ-specific building for user - RejectionReason.RequiresBuildingInAllCities.apply { - errorMessage = unique.text.fillPlaceholders(equivalentBuildingName, numberOfCitiesRequired.toString()) + - " ($numberOfCitiesWithBuilding/$numberOfCitiesRequired)" - } - ) - } - } - - UniqueType.RequiresBuildingInAllCities -> { - val filter = unique.params[0] - if (civInfo.gameInfo.ruleSet.buildings.containsKey(filter) - && civInfo.cities.any { - !it.isPuppet && !it.cityConstructions.containsBuildingOrEquivalent(unique.params[0]) - } - ) { - rejectionReasons.add( - // replace with civ-specific building for user - RejectionReason.RequiresBuildingInAllCities.apply { - errorMessage = "Requires a [${civInfo.getEquivalentBuilding(unique.params[0])}] in all cities" - } - ) - } - } - - UniqueType.HiddenBeforeAmountPolicies -> { - if (cityConstructions.cityInfo.civInfo.getCompletedPolicyBranchesCount() < unique.params[0].toInt()) - rejectionReasons.add(RejectionReason.MorePolicyBranches.apply { errorMessage = unique.text }) - } - UniqueType.HiddenWithoutVictoryType -> { - if (!civInfo.gameInfo.gameParameters.victoryTypes.contains(VictoryType.valueOf(unique.params[0]))) - rejectionReasons.add(RejectionReason.HiddenWithoutVictory.apply { errorMessage = unique.text }) - } - } - if (requiredBuilding != null && !cityConstructions.containsBuildingOrEquivalent(requiredBuilding!!)) { - if (!civInfo.gameInfo.ruleSet.buildings.containsKey(requiredBuilding!!)) { - rejectionReasons.add( - RejectionReason.InvalidRequiredBuilding - .apply { errorMessage = "Requires a [${requiredBuilding}] in this city, which doesn't seem to exist in this ruleset!" } - ) - } else { - rejectionReasons.add( - RejectionReason.RequiresBuildingInThisCity.apply { errorMessage = "Requires a [${civInfo.getEquivalentBuilding(requiredBuilding!!)}] in this city"} - ) - } + rejectionReasons.add(RejectionReason.RequiresBuildingInThisCity.apply { errorMessage = "Requires a [${civInfo.getEquivalentBuilding(requiredBuilding!!)}] in this city"}) } + val cannotBeBuiltWithUnique = uniqueObjects .firstOrNull { it.isOfType(UniqueType.CannotBeBuiltWith) } if (cannotBeBuiltWithUnique != null && cityConstructions.containsBuildingOrEquivalent(cannotBeBuiltWithUnique.params[0])) diff --git a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt index 34417905d3..39f879c330 100644 --- a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt @@ -351,25 +351,27 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { if (isWaterUnit() && !cityConstructions.cityInfo.isCoastal()) 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)) + rejectionReasons.add(RejectionReason.ShouldNotBeDisplayed) - for (unique in uniqueObjects.filter { it.type == UniqueType.OnlyAvailableWhen }){ - if (!unique.conditionalsApply(civInfo, cityConstructions.cityInfo)) - rejectionReasons.add(RejectionReason.ShouldNotBeDisplayed) - } - - for (unique in getMatchingUniques(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.NotDisplayedWithout.placeholderText -> { + 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) + rejectionReasons.add(RejectionReason.PopulationRequirement.apply { errorMessage = unique.text }) + } } + val civRejectionReasons = getRejectionReasons(civInfo) if (civRejectionReasons.isNotEmpty()) { rejectionReasons.addAll(civRejectionReasons) } - for (unique in getMatchingUniques(UniqueType.RequiresPopulation)) - if (unique.params[0].toInt() > cityConstructions.cityInfo.population.population) - rejectionReasons.add(RejectionReason.PopulationRequirement.apply { errorMessage = unique.text }) return rejectionReasons } @@ -377,9 +379,6 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { val rejectionReasons = RejectionReasons() val ruleSet = civInfo.gameInfo.ruleSet - if (hasUnique(UniqueType.Unbuildable)) - rejectionReasons.add(RejectionReason.Unbuildable) - if (requiredTech != null && !civInfo.tech.isResearched(requiredTech!!)) rejectionReasons.add(RejectionReason.RequiresTech.apply { this.errorMessage = "$requiredTech not researched" }) if (obsoleteTech != null && civInfo.tech.isResearched(obsoleteTech!!)) @@ -393,22 +392,35 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { if (!civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled && isNuclearWeapon()) rejectionReasons.add(RejectionReason.DisabledBySetting) - // This should be deprecated and replaced with the already-existing "only available when" unique, see above - for (unique in getMatchingUniques(UniqueType.UnlockedWith) + getMatchingUniques(UniqueType.Requires)) { - val filter = unique.params[0] - when { - ruleSet.technologies.contains(filter) -> - if (!civInfo.tech.isResearched(filter)) - rejectionReasons.add(RejectionReason.RequiresTech.apply { errorMessage = unique.text }) - ruleSet.policies.contains(filter) -> - if (!civInfo.policies.isAdopted(filter)) - rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text }) - ruleSet.eras.contains(filter) -> - if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber) - rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text }) - ruleSet.buildings.contains(filter) -> - if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) }) - rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.apply { errorMessage = unique.text }) + for (unique in uniqueObjects) { + when (unique.placeholderText) { + UniqueType.Unbuildable.placeholderText -> + 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 -> { + val filter = unique.params[0] + when { + ruleSet.technologies.contains(filter) -> + if (!civInfo.tech.isResearched(filter)) + rejectionReasons.add(RejectionReason.RequiresTech.apply { errorMessage = unique.text }) + ruleSet.policies.contains(filter) -> + if (!civInfo.policies.isAdopted(filter)) + rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text }) + ruleSet.eras.contains(filter) -> + if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber) + rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text }) + ruleSet.buildings.contains(filter) -> + if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) }) + rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.apply { errorMessage = unique.text }) + } + } + + UniqueType.FoundCity.placeholderText-> if (civInfo.isCityState() || civInfo.isOneCityChallenger()) + rejectionReasons.add(RejectionReason.NoSettlerForOneCityPlayers) + + UniqueType.MaxNumberBuildable.placeholderText -> if (civInfo.civConstructions.countConstructedObjects(this) >= unique.params[0].toInt()) + rejectionReasons.add(RejectionReason.MaxNumberBuildable) } } @@ -420,21 +432,10 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { }) } } - - if ((civInfo.isCityState() || civInfo.isOneCityChallenger()) && hasUnique(UniqueType.FoundCity) - ) { - rejectionReasons.add(RejectionReason.NoSettlerForOneCityPlayers) - } if (civInfo.getMatchingUniques(UniqueType.CannotBuildUnits).any { matchesFilter(it.params[0]) }) { rejectionReasons.add(RejectionReason.CannotBeBuilt) } - - for (unique in getMatchingUniques(UniqueType.MaxNumberBuildable)) { - if (civInfo.civConstructions.countConstructedObjects(this) >= unique.params[0].toInt()) - rejectionReasons.add(RejectionReason.MaxNumberBuildable) - } - return rejectionReasons }