Reordered the region of other global uniques and wrote a few unique tests (#9611)

This commit is contained in:
Xander Lenstra
2023-06-17 19:59:51 +02:00
committed by GitHub
parent 6be79671f3
commit 639d34e28d
10 changed files with 467 additions and 374 deletions

View File

@ -534,8 +534,8 @@ class City : IsPartOfGameInfoSerialization {
/** Implements [UniqueParameterType.CityFilter][com.unciv.models.ruleset.unique.UniqueParameterType.CityFilter] */
fun matchesFilter(filter: String, viewingCiv: Civilization = civ): Boolean {
return when (filter) {
"in this city" -> true
"in all cities" -> true // Filtered by the way uniques are found
"in this city" -> true // Filtered by the way uniques are found
"in all cities" -> true
"in other cities" -> true // Filtered by the way uniques are found
"in all coastal cities" -> isCoastal()
"in capital" -> isCapital()

View File

@ -245,9 +245,9 @@ class CivInfoTransientCache(val civInfo: Civilization) {
}
fun updateHasActiveEnemyMovementPenalty() {
civInfo.hasActiveEnemyMovementPenalty = civInfo.hasUnique(UniqueType.EnemyLandUnitsSpendExtraMovement)
civInfo.hasActiveEnemyMovementPenalty = civInfo.hasUnique(UniqueType.EnemyUnitsSpendExtraMovement)
civInfo.enemyMovementPenaltyUniques =
civInfo.getMatchingUniques(UniqueType.EnemyLandUnitsSpendExtraMovement)
civInfo.getMatchingUniques(UniqueType.EnemyUnitsSpendExtraMovement)
}
fun updateCitiesConnectedToCapital(initialSetup: Boolean = false) {

View File

@ -19,7 +19,7 @@ class UnitMovement(val unit: MapUnit) {
fun getEnemyMovementPenalty(civInfo:Civilization, enemyUnit: MapUnit): Float {
if (civInfo.enemyMovementPenaltyUniques != null && civInfo.enemyMovementPenaltyUniques!!.any()) {
return civInfo.enemyMovementPenaltyUniques!!.sumOf {
if (it.type!! == UniqueType.EnemyLandUnitsSpendExtraMovement
if (it.type!! == UniqueType.EnemyUnitsSpendExtraMovement
&& enemyUnit.matchesFilter(it.params[0]))
it.params[1].toInt()
else 0

View File

@ -683,7 +683,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
&& cityInfo.matchesFilter(it.params[1])})
UniqueTriggerActivation.triggerCivwideUnique(unique, cityInfo.civ, cityInfo, triggerNotificationText = triggerNotificationText)
if (hasUnique(UniqueType.EnemyLandUnitsSpendExtraMovement))
if (hasUnique(UniqueType.EnemyUnitsSpendExtraMovement))
civInfo.cache.updateHasActiveEnemyMovementPenalty()
// Korean unique - apparently gives the same as the research agreement

View File

@ -73,7 +73,7 @@ enum class UniqueFlag {
}
// I didn't put this is a companion object because APPARENTLY doing that means you can't use it in the init function.
// I didn't put this in a companion object because APPARENTLY doing that means you can't use it in the init function.
val numberRegex = Regex("\\d+$") // Any number of trailing digits
enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: List<UniqueFlag> = emptyList()) {
@ -100,8 +100,6 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
StatsFromTradeRoute("[stats] from each Trade Route", UniqueTarget.Global, UniqueTarget.FollowerBelief),
StatsFromGlobalCitiesFollowingReligion("[stats] for each global city following this religion", UniqueTarget.FounderBelief),
StatsFromGlobalFollowers("[stats] from every [amount] global followers [cityFilter]", UniqueTarget.FounderBelief),
// Used for City center
EnsureMinimumStats("Ensures a minimum tile yield of [stats]", UniqueTarget.Improvement),
// Stat percentage boosts
StatPercentBonus("[relativeAmount]% [stat]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
@ -128,6 +126,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
CityStateMilitaryUnits("Provides military units every ≈[amount] turns", UniqueTarget.CityState),
CityStateUniqueLuxury("Provides a unique luxury", UniqueTarget.CityState), // No conditional support as of yet
// Todo: Lowercase the 'U' of 'Units' in this unique
CityStateGiftedUnitsStartWithXp("Military Units gifted from City-States start with [amount] XP", UniqueTarget.Global),
CityStateMoreGiftedUnits("Militaristic City-States grant units [amount] times as fast when you are at war with a common nation", UniqueTarget.Global),
@ -149,32 +148,24 @@ 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.Global),
CostsResources("Costs [amount] [stockpiledResource]", UniqueTarget.Improvement, UniqueTarget.Building, UniqueTarget.Unit),
/// Growth
GrowthPercentBonus("[relativeAmount]% growth [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
CarryOverFood("[relativeAmount]% Food is carried over after population increases [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
GainFreeBuildings("Gain a free [buildingName] [cityFilter]", UniqueTarget.Global),
GreatPersonPointPercentage("[relativeAmount]% Great Person generation [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
DisablesReligion("Starting in this era disables religion", UniqueTarget.Era),
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),
StatsWhenAdoptingReligionSpeed("[stats] when a city adopts this religion for the first time (modified by game speed)", UniqueTarget.Global),
StatsWhenAdoptingReligion("[stats] when a city adopts this religion for the first time", UniqueTarget.Global),
UnhappinessFromPopulationTypePercentageChange("[relativeAmount]% Unhappiness from [populationFilter] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
// Todo: moddability: specialists -> [populationFilter]
FoodConsumptionBySpecialists("[relativeAmount]% Food consumption by specialists [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
ExcessHappinessToGlobalStat("[relativeAmount]% of excess happiness converted to [stat]", UniqueTarget.Global),
BorderGrowthPercentage("[relativeAmount]% Culture cost of natural border growth [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
TileCostPercentage("[relativeAmount]% Gold cost of acquiring tiles [cityFilter]", UniqueTarget.FollowerBelief, UniqueTarget.Global),
/// Happiness
UnhappinessFromCitiesDoubled("Unhappiness from number of Cities doubled", UniqueTarget.Global),
UnhappinessFromPopulationTypePercentageChange("[relativeAmount]% Unhappiness from [populationFilter] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
ExcessHappinessToGlobalStat("[relativeAmount]% of excess happiness converted to [stat]", UniqueTarget.Global),
RetainHappinessFromLuxury("Retain [relativeAmount]% of the happiness from a luxury after the last copy has been traded away", UniqueTarget.Global),
BonusHappinessFromLuxury("[amount] Happiness from each type of luxury resource", UniqueTarget.Global),
/// Unit Production
CannotBuildUnits("Cannot build [baseUnitFilter] units", UniqueTarget.Global),
EnablesConstructionOfSpaceshipParts("Enables construction of Spaceship parts", UniqueTarget.Global),
/// Buying units/buildings
// There is potential to merge these
BuyUnitsIncreasingCost("May buy [baseUnitFilter] units for [amount] [stat] [cityFilter] at an increasing price ([amount])", UniqueTarget.Global, UniqueTarget.FollowerBelief),
BuyBuildingsIncreasingCost("May buy [buildingFilter] buildings for [amount] [stat] [cityFilter] at an increasing price ([amount])", UniqueTarget.Global, UniqueTarget.FollowerBelief),
@ -182,113 +173,140 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
BuyBuildingsForAmountStat("May buy [buildingFilter] buildings for [amount] [stat] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
BuyUnitsWithStat("May buy [baseUnitFilter] units with [stat] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
BuyBuildingsWithStat("May buy [buildingFilter] buildings with [stat] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
BuyUnitsByProductionCost("May buy [baseUnitFilter] units with [stat] for [amount] times their normal Production cost", UniqueTarget.FollowerBelief, UniqueTarget.Global),
BuyBuildingsByProductionCost("May buy [buildingFilter] buildings with [stat] for [amount] times their normal Production cost", UniqueTarget.FollowerBelief, UniqueTarget.Global),
EnablesCivWideStatProduction("Enables conversion of city production to [civWideStat]", UniqueTarget.Global),
BuyItemsDiscount("[stat] cost of purchasing items in cities [relativeAmount]%", UniqueTarget.Global, UniqueTarget.FollowerBelief),
BuyBuildingsDiscount("[stat] cost of purchasing [buildingFilter] buildings [relativeAmount]%", UniqueTarget.Global, UniqueTarget.FollowerBelief),
BuyUnitsDiscount("[stat] cost of purchasing [baseUnitFilter] units [relativeAmount]%", UniqueTarget.Global, UniqueTarget.FollowerBelief),
/// Production to Stat conversion
EnablesCivWideStatProduction("Enables conversion of city production to [civWideStat]", UniqueTarget.Global),
ProductionToCivWideStatConversionBonus("Production to [civWideStat] conversion in cities changed by [relativeAmount]%", UniqueTarget.Global),
/// Improvements
// Should be replaced with moddable improvements when roads become moddable
RoadMovementSpeed("Improves movement speed on roads",UniqueTarget.Global),
RoadsConnectAcrossRivers("Roads connect tiles across rivers", UniqueTarget.Global),
RoadMaintenance("[relativeAmount]% maintenance on road & railroads", UniqueTarget.Global),
NoImprovementMaintenanceInSpecificTiles("No Maintenance costs for improvements in [tileFilter] tiles", UniqueTarget.Global),
TileImprovementTime("[relativeAmount]% tile improvement construction time", UniqueTarget.Global, UniqueTarget.Unit),
/// Building Maintenance
GainFreeBuildings("Gain a free [buildingName] [cityFilter]", UniqueTarget.Global),
BuildingMaintenance("[relativeAmount]% maintenance cost for buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
/// Border growth
BorderGrowthPercentage("[relativeAmount]% Culture cost of natural border growth [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
TileCostPercentage("[relativeAmount]% Gold cost of acquiring tiles [cityFilter]", UniqueTarget.FollowerBelief, UniqueTarget.Global),
/// Policy Cost
LessPolicyCostFromCities("Each city founded increases culture cost of policies [relativeAmount]% less than normal", UniqueTarget.Global),
LessPolicyCost("[relativeAmount]% Culture cost of adopting new Policies", UniqueTarget.Global),
/// Natural Wonders
StatsFromNaturalWonders("[stats] for every known Natural Wonder", UniqueTarget.Global),
// TODO: moddability of the numbers
GoldWhenDiscoveringNaturalWonder("100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it)", UniqueTarget.Global),
/// Great Persons
GreatPersonPointPercentage("[relativeAmount]% Great Person generation [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
ProvidesGoldWheneverGreatPersonExpended("Provides a sum of gold each time you spend a Great Person", UniqueTarget.Global),
ProvidesStatsWheneverGreatPersonExpended("[stats] whenever a Great Person is expended", UniqueTarget.Global),
PercentGoldFromTradeMissions("[relativeAmount]% Gold from Great Merchant trade missions", UniqueTarget.Global),
GreatGeneralProvidesDoubleCombatBonus("Great General provides double combat bonus", UniqueTarget.Unit, UniqueTarget.Global),
// 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),
MayanCalendarDisplay("Once The Long Count activates, the year on the world screen displays as the traditional Mayan Long Count.", UniqueTarget.Global),
RetainHappinessFromLuxury("Retain [relativeAmount]% of the happiness from a luxury after the last copy has been traded away", UniqueTarget.Global),
BonusHappinessFromLuxury("[amount] Happiness from each type of luxury resource", UniqueTarget.Global),
LessPolicyCostFromCities("Each city founded increases culture cost of policies [relativeAmount]% less than normal", UniqueTarget.Global),
LessPolicyCost("[relativeAmount]% Culture cost of adopting new Policies", UniqueTarget.Global),
// Todo: Sign should not be part of the unique placeholder
StrategicResourcesIncrease("Quantity of strategic resources produced by the empire +[relativeAmount]%", UniqueTarget.Global), // used in Policy
DoubleResourceProduced("Double quantity of [resource] produced", UniqueTarget.Global),
StatsFromNaturalWonders("[stats] for every known Natural Wonder", UniqueTarget.Global),
EnablesConstructionOfSpaceshipParts("Enables construction of Spaceship parts", UniqueTarget.Global),
EnemyLandUnitsSpendExtraMovement("Enemy [mapUnitFilter] units must spend [amount] extra movement points when inside your territory", UniqueTarget.Global),
ProductionToCivWideStatConversionBonus("Production to [civWideStat] conversion in cities changed by [relativeAmount]%", UniqueTarget.Global),
// Misc national uniques
NotifiedOfBarbarianEncampments("Notified of new Barbarian encampments", UniqueTarget.Global),
BorrowsCityNames("\"Borrows\" city names from other civilizations in the game", UniqueTarget.Global),
GoldWhenDiscoveringNaturalWonder("100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it)", UniqueTarget.Global),
UnhappinessFromCitiesDoubled("Unhappiness from number of Cities doubled", UniqueTarget.Global),
GreatGeneralProvidesDoubleCombatBonus("Great General provides double combat bonus", UniqueTarget.Unit, UniqueTarget.Global),
TechBoostWhenScientificBuildingsBuiltInCapital("Receive a tech boost when scientific buildings/wonders are built in capital", UniqueTarget.Global),
MayNotGenerateGreatProphet("May not generate great prophet equivalents naturally", UniqueTarget.Global),
GainFromEncampment("When conquering an encampment, earn [amount] Gold and recruit a Barbarian unit", UniqueTarget.Global),
GainFromDefeatingUnit("When defeating a [mapUnitFilter] unit, earn [amount] Gold and recruit it", UniqueTarget.Global),
TripleGoldFromEncampmentsAndCities("Receive triple Gold from Barbarian encampments and pillaging Cities", UniqueTarget.Global),
CitiesAreRazedXTimesFaster("Cities are razed [amount] times as fast", UniqueTarget.Global),
GreatPersonBoostWithFriendship("When declaring friendship, both parties gain a [relativeAmount]% boost to great person generation", UniqueTarget.Global),
NoImprovementMaintenanceInSpecificTiles("No Maintenance costs for improvements in [tileFilter] tiles", UniqueTarget.Global),
OtherCivsCityStateRelationsDegradeFaster("Influence of all other civilizations with all city-states degrades [relativeAmount]% faster", UniqueTarget.Global),
LandUnitsCrossTerrainAfterUnitGained("Land units may cross [terrainName] tiles after the first [baseUnitFilter] is earned", UniqueTarget.Global),
GainInfluenceWithUnitGiftToCityState("Gain [amount] Influence with a [baseUnitFilter] gift to a City-State", UniqueTarget.Global),
FaithCostOfGreatProphetChange("[relativeAmount]% Faith cost of generating Great Prophet equivalents", UniqueTarget.Global),
RestingPointOfCityStatesFollowingReligionChange("Resting point for Influence with City-States following this religion [amount]", UniqueTarget.Global),
MayNotAnnexCities("May not annex cities", UniqueTarget.Nation),
ProvidesGoldWheneverGreatPersonExpended("Provides a sum of gold each time you spend a Great Person", UniqueTarget.Global),
ProvidesStatsWheneverGreatPersonExpended("[stats] whenever a Great Person is expended", UniqueTarget.Global),
/// Unit Maintenance & Supply
BaseUnitSupply("[amount] Unit Supply", UniqueTarget.Global),
UnitSupplyPerPop("[amount] Unit Supply per [amount] population [cityFilter]", UniqueTarget.Global),
UnitSupplyPerCity("[amount] Unit Supply per city", UniqueTarget.Global),
FreeUnits("[amount] units cost no maintenance", UniqueTarget.Global),
UnitsInCitiesNoMaintenance("Units in cities cost no Maintenance", UniqueTarget.Global),
// Acts as a trigger - this should be generalized somehow but the current setup does not allow this
// It would currently mean cycling through EVERY unique type to find ones with a specific conditional...
ReceiveFreeUnitWhenDiscoveringTech("Receive free [unit] when you discover [tech]", UniqueTarget.Global),
// Units entering Tiles
// ToDo: make per unit and use unit filters?
LandUnitEmbarkation("Enables embarkation for land units", UniqueTarget.Global),
UnitsMayEnterOcean("Enables [mapUnitFilter] units to enter ocean tiles", UniqueTarget.Global),
LandUnitsCrossTerrainAfterUnitGained("Land units may cross [terrainName] tiles after the first [baseUnitFilter] is earned", UniqueTarget.Global),
EnemyUnitsSpendExtraMovement("Enemy [mapUnitFilter] units must spend [amount] extra movement points when inside your territory", UniqueTarget.Global),
/// Unit Abilities
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),
// 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),
/// City Strength
BetterDefensiveBuildings("[relativeAmount]% City Strength from defensive buildings", UniqueTarget.Global),
StrengthForCities("[relativeAmount]% Strength for cities", UniqueTarget.Global, UniqueTarget.FollowerBelief),
/// Resource production & consumption
ConsumesResources("Consumes [amount] [resource]", UniqueTarget.Improvement, UniqueTarget.Building, UniqueTarget.Unit),
ProvidesResources("Provides [amount] [resource]", UniqueTarget.Improvement, UniqueTarget.Global),
// Todo: Sign should not be part of the unique placeholder
CostsResources("Costs [amount] [stockpiledResource]", UniqueTarget.Improvement, UniqueTarget.Building, UniqueTarget.Unit),
StrategicResourcesIncrease("Quantity of strategic resources produced by the empire +[relativeAmount]%", UniqueTarget.Global), // used by Policies
DoubleResourceProduced("Double quantity of [resource] produced", UniqueTarget.Global),
/// Agreements
EnablesOpenBorders("Enables Open Borders agreements", UniqueTarget.Global),
// Should the 'R' in 'Research agreements' be capitalized?
EnablesResearchAgreements("Enables Research agreements", UniqueTarget.Global),
ScienceFromResearchAgreements("Science gained from research agreements [relativeAmount]%", UniqueTarget.Global),
TriggersVictory("Triggers victory", UniqueTarget.Global),
TriggersCulturalVictory("Triggers a Cultural Victory upon completion", UniqueTarget.Global),
GreatPersonBoostWithFriendship("When declaring friendship, both parties gain a [relativeAmount]% boost to great person generation", UniqueTarget.Global),
BetterDefensiveBuildings("[relativeAmount]% City Strength from defensive buildings", UniqueTarget.Global),
TileImprovementTime("[relativeAmount]% tile improvement construction time", UniqueTarget.Global, UniqueTarget.Unit),
PercentGoldFromTradeMissions("[relativeAmount]% 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),
/// City State Influence
OtherCivsCityStateRelationsDegradeFaster("Influence of all other civilizations with all city-states degrades [relativeAmount]% faster", UniqueTarget.Global),
GainInfluenceWithUnitGiftToCityState("Gain [amount] Influence with a [baseUnitFilter] gift to a City-State", UniqueTarget.Global),
RestingPointOfCityStatesFollowingReligionChange("Resting point for Influence with City-States following this religion [amount]", UniqueTarget.Global),
GoldenAgeLength("[relativeAmount]% Golden Age length", UniqueTarget.Global),
StrengthForCities("[relativeAmount]% Strength for cities", UniqueTarget.Global, UniqueTarget.FollowerBelief),
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),
UnitsMayEnterOcean("Enables [mapUnitFilter] units to enter ocean tiles", UniqueTarget.Global),
PopulationLossFromNukes("Population loss from nuclear attacks [relativeAmount]% [cityFilter]", UniqueTarget.Global),
/// Barbarian Encampments, Pillaging them & Converting Units
NotifiedOfBarbarianEncampments("Notified of new Barbarian encampments", UniqueTarget.Global),
TripleGoldFromEncampmentsAndCities("Receive triple Gold from Barbarian encampments and pillaging Cities", UniqueTarget.Global),
GainFromEncampment("When conquering an encampment, earn [amount] Gold and recruit a Barbarian unit", UniqueTarget.Global),
GainFromDefeatingUnit("When defeating a [mapUnitFilter] unit, earn [amount] Gold and recruit it", UniqueTarget.Global),
/// Religion
DisablesReligion("Starting in this era disables religion", UniqueTarget.Era),
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),
StatsWhenAdoptingReligionSpeed("[stats] when a city adopts this religion for the first time (modified by game speed)", UniqueTarget.Global),
StatsWhenAdoptingReligion("[stats] when a city adopts this religion for the first time", UniqueTarget.Global),
NaturalReligionSpreadStrength("[relativeAmount]% Natural religion spread [cityFilter]", UniqueTarget.FollowerBelief, UniqueTarget.Global),
ReligionSpreadDistance("Religion naturally spreads to cities [amount] tiles away", UniqueTarget.Global, UniqueTarget.FollowerBelief),
MayNotGenerateGreatProphet("May not generate great prophet equivalents naturally", UniqueTarget.Global),
FaithCostOfGreatProphetChange("[relativeAmount]% Faith cost of generating Great Prophet equivalents", UniqueTarget.Global),
UnitStartingActions("[baseUnitFilter] units built [cityFilter] can [action] [amount] extra times", UniqueTarget.Global, UniqueTarget.FollowerBelief),
/// Things you get at the start of the game
StartingTech("Starting tech", UniqueTarget.Tech),
StartsWithTech("Starts with [tech]", UniqueTarget.Nation),
StartsWithPolicy("Starts with [policy] adopted", UniqueTarget.Nation),
ResearchableMultipleTimes("Can be continually researched", UniqueTarget.Global),
BaseUnitSupply("[amount] Unit Supply", UniqueTarget.Global),
UnitSupplyPerPop("[amount] Unit Supply per [amount] population [cityFilter]", UniqueTarget.Global),
UnitSupplyPerCity("[amount] Unit Supply per city", UniqueTarget.Global),
UnitsInCitiesNoMaintenance("Units in cities cost no Maintenance", UniqueTarget.Global),
/// Victory
TriggersVictory("Triggers victory", UniqueTarget.Global),
TriggersCulturalVictory("Triggers a Cultural Victory upon completion", UniqueTarget.Global),
/// Misc.
MayNotAnnexCities("May not annex cities", UniqueTarget.Global),
BorrowsCityNames("\"Borrows\" city names from other civilizations in the game", UniqueTarget.Global),
CitiesAreRazedXTimesFaster("Cities are razed [amount] times as fast", UniqueTarget.Global),
TechBoostWhenScientificBuildingsBuiltInCapital("Receive a tech boost when scientific buildings/wonders are built in capital", UniqueTarget.Global),
ResearchableMultipleTimes("Can be continually researched", UniqueTarget.Tech),
GoldenAgeLength("[relativeAmount]% Golden Age length", UniqueTarget.Global),
PopulationLossFromNukes("Population loss from nuclear attacks [relativeAmount]% [cityFilter]", UniqueTarget.Global),
SpawnRebels("Rebel units may spawn", UniqueTarget.Global),
//endregion
//endregion Global uniques
@ -594,6 +612,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
ImprovementBuildableByFreshWater("Can also be built on tiles adjacent to fresh water", UniqueTarget.Improvement),
ImprovementStatsOnTile("[stats] from [tileFilter] tiles", UniqueTarget.Improvement),
ImprovementStatsForAdjacencies("[stats] for each adjacent [tileFilter]", UniqueTarget.Improvement),
EnsureMinimumStats("Ensures a minimum tile yield of [stats]", UniqueTarget.Improvement), // City center
CanBuildOutsideBorders("Can be built outside your borders", UniqueTarget.Improvement),
CanBuildJustOutsideBorders("Can be built just outside your borders", UniqueTarget.Improvement),

View File

@ -319,21 +319,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "City-State Influence recovers at twice the normal rate"
Applicable to: Global
??? example "[amount] units cost no maintenance"
Example: "[3] units cost no maintenance"
Applicable to: Global
??? example "Cannot build [baseUnitFilter] units"
Example: "Cannot build [Melee] units"
Applicable to: Global
??? example "Provides [amount] [resource]"
Example: "Provides [3] [Iron]"
Applicable to: Global, Improvement
??? example "[relativeAmount]% growth [cityFilter]"
Example: "[+20]% growth [in all cities]"
@ -344,34 +329,12 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Global, FollowerBelief
??? example "Gain a free [buildingName] [cityFilter]"
Example: "Gain a free [Library] [in all cities]"
Applicable to: Global
??? example "[relativeAmount]% Great Person generation [cityFilter]"
Example: "[+20]% Great Person generation [in all cities]"
??? example "[relativeAmount]% Food consumption by specialists [cityFilter]"
Example: "[+20]% Food consumption by specialists [in all cities]"
Applicable to: Global, FollowerBelief
??? example "May choose [amount] additional [beliefType] beliefs when [foundingOrEnhancing] a religion"
Example: "May choose [3] additional [Follower] beliefs when [founding] a religion"
Applicable to: Global
??? example "May choose [amount] additional belief(s) of any type when [foundingOrEnhancing] a religion"
Example: "May choose [3] additional belief(s) of any type when [founding] a religion"
Applicable to: Global
??? example "[stats] when a city adopts this religion for the first time (modified by game speed)"
Example: "[+1 Gold, +2 Production] when a city adopts this religion for the first time (modified by game speed)"
Applicable to: Global
??? example "[stats] when a city adopts this religion for the first time"
Example: "[+1 Gold, +2 Production] when a city adopts this religion for the first time"
??? example "Unhappiness from number of Cities doubled"
Applicable to: Global
??? example "[relativeAmount]% Unhappiness from [populationFilter] [cityFilter]"
@ -379,25 +342,28 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Global, FollowerBelief
??? example "[relativeAmount]% Food consumption by specialists [cityFilter]"
Example: "[+20]% Food consumption by specialists [in all cities]"
Applicable to: Global, FollowerBelief
??? example "[relativeAmount]% of excess happiness converted to [stat]"
Example: "[+20]% of excess happiness converted to [Culture]"
Applicable to: Global
??? example "[relativeAmount]% Culture cost of natural border growth [cityFilter]"
Example: "[+20]% Culture cost of natural border growth [in all cities]"
??? example "Retain [relativeAmount]% of the happiness from a luxury after the last copy has been traded away"
Example: "Retain [+20]% of the happiness from a luxury after the last copy has been traded away"
Applicable to: Global, FollowerBelief
Applicable to: Global
??? example "[relativeAmount]% Gold cost of acquiring tiles [cityFilter]"
Example: "[+20]% Gold cost of acquiring tiles [in all cities]"
??? example "[amount] Happiness from each type of luxury resource"
Example: "[3] Happiness from each type of luxury resource"
Applicable to: Global, FollowerBelief
Applicable to: Global
??? example "Cannot build [baseUnitFilter] units"
Example: "Cannot build [Melee] units"
Applicable to: Global
??? example "Enables construction of Spaceship parts"
Applicable to: Global
??? example "May buy [baseUnitFilter] units for [amount] [stat] [cityFilter] at an increasing price ([amount])"
Example: "May buy [Melee] units for [3] [Culture] [in all cities] at an increasing price ([3])"
@ -439,11 +405,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Global, FollowerBelief
??? example "Enables conversion of city production to [civWideStat]"
Example: "Enables conversion of city production to [Gold]"
Applicable to: Global
??? example "[stat] cost of purchasing items in cities [relativeAmount]%"
Example: "[Culture] cost of purchasing items in cities [+20]%"
@ -459,6 +420,16 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Global, FollowerBelief
??? example "Enables conversion of city production to [civWideStat]"
Example: "Enables conversion of city production to [Gold]"
Applicable to: Global
??? example "Production to [civWideStat] conversion in cities changed by [relativeAmount]%"
Example: "Production to [Gold] conversion in cities changed by [+20]%"
Applicable to: Global
??? example "Improves movement speed on roads"
Applicable to: Global
@ -470,28 +441,35 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Global
??? example "No Maintenance costs for improvements in [tileFilter] tiles"
Example: "No Maintenance costs for improvements in [Farm] tiles"
Applicable to: Global
??? example "[relativeAmount]% tile improvement construction time"
Example: "[+20]% tile improvement construction time"
Applicable to: Global, Unit
??? example "Gain a free [buildingName] [cityFilter]"
Example: "Gain a free [Library] [in all cities]"
Applicable to: Global
??? example "[relativeAmount]% maintenance cost for buildings [cityFilter]"
Example: "[+20]% maintenance cost for buildings [in all cities]"
Applicable to: Global, FollowerBelief
??? example "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."
Example: "Receive a free Great Person at the end of every [comment] (every 394 years), after researching [Agriculture]. Each bonus person can only be chosen once."
??? example "[relativeAmount]% Culture cost of natural border growth [cityFilter]"
Example: "[+20]% Culture cost of natural border growth [in all cities]"
Applicable to: Global
Applicable to: Global, FollowerBelief
??? example "Once The Long Count activates, the year on the world screen displays as the traditional Mayan Long Count."
Applicable to: Global
??? example "[relativeAmount]% Gold cost of acquiring tiles [cityFilter]"
Example: "[+20]% Gold cost of acquiring tiles [in all cities]"
??? example "Retain [relativeAmount]% of the happiness from a luxury after the last copy has been traded away"
Example: "Retain [+20]% of the happiness from a luxury after the last copy has been traded away"
Applicable to: Global
??? example "[amount] Happiness from each type of luxury resource"
Example: "[3] Happiness from each type of luxury resource"
Applicable to: Global
Applicable to: Global, FollowerBelief
??? example "Each city founded increases culture cost of policies [relativeAmount]% less than normal"
Example: "Each city founded increases culture cost of policies [+20]% less than normal"
@ -503,107 +481,18 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Global
??? example "Quantity of strategic resources produced by the empire +[relativeAmount]%"
Example: "Quantity of strategic resources produced by the empire +[+20]%"
Applicable to: Global
??? example "Double quantity of [resource] produced"
Example: "Double quantity of [Iron] produced"
Applicable to: Global
??? example "[stats] for every known Natural Wonder"
Example: "[+1 Gold, +2 Production] for every known Natural Wonder"
Applicable to: Global
??? example "Enables construction of Spaceship parts"
Applicable to: Global
??? example "Enemy [mapUnitFilter] units must spend [amount] extra movement points when inside your territory"
Example: "Enemy [Wounded] units must spend [3] extra movement points when inside your territory"
Applicable to: Global
??? example "Production to [civWideStat] conversion in cities changed by [relativeAmount]%"
Example: "Production to [Gold] conversion in cities changed by [+20]%"
Applicable to: Global
??? example "Notified of new Barbarian encampments"
Applicable to: Global
??? example ""Borrows" city names from other civilizations in the game"
Applicable to: Global
??? example "100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it)"
Applicable to: Global
??? example "Unhappiness from number of Cities doubled"
Applicable to: Global
??? example "[relativeAmount]% Great Person generation [cityFilter]"
Example: "[+20]% Great Person generation [in all cities]"
??? example "Great General provides double combat bonus"
Applicable to: Global, Unit
??? example "Receive a tech boost when scientific buildings/wonders are built in capital"
Applicable to: Global
??? example "May not generate great prophet equivalents naturally"
Applicable to: Global
??? example "When conquering an encampment, earn [amount] Gold and recruit a Barbarian unit"
Example: "When conquering an encampment, earn [3] Gold and recruit a Barbarian unit"
Applicable to: Global
??? example "When defeating a [mapUnitFilter] unit, earn [amount] Gold and recruit it"
Example: "When defeating a [Wounded] unit, earn [3] Gold and recruit it"
Applicable to: Global
??? example "Receive triple Gold from Barbarian encampments and pillaging Cities"
Applicable to: Global
??? example "Cities are razed [amount] times as fast"
Example: "Cities are razed [3] times as fast"
Applicable to: Global
??? example "When declaring friendship, both parties gain a [relativeAmount]% boost to great person generation"
Example: "When declaring friendship, both parties gain a [+20]% boost to great person generation"
Applicable to: Global
??? example "No Maintenance costs for improvements in [tileFilter] tiles"
Example: "No Maintenance costs for improvements in [Farm] tiles"
Applicable to: Global
??? example "Influence of all other civilizations with all city-states degrades [relativeAmount]% faster"
Example: "Influence of all other civilizations with all city-states degrades [+20]% faster"
Applicable to: Global
??? example "Land units may cross [terrainName] tiles after the first [baseUnitFilter] is earned"
Example: "Land units may cross [Forest] tiles after the first [Melee] is earned"
Applicable to: Global
??? example "Gain [amount] Influence with a [baseUnitFilter] gift to a City-State"
Example: "Gain [3] Influence with a [Melee] gift to a City-State"
Applicable to: Global
??? example "[relativeAmount]% Faith cost of generating Great Prophet equivalents"
Example: "[+20]% Faith cost of generating Great Prophet equivalents"
Applicable to: Global
??? example "Resting point for Influence with City-States following this religion [amount]"
Example: "Resting point for Influence with City-States following this religion [3]"
Applicable to: Global
Applicable to: Global, FollowerBelief
??? example "Provides a sum of gold each time you spend a Great Person"
Applicable to: Global
@ -613,97 +502,20 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Global
??? example "Receive free [unit] when you discover [tech]"
Example: "Receive free [Musketman] when you discover [Agriculture]"
Applicable to: Global
??? example "Enables Open Borders agreements"
Applicable to: Global
??? example "Enables Research agreements"
Applicable to: Global
??? example "Science gained from research agreements [relativeAmount]%"
Example: "Science gained from research agreements [+20]%"
Applicable to: Global
??? example "Triggers victory"
Applicable to: Global
??? example "Triggers a Cultural Victory upon completion"
Applicable to: Global
??? example "[relativeAmount]% City Strength from defensive buildings"
Example: "[+20]% City Strength from defensive buildings"
Applicable to: Global
??? example "[relativeAmount]% tile improvement construction time"
Example: "[+20]% tile improvement construction time"
Applicable to: Global, Unit
??? example "[relativeAmount]% Gold from Great Merchant trade missions"
Example: "[+20]% Gold from Great Merchant trade missions"
Applicable to: Global
??? example "[mapUnitFilter] Units adjacent to this city heal [amount] HP per turn when healing"
Example: "[Wounded] Units adjacent to this city heal [3] HP per turn when healing"
??? example "Great General provides double combat bonus"
Applicable to: Global, Unit
Applicable to: Global, FollowerBelief
??? example "[relativeAmount]% Golden Age length"
Example: "[+20]% Golden Age length"
??? example "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."
Example: "Receive a free Great Person at the end of every [comment] (every 394 years), after researching [Agriculture]. Each bonus person can only be chosen once."
Applicable to: Global
??? example "[relativeAmount]% Strength for cities"
Example: "[+20]% Strength for cities"
Applicable to: Global, FollowerBelief
??? example "New [baseUnitFilter] units start with [amount] Experience [cityFilter]"
Example: "New [Melee] units start with [3] Experience [in all cities]"
Applicable to: Global, FollowerBelief
??? example "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
??? example "[baseUnitFilter] units built [cityFilter] can [action] [amount] extra times"
Example: "[Melee] units built [in all cities] can [Spread Religion] [3] extra times"
Applicable to: Global, FollowerBelief
??? example "Enables embarkation for land units"
Applicable to: Global
??? example "Enables [mapUnitFilter] units to enter ocean tiles"
Example: "Enables [Wounded] units to enter ocean tiles"
Applicable to: Global
??? example "Population loss from nuclear attacks [relativeAmount]% [cityFilter]"
Example: "Population loss from nuclear attacks [+20]% [in all cities]"
Applicable to: Global
??? example "[relativeAmount]% Natural religion spread [cityFilter]"
Example: "[+20]% Natural religion spread [in all cities]"
Applicable to: Global, FollowerBelief
??? example "Religion naturally spreads to cities [amount] tiles away"
Example: "Religion naturally spreads to cities [3] tiles away"
Applicable to: Global, FollowerBelief
??? example "Can be continually researched"
??? example "Once The Long Count activates, the year on the world screen displays as the traditional Mayan Long Count."
Applicable to: Global
??? example "[amount] Unit Supply"
@ -721,9 +533,197 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Global
??? example "[amount] units cost no maintenance"
Example: "[3] units cost no maintenance"
Applicable to: Global
??? example "Units in cities cost no Maintenance"
Applicable to: Global
??? example "Receive free [unit] when you discover [tech]"
Example: "Receive free [Musketman] when you discover [Agriculture]"
Applicable to: Global
??? example "Enables embarkation for land units"
Applicable to: Global
??? example "Enables [mapUnitFilter] units to enter ocean tiles"
Example: "Enables [Wounded] units to enter ocean tiles"
Applicable to: Global
??? example "Land units may cross [terrainName] tiles after the first [baseUnitFilter] is earned"
Example: "Land units may cross [Forest] tiles after the first [Melee] is earned"
Applicable to: Global
??? example "Enemy [mapUnitFilter] units must spend [amount] extra movement points when inside your territory"
Example: "Enemy [Wounded] units must spend [3] extra movement points when inside your territory"
Applicable to: Global
??? example "New [baseUnitFilter] units start with [amount] Experience [cityFilter]"
Example: "New [Melee] units start with [3] Experience [in all cities]"
Applicable to: Global, FollowerBelief
??? example "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
??? example "[mapUnitFilter] Units adjacent to this city heal [amount] HP per turn when healing"
Example: "[Wounded] Units adjacent to this city heal [3] HP per turn when healing"
Applicable to: Global, FollowerBelief
??? example "[relativeAmount]% City Strength from defensive buildings"
Example: "[+20]% City Strength from defensive buildings"
Applicable to: Global
??? example "[relativeAmount]% Strength for cities"
Example: "[+20]% Strength for cities"
Applicable to: Global, FollowerBelief
??? example "Provides [amount] [resource]"
Example: "Provides [3] [Iron]"
Applicable to: Global, Improvement
??? example "Quantity of strategic resources produced by the empire +[relativeAmount]%"
Example: "Quantity of strategic resources produced by the empire +[+20]%"
Applicable to: Global
??? example "Double quantity of [resource] produced"
Example: "Double quantity of [Iron] produced"
Applicable to: Global
??? example "Enables Open Borders agreements"
Applicable to: Global
??? example "Enables Research agreements"
Applicable to: Global
??? example "Science gained from research agreements [relativeAmount]%"
Example: "Science gained from research agreements [+20]%"
Applicable to: Global
??? example "When declaring friendship, both parties gain a [relativeAmount]% boost to great person generation"
Example: "When declaring friendship, both parties gain a [+20]% boost to great person generation"
Applicable to: Global
??? example "Influence of all other civilizations with all city-states degrades [relativeAmount]% faster"
Example: "Influence of all other civilizations with all city-states degrades [+20]% faster"
Applicable to: Global
??? example "Gain [amount] Influence with a [baseUnitFilter] gift to a City-State"
Example: "Gain [3] Influence with a [Melee] gift to a City-State"
Applicable to: Global
??? example "Resting point for Influence with City-States following this religion [amount]"
Example: "Resting point for Influence with City-States following this religion [3]"
Applicable to: Global
??? example "Notified of new Barbarian encampments"
Applicable to: Global
??? example "Receive triple Gold from Barbarian encampments and pillaging Cities"
Applicable to: Global
??? example "When conquering an encampment, earn [amount] Gold and recruit a Barbarian unit"
Example: "When conquering an encampment, earn [3] Gold and recruit a Barbarian unit"
Applicable to: Global
??? example "When defeating a [mapUnitFilter] unit, earn [amount] Gold and recruit it"
Example: "When defeating a [Wounded] unit, earn [3] Gold and recruit it"
Applicable to: Global
??? example "May choose [amount] additional [beliefType] beliefs when [foundingOrEnhancing] a religion"
Example: "May choose [3] additional [Follower] beliefs when [founding] a religion"
Applicable to: Global
??? example "May choose [amount] additional belief(s) of any type when [foundingOrEnhancing] a religion"
Example: "May choose [3] additional belief(s) of any type when [founding] a religion"
Applicable to: Global
??? example "[stats] when a city adopts this religion for the first time (modified by game speed)"
Example: "[+1 Gold, +2 Production] when a city adopts this religion for the first time (modified by game speed)"
Applicable to: Global
??? example "[stats] when a city adopts this religion for the first time"
Example: "[+1 Gold, +2 Production] when a city adopts this religion for the first time"
Applicable to: Global
??? example "[relativeAmount]% Natural religion spread [cityFilter]"
Example: "[+20]% Natural religion spread [in all cities]"
Applicable to: Global, FollowerBelief
??? example "Religion naturally spreads to cities [amount] tiles away"
Example: "Religion naturally spreads to cities [3] tiles away"
Applicable to: Global, FollowerBelief
??? example "May not generate great prophet equivalents naturally"
Applicable to: Global
??? example "[relativeAmount]% Faith cost of generating Great Prophet equivalents"
Example: "[+20]% Faith cost of generating Great Prophet equivalents"
Applicable to: Global
??? example "[baseUnitFilter] units built [cityFilter] can [action] [amount] extra times"
Example: "[Melee] units built [in all cities] can [Spread Religion] [3] extra times"
Applicable to: Global, FollowerBelief
??? example "Triggers victory"
Applicable to: Global
??? example "Triggers a Cultural Victory upon completion"
Applicable to: Global
??? example "May not annex cities"
Applicable to: Global
??? example ""Borrows" city names from other civilizations in the game"
Applicable to: Global
??? example "Cities are razed [amount] times as fast"
Example: "Cities are razed [3] times as fast"
Applicable to: Global
??? example "Receive a tech boost when scientific buildings/wonders are built in capital"
Applicable to: Global
??? example "[relativeAmount]% Golden Age length"
Example: "[+20]% Golden Age length"
Applicable to: Global
??? example "Population loss from nuclear attacks [relativeAmount]% [cityFilter]"
Example: "Population loss from nuclear attacks [+20]% [in all cities]"
Applicable to: Global
??? example "Rebel units may spawn"
Applicable to: Global
@ -863,9 +863,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "Will not be chosen for new games"
Applicable to: Nation
??? example "May not annex cities"
Applicable to: Nation
??? example "Starts with [tech]"
Example: "Starts with [Agriculture]"
@ -890,6 +887,9 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "Starting tech"
Applicable to: Tech
??? example "Can be continually researched"
Applicable to: Tech
??? example "Only available"
Applicable to: Tech, Policy, FounderBelief, FollowerBelief, Building, Unit, Promotion, Improvement, Ruins
@ -1514,11 +1514,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Terrain
## Improvement uniques
??? example "Ensures a minimum tile yield of [stats]"
Example: "Ensures a minimum tile yield of [+1 Gold, +2 Production]"
Applicable to: Improvement
??? example "Can also be built on tiles adjacent to fresh water"
Applicable to: Improvement
@ -1532,6 +1527,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Improvement
??? example "Ensures a minimum tile yield of [stats]"
Example: "Ensures a minimum tile yield of [+1 Gold, +2 Production]"
Applicable to: Improvement
??? example "Can be built outside your borders"
Applicable to: Improvement

View File

@ -524,6 +524,56 @@ class GlobalUniquesTests {
//endregion
// region Other Global Uniques
// region growth
@Test
fun growthPercentBonusTest() {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val building = game.createBuilding("[+100]% growth [in all cities]")
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["[Buildings] ([Growth])"]!!.equals(Stats(food=2f)))
}
@Test
fun carryOverFoodTest() {
val civInfo = game.addCiv("[50]% Food is carried over after population increases [in all cities]")
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val foodNecessary = cityInfo.population.getFoodToNextPopulation()
cityInfo.population.nextTurn(foodNecessary)
Assert.assertTrue(cityInfo.population.foodStored == (foodNecessary * 0.5f).toInt())
}
@Test
fun foodConsumptionBySpecialistsTest() {
val civInfo = game.addCiv("[-50]% Food consumption by specialists [in all cities]")
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 1)
val building = game.createBuilding()
val specialistName = game.createSpecialist()
building.specialistSlots.add(specialistName, 1)
cityInfo.population.specialistAllocations[specialistName] = 1
cityInfo.cityStats.update()
print(cityInfo.cityStats.finalStatList)
Assert.assertTrue(cityInfo.cityStats.finalStatList["Population"]!!.food == -1f)
}
// endregion growth
// region Great Persons
@Test
fun statsSpendingGreatPeople() {
val civInfo = game.addCiv()
@ -538,27 +588,8 @@ class GlobalUniquesTests {
unit.consume()
Assert.assertTrue(civInfo.gold == 250)
}
// endregion
@Test
fun pillageYieldTest() {
game.makeHexagonalMap(2)
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f, 0f), Constants.grassland)
val cityTile = game.setTileFeatures(Vector2(2f,0f), Constants.grassland)
val cityInfo = game.addCity(civInfo, cityTile, true)
cityInfo.population.foodStored = 0 // just to be sure
civInfo.addGold(-civInfo.gold) // reset gold just to be sure
val testImprovement = game.createTileImprovement("Pillaging this improvement yields [+20 Gold, +11 Food]")
tile.changeImprovement(testImprovement.name)
val unit = game.addUnit("Warrior", civInfo, tile)
unit.currentMovement = 2f
val pillageAction = UnitActionsPillage.getPillageAction(unit)
pillageAction?.action?.invoke()
Assert.assertTrue("Pillaging should transfer gold to the civ", civInfo.gold == 20)
Assert.assertTrue("Pillaging should transfer food to the nearest city", cityInfo.population.foodStored == 11)
}
// endregion
}

View File

@ -54,7 +54,7 @@ class TestGame {
gameInfo.currentPlayerCiv = Civilization() // Will be uninitialized, do not build on for tests
// Create a tilemap, needed for city centers
gameInfo.tileMap = TileMap(1, ruleset, false)
gameInfo.tileMap = TileMap(0, ruleset, false)
tileMap.mapParameters.mapSize = MapSizeNew(0, 0)
tileMap.ruleset = ruleset
tileMap.gameInfo = gameInfo

View File

@ -0,0 +1,42 @@
package com.unciv.uniques
import com.badlogic.gdx.math.Vector2
import com.unciv.Constants
import com.unciv.testing.GdxTestRunner
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsPillage
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(GdxTestRunner::class)
class TileUniquesTests {
private lateinit var game: TestGame
@Before
fun initTheWorld() {
game = TestGame()
}
@Test
fun pillageYieldTest() {
game.makeHexagonalMap(2)
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f, 0f), Constants.grassland)
val cityTile = game.setTileFeatures(Vector2(2f,0f), Constants.grassland)
val cityInfo = game.addCity(civInfo, cityTile, true)
cityInfo.population.foodStored = 0 // just to be sure
civInfo.addGold(-civInfo.gold) // reset gold just to be sure
val testImprovement = game.createTileImprovement("Pillaging this improvement yields [+20 Gold, +11 Food]")
tile.changeImprovement(testImprovement.name)
val unit = game.addUnit("Warrior", civInfo, tile)
unit.currentMovement = 2f
val pillageAction = UnitActionsPillage.getPillageAction(unit)
pillageAction?.action?.invoke()
Assert.assertTrue("Pillaging should transfer gold to the civ", civInfo.gold == 20)
Assert.assertTrue("Pillaging should transfer food to the nearest city", cityInfo.population.foodStored == 11)
}
}

View File

@ -55,6 +55,7 @@ class UnitUniquesTests {
Assert.assertFalse("Test preparation failed to add ConsumesResources to Manufactory",
improvement.uniqueObjects.none { it.type == UniqueType.ConsumesResources })
game.makeHexagonalMap(1)
val civ = game.addCiv(isPlayer = true)
val centerTile = game.getTile(Vector2.Zero)
val capital = game.addCity(civ, centerTile)