Added unique types, added regions for easier location

This commit is contained in:
yairm210 2021-12-03 10:45:27 +02:00
parent e054863bd8
commit 0def261012
7 changed files with 63 additions and 26 deletions

View File

@ -129,7 +129,7 @@ object UnitAutomation {
// Might die next turn - move! // Might die next turn - move!
if (unit.health <= unit.getDamageFromTerrain() && tryHealUnit(unit)) return if (unit.health <= unit.getDamageFromTerrain() && tryHealUnit(unit)) return
if (unit.isCivilian() || unit.hasUnique(UniqueType.CannotAttack)) { if (unit.isCivilian()) {
if (tryRunAwayIfNeccessary(unit)) return if (tryRunAwayIfNeccessary(unit)) return
if (unit.hasUnique(UniqueType.FoundCity)) if (unit.hasUnique(UniqueType.FoundCity))

View File

@ -122,7 +122,7 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
var goldGained = 0 var goldGained = 0
val discoveredNaturalWonders = civInfo.gameInfo.civilizations.filter { it != civInfo && it.isMajorCiv() } val discoveredNaturalWonders = civInfo.gameInfo.civilizations.filter { it != civInfo && it.isMajorCiv() }
.flatMap { it.naturalWonders } .flatMap { it.naturalWonders }
if (tile.hasUnique("Grants 500 Gold to the first civilization to discover it") if (tile.hasUnique(UniqueType.GrantsGoldToFirstToDiscover)
&& !discoveredNaturalWonders.contains(tile.naturalWonder!!)) { && !discoveredNaturalWonders.contains(tile.naturalWonder!!)) {
goldGained += 500 goldGained += 500
} }

View File

@ -595,7 +595,7 @@ class CivilizationInfo {
fun canSignResearchAgreement(): Boolean { fun canSignResearchAgreement(): Boolean {
if (!isMajorCiv()) return false if (!isMajorCiv()) return false
if (!hasUnique("Enables Research agreements")) return false if (!hasUnique(UniqueType.EnablesResearchAgreements)) return false
if (gameInfo.ruleSet.technologies.values if (gameInfo.ruleSet.technologies.values
.none { tech.canBeResearched(it.name) && !tech.isResearched(it.name) }) return false .none { tech.canBeResearched(it.name) && !tech.isResearched(it.name) }) return false
return true return true

View File

@ -2,6 +2,7 @@ package com.unciv.logic.civilization
import com.unciv.models.Counter import com.unciv.models.Counter
import com.unciv.models.ruleset.VictoryType import com.unciv.models.ruleset.VictoryType
import com.unciv.models.ruleset.unique.UniqueType
class VictoryManager { class VictoryManager {
@Transient @Transient
@ -68,7 +69,7 @@ class VictoryManager {
fun hasWonScientificVictory() = hasVictoryType(VictoryType.Scientific) && spaceshipPartsRemaining() == 0 fun hasWonScientificVictory() = hasVictoryType(VictoryType.Scientific) && spaceshipPartsRemaining() == 0
fun hasWonCulturalVictory() = hasVictoryType(VictoryType.Cultural) fun hasWonCulturalVictory() = hasVictoryType(VictoryType.Cultural)
&& civInfo.hasUnique("Triggers a Cultural Victory upon completion") && civInfo.hasUnique(UniqueType.TriggersCulturalVictory)
fun hasWonDominationVictory(): Boolean { fun hasWonDominationVictory(): Boolean {
return hasVictoryType(VictoryType.Domination) return hasVictoryType(VictoryType.Domination)
@ -85,7 +86,7 @@ class VictoryManager {
if (hasWonScientificVictory()) return VictoryType.Scientific if (hasWonScientificVictory()) return VictoryType.Scientific
if (hasWonCulturalVictory()) return VictoryType.Cultural if (hasWonCulturalVictory()) return VictoryType.Cultural
if (hasWonDiplomaticVictory()) return VictoryType.Diplomatic if (hasWonDiplomaticVictory()) return VictoryType.Diplomatic
if (civInfo.hasUnique("Triggers victory")) return VictoryType.Neutral if (civInfo.hasUnique(UniqueType.TriggersVictory)) return VictoryType.Neutral
return null return null
} }

View File

@ -53,9 +53,9 @@ class NaturalWonderGenerator(val ruleset: Ruleset, val randomness: MapGeneration
private fun Unique.getIntParam(index: Int) = params[index].toInt() private fun Unique.getIntParam(index: Int) = params[index].toInt()
private fun spawnSpecificWonder(tileMap: TileMap, wonder: Terrain): Boolean { private fun spawnSpecificWonder(tileMap: TileMap, naturalWonder: Terrain): Boolean {
val continentsRelevant = wonder.hasUnique(UniqueType.NaturalWonderLargerLandmass) || val continentsRelevant = naturalWonder.hasUnique(UniqueType.NaturalWonderLargerLandmass) ||
wonder.hasUnique(UniqueType.NaturalWonderSmallerLandmass) naturalWonder.hasUnique(UniqueType.NaturalWonderSmallerLandmass)
val sortedContinents = if (continentsRelevant) val sortedContinents = if (continentsRelevant)
tileMap.continentSizes.asSequence() tileMap.continentSizes.asSequence()
.sortedByDescending { it.value } .sortedByDescending { it.value }
@ -65,8 +65,8 @@ class NaturalWonderGenerator(val ruleset: Ruleset, val randomness: MapGeneration
val suitableLocations = tileMap.values.filter { tile-> val suitableLocations = tileMap.values.filter { tile->
tile.resource == null && tile.resource == null &&
wonder.occursOn.contains(tile.getLastTerrain().name) && naturalWonder.occursOn.contains(tile.getLastTerrain().name) &&
wonder.uniqueObjects.all { unique -> naturalWonder.uniqueObjects.all { unique ->
when (unique.type) { when (unique.type) {
UniqueType.NaturalWonderNeighborCount -> { UniqueType.NaturalWonderNeighborCount -> {
val count = tile.neighbors.count { val count = tile.neighbors.count {
@ -96,7 +96,7 @@ class NaturalWonderGenerator(val ruleset: Ruleset, val randomness: MapGeneration
} }
} }
return trySpawnOnSuitableLocation(suitableLocations, wonder) return trySpawnOnSuitableLocation(suitableLocations, naturalWonder)
} }
private fun trySpawnOnSuitableLocation(suitableLocations: List<TileInfo>, wonder: Terrain): Boolean { private fun trySpawnOnSuitableLocation(suitableLocations: List<TileInfo>, wonder: Terrain): Boolean {

View File

@ -61,10 +61,9 @@ enum class UniqueFlag {
enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags: List<UniqueFlag> = emptyList()) { enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags: List<UniqueFlag> = emptyList()) {
//////////////////////////////////////// GLOBAL UNIQUES //////////////////////////////////////// //////////////////////////////////////// region GLOBAL UNIQUES ////////////////////////////////////////
// region Stat providing uniques
/////// Stat providing uniques
Stats("[stats]", UniqueTarget.Global, UniqueTarget.FollowerBelief, UniqueTarget.Improvement), Stats("[stats]", UniqueTarget.Global, UniqueTarget.FollowerBelief, UniqueTarget.Improvement),
StatsPerCity("[stats] [cityFilter]", UniqueTarget.Global), StatsPerCity("[stats] [cityFilter]", UniqueTarget.Global),
@ -101,6 +100,8 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
StatPercentFromReligionFollowers("[amount]% [stat] from every follower, up to [amount]%", UniqueTarget.FollowerBelief, UniqueTarget.Global), StatPercentFromReligionFollowers("[amount]% [stat] from every follower, up to [amount]%", UniqueTarget.FollowerBelief, UniqueTarget.Global),
//endregion Stat providing uniques
PercentProductionWonders("[amount]% Production when constructing [buildingFilter] wonders [cityFilter]", UniqueTarget.Global, UniqueTarget.Resource, UniqueTarget.FollowerBelief), PercentProductionWonders("[amount]% Production when constructing [buildingFilter] wonders [cityFilter]", UniqueTarget.Global, UniqueTarget.Resource, UniqueTarget.FollowerBelief),
PercentProductionBuildings("[amount]% Production when constructing [buildingFilter] buildings [cityFilter]", UniqueTarget.Global), PercentProductionBuildings("[amount]% Production when constructing [buildingFilter] buildings [cityFilter]", UniqueTarget.Global),
PercentProductionUnits("[amount]% Production when constructing [baseUnitFilter] units [cityFilter]", UniqueTarget.Global), PercentProductionUnits("[amount]% Production when constructing [baseUnitFilter] units [cityFilter]", UniqueTarget.Global),
@ -125,7 +126,7 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
UnhappinessFromPopulationPercentageChangeOld2("Unhappiness from population decreased by [amount]% [cityFilter]", UniqueTarget.Global), UnhappinessFromPopulationPercentageChangeOld2("Unhappiness from population decreased by [amount]% [cityFilter]", UniqueTarget.Global),
/////// City-State related uniques // region City-State related uniques
// I don't like the fact that currently "city state bonuses" are separate from the "global bonuses", // I don't like the fact that currently "city state bonuses" are separate from the "global bonuses",
// todo: merge city state bonuses into global bonuses // todo: merge city state bonuses into global bonuses
@ -142,6 +143,8 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
CityStateCanGiftGreatPeople("Allied City-States will occasionally gift Great People", UniqueTarget.Global), // used in Policy CityStateCanGiftGreatPeople("Allied City-States will occasionally gift Great People", UniqueTarget.Global), // used in Policy
CityStateDeprecated("Will not be chosen for new games", UniqueTarget.Nation), // implemented for CS only for now CityStateDeprecated("Will not be chosen for new games", UniqueTarget.Nation), // implemented for CS only for now
// endregion
/////// Other global uniques /////// Other global uniques
FreeUnits("[amount] units cost no maintenance", UniqueTarget.Global), FreeUnits("[amount] units cost no maintenance", UniqueTarget.Global),
@ -195,8 +198,13 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
RetainHappinessFromLuxury("Retain [amount]% of the happiness from a luxury after the last copy has been traded away", UniqueTarget.Nation), RetainHappinessFromLuxury("Retain [amount]% of the happiness from a luxury after the last copy has been traded away", UniqueTarget.Nation),
EnablesResearchAgreements("Enables Research agreements", UniqueTarget.Global),
TriggersVictory("Triggers victory", UniqueTarget.Global),
TriggersCulturalVictory("Triggers a Cultural Victory upon completion", UniqueTarget.Global),
///////////////////////////////////////// CONSTRUCTION UNIQUES ///////////////////////////////////////// //endregion Global uniques
///////////////////////////////////////// region CONSTRUCTION UNIQUES /////////////////////////////////////////
Unbuildable("Unbuildable", UniqueTarget.Building, UniqueTarget.Unit), Unbuildable("Unbuildable", UniqueTarget.Building, UniqueTarget.Unit),
CannotBePurchased("Cannot be purchased", UniqueTarget.Building, UniqueTarget.Unit), CannotBePurchased("Cannot be purchased", UniqueTarget.Building, UniqueTarget.Unit),
@ -204,7 +212,10 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
CanBePurchasedForAmountStat("Can be purchased for [amount] [stat] [cityFilter]", UniqueTarget.Building, UniqueTarget.Unit), CanBePurchasedForAmountStat("Can be purchased for [amount] [stat] [cityFilter]", UniqueTarget.Building, UniqueTarget.Unit),
MaxNumberBuildable("Limited to [amount] per Civilization", UniqueTarget.Building, UniqueTarget.Unit), MaxNumberBuildable("Limited to [amount] per Civilization", UniqueTarget.Building, UniqueTarget.Unit),
///////////////////////////////////////// BUILDING UNIQUES ///////////////////////////////////////// //endregion
///////////////////////////////////////// region BUILDING UNIQUES /////////////////////////////////////////
CostIncreasesPerCity("Cost increases by [amount] per owned city", UniqueTarget.Building), CostIncreasesPerCity("Cost increases by [amount] per owned city", UniqueTarget.Building),
@ -221,8 +232,10 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
MustBeNextTo("Must be next to [terrainFilter]", UniqueTarget.Building), MustBeNextTo("Must be next to [terrainFilter]", UniqueTarget.Building),
MustNotBeNextTo("Must not be next to [terrainFilter]", UniqueTarget.Building), MustNotBeNextTo("Must not be next to [terrainFilter]", UniqueTarget.Building),
//endregion
///////////////////////////////////////// UNIT UNIQUES /////////////////////////////////////////
///////////////////////////////////////// region UNIT UNIQUES /////////////////////////////////////////
FoundCity("Founds a new city", UniqueTarget.Unit), FoundCity("Founds a new city", UniqueTarget.Unit),
BuildImprovements("Can build [improvementFilter/terrainFilter] improvements on tiles", UniqueTarget.Unit), BuildImprovements("Can build [improvementFilter/terrainFilter] improvements on tiles", UniqueTarget.Unit),
@ -322,9 +335,11 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
ReligiousUnit("Religious Unit", UniqueTarget.Unit), ReligiousUnit("Religious Unit", UniqueTarget.Unit),
///////////////////////////////////////// TILE UNIQUES ///////////////////////////////////////// //endregion
///////////////////////////////////////// region TILE UNIQUES /////////////////////////////////////////
// region natural wonders
NaturalWonderNeighborCount("Must be adjacent to [amount] [simpleTerrain] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)), NaturalWonderNeighborCount("Must be adjacent to [amount] [simpleTerrain] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderNeighborsRange("Must be adjacent to [amount] to [amount] [simpleTerrain] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)), NaturalWonderNeighborsRange("Must be adjacent to [amount] to [amount] [simpleTerrain] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderSmallerLandmass("Must not be on [amount] largest landmasses", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)), NaturalWonderSmallerLandmass("Must not be on [amount] largest landmasses", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
@ -332,9 +347,10 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
NaturalWonderLatitude("Occurs on latitudes from [amount] to [amount] percent of distance equator to pole", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)), NaturalWonderLatitude("Occurs on latitudes from [amount] to [amount] percent of distance equator to pole", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderGroups("Occurs in groups of [amount] to [amount] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)), NaturalWonderGroups("Occurs in groups of [amount] to [amount] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderConvertNeighbors("Neighboring tiles will convert to [baseTerrain]", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)), NaturalWonderConvertNeighbors("Neighboring tiles will convert to [baseTerrain]", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
// The "Except [terrainFilter]" could theoretically be implemented with a conditional // The "Except [terrainFilter]" could theoretically be implemented with a conditional
NaturalWonderConvertNeighborsExcept("Neighboring tiles except [baseTerrain] will convert to [baseTerrain]", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)), NaturalWonderConvertNeighborsExcept("Neighboring tiles except [baseTerrain] will convert to [baseTerrain]", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
GrantsGoldToFirstToDiscover("Grants 500 Gold to the first civilization to discover it", UniqueTarget.Terrain),
// endregion
DamagesContainingUnits("Units ending their turn on this terrain take [amount] damage", UniqueTarget.Terrain), DamagesContainingUnits("Units ending their turn on this terrain take [amount] damage", UniqueTarget.Terrain),
TerrainGrantsPromotion("Grants [promotion] ([comment]) to adjacent [mapUnitFilter] units for the rest of the game", UniqueTarget.Terrain), TerrainGrantsPromotion("Grants [promotion] ([comment]) to adjacent [mapUnitFilter] units for the rest of the game", UniqueTarget.Terrain),
@ -382,7 +398,9 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
ResourceAmountOnTiles("Deposits in [tileFilter] tiles always provide [amount] resources", UniqueTarget.Resource), ResourceAmountOnTiles("Deposits in [tileFilter] tiles always provide [amount] resources", UniqueTarget.Resource),
CityStateOnlyResource("Can only be created by Mercantile City-States", UniqueTarget.Resource), CityStateOnlyResource("Can only be created by Mercantile City-States", UniqueTarget.Resource),
////// Improvement uniques //endregion
////// region Improvement uniques
ImprovementBuildableByFreshWater("Can also be built on tiles adjacent to fresh water", UniqueTarget.Improvement), ImprovementBuildableByFreshWater("Can also be built on tiles adjacent to fresh water", UniqueTarget.Improvement),
ImprovementStatsOnTile("[stats] from [tileFilter] tiles", UniqueTarget.Improvement), ImprovementStatsOnTile("[stats] from [tileFilter] tiles", UniqueTarget.Improvement),
@Deprecated("As of 3.17.10", ReplaceWith("[stats] from [tileFilter] tiles <after discovering [tech]>"), DeprecationLevel.WARNING) @Deprecated("As of 3.17.10", ReplaceWith("[stats] from [tileFilter] tiles <after discovering [tech]>"), DeprecationLevel.WARNING)
@ -409,7 +427,9 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
Unpillagable("Unpillagable", UniqueTarget.Improvement), Unpillagable("Unpillagable", UniqueTarget.Improvement),
Indestructible("Indestructible", UniqueTarget.Improvement), Indestructible("Indestructible", UniqueTarget.Improvement),
///////////////////////////////////////// CONDITIONALS ///////////////////////////////////////// //endregion
///////////////////////////////////////// region CONDITIONALS /////////////////////////////////////////
/////// civ conditionals /////// civ conditionals
@ -446,12 +466,14 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
ConditionalNeighborTiles("with [amount] to [amount] neighboring [tileFilter] tiles", UniqueTarget.Conditional), ConditionalNeighborTiles("with [amount] to [amount] neighboring [tileFilter] tiles", UniqueTarget.Conditional),
ConditionalNeighborTilesAnd("with [amount] to [amount] neighboring [tileFilter] [tileFilter] tiles", UniqueTarget.Conditional), ConditionalNeighborTilesAnd("with [amount] to [amount] neighboring [tileFilter] [tileFilter] tiles", UniqueTarget.Conditional),
/////// region conditionals /////// area conditionals
ConditionalOnWaterMaps("on water maps", UniqueTarget.Conditional), ConditionalOnWaterMaps("on water maps", UniqueTarget.Conditional),
ConditionalInRegionOfType("in [regionType] Regions", UniqueTarget.Conditional), ConditionalInRegionOfType("in [regionType] Regions", UniqueTarget.Conditional),
ConditionalInRegionExceptOfType("in all except [regionType] Regions", UniqueTarget.Conditional), ConditionalInRegionExceptOfType("in all except [regionType] Regions", UniqueTarget.Conditional),
///////////////////////////////////////// TRIGGERED ONE-TIME ///////////////////////////////////////// //endregion
///////////////////////////////////////// region TRIGGERED ONE-TIME /////////////////////////////////////////
OneTimeFreeUnit("Free [baseUnitFilter] appears", UniqueTarget.Global), // used in Policies, Buildings OneTimeFreeUnit("Free [baseUnitFilter] appears", UniqueTarget.Global), // used in Policies, Buildings
@ -495,6 +517,8 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
@Deprecated("As of 3.16.15 - removed 3.18.4", ReplaceWith("Provides a [buildingName] in your first [amount] cities for free"), DeprecationLevel.ERROR) @Deprecated("As of 3.16.15 - removed 3.18.4", ReplaceWith("Provides a [buildingName] in your first [amount] cities for free"), DeprecationLevel.ERROR)
FreeSpecificBuildingsDeprecated("Immediately creates a [buildingName] in each of your first [amount] cities for free", UniqueTarget.Global), FreeSpecificBuildingsDeprecated("Immediately creates a [buildingName] in each of your first [amount] cities for free", UniqueTarget.Global),
//endregion
///////////////////////////////////////////// META ///////////////////////////////////////////// ///////////////////////////////////////////// META /////////////////////////////////////////////

View File

@ -210,6 +210,15 @@ Example: "May buy [buildingFilter] buildings with [Culture] for [20] times their
Applicable to: Global, FollowerBelief Applicable to: Global, FollowerBelief
#### Enables Research agreements
Applicable to: Global
#### Triggers victory
Applicable to: Global
#### Triggers a Cultural Victory upon completion
Applicable to: Global
#### [amount]% Strength #### [amount]% Strength
Example: "[20]% Strength" Example: "[20]% Strength"
@ -566,6 +575,9 @@ Example: "Neighboring tiles except [baseTerrain] will convert to [baseTerrain]"
Applicable to: Terrain Applicable to: Terrain
#### Grants 500 Gold to the first civilization to discover it
Applicable to: Terrain
#### Units ending their turn on this terrain take [amount] damage #### Units ending their turn on this terrain take [amount] damage
Example: "Units ending their turn on this terrain take [20] damage" Example: "Units ending their turn on this terrain take [20] damage"