mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 07:17:50 +07:00
Typed all remaining uniques using CityInfo.GetMatchingUniques and removed that function (#6071)
* Typed all remaining uniques using CityInfo.GetMatchingUniques and removed that function * Fixed two NullPtrExceptions * Fixed syntax
This commit is contained in:
@ -123,7 +123,7 @@
|
||||
{
|
||||
"name": "Asceticism",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+1 Happiness] from every [Shrine] in cities where this religion has at least [3] followers"]
|
||||
"uniques": ["[+1 Happiness] from every [Shrine] <in cities where this religion has at least [3] followers>"]
|
||||
},
|
||||
{
|
||||
"name": "Cathedrals",
|
||||
@ -133,7 +133,7 @@
|
||||
{
|
||||
"name": "Choral Music",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+2 Culture] from every [Temple] in cities where this religion has at least [5] followers"]
|
||||
"uniques": ["[+2 Culture] from every [Temple] <in cities where this religion has at least [5] followers>"]
|
||||
},
|
||||
{
|
||||
"name": "Divine inspiration",
|
||||
@ -158,7 +158,7 @@
|
||||
{
|
||||
"name": "Liturgical Drama",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+1 Faith] from every [Amphitheatre] in cities where this religion has at least [3] followers"]
|
||||
"uniques": ["[+1 Faith] from every [Amphitheatre] <in cities where this religion has at least [3] followers>"]
|
||||
},
|
||||
{
|
||||
"name": "Monasteries",
|
||||
@ -188,7 +188,7 @@
|
||||
{
|
||||
"name": "Religious Center",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+2 Happiness] from every [Temple] in cities where this religion has at least [5] followers"]
|
||||
"uniques": ["[+2 Happiness] from every [Temple] <in cities where this religion has at least [5] followers>"]
|
||||
},
|
||||
{
|
||||
"name": "Religious Community",
|
||||
@ -285,12 +285,12 @@
|
||||
{
|
||||
"name": "Religious Texts",
|
||||
"type": "Enhancer",
|
||||
"uniques": ["[+34]% Natural religion spread [in all cities]", "[+34]% Natural religion spread [in all cities] with [Printing Press]"]
|
||||
"uniques": ["[+34]% Natural religion spread [in all cities]", "[+34]% Natural religion spread [in all cities] <after discovering [Printing Press]>"]
|
||||
},
|
||||
{
|
||||
"name": "Religious Unity",
|
||||
"type": "Enhancer",
|
||||
"uniques": ["[+100]% Natural religion spread to [in City-State cities]"]
|
||||
"uniques": ["[+100]% Natural religion spread [in City-State cities]"]
|
||||
},
|
||||
{
|
||||
"name": "Reliquary",
|
||||
|
@ -222,7 +222,7 @@
|
||||
"innerColor": [238,201,9],
|
||||
"favoredReligion": "Christianity",
|
||||
"uniqueName": "The Glory of Rome",
|
||||
"uniques": ["+25% Production towards any buildings that already exist in the Capital"],
|
||||
"uniques": ["[+25]% Production towards any buildings that already exist in the Capital"],
|
||||
"cities": ["Rome","Antium","Cumae","Neapolis","Ravenna","Arretium","Mediolanum","Arpinum","Circei","Setia",
|
||||
"Satricum","Ardea","Ostia","Velitrae","Viroconium","Tarentum","Brundisium","Caesaraugusta","Caesarea","Palmyra",
|
||||
"Signia","Aquileia","Clusium","Sutrium","Cremona","Placentia","Hispalis","Artaxata","Aurelianorum","Nicopolis",
|
||||
|
@ -214,7 +214,7 @@
|
||||
"outerColor": [ 53,0,87],
|
||||
"innerColor": [238,201,9],
|
||||
"uniqueName": "The Glory of Rome",
|
||||
"uniques": ["+25% Production towards any buildings that already exist in the Capital"],
|
||||
"uniques": ["[+25]% Production towards any buildings that already exist in the Capital"],
|
||||
"cities": ["Rome","Antium","Cumae","Neapolis","Ravenna","Arretium","Mediolanum","Arpinum","Circei","Setia",
|
||||
"Satricum","Ardea","Ostia","Velitrae","Viroconium","Tarentum","Brundisium","Caesaraugusta","Caesarea","Palmyra",
|
||||
"Signia","Aquileia","Clusium","Sutrium","Cremona","Placentia","Hispalis","Artaxata","Aurelianorum","Nicopolis",
|
||||
|
@ -67,7 +67,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
addCultureBuildingChoice()
|
||||
addSpaceshipPartChoice()
|
||||
addOtherBuildingChoice()
|
||||
addReligousUnit()
|
||||
addReligiousUnit()
|
||||
|
||||
if (!cityInfo.isPuppet) {
|
||||
addWondersChoice()
|
||||
@ -342,9 +342,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
}
|
||||
}
|
||||
|
||||
private fun addReligousUnit(){
|
||||
|
||||
|
||||
private fun addReligiousUnit() {
|
||||
// these 4 if conditions are used to determine if an AI should buy units to spread religion, or spend faith to buy things like new military units or new buildings.
|
||||
// currently this AI can only buy inquisitors and missionaries with faith
|
||||
// this system will have to be reengineered to support buying other stuff with faith
|
||||
|
@ -734,11 +734,11 @@ object Battle {
|
||||
else -> 1f
|
||||
}
|
||||
// Deprecated since 3.16.11
|
||||
for (unique in targetedCity.getLocalMatchingUniques("Population loss from nuclear attacks -[]%")) {
|
||||
for (unique in targetedCity.getLocalMatchingUniques(UniqueType.PopulationLossFromNukesDeprecated)) {
|
||||
populationLoss *= 1 - unique.params[0].toFloat() / 100f
|
||||
}
|
||||
//
|
||||
for (unique in targetedCity.getMatchingUniques("Population loss from nuclear attacks []% []")) {
|
||||
for (unique in targetedCity.getMatchingUniques(UniqueType.PopulationLossFromNukes)) {
|
||||
if (!targetedCity.matchesFilter(unique.params[1])) continue
|
||||
populationLoss *= unique.params[0].toPercent()
|
||||
}
|
||||
|
@ -435,7 +435,9 @@ class CityInfo {
|
||||
}
|
||||
|
||||
var allGppPercentageBonus = 0
|
||||
for (unique in getMatchingUniques("[]% great person generation []")) {
|
||||
for (unique in getMatchingUniques(UniqueType.GreatPersonPointPercentage)
|
||||
+ getMatchingUniques(UniqueType.GreatPersonPointPercentageDeprecated)
|
||||
) {
|
||||
if (!matchesFilter(unique.params[1])) continue
|
||||
allGppPercentageBonus += unique.params[0].toInt()
|
||||
}
|
||||
@ -484,6 +486,33 @@ class CityInfo {
|
||||
200 + cityConstructions.getBuiltBuildings().sumOf { it.cityHealth }
|
||||
|
||||
override fun toString() = name // for debug
|
||||
|
||||
fun isHolyCity(): Boolean = religion.religionThisIsTheHolyCityOf != null
|
||||
|
||||
fun canBeDestroyed(justCaptured: Boolean = false): Boolean {
|
||||
return !isOriginalCapital && !isHolyCity() && (!isCapital() || justCaptured)
|
||||
}
|
||||
|
||||
fun getForceEvaluation(): Int {
|
||||
// Same as for units, so higher values count more
|
||||
return CityCombatant(this).getDefendingStrength().toFloat().pow(1.5f).toInt()
|
||||
}
|
||||
|
||||
fun getNeighbouringCivs(): Set<String> {
|
||||
val tilesList: HashSet<TileInfo> = getTiles().toHashSet()
|
||||
val cityPositionList: ArrayList<TileInfo> = arrayListOf()
|
||||
|
||||
for (tiles in tilesList)
|
||||
for (tile in tiles.neighbors)
|
||||
if (!tilesList.contains(tile))
|
||||
cityPositionList.add(tile)
|
||||
|
||||
return cityPositionList
|
||||
.asSequence()
|
||||
.mapNotNull { it.getOwner()?.civName }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
//region state-changing functions
|
||||
@ -799,19 +828,6 @@ class CityInfo {
|
||||
// Looking at all the use cases, the following functions were written to handle all findMatchingUniques() problems.
|
||||
// Sadly, due to the large disparity between use cases, there needed to be lots of functions.
|
||||
|
||||
|
||||
// Finds matching uniques provided from both local and non-local sources.
|
||||
fun getMatchingUniques(
|
||||
placeholderText: String,
|
||||
// We might have this cached to avoid concurrency problems. If we don't, just get it directly
|
||||
localUniques: Sequence<Unique> = getLocalMatchingUniques(placeholderText),
|
||||
): Sequence<Unique> {
|
||||
// The localUniques might not be filtered when passed as a parameter, so we filter it anyway
|
||||
// The time loss shouldn't be that large I don't think
|
||||
return civInfo.getMatchingUniques(placeholderText, this) +
|
||||
localUniques.filter { it.placeholderText == placeholderText }
|
||||
}
|
||||
|
||||
// Finds matching uniques provided from both local and non-local sources.
|
||||
fun getMatchingUniques(
|
||||
uniqueType: UniqueType,
|
||||
@ -822,13 +838,6 @@ class CityInfo {
|
||||
localUniques.filter { it.isOfType(uniqueType) && it.conditionalsApply(stateForConditionals) }
|
||||
}
|
||||
|
||||
// Matching uniques provided by sources in the city itself
|
||||
fun getLocalMatchingUniques(placeholderText: String): Sequence<Unique> {
|
||||
return cityConstructions.builtBuildingUniqueMap.getUniques(placeholderText)
|
||||
.filter { !it.isAntiLocalEffect } +
|
||||
religion.getUniques().filter { it.placeholderText == placeholderText }
|
||||
}
|
||||
|
||||
fun getLocalMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals? = null): Sequence<Unique> {
|
||||
return (
|
||||
cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType)
|
||||
@ -859,33 +868,6 @@ class CityInfo {
|
||||
.filter { !it.isLocalEffect }
|
||||
// Note that we don't query religion here, as those only have local effects
|
||||
}
|
||||
|
||||
fun isHolyCity(): Boolean = religion.religionThisIsTheHolyCityOf != null
|
||||
|
||||
fun canBeDestroyed(justCaptured: Boolean = false): Boolean {
|
||||
return !isOriginalCapital && !isHolyCity() && (!isCapital() || justCaptured)
|
||||
}
|
||||
|
||||
fun getForceEvaluation(): Int {
|
||||
// Same as for units, so higher values count more
|
||||
return CityCombatant(this).getDefendingStrength().toFloat().pow(1.5f).toInt()
|
||||
}
|
||||
|
||||
|
||||
fun getNeighbouringCivs(): Set<String> {
|
||||
val tilesList: HashSet<TileInfo> = getTiles().toHashSet()
|
||||
val cityPositionList: ArrayList<TileInfo> = arrayListOf()
|
||||
|
||||
for (tiles in tilesList)
|
||||
for (tile in tiles.neighbors)
|
||||
if (!tilesList.contains(tile))
|
||||
cityPositionList.add(tile)
|
||||
|
||||
return cityPositionList
|
||||
.asSequence()
|
||||
.mapNotNull { it.getOwner()?.civName }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
|
||||
//endregion
|
||||
}
|
@ -6,6 +6,8 @@ import com.unciv.models.Counter
|
||||
import com.unciv.models.Religion
|
||||
import com.unciv.models.metadata.GameSpeed
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.utils.toPercent
|
||||
|
||||
class CityInfoReligionManager {
|
||||
@Transient
|
||||
@ -113,7 +115,7 @@ class CityInfoReligionManager {
|
||||
|
||||
if (newMajorityReligion in religionsAtSomePointAdopted) return
|
||||
|
||||
val religionOwningCiv = cityInfo.civInfo.gameInfo.getCivilization(newMajorityReligionObject.foundingCivName)
|
||||
val religionOwningCiv = newMajorityReligionObject.getFounder()
|
||||
for (unique in newMajorityReligionObject.getFounderUniques()) {
|
||||
val statsGranted = when (unique.placeholderText) {
|
||||
"[] when a city adopts this religion for the first time (modified by game speed)" ->
|
||||
@ -254,13 +256,15 @@ class CityInfoReligionManager {
|
||||
|
||||
private fun getSpreadRange(): Int {
|
||||
var spreadRange = 10
|
||||
for (unique in cityInfo.getMatchingUniques("Religion naturally spreads to cities [] tiles away"))
|
||||
spreadRange += unique.params[0].toInt()
|
||||
|
||||
if (getMajorityReligion() != null)
|
||||
for (unique in getMajorityReligion()!!.getFounderUniques()
|
||||
.filter { it.placeholderText == "Religion naturally spreads to cities [] tiles away"}
|
||||
) spreadRange += unique.params[0].toInt()
|
||||
for (unique in cityInfo.getLocalMatchingUniques(UniqueType.ReligionSpreadDistance)) {
|
||||
spreadRange += unique.params[0].toInt()
|
||||
}
|
||||
|
||||
if (getMajorityReligion() != null) {
|
||||
for (unique in getMajorityReligion()!!.getFounder().getMatchingUniques(UniqueType.ReligionSpreadDistance))
|
||||
spreadRange += unique.params[0].toInt()
|
||||
}
|
||||
|
||||
return spreadRange
|
||||
}
|
||||
@ -295,17 +299,27 @@ class CityInfoReligionManager {
|
||||
|
||||
private fun pressureAmountToAdjacentCities(pressuredCity: CityInfo): Int {
|
||||
var pressure = pressureFromAdjacentCities.toFloat()
|
||||
|
||||
for (unique in cityInfo.getMatchingUniques("[]% Natural religion spread []")) {
|
||||
|
||||
// Follower beliefs of this religion
|
||||
for (unique in cityInfo.getLocalMatchingUniques(UniqueType.NaturalReligionSpreadStrength)) {
|
||||
if (pressuredCity.matchesFilter(unique.params[1]))
|
||||
pressure *= 1f + unique.params[0].toFloat() / 100f
|
||||
pressure *= unique.params[0].toPercent()
|
||||
}
|
||||
|
||||
for (unique in cityInfo.getMatchingUniques("[]% Natural religion spread [] with []"))
|
||||
if (pressuredCity.matchesFilter(unique.params[1])
|
||||
&& cityInfo.civInfo.hasTechOrPolicy(unique.params[2])
|
||||
) pressure *= 1f + unique.params[0].toFloat() / 100f
|
||||
|
||||
|
||||
// Founder beliefs of this religion
|
||||
if (getMajorityReligion() != null) {
|
||||
for (unique in getMajorityReligion()!!.getFounder().getMatchingUniques(UniqueType.NaturalReligionSpreadStrength))
|
||||
if (pressuredCity.matchesFilter(unique.params[1]))
|
||||
pressure *= unique.params[0].toPercent()
|
||||
}
|
||||
|
||||
// Deprecated since 3.19.3
|
||||
for (unique in cityInfo.getLocalMatchingUniques(UniqueType.NaturalReligionSpreadStrengthWith))
|
||||
if (pressuredCity.matchesFilter(unique.params[1])
|
||||
&& cityInfo.civInfo.hasTechOrPolicy(unique.params[2])
|
||||
) pressure *= unique.params[0].toPercent()
|
||||
//
|
||||
|
||||
return pressure.toInt()
|
||||
}
|
||||
}
|
@ -88,7 +88,7 @@ class CityStats(val cityInfo: CityInfo) {
|
||||
if (!cityInfo.isCapital() && cityInfo.isConnectedToCapital()) {
|
||||
val civInfo = cityInfo.civInfo
|
||||
stats.gold = civInfo.getCapital().population.population * 0.15f + cityInfo.population.population * 1.1f - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5)
|
||||
for (unique in cityInfo.getMatchingUniques("[] from each Trade Route"))
|
||||
for (unique in cityInfo.getMatchingUniques(UniqueType.StatsFromTradeRoute))
|
||||
stats.add(unique.stats)
|
||||
if (civInfo.hasUnique("Gold from all trade routes +25%")) stats.gold *= 1.25f // Machu Picchu speciality
|
||||
}
|
||||
@ -314,13 +314,17 @@ class CityStats(val cityInfo: CityInfo) {
|
||||
unique.params[0].toFloat() * cityInfo.religion.getFollowersOfMajorityReligion(),
|
||||
unique.params[2].toFloat()
|
||||
))
|
||||
|
||||
|
||||
if (currentConstruction is Building
|
||||
&& cityInfo.civInfo.cities.isNotEmpty()
|
||||
&& cityInfo.civInfo.getCapital().cityConstructions.builtBuildings.contains(currentConstruction.name)
|
||||
) {
|
||||
for (unique in cityInfo.getMatchingUniques("+25% Production towards any buildings that already exist in the Capital"))
|
||||
addUniqueStats(unique, Stat.Production, 25f)
|
||||
// Deprecated since 3.19.3
|
||||
for (unique in cityInfo.getMatchingUniques(UniqueType.PercentProductionBuildingsInCapitalDeprecated))
|
||||
addUniqueStats(unique, Stat.Production, 25f)
|
||||
//
|
||||
for (unique in cityInfo.getMatchingUniques(UniqueType.PercentProductionBuildingsInCapital))
|
||||
addUniqueStats(unique, Stat.Production, unique.params[0].toFloat())
|
||||
}
|
||||
|
||||
return sourceToStats
|
||||
@ -361,7 +365,7 @@ class CityStats(val cityInfo: CityInfo) {
|
||||
|
||||
// e.g. "-[50]% maintenance costs for buildings [in this city]"
|
||||
// Deprecated since 3.18.17
|
||||
for (unique in cityInfo.getMatchingUniques(UniqueType.DecrasedBuildingMaintenanceDeprecated)) {
|
||||
for (unique in cityInfo.getMatchingUniques(UniqueType.DecreasedBuildingMaintenanceDeprecated)) {
|
||||
buildingsMaintenance *= (1f - unique.params[0].toFloat() / 100)
|
||||
}
|
||||
//
|
||||
|
@ -739,10 +739,10 @@ class MapUnit {
|
||||
}
|
||||
|
||||
val healingCity = tileInfo.getTilesInDistance(1).firstOrNull {
|
||||
it.isCityCenter() && it.getCity()!!.getMatchingUniques("[] Units adjacent to this city heal [] HP per turn when healing").any()
|
||||
it.isCityCenter() && it.getCity()!!.getMatchingUniques(UniqueType.CityHealingUnits).any()
|
||||
}?.getCity()
|
||||
if (healingCity != null) {
|
||||
for (unique in healingCity.getMatchingUniques("[] Units adjacent to this city heal [] HP per turn when healing")) {
|
||||
for (unique in healingCity.getMatchingUniques(UniqueType.CityHealingUnits)) {
|
||||
if (!matchesFilter(unique.params[0])) continue
|
||||
healing += unique.params[1].toInt()
|
||||
}
|
||||
@ -1160,7 +1160,7 @@ class MapUnit {
|
||||
val baseAmount = getBaseMaxActionUses(action)
|
||||
val additional =
|
||||
if (buildCity == null) 0
|
||||
else buildCity.getMatchingUniques("[] units built [] can [] [] extra times")
|
||||
else buildCity.getMatchingUniques(UniqueType.UnitStartingActions)
|
||||
.filter { matchesFilter(it.params[0]) && buildCity.matchesFilter(it.params[1]) && it.params[2] == action }
|
||||
.sumOf { it.params[3].toInt() }
|
||||
|
||||
|
@ -91,4 +91,6 @@ class Religion() : INamed {
|
||||
fun isMajorReligion() = getBeliefs(BeliefType.Founder).any()
|
||||
|
||||
fun isEnhancedReligion() = getBeliefs(BeliefType.Enhancer).any()
|
||||
|
||||
fun getFounder() = gameInfo.civilizations.first { it.civName == foundingCivName }
|
||||
}
|
||||
|
@ -173,9 +173,11 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
|
||||
stats.add(unique.stats)
|
||||
}
|
||||
|
||||
for (unique in city.getMatchingUniques("[] from every [] in cities where this religion has at least [] followers"))
|
||||
if (unique.params[2].toInt() <= city.religion.getFollowersOfMajorityReligion() && matchesFilter(unique.params[1]))
|
||||
stats.add(unique.stats)
|
||||
// Deprecated since 3.19.3
|
||||
for (unique in city.getMatchingUniques(UniqueType.StatsForBuildingsWithFollowers))
|
||||
if (unique.params[2].toInt() <= city.religion.getFollowersOfMajorityReligion() && matchesFilter(unique.params[1]))
|
||||
stats.add(unique.stats)
|
||||
//
|
||||
|
||||
@Suppress("RemoveRedundantQualifierName") // make it clearer Building inherits Stats
|
||||
for (unique in getMatchingUniques(UniqueType.StatsWithResource))
|
||||
|
@ -83,6 +83,8 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
||||
|
||||
UniqueType.ConditionalSpecialistCount ->
|
||||
state.cityInfo != null && state.cityInfo.population.getNumberOfSpecialists() >= condition.params[0].toInt()
|
||||
UniqueType.ConditionalFollowerCount ->
|
||||
state.cityInfo != null && state.cityInfo.religion.getFollowersOfMajorityReligion() >= condition.params[0].toInt()
|
||||
UniqueType.ConditionalWhenGarrisoned ->
|
||||
state.cityInfo != null && state.cityInfo.getCenterTile().militaryUnit != null && state.cityInfo.getCenterTile().militaryUnit!!.canGarrison()
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.unciv.models.ruleset.unique
|
||||
|
||||
import com.unciv.Constants
|
||||
import com.unciv.models.ruleset.BeliefType
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.VictoryType
|
||||
@ -302,6 +303,16 @@ enum class UniqueParameterType(val parameterName:String) {
|
||||
else UniqueType.UniqueComplianceErrorSeverity.RulesetInvariant
|
||||
}
|
||||
},
|
||||
Action("action") {
|
||||
private val knownValues = setOf(Constants.spreadReligionAbilityCount, Constants.removeHeresyAbilityCount)
|
||||
override fun getErrorSeverity(
|
||||
parameterText: String,
|
||||
ruleset: Ruleset
|
||||
): UniqueType.UniqueComplianceErrorSeverity? {
|
||||
return if (parameterText in knownValues) null
|
||||
else UniqueType.UniqueComplianceErrorSeverity.RulesetInvariant
|
||||
}
|
||||
},
|
||||
/** Behaves like [Unknown], but states explicitly the parameter is OK and its contents are ignored */
|
||||
Comment("comment") {
|
||||
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset):
|
||||
|
@ -70,9 +70,10 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
StatsPerCity("[stats] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
StatsFromSpecialist("[stats] from every specialist [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
StatsPerPopulation("[stats] per [amount] population [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
// ToDo: Reword to `[stats] <in cities with [amount] or more population>` for consistency with other conditionals
|
||||
StatsFromXPopulation("[stats] in cities with [amount] or more population", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
StatsFromCitiesOnSpecificTiles("[stats] in cities on [terrainFilter] tiles", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
@Deprecated("As of 3.18.14", ReplaceWith("[stats] [in all cities] <before discovering [tech]> OR [stats] [in all cities] <before adopting [policy]>"))
|
||||
StatsFromCitiesBefore("[stats] per turn from cities before [tech/policy]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
@ -84,7 +85,9 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
StatsFromTilesWithout("[stats] from [tileFilter] tiles without [tileFilter] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
// This is a doozy
|
||||
StatsFromObject("[stats] from every [tileFilter/specialist/buildingFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
@Deprecated("As of 3.19.3", ReplaceWith("[stats] from every [buildingFilter] <in cities where this religion has at least [amount] followers>"))
|
||||
StatsForBuildingsWithFollowers("[stats] from every [buildingFilter] in cities where this religion has at least [amount] followers", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
StatsFromTradeRoute("[stats] from each Trade Route", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
// Stat percentage boosts
|
||||
StatPercentBonus("[amount]% [stat]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
@ -97,12 +100,16 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
AllStatsSignedPercentFromObject("+[amount]% yield from every [tileFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
StatPercentFromReligionFollowers("[amount]% [stat] from every follower, up to [amount]%", UniqueTarget.FollowerBelief),
|
||||
BonusStatsFromCityStates("[amount]% [stat] from City-States", UniqueTarget.Global),
|
||||
|
||||
NullifiesStat("Nullifies [stat] [cityFilter]", UniqueTarget.Global),
|
||||
NullifiesGrowth("Nullifies Growth [cityFilter]", UniqueTarget.Global),
|
||||
|
||||
PercentProductionWonders("[amount]% Production when constructing [buildingFilter] wonders [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
PercentProductionBuildings("[amount]% Production when constructing [buildingFilter] buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
PercentProductionUnits("[amount]% Production when constructing [baseUnitFilter] units [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
PercentProductionBuildingsInCapital("[amount]% Production towards any buildings that already exist in the Capital", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
@Deprecated("As of 3.19.3", ReplaceWith("[amount]% Production towards any buildings that already exist in the Capital"))
|
||||
PercentProductionBuildingsInCapitalDeprecated("+25% Production towards any buildings that already exist in the Capital", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
//endregion Stat providing uniques
|
||||
|
||||
@ -143,6 +150,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
/////// region Other global uniques
|
||||
|
||||
FreeUnits("[amount] units cost no maintenance", UniqueTarget.Global),
|
||||
CannotBuildUnits("Cannot build [baseUnitFilter] units", UniqueTarget.Global),
|
||||
|
||||
ConsumesResources("Consumes [amount] [resource]", UniqueTarget.Improvement, UniqueTarget.Building, UniqueTarget.Unit),
|
||||
ProvidesResources("Provides [amount] [resource]", UniqueTarget.Improvement, UniqueTarget.Building),
|
||||
@ -155,6 +163,8 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
CarryOverFoodAlsoDeprecated("[amount]% of food is carried over [cityFilter] after population increases", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
GainFreeBuildings("Gain a free [buildingName] [cityFilter]", UniqueTarget.Global),
|
||||
GreatPersonPointPercentage("[amount]% Great Person generation [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
GreatPersonPointPercentageDeprecated("[amount]% great person generation [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
FreeExtraBeliefs("May choose [amount] additional [beliefType] beliefs when [foundingOrEnhancing] a religion", UniqueTarget.Global),
|
||||
FreeExtraAnyBeliefs("May choose [amount] additional belief(s) of any type when [foundingOrEnhancing] a religion", UniqueTarget.Global),
|
||||
@ -209,7 +219,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
|
||||
BuildingMaintenance("[amount]% maintenance cost for buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
@Deprecated("As of 3.18.17", ReplaceWith("[-amount]% maintenace cost for buildings [cityFilter]"))
|
||||
DecrasedBuildingMaintenanceDeprecated("-[amount]% maintenance cost for buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
DecreasedBuildingMaintenanceDeprecated("-[amount]% maintenance cost for buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
// This should probably support conditionals, e.g. <after discovering [tech]>
|
||||
MayanGainGreatPerson("Receive a free Great Person at the end of every [comment] (every 394 years), after researching [tech]. Each bonus person can only be chosen once.", UniqueTarget.Global),
|
||||
@ -233,14 +243,14 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
TriggersVictory("Triggers victory", UniqueTarget.Global),
|
||||
TriggersCulturalVictory("Triggers a Cultural Victory upon completion", UniqueTarget.Global),
|
||||
|
||||
CannotBuildUnits("Cannot build [baseUnitFilter] units", UniqueTarget.Global),
|
||||
|
||||
BetterDefensiveBuildings("[amount]% City Strength from defensive buildings", UniqueTarget.Global),
|
||||
@Deprecated("As of 3.18.17", ReplaceWith("[+25]% City Strength from defensive buildings"))
|
||||
DefensiveBuilding25("Defensive buildings in all cities are 25% more effective", UniqueTarget.Global),
|
||||
|
||||
TileImprovementTime("[amount]% tile improvement construction time", UniqueTarget.Global),
|
||||
PercentGoldFromTradeMissions("[amount]% Gold from Great Merchant trade missions", UniqueTarget.Global),
|
||||
// Todo: Lowercase the 'U' of 'Units' in this unique
|
||||
CityHealingUnits("[mapUnitFilter] Units adjacent to this city heal [amount] HP per turn when healing", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
@Deprecated("As of 3.18.17", ReplaceWith("[amount]% Strength <for [mapUnitFilter] units> <when adjacent to a [mapUnitFilter] unit>"))
|
||||
StrengthFromAdjacentUnits("[amount]% Strength for [mapUnitFilter] units which have another [mapUnitFilter] unit in an adjacent tile", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
@ -262,10 +272,21 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
StrengthForGarrisonedCitiesAttacking("+[amount]% attacking strength for cities with garrisoned units", UniqueTarget.Global),
|
||||
|
||||
UnitStartingExperience("New [baseUnitFilter] units start with [amount] Experience [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
UnitStartingPromotions("All newly-trained [baseUnitFilter] units [cityFilter] receive the [promotion] promotion", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
UnitStartingActions("[baseUnitFilter] units built [cityFilter] can [action] [amount] extra times", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
// ToDo: make per unit and use unit filters?
|
||||
LandUnitEmbarkation("Enables embarkation for land units", UniqueTarget.Global),
|
||||
EmbarkedUnitsMayEnterOcean("Enables embarked units to enter ocean tiles", UniqueTarget.Global),
|
||||
|
||||
PopulationLossFromNukes("Population loss from nuclear attacks [amount]% [cityFilter]", UniqueTarget.Global),
|
||||
@Deprecated("As of 3.19.2", ReplaceWith("Population loss from nuclear attacks [-amount]% [in this city]"))
|
||||
PopulationLossFromNukesDeprecated("Population loss from nuclear attacks -[amount]%", UniqueTarget.Global),
|
||||
|
||||
NaturalReligionSpreadStrength("[amount]% Natural religion spread [cityFilter]", UniqueTarget.FollowerBelief, UniqueTarget.Global),
|
||||
@Deprecated("As of 3.19.3", ReplaceWith("[amount]% Natural religion spread [cityFilter] <after discovering [tech]> OR [amount]% natural religion spread [cityFilter] <after adopting [policy]>"))
|
||||
NaturalReligionSpreadStrengthWith("[amount]% Natural religion spread [cityFilter] with [tech/policy]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
ReligionSpreadDistance("Religion naturally spreads to cities [amount] tiles away", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
|
||||
IncompatibleWith("Incompatible with [policy/tech/promotion]", UniqueTarget.Policy, UniqueTarget.Tech, UniqueTarget.Promotion),
|
||||
StartingTech("Starting tech", UniqueTarget.Tech),
|
||||
StartsWithTech("Starts with [tech]", UniqueTarget.Nation),
|
||||
@ -538,6 +559,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
|
||||
/////// city conditionals
|
||||
ConditionalSpecialistCount("if this city has at least [amount] specialists", UniqueTarget.Conditional),
|
||||
ConditionalFollowerCount("in cities where this religion has at least [amount] followers", UniqueTarget.Conditional),
|
||||
ConditionalWhenGarrisoned("with a garrison", UniqueTarget.Conditional),
|
||||
|
||||
/////// unit conditionals
|
||||
|
@ -482,7 +482,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
}
|
||||
unit.promotions.XP = XP
|
||||
|
||||
for (unique in cityConstructions.cityInfo.getMatchingUniques("All newly-trained [] units [] receive the [] promotion")
|
||||
for (unique in cityConstructions.cityInfo.getMatchingUniques(UniqueType.UnitStartingPromotions)
|
||||
.filter { cityConstructions.cityInfo.matchesFilter(it.params[1]) }) {
|
||||
val filter = unique.params[0]
|
||||
val promotion = unique.params.last()
|
||||
|
@ -74,7 +74,7 @@ class ReligionOverviewTable(
|
||||
val button: Button
|
||||
if (religion.isPantheon()) {
|
||||
val image = if (viewingPlayer.knows(religion.foundingCivName) || viewingPlayer.civName == religion.foundingCivName)
|
||||
ImageGetter.getNationIndicator(gameInfo.getCivilization(religion.foundingCivName).nation, 60f)
|
||||
ImageGetter.getNationIndicator(religion.getFounder().nation, 60f)
|
||||
else
|
||||
ImageGetter.getRandomNationIndicator(60f)
|
||||
button = Button(image, BaseScreen.skin)
|
||||
@ -126,7 +126,7 @@ class ReligionOverviewTable(
|
||||
}
|
||||
}
|
||||
statsTable.add("Cities following this religion:".toLabel()).left()
|
||||
statsTable.add(gameInfo.getCivilization(religion.foundingCivName).religionManager.numberOfCitiesFollowingThisReligion().toString()).right().pad(5f).row()
|
||||
statsTable.add(religion.getFounder().religionManager.numberOfCitiesFollowingThisReligion().toString()).right().pad(5f).row()
|
||||
|
||||
val minWidth = max(statsTable.minWidth, beliefsTable.minWidth) + 5
|
||||
|
||||
|
@ -6,6 +6,12 @@ These are split into two categories:
|
||||
Note that all of these are case-sensitive!
|
||||
|
||||
|
||||
## action
|
||||
An action that a unit can preform. Currently, there are only two actions part of this:
|
||||
- `Spread Religion`
|
||||
- `Remove Foreign religions from your own cities`
|
||||
|
||||
|
||||
## amount
|
||||
This indicates a whole number, possibly with a + or - sign, such as `2`, `+13`, or `-3`.
|
||||
|
||||
|
@ -71,6 +71,11 @@ Example: "[+1 Gold, +2 Production] from every [tileFilter/specialist/buildingFil
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### [stats] from each Trade Route
|
||||
Example: "[+1 Gold, +2 Production] from each Trade Route"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### [amount]% [stat]
|
||||
Example: "[20]% [Culture]"
|
||||
|
||||
@ -121,6 +126,11 @@ Example: "[20]% Production when constructing [Melee] units [in all cities]"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### [amount]% Production towards any buildings that already exist in the Capital
|
||||
Example: "[20]% Production towards any buildings that already exist in the Capital"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### Military Units gifted from City-States start with [amount] XP
|
||||
Example: "Military Units gifted from City-States start with [20] XP"
|
||||
|
||||
@ -177,6 +187,11 @@ Example: "[20] units cost no maintenance"
|
||||
|
||||
Applicable to: Global
|
||||
|
||||
#### Cannot build [baseUnitFilter] units
|
||||
Example: "Cannot build [Melee] units"
|
||||
|
||||
Applicable to: Global
|
||||
|
||||
#### [amount]% growth [cityFilter]
|
||||
Example: "[20]% growth [in all cities]"
|
||||
|
||||
@ -192,6 +207,16 @@ Example: "Gain a free [Library] [in all cities]"
|
||||
|
||||
Applicable to: Global
|
||||
|
||||
#### [amount]% Great Person generation [cityFilter]
|
||||
Example: "[20]% Great Person generation [in all cities]"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### [amount]% great person generation [cityFilter]
|
||||
Example: "[20]% great person generation [in all cities]"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### May choose [amount] additional [beliefType] beliefs when [foundingOrEnhancing] a religion
|
||||
Example: "May choose [20] additional [Follower] beliefs when [founding] a religion"
|
||||
|
||||
@ -354,11 +379,6 @@ Applicable to: Global
|
||||
#### Triggers a Cultural Victory upon completion
|
||||
Applicable to: Global
|
||||
|
||||
#### Cannot build [baseUnitFilter] units
|
||||
Example: "Cannot build [Melee] units"
|
||||
|
||||
Applicable to: Global
|
||||
|
||||
#### [amount]% City Strength from defensive buildings
|
||||
Example: "[20]% City Strength from defensive buildings"
|
||||
|
||||
@ -374,6 +394,11 @@ Example: "[20]% Gold from Great Merchant trade missions"
|
||||
|
||||
Applicable to: Global
|
||||
|
||||
#### [mapUnitFilter] Units adjacent to this city heal [amount] HP per turn when healing
|
||||
Example: "[Wounded] Units adjacent to this city heal [20] HP per turn when healing"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### [amount]% Golden Age length
|
||||
Example: "[20]% Golden Age length"
|
||||
|
||||
@ -389,12 +414,37 @@ Example: "New [Melee] units start with [20] Experience [in all cities]"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### All newly-trained [baseUnitFilter] units [cityFilter] receive the [promotion] promotion
|
||||
Example: "All newly-trained [Melee] units [in all cities] receive the [Shock I] promotion"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### [baseUnitFilter] units built [cityFilter] can [action] [amount] extra times
|
||||
Example: "[Melee] units built [in all cities] can [action] [20] extra times"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### Enables embarkation for land units
|
||||
Applicable to: Global
|
||||
|
||||
#### Enables embarked units to enter ocean tiles
|
||||
Applicable to: Global
|
||||
|
||||
#### Population loss from nuclear attacks [amount]% [cityFilter]
|
||||
Example: "Population loss from nuclear attacks [20]% [in all cities]"
|
||||
|
||||
Applicable to: Global
|
||||
|
||||
#### [amount]% Natural religion spread [cityFilter]
|
||||
Example: "[20]% Natural religion spread [in all cities]"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### Religion naturally spreads to cities [amount] tiles away
|
||||
Example: "Religion naturally spreads to cities [20] tiles away"
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
#### Can be continually researched
|
||||
Applicable to: Global
|
||||
|
||||
@ -1275,6 +1325,11 @@ Example: "<if this city has at least [20] specialists>"
|
||||
|
||||
Applicable to: Conditional
|
||||
|
||||
#### <in cities where this religion has at least [amount] followers>
|
||||
Example: "<in cities where this religion has at least [20] followers>"
|
||||
|
||||
Applicable to: Conditional
|
||||
|
||||
#### <with a garrison>
|
||||
Applicable to: Conditional
|
||||
|
||||
@ -1364,8 +1419,10 @@ Applicable to: Conditional
|
||||
## Deprecated uniques
|
||||
- "[stats] per turn from cities before [tech/policy]" - Deprecated As of 3.18.14, replace with "[stats] [in all cities] <before discovering [tech]> OR [stats] [in all cities] <before adopting [policy]>"
|
||||
- "[stats] from every Wonder" - Deprecated As of 3.19.1, replace with "[stats] from every [Wonder]"
|
||||
- "[stats] from every [buildingFilter] in cities where this religion has at least [amount] followers" - Deprecated As of 3.19.3, replace with "[stats] from every [buildingFilter] <in cities where this religion has at least [amount] followers>"
|
||||
- "+[amount]% [stat] from every [tileFilter/specialist/buildingName]" - Deprecated As of 3.18.17, replace with "[amount]% [stat] from every [tileFilter/specialist/buildingName]"
|
||||
- "+[amount]% yield from every [tileFilter]" - Deprecated As of 3.18.17, replace with "[+amount]% Yield from every [tileFilter]"
|
||||
- "+25% Production towards any buildings that already exist in the Capital" - Deprecated As of 3.19.3, replace with "[amount]% Production towards any buildings that already exist in the Capital"
|
||||
- "City-State Influence degrades [amount]% slower" - Deprecated As of 3.18.17, replace with "[-amount]% City-State Influence degradation"
|
||||
- "Quantity of Resources gifted by City-States increased by [amount]%" - Deprecated As of 3.18.17, replace with "[+amount]% resources gifted by City-States"
|
||||
- "Happiness from Luxury Resources gifted by City-States increased by [amount]%" - Deprecated As of 3.18.17, replace with "[+amount]% Happiness from luxury resources gifted by City-States"
|
||||
@ -1390,6 +1447,8 @@ Applicable to: Conditional
|
||||
- "+[amount]% Defensive Strength for cities" - Deprecated As of 3.18.17, replace with "[+amount]% Strength for cities <when defending>"
|
||||
- "[amount]% Attacking Strength for cities" - Deprecated As of 3.18.17, replace with "[amount]% Strength for cities <when attacking>"
|
||||
- "+[amount]% attacking strength for cities with garrisoned units" - Deprecated As of 3.19.1, replace with "[amount]% Strength for cities <with a garrison> <when attacking>"
|
||||
- "Population loss from nuclear attacks -[amount]%" - Deprecated As of 3.19.2, replace with "Population loss from nuclear attacks [-amount]% [in this city]"
|
||||
- "[amount]% Natural religion spread [cityFilter] with [tech/policy]" - Deprecated As of 3.19.3, replace with "[amount]% Natural religion spread [cityFilter] <after discovering [tech]> OR [amount]% natural religion spread [cityFilter] <after adopting [policy]>"
|
||||
- "Melee units pay no movement cost to pillage" - Deprecated As of 3.18.17, replace with "No movement cost to pillage <for [Melee] units>"
|
||||
- "[mapUnitFilter] units gain [amount]% more Experience from combat" - Deprecated As of 3.18.12, replace with "[amount]% XP gained from combat <for [mapUnitFilter] units>"
|
||||
- "[amount]% maintenance costs for [mapUnitFilter] units" - Deprecated As of 3.18.14, replace with "[amount]% maintenance costs <for [mapUnitFilter] units>"
|
||||
|
Reference in New Issue
Block a user