mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-05 21:11:35 +07:00
Add "Unavailable" unique for all except beliefs, which are a mess right now
I think a lot of the 'hidden after' can be replaced by the Unavailable, but that's for later ;)
This commit is contained in:
parent
ab7f23835e
commit
c8bc15c800
@ -166,8 +166,9 @@ class PolicyManager : IsPartOfGameInfoSerialization {
|
||||
if (policy.policyBranchType == PolicyBranchType.BranchComplete) return false
|
||||
if (!getAdoptedPolicies().containsAll(policy.requires!!)) return false
|
||||
if (checkEra && civInfo.gameInfo.ruleset.eras[policy.branch.era]!!.eraNumber > civInfo.getEraNumber()) return false
|
||||
if (policy.uniqueObjects.filter { it.type == UniqueType.OnlyAvailable }
|
||||
if (policy.getMatchingUniques(UniqueType.OnlyAvailable, StateForConditionals.IgnoreConditionals)
|
||||
.any { !it.conditionalsApply(civInfo) }) return false
|
||||
if (policy.hasUnique(UniqueType.Unavailable)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -31,18 +31,8 @@ class RuinsManager(
|
||||
}
|
||||
|
||||
private fun getShuffledPossibleRewards(triggeringUnit: MapUnit): Iterable<RuinReward> {
|
||||
val stateForOnlyAvailableWhen = StateForConditionals(civInfo, unit = triggeringUnit, tile = triggeringUnit.getTile())
|
||||
val candidates =
|
||||
validRewards.asSequence()
|
||||
// Filter out what shouldn't be considered right now, before the random choice
|
||||
.filterNot { possibleReward ->
|
||||
possibleReward.name in lastChosenRewards
|
||||
|| civInfo.gameInfo.difficulty in possibleReward.excludedDifficulties
|
||||
|| possibleReward.hasUnique(UniqueType.HiddenWithoutReligion) && !civInfo.gameInfo.isReligionEnabled()
|
||||
|| possibleReward.hasUnique(UniqueType.HiddenAfterGreatProphet) && civInfo.religionManager.greatProphetsEarned() > 0
|
||||
|| possibleReward.getMatchingUniques(UniqueType.OnlyAvailable, StateForConditionals.IgnoreConditionals)
|
||||
.any { !it.conditionalsApply(stateForOnlyAvailableWhen) }
|
||||
}
|
||||
validRewards.asSequence().filter { isPossibleReward(it, triggeringUnit) }
|
||||
// This might be a dirty way to do this, but it works (we do have randomWeighted in CollectionExtensions, but below we
|
||||
// need to choose another when the first choice's TriggerActivations report failure, and that's simpler this way)
|
||||
// For each possible reward, this feeds (reward.weight) copies of this reward to the overall Sequence to implement 'weight'.
|
||||
@ -55,6 +45,18 @@ class RuinsManager(
|
||||
return candidates
|
||||
}
|
||||
|
||||
private fun isPossibleReward(ruinReward: RuinReward, unit: MapUnit): Boolean {
|
||||
if (ruinReward.name in lastChosenRewards) return false
|
||||
if (civInfo.gameInfo.difficulty in ruinReward.excludedDifficulties) return false
|
||||
val stateForConditionals = StateForConditionals(civInfo, unit = unit, tile = unit.getTile())
|
||||
if (ruinReward.hasUnique(UniqueType.HiddenWithoutReligion, stateForConditionals) && !civInfo.gameInfo.isReligionEnabled()) return false
|
||||
if (ruinReward.hasUnique(UniqueType.HiddenAfterGreatProphet, stateForConditionals) && civInfo.religionManager.greatProphetsEarned() > 0) return false
|
||||
if (ruinReward.hasUnique(UniqueType.Unavailable, stateForConditionals)) return false
|
||||
if (ruinReward.getMatchingUniques(UniqueType.OnlyAvailable, StateForConditionals.IgnoreConditionals)
|
||||
.any { !it.conditionalsApply(stateForConditionals) }) return false
|
||||
return true
|
||||
}
|
||||
|
||||
fun selectNextRuinsReward(triggeringUnit: MapUnit) {
|
||||
for (possibleReward in getShuffledPossibleRewards(triggeringUnit)) {
|
||||
var atLeastOneUniqueHadEffect = false
|
||||
|
@ -161,8 +161,9 @@ class TechManager : IsPartOfGameInfoSerialization {
|
||||
|
||||
fun canBeResearched(techName: String): Boolean {
|
||||
val tech = getRuleset().technologies[techName]!!
|
||||
if (tech.uniqueObjects.any { it.type == UniqueType.OnlyAvailable && !it.conditionalsApply(civInfo) })
|
||||
if (tech.getMatchingUniques(UniqueType.OnlyAvailable, StateForConditionals.IgnoreConditionals).any { !it.conditionalsApply(civInfo) })
|
||||
return false
|
||||
if (tech.hasUnique(UniqueType.Unavailable, StateForConditionals(civInfo))) return false
|
||||
|
||||
if (isResearched(tech.name) && !tech.isContinuallyResearchable())
|
||||
return false
|
||||
|
@ -113,14 +113,18 @@ class UnitPromotions : IsPartOfGameInfoSerialization {
|
||||
* Checks unit type, already acquired promotions, prerequisites and incompatibility uniques.
|
||||
*/
|
||||
fun getAvailablePromotions(): Sequence<Promotion> {
|
||||
return unit.civ.gameInfo.ruleset.unitPromotions.values
|
||||
.asSequence()
|
||||
.filter { unit.type.name in it.unitTypes && it.name !in promotions }
|
||||
.filter { it.prerequisites.isEmpty() || it.prerequisites.any { p->p in promotions } }
|
||||
.filter { promotion -> promotion.uniqueObjects
|
||||
.none { it.type == UniqueType.OnlyAvailable
|
||||
&& !it.conditionalsApply(StateForConditionals(unit.civ, unit = unit)) }
|
||||
}
|
||||
return unit.civ.gameInfo.ruleset.unitPromotions.values.asSequence().filter { isAvailable(it) }
|
||||
}
|
||||
|
||||
private fun isAvailable(promotion: Promotion):Boolean {
|
||||
if (promotion.name in promotions) return false
|
||||
if (unit.type.name !in promotion.unitTypes) return false
|
||||
if (promotion.prerequisites.isNotEmpty() && promotion.prerequisites.none { it in promotions }) return false
|
||||
val stateForConditionals = StateForConditionals(unit.civ, unit = unit)
|
||||
if (promotion.hasUnique(UniqueType.Unavailable, stateForConditionals)) return false
|
||||
if (promotion.getMatchingUniques(UniqueType.OnlyAvailable, StateForConditionals.IgnoreConditionals)
|
||||
.any { !it.conditionalsApply(stateForConditionals) }) return false
|
||||
return true
|
||||
}
|
||||
|
||||
fun clone(): UnitPromotions {
|
||||
|
@ -53,6 +53,9 @@ class TileInfoImprovementFunctions(val tile: Tile) {
|
||||
else if (improvement.hasUnique(UniqueType.Unbuildable, stateForConditionals))
|
||||
yield(ImprovementBuildingProblem.ConditionallyUnbuildable)
|
||||
|
||||
if (improvement.hasUnique(UniqueType.Unavailable, stateForConditionals))
|
||||
yield(ImprovementBuildingProblem.ConditionallyUnbuildable)
|
||||
|
||||
if (tile.getOwner() != civInfo && !improvement.hasUnique(UniqueType.CanBuildOutsideBorders, stateForConditionals)) {
|
||||
if (!improvement.hasUnique(UniqueType.CanBuildJustOutsideBorders, stateForConditionals))
|
||||
yield(ImprovementBuildingProblem.OutsideBorders)
|
||||
|
@ -255,6 +255,10 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
|
||||
if (!unique.conditionalsApply(civ, cityConstructions.city))
|
||||
yield(RejectionReasonType.ShouldNotBeDisplayed.toInstance())
|
||||
|
||||
UniqueType.Unavailable ->
|
||||
if (!unique.conditionalsApply(civ, cityConstructions.city))
|
||||
yield(RejectionReasonType.ShouldNotBeDisplayed.toInstance())
|
||||
|
||||
UniqueType.RequiresPopulation ->
|
||||
if (unique.params[0].toInt() > cityConstructions.city.population.population)
|
||||
yield(RejectionReasonType.PopulationRequirement.toInstance(unique.text))
|
||||
|
@ -93,7 +93,9 @@ open class Policy : RulesetObject() {
|
||||
fun isEnabledByPolicy(rulesetObject: IRulesetObject) =
|
||||
rulesetObject.getMatchingUniques(UniqueType.OnlyAvailable, StateForConditionals.IgnoreConditionals).any { it.conditionals.any {
|
||||
it.type == UniqueType.ConditionalAfterPolicyOrBelief && it.params[0] == name
|
||||
} }
|
||||
} } || rulesetObject.getMatchingUniques(UniqueType.Unavailable).any { it.conditionals.any {
|
||||
it.type == UniqueType.ConditionalBeforePolicyOrBelief && it.params[0] == name
|
||||
}}
|
||||
|
||||
val enabledBuildings = ruleset.buildings.values.filter { isEnabledByPolicy(it) }
|
||||
val enabledUnits = ruleset.units.values.filter { isEnabledByPolicy(it) }
|
||||
@ -110,6 +112,8 @@ open class Policy : RulesetObject() {
|
||||
fun isDisabledByPolicy(rulesetObject: IRulesetObject) =
|
||||
rulesetObject.getMatchingUniques(UniqueType.OnlyAvailable, StateForConditionals.IgnoreConditionals).any { it.conditionals.any {
|
||||
it.type == UniqueType.ConditionalBeforePolicyOrBelief && it.params[0] == name
|
||||
} } || rulesetObject.getMatchingUniques(UniqueType.Unavailable).any { it.conditionals.any {
|
||||
it.type == UniqueType.ConditionalAfterPolicyOrBelief && it.params[0] == name
|
||||
} }
|
||||
|
||||
|
||||
|
@ -54,8 +54,8 @@ interface IHasUniques : INamed {
|
||||
// Currently an OnlyAvailableWhen can have multiple conditionals, implicitly a conjunction.
|
||||
// Therefore, if any of its several conditionals is a ConditionalTech, then that tech is required.
|
||||
.flatMap{ it.conditionals }
|
||||
.filter{ it.isOfType(UniqueType.ConditionalTech) }
|
||||
.map{ it.params[0] }
|
||||
.filter{ it.type == UniqueType.ConditionalTech }
|
||||
.map { it.params[0] }
|
||||
}
|
||||
|
||||
fun legacyRequiredTechs(): Sequence<String> = sequenceOf()
|
||||
|
@ -263,8 +263,11 @@ enum class UniqueType(
|
||||
MaxNumberBuildable("Limited to [amount] per Civilization", UniqueTarget.Building, UniqueTarget.Unit),
|
||||
HiddenBeforeAmountPolicies("Hidden until [amount] social policy branches have been completed", UniqueTarget.Building, UniqueTarget.Unit),
|
||||
// Meant to be used together with conditionals, like "Only available <after adopting [policy]> <while the empire is happy>"
|
||||
/** A special unique, as it only activates when it has conditionals that *do not* apply */
|
||||
OnlyAvailable("Only available", UniqueTarget.Unit, UniqueTarget.Building, UniqueTarget.Improvement,
|
||||
UniqueTarget.Policy, UniqueTarget.Tech, UniqueTarget.Promotion, UniqueTarget.Ruins, UniqueTarget.FollowerBelief, UniqueTarget.FounderBelief),
|
||||
Unavailable("Unavailable", UniqueTarget.Unit, UniqueTarget.Building, UniqueTarget.Improvement,
|
||||
UniqueTarget.Policy, UniqueTarget.Tech, UniqueTarget.Promotion, UniqueTarget.Ruins),
|
||||
|
||||
ConvertFoodToProductionWhenConstructed("Excess Food converted to Production when under construction", UniqueTarget.Building, UniqueTarget.Unit),
|
||||
RequiresPopulation("Requires at least [amount] population", UniqueTarget.Building, UniqueTarget.Unit),
|
||||
|
@ -163,6 +163,9 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
if (!unique.conditionalsApply(civInfo, cityConstructions.city))
|
||||
yield(RejectionReasonType.ShouldNotBeDisplayed.toInstance())
|
||||
|
||||
for (unique in getMatchingUniques(UniqueType.Unavailable, StateForConditionals(civInfo, cityConstructions.city)))
|
||||
yield(RejectionReasonType.ShouldNotBeDisplayed.toInstance())
|
||||
|
||||
for (unique in getMatchingUniques(UniqueType.RequiresPopulation))
|
||||
if (unique.params[0].toInt() > cityConstructions.city.population.population)
|
||||
yield(RejectionReasonType.PopulationRequirement.toInstance(unique.text))
|
||||
|
Loading…
Reference in New Issue
Block a user