diff --git a/android/assets/Flags.atlas b/android/assets/Flags.atlas index c85549d6b4..73396a2217 100644 --- a/android/assets/Flags.atlas +++ b/android/assets/Flags.atlas @@ -39,178 +39,185 @@ FlagIcons/English orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Finnish +FlagIcons/Filipino rotate: false xy: 276, 276 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/French +FlagIcons/Finnish rotate: false xy: 140, 4 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/German +FlagIcons/French rotate: false xy: 276, 140 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Greek +FlagIcons/German rotate: false xy: 412, 276 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Hungarian +FlagIcons/Greek rotate: false xy: 276, 4 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Indonesian +FlagIcons/Hungarian rotate: false xy: 412, 140 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Italian +FlagIcons/Indonesian rotate: false xy: 548, 276 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Japanese +FlagIcons/Italian rotate: false xy: 412, 4 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Korean +FlagIcons/Japanese rotate: false xy: 548, 140 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Lithuanian +FlagIcons/Korean rotate: false xy: 684, 276 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Malay +FlagIcons/Lithuanian rotate: false xy: 548, 4 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 +FlagIcons/Malay + rotate: false + xy: 684, 140 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 FlagIcons/Persian_(Pinglish-DIN) - rotate: false - xy: 684, 140 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -FlagIcons/Persian_(Pinglish-UN) - rotate: false - xy: 684, 140 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -FlagIcons/Polish rotate: false xy: 820, 276 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Portuguese +FlagIcons/Persian_(Pinglish-UN) + rotate: false + xy: 820, 276 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +FlagIcons/Polish rotate: false xy: 684, 4 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Romanian +FlagIcons/Portuguese rotate: false xy: 820, 140 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Russian +FlagIcons/Romanian rotate: false xy: 956, 276 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Simplified_Chinese +FlagIcons/Russian rotate: false xy: 820, 4 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Spanish +FlagIcons/Simplified_Chinese rotate: false xy: 956, 140 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Swedish +FlagIcons/Spanish rotate: false xy: 1092, 276 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Thai +FlagIcons/Swedish rotate: false xy: 956, 4 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Traditional_Chinese +FlagIcons/Thai rotate: false xy: 1092, 140 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Turkish +FlagIcons/Traditional_Chinese rotate: false xy: 1228, 276 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Ukrainian +FlagIcons/Turkish rotate: false xy: 1092, 4 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -FlagIcons/Vietnamese +FlagIcons/Ukrainian rotate: false xy: 1228, 140 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 +FlagIcons/Vietnamese + rotate: false + xy: 1364, 276 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 diff --git a/android/assets/Flags.png b/android/assets/Flags.png index 2a3ae9ec9e..3f40ca568e 100644 Binary files a/android/assets/Flags.png and b/android/assets/Flags.png differ diff --git a/core/src/com/unciv/logic/city/CityConstructions.kt b/core/src/com/unciv/logic/city/CityConstructions.kt index 12c70e6b2b..10721574b1 100644 --- a/core/src/com/unciv/logic/city/CityConstructions.kt +++ b/core/src/com/unciv/logic/city/CityConstructions.kt @@ -378,7 +378,7 @@ class CityConstructions { } } else if (construction is BaseUnit) { // Production put into upgradable units gets put into upgraded version - if (rejectionReasons.all { it == RejectionReason.Obsoleted } && construction.upgradesTo != null) { + if (rejectionReasons.all { it.rejectionReason == RejectionReason.Obsoleted } && construction.upgradesTo != null) { inProgressConstructions[construction.upgradesTo!!] = (inProgressConstructions[construction.upgradesTo!!] ?: 0) + workDone } diff --git a/core/src/com/unciv/logic/city/IConstruction.kt b/core/src/com/unciv/logic/city/IConstruction.kt index bb1f5f57cd..fc6bc7695c 100644 --- a/core/src/com/unciv/logic/city/IConstruction.kt +++ b/core/src/com/unciv/logic/city/IConstruction.kt @@ -44,7 +44,7 @@ interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques { /** Checks if the construction should be purchasable, not whether it can be bought with a stat at all */ fun isPurchasable(cityConstructions: CityConstructions): Boolean { val rejectionReasons = getRejectionReasons(cityConstructions) - return rejectionReasons.all { it == RejectionReason.Unbuildable } + return rejectionReasons.all { it.rejectionReason == RejectionReason.Unbuildable } } fun canBePurchasedWithAnyStat(cityInfo: CityInfo): Boolean { @@ -82,18 +82,22 @@ interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques { -class RejectionReasons: HashSet() { +class RejectionReasons: HashSet() { + + fun add(rejectionReason: RejectionReason) = add(RejectionReasonInstance(rejectionReason)) + + fun contains(rejectionReason: RejectionReason) = any { it.rejectionReason == rejectionReason } - fun filterTechPolicyEraWonderRequirements(): HashSet { - return filterNot { it in techPolicyEraWonderRequirements }.toHashSet() + fun filterTechPolicyEraWonderRequirements(): List { + return filterNot { it.rejectionReason in techPolicyEraWonderRequirements } } fun hasAReasonToBeRemovedFromQueue(): Boolean { - return any { it in reasonsToDefinitivelyRemoveFromQueue } + return any { it.rejectionReason in reasonsToDefinitivelyRemoveFromQueue } } fun getMostImportantRejectionReason(): String? { - return orderOfErrorMessages.firstOrNull { it in this }?.errorMessage + return orderOfErrorMessages.firstOrNull { contains(it) }?.errorMessage } // Used for constant variables in the functions above @@ -127,9 +131,7 @@ class RejectionReasons: HashSet() { } -// TODO: Put a wrapper class around this containing the errorMessage, so that we don't -// change the value of a enum constant sometimes. -enum class RejectionReason(val shouldShow: Boolean, var errorMessage: String) { +enum class RejectionReason(val shouldShow: Boolean, val errorMessage: String) { AlreadyBuilt(false, "Building already built in this city"), Unbuildable(false, "Unbuildable"), CanOnlyBePurchased(true, "Can only be purchased"), @@ -178,9 +180,18 @@ enum class RejectionReason(val shouldShow: Boolean, var errorMessage: String) { PopulationRequirement(true, "Requires more population"), - NoSettlerForOneCityPlayers(false, "No settlers for city-states or one-city challengers"), + NoSettlerForOneCityPlayers(false, "No settlers for city-states or one-city challengers"); + + fun toInstance(errorMessage: String = this.errorMessage, + shouldShow: Boolean = this.shouldShow): RejectionReasonInstance { + return RejectionReasonInstance(this, errorMessage, shouldShow) + } } +data class RejectionReasonInstance(val rejectionReason:RejectionReason, + val errorMessage: String = rejectionReason.errorMessage, + val shouldShow: Boolean = rejectionReason.shouldShow) + open class PerpetualConstruction(override var name: String, val description: String) : IConstruction { diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index ac8cd611e6..11dda619d1 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -434,7 +434,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { return rejectionReasons.none { !it.shouldShow } || ( canBePurchasedWithAnyStat(cityConstructions.cityInfo) - && rejectionReasons.all { it == RejectionReason.Unbuildable } + && rejectionReasons.all { it.rejectionReason == RejectionReason.Unbuildable } ) } @@ -471,25 +471,25 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { UniqueType.MustBeOn -> if (!cityCenter.matchesTerrainFilter(unique.params[0], civInfo)) - rejectionReasons.add(RejectionReason.MustBeOnTile.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.MustBeOnTile.toInstance(unique.text)) UniqueType.MustNotBeOn -> if (cityCenter.matchesTerrainFilter(unique.params[0], civInfo)) - rejectionReasons.add(RejectionReason.MustNotBeOnTile.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.MustNotBeOnTile.toInstance(unique.text)) UniqueType.MustBeNextTo -> if (!cityCenter.isAdjacentTo(unique.params[0])) - rejectionReasons.add(RejectionReason.MustBeNextToTile.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.MustBeNextToTile.toInstance(unique.text)) UniqueType.MustNotBeNextTo -> if (cityCenter.getTilesInDistance(1).any { it.matchesFilter(unique.params[0], civInfo) }) - rejectionReasons.add(RejectionReason.MustNotBeNextToTile.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.MustNotBeNextToTile.toInstance(unique.text)) 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 }) + rejectionReasons.add(RejectionReason.MustOwnTile.toInstance(unique.text)) // Deprecated since 3.16.11 UniqueType.CanOnlyBeBuiltInAnnexedCities -> @@ -497,16 +497,16 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { cityConstructions.cityInfo.isPuppet || cityConstructions.cityInfo.civInfo.civName == cityConstructions.cityInfo.foundingCiv ) - rejectionReasons.add(RejectionReason.CanOnlyBeBuiltInSpecificCities.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.CanOnlyBeBuiltInSpecificCities.toInstance(unique.text)) // UniqueType.CanOnlyBeBuiltInCertainCities -> if (!cityConstructions.cityInfo.matchesFilter(unique.params[0])) - rejectionReasons.add(RejectionReason.CanOnlyBeBuiltInSpecificCities.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.CanOnlyBeBuiltInSpecificCities.toInstance(unique.text)) UniqueType.ObsoleteWith -> if (civInfo.tech.isResearched(unique.params[0])) - rejectionReasons.add(RejectionReason.Obsoleted.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.Obsoleted.toInstance(unique.text)) UniqueType.HiddenWithoutReligion -> if (!civInfo.gameInfo.isReligionEnabled()) @@ -522,22 +522,22 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { when { ruleSet.technologies.contains(filter) -> if (!civInfo.tech.isResearched(filter)) - rejectionReasons.add(RejectionReason.RequiresTech.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.RequiresTech.toInstance(unique.text)) ruleSet.policies.contains(filter) -> if (!civInfo.policies.isAdopted(filter)) - rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.RequiresPolicy.toInstance(unique.text)) ruleSet.eras.contains(filter) -> if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber) - rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.UnlockedWithEra.toInstance(unique.text)) ruleSet.buildings.contains(filter) -> if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) }) - rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.toInstance(unique.text)) } } UniqueType.SpaceshipPart -> { if (!civInfo.hasUnique(UniqueType.EnablesConstructionOfSpaceshipParts)) - rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.apply { errorMessage = "Apollo project not built!" }) + rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.toInstance("Apollo project not built!")) if (civInfo.victoryManager.unconstructedSpaceshipParts()[name] == 0) rejectionReasons.add(RejectionReason.ReachedBuildCap) } @@ -547,7 +547,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { 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" } + RejectionReason.RequiresBuildingInThisCity.toInstance("Requires a [${civInfo.getEquivalentBuilding(filter)}] in this city") ) } @@ -561,11 +561,10 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { 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()) + + RejectionReason.RequiresBuildingInAllCities.toInstance( + unique.text.fillPlaceholders(equivalentBuildingName, numberOfCitiesRequired.toString()) + " ($numberOfCitiesWithBuilding/$numberOfCitiesRequired)" - } - ) + ) ) } } @@ -578,33 +577,33 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { ) { rejectionReasons.add( // replace with civ-specific building for user - RejectionReason.RequiresBuildingInAllCities.apply { - errorMessage = "Requires a [${civInfo.getEquivalentBuilding(unique.params[0])}] in all cities" - } + RejectionReason.RequiresBuildingInAllCities.toInstance( + "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 }) + rejectionReasons.add(RejectionReason.MorePolicyBranches.toInstance(unique.text)) } UniqueType.HiddenWithoutVictoryType -> { if (!civInfo.gameInfo.gameParameters.victoryTypes.contains(VictoryType.valueOf(unique.params[0]))) - rejectionReasons.add(RejectionReason.HiddenWithoutVictory.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.HiddenWithoutVictory.toInstance(unique.text)) } } } if (uniqueTo != null && uniqueTo != civInfo.civName) - rejectionReasons.add(RejectionReason.UniqueToOtherNation.apply { errorMessage = "Unique to $uniqueTo"}) + rejectionReasons.add(RejectionReason.UniqueToOtherNation.toInstance("Unique to $uniqueTo")) if (civInfo.gameInfo.ruleSet.buildings.values.any { it.uniqueTo == civInfo.civName && it.replaces == name }) rejectionReasons.add(RejectionReason.ReplacedByOurUnique) if (requiredTech != null && !civInfo.tech.isResearched(requiredTech!!)) - rejectionReasons.add(RejectionReason.RequiresTech.apply { "$requiredTech not researched!"}) + rejectionReasons.add(RejectionReason.RequiresTech.toInstance("$requiredTech not researched!")) // Regular wonders if (isWonder) { @@ -635,19 +634,17 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { } if (requiredBuilding != null && !cityConstructions.containsBuildingOrEquivalent(requiredBuilding!!)) { - rejectionReasons.add(RejectionReason.RequiresBuildingInThisCity.apply { errorMessage = "Requires a [${civInfo.getEquivalentBuilding(requiredBuilding!!)}] in this city"}) + rejectionReasons.add(RejectionReason.RequiresBuildingInThisCity.toInstance("Requires a [${civInfo.getEquivalentBuilding(requiredBuilding!!)}] in this city")) } val cannotBeBuiltWithUnique = uniqueObjects .firstOrNull { it.isOfType(UniqueType.CannotBeBuiltWith) } if (cannotBeBuiltWithUnique != null && cityConstructions.containsBuildingOrEquivalent(cannotBeBuiltWithUnique.params[0])) - rejectionReasons.add(RejectionReason.CannotBeBuiltWith.apply { errorMessage = cannotBeBuiltWithUnique.text }) + rejectionReasons.add(RejectionReason.CannotBeBuiltWith.toInstance(cannotBeBuiltWithUnique.text)) for ((resource, amount) in getResourceRequirements()) if (civInfo.getCivResourcesByName()[resource]!! < amount) { - rejectionReasons.add(RejectionReason.ConsumesResources.apply { - errorMessage = "Consumes [$amount] [$resource]" - }) + rejectionReasons.add(RejectionReason.ConsumesResources.toInstance("Consumes [$amount] [$resource]" )) } if (requiredNearbyImprovedResources != null) { @@ -661,7 +658,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { ) } if (!containsResourceWithImprovement) - rejectionReasons.add(RejectionReason.RequiresNearbyResource.apply { errorMessage = "Nearby $requiredNearbyImprovedResources required" }) + rejectionReasons.add(RejectionReason.RequiresNearbyResource.toInstance("Nearby $requiredNearbyImprovedResources required")) } return rejectionReasons diff --git a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt index d0f147d8ad..dbe2fab86d 100644 --- a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt @@ -342,7 +342,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { return rejectionReasons.none { !it.shouldShow } || ( canBePurchasedWithAnyStat(cityConstructions.cityInfo) - && rejectionReasons.all { it == RejectionReason.Unbuildable } + && rejectionReasons.all { it.rejectionReason == RejectionReason.Unbuildable } ) } @@ -365,7 +365,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { } UniqueType.RequiresPopulation -> if (unique.params[0].toInt() > cityConstructions.cityInfo.population.population) - rejectionReasons.add(RejectionReason.PopulationRequirement.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.PopulationRequirement.toInstance(unique.text)) } } @@ -381,14 +381,14 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { val ruleSet = civInfo.gameInfo.ruleSet if (requiredTech != null && !civInfo.tech.isResearched(requiredTech!!)) - rejectionReasons.add(RejectionReason.RequiresTech.apply { this.errorMessage = "$requiredTech not researched" }) + rejectionReasons.add(RejectionReason.RequiresTech.toInstance("$requiredTech not researched")) if (obsoleteTech != null && civInfo.tech.isResearched(obsoleteTech!!)) - rejectionReasons.add(RejectionReason.Obsoleted.apply { this.errorMessage = "Obsolete by $obsoleteTech" }) + rejectionReasons.add(RejectionReason.Obsoleted.toInstance("Obsolete by $obsoleteTech")) if (uniqueTo != null && uniqueTo != civInfo.civName) - rejectionReasons.add(RejectionReason.UniqueToOtherNation.apply { this.errorMessage = "Unique to $uniqueTo" }) + rejectionReasons.add(RejectionReason.UniqueToOtherNation.toInstance("Unique to $uniqueTo")) if (ruleSet.units.values.any { it.uniqueTo == civInfo.civName && it.replaces == name }) - rejectionReasons.add(RejectionReason.ReplacedByOurUnique.apply { this.errorMessage = "Our unique unit replaces this" }) + rejectionReasons.add(RejectionReason.ReplacedByOurUnique.toInstance("Our unique unit replaces this")) if (!civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled && isNuclearWeapon()) rejectionReasons.add(RejectionReason.DisabledBySetting) @@ -404,16 +404,16 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { when { ruleSet.technologies.contains(filter) -> if (!civInfo.tech.isResearched(filter)) - rejectionReasons.add(RejectionReason.RequiresTech.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.RequiresTech.toInstance(unique.text)) ruleSet.policies.contains(filter) -> if (!civInfo.policies.isAdopted(filter)) - rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.RequiresPolicy.toInstance(unique.text)) ruleSet.eras.contains(filter) -> if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber) - rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.UnlockedWithEra.toInstance(unique.text)) ruleSet.buildings.contains(filter) -> if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) }) - rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.apply { errorMessage = unique.text }) + rejectionReasons.add(RejectionReason.RequiresBuildingInSomeCity.toInstance(unique.text)) } } @@ -428,15 +428,19 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { if (!civInfo.isBarbarian()) { // Barbarians don't need resources for ((resource, amount) in getResourceRequirements()) if (civInfo.getCivResourcesByName()[resource]!! < amount) { - rejectionReasons.add(RejectionReason.ConsumesResources.apply { - errorMessage = "Consumes [$amount] [$resource]" - }) + rejectionReasons.add(RejectionReason.ConsumesResources.toInstance("Consumes [$amount] [$resource]")) } } - if (civInfo.getMatchingUniques(UniqueType.CannotBuildUnits).any { matchesFilter(it.params[0]) }) { - rejectionReasons.add(RejectionReason.CannotBeBuilt) - } + for (unique in civInfo.getMatchingUniques(UniqueType.CannotBuildUnits)) + if (this.matchesFilter(unique.params[0])) { + val rejectionReason = RejectionReason.CannotBeBuilt.toInstance() + if (unique.conditionals.any { it.type == UniqueType.ConditionalBelowHappiness }){ + rejectionReasons.add(RejectionReason.CannotBeBuilt.toInstance(unique.text, true)) + } + else rejectionReasons.add(RejectionReason.CannotBeBuilt) + } + return rejectionReasons } diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt index 715574e375..e4fcb5f7df 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt @@ -166,7 +166,7 @@ object UnitActions { * (no movement left, too close to another city). */ fun getFoundCityAction(unit: MapUnit, tile: TileInfo): UnitAction? { - if (!(unit.hasUnique(UniqueType.FoundCity)) + if (!unit.hasUnique(UniqueType.FoundCity) || tile.isWater || tile.isImpassible()) return null // Spain should still be able to build Conquistadors in a one city challenge - but can't settle them if (unit.civInfo.isOneCityChallenger() && unit.civInfo.hasEverOwnedOriginalCapital == true) return null