Wrap INonPerpetualConstruction.requiredTech into function (#10585)

* Update IConstruction.kt

* Update Building.kt

* Update BaseUnit.kt

* Update BaseUnit.kt

* Update Building.kt

* Update IConstruction.kt

* Update IConstruction.kt

* Update IConstruction.kt

* Update CityStateFunctions.kt

* Update Building.kt

* Update IConstruction.kt

* Update IConstruction.kt

* Update BaseUnit.kt

* Update RulesetValidator.kt

* Update TechnologyDescriptions.kt

* Update CityStateDiplomacyTable.kt

* Update CityStateDiplomacyTable.kt
This commit is contained in:
dHannasch 2023-11-25 23:48:09 -07:00 committed by GitHub
parent acfe8a3ad1
commit 09fdd8b8e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 22 deletions

View File

@ -51,7 +51,7 @@ class CityStateFunctions(val civInfo: Civilization) {
// Unique unit for militaristic city-states
if (uniqueTypes.contains(UniqueType.CityStateMilitaryUnits)) {
val possibleUnits = ruleset.units.values.filter { it.requiredTech != null
val possibleUnits = ruleset.units.values.filter { it.requiredTechs().any()
&& ruleset.eras[ruleset.technologies[it.requiredTech!!]!!.era()]!!.eraNumber > ruleset.eras[startingEra]!!.eraNumber // Not from the start era or before
&& it.uniqueTo != null && it.uniqueTo in unusedMajorCivs // Must be from a major civ not in the game
&& ruleset.unitTypes[it.unitType]!!.isLandUnit() && ( it.strength > 0 || it.rangedStrength > 0 ) } // Must be a land military unit

View File

@ -22,6 +22,7 @@ import com.unciv.ui.objectdescriptions.BuildingDescriptions
class Building : RulesetStatsObject(), INonPerpetualConstruction {
@Deprecated("The functionality provided by the requiredTech field is provided by the OnlyAvailableWhen unique.")
override var requiredTech: String? = null
override var cost: Int = -1
@ -360,8 +361,9 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
if (civ.cache.uniqueBuildings.any { it.replaces == name })
yield(RejectionReasonType.ReplacedByOurUnique.toInstance())
if (requiredTech != null && !civ.tech.isResearched(requiredTech!!))
yield(RejectionReasonType.RequiresTech.toInstance("$requiredTech not researched!"))
for (requiredTech: String in requiredTechs())
if (!civ.tech.isResearched(requiredTech))
yield(RejectionReasonType.RequiresTech.toInstance("$requiredTech not researched!"))
// Regular wonders
if (isWonder) {

View File

@ -29,8 +29,13 @@ interface IConstruction : INamed {
interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques {
var cost: Int
val hurryCostModifier: Int
// Future development should not increase the role of requiredTech, and should reduce it when possible.
// https://yairm210.github.io/Unciv/Developers/Translations%2C-mods%2C-and-modding-freedom-in-Open-Source#filters
@Deprecated("The functionality provided by the requiredTech field is provided by the OnlyAvailableWhen unique.")
var requiredTech: String?
fun requiredTechs(): Sequence<String> = if (requiredTech == null) sequenceOf() else sequenceOf(requiredTech!!)
fun getProductionCost(civInfo: Civilization): Int
fun getStatBuyCost(city: City, stat: Stat): Int?
fun getRejectionReasons(cityConstructions: CityConstructions): Sequence<RejectionReason>

View File

@ -39,6 +39,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
var unitType: String = ""
val type by lazy { ruleset.unitTypes[unitType]!! }
@Deprecated("The functionality provided by the requiredTech field is provided by the OnlyAvailableWhen unique.")
override var requiredTech: String? = null
var requiredResource: String? = null
@ -155,8 +156,9 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
city: City? = null,
additionalResources: Counter<String> = Counter.ZERO
): Sequence<RejectionReason> = sequence {
if (requiredTech != null && !civ.tech.isResearched(requiredTech!!))
yield(RejectionReasonType.RequiresTech.toInstance("$requiredTech not researched"))
for (requiredTech: String in requiredTechs())
if (!civ.tech.isResearched(requiredTech))
yield(RejectionReasonType.RequiresTech.toInstance("$requiredTech not researched"))
if (obsoleteTech != null && civ.tech.isResearched(obsoleteTech!!))
yield(RejectionReasonType.Obsoleted.toInstance("Obsolete by $obsoleteTech"))
@ -289,7 +291,8 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
else -> {
if (type.matchesFilter(filter)) return true
if (requiredTech != null && ruleset.technologies[requiredTech]?.matchesFilter(filter) == true) return true
for (requiredTech: String in requiredTechs())
if (ruleset.technologies[requiredTech]?.matchesFilter(filter) == true) return true
if (
// Uniques using these kinds of filters should be deprecated and replaced with adjective-only parameters
filter.endsWith(" units")

View File

@ -433,8 +433,9 @@ class RulesetValidator(val ruleset: Ruleset) {
for (building in ruleset.buildings.values) {
addBuildingErrorRulesetInvariant(building, lines)
if (building.requiredTech != null && !ruleset.technologies.containsKey(building.requiredTech!!))
lines += "${building.name} requires tech ${building.requiredTech} which does not exist!"
for (requiredTech: String in building.requiredTechs())
if (!ruleset.technologies.containsKey(requiredTech))
lines += "${building.name} requires tech ${requiredTech} which does not exist!"
for (specialistName in building.specialistSlots.keys)
if (!ruleset.specialists.containsKey(specialistName))
lines += "${building.name} provides specialist $specialistName which does not exist!"
@ -575,7 +576,7 @@ class RulesetValidator(val ruleset: Ruleset) {
}
private fun addBuildingErrorRulesetInvariant(building: Building, lines: RulesetErrorList) {
if (building.requiredTech == null && building.cost == -1 && !building.hasUnique(
if (building.requiredTechs().none() && building.cost == -1 && !building.hasUnique(
UniqueType.Unbuildable
)
)
@ -653,8 +654,9 @@ class RulesetValidator(val ruleset: Ruleset) {
/** Collects all RulesetSpecific checks for a BaseUnit */
private fun checkUnitRulesetSpecific(unit: BaseUnit, lines: RulesetErrorList) {
if (unit.requiredTech != null && !ruleset.technologies.containsKey(unit.requiredTech!!))
lines += "${unit.name} requires tech ${unit.requiredTech} which does not exist!"
for (requiredTech: String in unit.requiredTechs())
if (!ruleset.technologies.containsKey(requiredTech))
lines += "${unit.name} requires tech ${requiredTech} which does not exist!"
if (unit.obsoleteTech != null && !ruleset.technologies.containsKey(unit.obsoleteTech!!))
lines += "${unit.name} obsoletes at tech ${unit.obsoleteTech} which does not exist!"
if (unit.upgradesTo != null && !ruleset.units.containsKey(unit.upgradesTo!!))
@ -664,14 +666,15 @@ class RulesetValidator(val ruleset: Ruleset) {
if (unit.upgradesTo!=null && ruleset.units.containsKey(unit.upgradesTo!!)
&& unit.obsoleteTech!=null && ruleset.technologies.containsKey(unit.obsoleteTech!!)) {
val upgradedUnit = ruleset.units[unit.upgradesTo!!]!!
if (upgradedUnit.requiredTech != null && upgradedUnit.requiredTech != unit.obsoleteTech
&& !getPrereqTree(unit.obsoleteTech!!).contains(upgradedUnit.requiredTech)
)
lines.add(
"${unit.name} obsoletes at tech ${unit.obsoleteTech}," +
" and therefore ${upgradedUnit.requiredTech} for its upgrade ${upgradedUnit.name} may not yet be researched!",
RulesetErrorSeverity.Warning
for (requiredTech: String in upgradedUnit.requiredTechs())
if (requiredTech != unit.obsoleteTech
&& !getPrereqTree(unit.obsoleteTech!!).contains(requiredTech)
)
lines.add(
"${unit.name} obsoletes at tech ${unit.obsoleteTech}," +
" and therefore ${requiredTech} for its upgrade ${upgradedUnit.name} may not yet be researched!",
RulesetErrorSeverity.Warning
)
}
for (resource in unit.getResourceRequirementsPerTurn(StateForConditionals.IgnoreConditionals).keys)

View File

@ -272,7 +272,7 @@ object TechnologyDescriptions {
*/
// Used for Civilopedia, Alert and Picker, so if any of these decide to ignore the "Will not be displayed in Civilopedia" unique this needs refactoring
private fun getEnabledBuildings(techName: String, ruleset: Ruleset, civInfo: Civilization?) =
getFilteredBuildings(ruleset, civInfo) { it.requiredTech == techName }
getFilteredBuildings(ruleset, civInfo) { it.requiredTechs().contains(techName) }
/**
* Returns a Sequence of [RulesetStatsObject]s obsoleted by this Technology, filtered for [civInfo]'s uniques,
@ -334,7 +334,7 @@ object TechnologyDescriptions {
val (nuclearWeaponsEnabled, religionEnabled) = getNukeAndReligionSwitches(civInfo)
return ruleset.units.values.asSequence()
.filter {
it.requiredTech == techName
it.requiredTechs().contains(techName)
&& (it.uniqueTo == civInfo?.civName || it.uniqueTo == null && civInfo?.getEquivalentUnit(it) == it)
&& (nuclearWeaponsEnabled || !it.isNuclearWeapon())
&& (religionEnabled || !it.hasUnique(UniqueType.HiddenWithoutReligion))

View File

@ -196,8 +196,10 @@ class CityStateDiplomacyTable(private val diplomacyScreen: DiplomacyScreen) {
if (otherCiv.cityStateUniqueUnit != null) {
val unitName = otherCiv.cityStateUniqueUnit
val techName = viewingCiv.gameInfo.ruleset.units[otherCiv.cityStateUniqueUnit]!!.requiredTech
diplomacyTable.add("[${otherCiv.civName}] is able to provide [${unitName}] once [${techName}] is researched.".toLabel(fontSize = Constants.defaultFontSize)).row()
val techNames = viewingCiv.gameInfo.ruleset.units[otherCiv.cityStateUniqueUnit]!!.requiredTechs()
val techAndTech = techNames.joinToString(" and ")
val isOrAre = if (techNames.count() == 1) "is" else "are"
diplomacyTable.add("[${otherCiv.civName}] is able to provide [${unitName}] once [${techAndTech}] [${isOrAre}] researched.".toLabel(fontSize = Constants.defaultFontSize)).row()
}
return diplomacyTable