mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 13:55:54 -04:00
Merge branch 'yairm210:master' into updated-so-you-can-build-naval-unit-on-water-tile
This commit is contained in:
commit
22935e661d
@ -3,7 +3,7 @@ package com.unciv.build
|
||||
|
||||
object BuildConfig {
|
||||
const val appName = "Unciv"
|
||||
const val appCodeNumber = 1158
|
||||
const val appVersion = "4.17.17"
|
||||
const val appCodeNumber = 1159
|
||||
const val appVersion = "4.17.17-patch1"
|
||||
const val identifier = "com.unciv.app"
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ open class UncivGame(val isConsoleMode: Boolean = false) : Game(), PlatformSpeci
|
||||
|
||||
companion object {
|
||||
//region AUTOMATICALLY GENERATED VERSION DATA - DO NOT CHANGE THIS REGION, INCLUDING THIS COMMENT
|
||||
val VERSION = Version("4.17.17", 1158)
|
||||
val VERSION = Version("4.17.17-patch1", 1159)
|
||||
//endregion
|
||||
|
||||
/** Global reference to the one Gdx.Game instance created by the platform launchers - do not use without checking [isCurrentInitialized] first. */
|
||||
|
@ -297,6 +297,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions) {
|
||||
} else value += when {
|
||||
building.hasUnique(UniqueType.CreatesOneImprovement) -> 5f // District-type buildings, should be weighed by the stats (incl. adjacencies) of the improvement
|
||||
building.hasUnique(UniqueType.ProvidesResources) -> 2f // Should be weighed by how much we need the resources
|
||||
building.hasUnique(UniqueType.StatPercentFromObjectToResource) -> 1.5f // Should be weighed by the amount of active improvementFilter/buildingFilter in the city
|
||||
else -> 0f
|
||||
}
|
||||
return value
|
||||
|
@ -130,6 +130,7 @@ object ReligiousUnitAutomation {
|
||||
return null
|
||||
|
||||
val holyCity = unit.civ.religionManager.getHolyCity()
|
||||
// Our own holy city was taken over!
|
||||
if (holyCity != null && holyCity.religion.getMajorityReligion() != unit.civ.religionManager.religion!!)
|
||||
return holyCity
|
||||
|
||||
@ -137,12 +138,22 @@ object ReligiousUnitAutomation {
|
||||
if (blockedHolyCity != null)
|
||||
return blockedHolyCity
|
||||
|
||||
return unit.civ.cities.asSequence()
|
||||
.filter { it.religion.getMajorityReligion() != null }
|
||||
.filter { it.religion.getMajorityReligion()!! != unit.civ.religionManager.religion }
|
||||
// Don't go if it takes too long
|
||||
// Find cities
|
||||
val relevantCities = unit.civ.gameInfo.getCities()
|
||||
.filter { it.getCenterTile().isExplored(unit.civ) } // Cities we know about
|
||||
// Someone else is controlling this city
|
||||
.filter {
|
||||
val majorityReligion = it.religion.getMajorityReligion()
|
||||
majorityReligion != null && majorityReligion != unit.civ.religionManager.religion
|
||||
}
|
||||
|
||||
val closeCity = relevantCities
|
||||
.filter { it.getCenterTile().aerialDistanceTo(unit.currentTile) <= 20 }
|
||||
.maxByOrNull { it.religion.getPressureDeficit(unit.civ.religionManager.religion?.name) }
|
||||
// Find the city that we're the closest to converting
|
||||
.minByOrNull { it.religion.getPressureDeficit(unit.civ.religionManager.religion?.name) }
|
||||
if (closeCity != null) return closeCity
|
||||
|
||||
return relevantCities.minByOrNull { it.religion.getPressureDeficit(unit.civ.religionManager.religion?.name) }
|
||||
}
|
||||
|
||||
|
||||
|
@ -170,9 +170,9 @@ class City : IsPartOfGameInfoSerialization, INamed {
|
||||
@Readonly fun getCenterTileOrNull(): Tile? = if (::centerTile.isInitialized) centerTile else null
|
||||
@Readonly fun getTiles(): Sequence<Tile> = tiles.asSequence().map { tileMap[it] }
|
||||
@Readonly fun getWorkableTiles() = tilesInRange.asSequence().filter { it.getOwner() == civ }
|
||||
@Readonly fun getWorkedTiles(): Sequence<Tile> = workedTiles.asSequence().map { tileMap[it] }
|
||||
@Readonly fun isWorked(tile: Tile) = workedTiles.contains(tile.position)
|
||||
|
||||
|
||||
@Readonly fun isCapital(): Boolean = cityConstructions.builtBuildingUniqueMap.hasUnique(UniqueType.IndicatesCapital, state)
|
||||
@Readonly fun isCoastal(): Boolean = centerTile.isCoastalTile()
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
package com.unciv.logic.city
|
||||
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.ruleset.tile.ResourceSupplyList
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.unique.GameContext
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import yairm210.purity.annotations.LocalState
|
||||
import yairm210.purity.annotations.Readonly
|
||||
import com.unciv.models.ruleset.unique.UniqueParameterType
|
||||
|
||||
object CityResources {
|
||||
|
||||
@ -14,7 +16,7 @@ object CityResources {
|
||||
@Readonly
|
||||
fun getResourcesGeneratedByCity(city: City, resourceModifiers: Map<String, Float>): ResourceSupplyList {
|
||||
@LocalState val cityResources = getResourcesGeneratedByCityNotIncludingBuildings(city, resourceModifiers)
|
||||
cityResources += getCityResourcesGeneratedFromUniqueBuildings(city, resourceModifiers)
|
||||
cityResources += getCityResourcesGeneratedFromUniques(city, resourceModifiers, false)
|
||||
return cityResources
|
||||
}
|
||||
|
||||
@ -30,7 +32,7 @@ object CityResources {
|
||||
// We can't use getResourcesGeneratedByCity directly, because that would include the resources generated by buildings -
|
||||
// which are part of the civ-wide uniques, so we'd be getting them twice!
|
||||
// This way we get them once, but it is ugly, I welcome other ideas :/
|
||||
cityResources.add(getCityResourcesFromCiv(city, resourceModifers))
|
||||
cityResources.add(getCityResourcesGeneratedFromUniques(city, resourceModifers, true))
|
||||
|
||||
cityResources.removeAll { !it.resource.isCityWide }
|
||||
|
||||
@ -56,20 +58,6 @@ object CityResources {
|
||||
return cityResources
|
||||
}
|
||||
|
||||
@Readonly
|
||||
private fun getCityResourcesGeneratedFromUniqueBuildings(city: City, resourceModifer: Map<String, Float>): ResourceSupplyList {
|
||||
val buildingResources = ResourceSupplyList()
|
||||
for (unique in city.getMatchingUniques(UniqueType.ProvidesResources, city.state, false)) { // E.G "Provides [1] [Iron]"
|
||||
val resource = city.getRuleset().tileResources[unique.params[1]]
|
||||
?: continue
|
||||
buildingResources.add(
|
||||
resource, unique.getSourceNameForUser(),
|
||||
(unique.params[0].toFloat() * resourceModifer[resource.name]!!).toInt()
|
||||
)
|
||||
}
|
||||
return buildingResources
|
||||
}
|
||||
|
||||
/** Gets the number of resources available to this city
|
||||
* Accommodates both city-wide and civ-wide resources */
|
||||
@Readonly
|
||||
@ -129,18 +117,46 @@ object CityResources {
|
||||
}
|
||||
|
||||
@Readonly
|
||||
private fun getCityResourcesFromCiv(city: City, resourceModifers: HashMap<String, Float>): ResourceSupplyList {
|
||||
val resourceSupplyList = ResourceSupplyList()
|
||||
// This includes the uniques from buildings, from this and all other cities
|
||||
for (unique in city.getMatchingUniques(UniqueType.ProvidesResources, city.state)) { // E.G "Provides [1] [Iron]"
|
||||
private fun getCityResourcesGeneratedFromUniques(city: City, resourceModifers: Map<String, Float>, includeCivUniques: Boolean = true): ResourceSupplyList {
|
||||
val buildingResources = ResourceSupplyList()
|
||||
for (unique in city.getMatchingUniques(UniqueType.ProvidesResources, city.state, includeCivUniques)) { // E.G "Provides [1] [Iron]"
|
||||
val resource = city.getRuleset().tileResources[unique.params[1]]
|
||||
?: continue
|
||||
resourceSupplyList.add(
|
||||
buildingResources.add(
|
||||
resource, unique.getSourceNameForUser(),
|
||||
(unique.params[0].toFloat() * resourceModifers[resource.name]!!).toInt()
|
||||
)
|
||||
}
|
||||
return resourceSupplyList
|
||||
|
||||
// StatPercentFromObjectToResource - Example: "[50]% of [Culture] from every [improvementFilter/buildingFilter] in the city added to [Iron]"
|
||||
for (unique in city.getMatchingUniques(UniqueType.StatPercentFromObjectToResource, city.state, includeCivUniques)) {
|
||||
val resource = city.getRuleset().tileResources[unique.params[3]] ?: continue
|
||||
val stat = Stat.safeValueOf(unique.params[1]) ?: continue
|
||||
val filter = unique.params[2]
|
||||
var amount = 0.0
|
||||
|
||||
// Building Filter
|
||||
if (UniqueParameterType.BuildingFilter.isKnownValue(filter, city.getRuleset())) {
|
||||
amount += city.cityConstructions.getBuiltBuildings()
|
||||
.filter { it.isStatRelated(stat) && it.matchesFilter(filter, city.state) }
|
||||
.sumOf { it.getStats(city)[stat].toDouble() }
|
||||
}
|
||||
|
||||
// Improvement Filter
|
||||
if (UniqueParameterType.ImprovementFilter.isKnownValue(filter, city.getRuleset())) {
|
||||
amount += city.getWorkedTiles()
|
||||
.mapNotNull { it.getUnpillagedTileImprovement() }
|
||||
.filter { it[stat] > 0f && it.matchesFilter(filter, city.state) }
|
||||
.sumOf { it[stat].toDouble() }
|
||||
}
|
||||
|
||||
if (amount > 0.0) {
|
||||
amount *= unique.params[0].toDouble() / 100.0 * (resourceModifers[resource.name] ?: 1f).toDouble()
|
||||
buildingResources.add(resource, unique.getSourceNameForUser(), amount.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
return buildingResources
|
||||
}
|
||||
|
||||
@Readonly
|
||||
|
@ -330,7 +330,8 @@ class CityReligionManager : IsPartOfGameInfoSerialization {
|
||||
return pressure.toInt()
|
||||
}
|
||||
|
||||
/** Calculates how much pressure this religion is lacking compared to the majority religion */
|
||||
/** Calculates how much pressure this religion is lacking compared to the majority religion
|
||||
* That is, if we gain more than this, we'll be the majority */
|
||||
@Readonly
|
||||
fun getPressureDeficit(otherReligion: String?): Int {
|
||||
val pressures = getPressures()
|
||||
|
@ -267,13 +267,8 @@ class UnitMovement(val unit: MapUnit) {
|
||||
* @return The tile that we reached this turn
|
||||
*/
|
||||
fun headTowards(destination: Tile): Tile {
|
||||
val escortUnit = if (unit.isEscorting()) unit.getOtherEscortUnit() else null
|
||||
val startTile = unit.getTile()
|
||||
val destinationTileThisTurn = getTileToMoveToThisTurn(destination)
|
||||
moveToTile(destinationTileThisTurn)
|
||||
if (startTile != unit.getTile() && escortUnit != null) {
|
||||
escortUnit.movement.headTowards(unit.getTile())
|
||||
}
|
||||
return unit.currentTile
|
||||
}
|
||||
|
||||
@ -748,10 +743,6 @@ class UnitMovement(val unit: MapUnit) {
|
||||
movementCostCache: HashMap<Pair<Tile, Tile>, Float> = HashMap(),
|
||||
includeOtherEscortUnit: Boolean = true
|
||||
): PathsToTilesWithinTurn {
|
||||
// val cacheResults = pathfindingCache.getDistanceToTiles(considerZoneOfControl)
|
||||
// if (cacheResults != null) {
|
||||
// return cacheResults
|
||||
// }
|
||||
val distanceToTiles = getMovementToTilesAtPosition(
|
||||
unit.currentTile.position,
|
||||
unit.currentMovement,
|
||||
@ -762,8 +753,6 @@ class UnitMovement(val unit: MapUnit) {
|
||||
includeOtherEscortUnit
|
||||
)
|
||||
|
||||
pathfindingCache.setDistanceToTiles(considerZoneOfControl, distanceToTiles)
|
||||
|
||||
return distanceToTiles
|
||||
}
|
||||
|
||||
@ -838,14 +827,13 @@ class UnitMovement(val unit: MapUnit) {
|
||||
class PathfindingCache(private val unit: MapUnit) {
|
||||
private var shortestPathCache = listOf<Tile>()
|
||||
private var destination: Tile? = null
|
||||
private val distanceToTilesCache = mutableMapOf<Boolean, PathsToTilesWithinTurn>()
|
||||
private var movement = -1f
|
||||
private var currentTile: Tile? = null
|
||||
|
||||
/** Check if the caches are valid (only checking if the unit has moved or consumed movement points;
|
||||
* the isPlayerCivilization check is performed in the functions because we want isValid() == false
|
||||
* to have a specific behavior) */
|
||||
private fun isValid(): Boolean = (movement == unit.currentMovement) && (unit.getTile() == currentTile)
|
||||
@Readonly private fun isValid(): Boolean = (movement == unit.currentMovement) && (unit.getTile() == currentTile)
|
||||
|
||||
fun getShortestPathCache(destination: Tile): List<Tile> {
|
||||
if (unit.civ.isHuman()) return listOf()
|
||||
@ -863,23 +851,7 @@ class PathfindingCache(private val unit: MapUnit) {
|
||||
}
|
||||
}
|
||||
|
||||
fun getDistanceToTiles(zoneOfControl: Boolean): PathsToTilesWithinTurn? {
|
||||
if (unit.civ.isHuman()) return null
|
||||
if (isValid())
|
||||
return distanceToTilesCache[zoneOfControl]
|
||||
return null
|
||||
}
|
||||
|
||||
fun setDistanceToTiles(zoneOfControl: Boolean, paths: PathsToTilesWithinTurn) {
|
||||
if (unit.civ.isHuman()) return
|
||||
if (!isValid()) {
|
||||
clear() // we want to reset the entire cache at this point
|
||||
}
|
||||
distanceToTilesCache[zoneOfControl] = paths
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
distanceToTilesCache.clear()
|
||||
movement = unit.currentMovement
|
||||
currentTile = unit.getTile()
|
||||
destination = null
|
||||
|
@ -143,7 +143,11 @@ class TileResource : RulesetStatsObject(), GameResource {
|
||||
val buildingsThatProvideThis = ruleset.buildings.values
|
||||
.filter { building ->
|
||||
building.uniqueObjects.any { unique ->
|
||||
unique.type == UniqueType.ProvidesResources && unique.params[1] == name
|
||||
when (unique.type) {
|
||||
UniqueType.ProvidesResources -> unique.params[1] == name
|
||||
UniqueType.StatPercentFromObjectToResource -> unique.params[3] == name
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buildingsThatProvideThis.isNotEmpty()) {
|
||||
|
@ -506,7 +506,7 @@ enum class UniqueParameterType(
|
||||
|
||||
/**Used by [UniqueType.ConditionalCityReligion]*/
|
||||
ReligionFilter("religionFilter", "major") {
|
||||
override val staticKnownValues = setOf("any", "major", "enhanced", "your", "foreign","enemy")
|
||||
override val staticKnownValues = setOf("any", "major", "enhanced", "your", "foreign", "enemy")
|
||||
override fun isKnownValue(parameterText: String, ruleset: Ruleset): Boolean {
|
||||
return when (parameterText) {
|
||||
in staticKnownValues -> true
|
||||
|
@ -102,7 +102,7 @@ object UniqueTriggerActivation {
|
||||
if (timingConditional != null) {
|
||||
return {
|
||||
civInfo.temporaryUniques.add(TemporaryUnique(unique, timingConditional.params[0].toInt()))
|
||||
if (unique.type in setOf(UniqueType.ProvidesResources, UniqueType.ConsumesResources))
|
||||
if (unique.type in setOf(UniqueType.ProvidesResources, UniqueType.ConsumesResources, UniqueType.StatPercentFromObjectToResource))
|
||||
civInfo.cache.updateCivResources()
|
||||
true
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ enum class UniqueType(
|
||||
StatPercentBonus("[relativeAmount]% [stat]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
StatPercentBonusCities("[relativeAmount]% [stat] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
StatPercentFromObject("[relativeAmount]% [stat] from every [tileFilter/buildingFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
StatPercentFromObjectToResource("[positiveAmount]% of [stat] from every [improvementFilter/buildingFilter] in the city added to [resource]", UniqueTarget.Building),
|
||||
AllStatsPercentFromObject("[relativeAmount]% Yield from every [tileFilter/buildingFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
StatPercentFromReligionFollowers("[relativeAmount]% [stat] from every follower, up to [relativeAmount]%", UniqueTarget.FollowerBelief, UniqueTarget.FounderBelief),
|
||||
BonusStatsFromCityStates("[relativeAmount]% [stat] from City-States", UniqueTarget.Global),
|
||||
|
@ -183,7 +183,7 @@ class UniqueValidator(val ruleset: Ruleset) {
|
||||
}
|
||||
|
||||
private val resourceUniques = setOf(UniqueType.ProvidesResources, UniqueType.ConsumesResources,
|
||||
UniqueType.PercentResourceProduction)
|
||||
UniqueType.PercentResourceProduction, UniqueType.StatPercentFromObjectToResource)
|
||||
private val resourceConditionals = setOf(
|
||||
UniqueType.ConditionalWithResource,
|
||||
UniqueType.ConditionalWithoutResource,
|
||||
|
@ -46,7 +46,7 @@ Allows filtering for specific nations. Used by [ModOptions.nationsToRemove](Mod-
|
||||
|
||||
Allowed values:
|
||||
|
||||
- `All`
|
||||
- `All`, `all`
|
||||
- `City-States`, `City-State`
|
||||
- `Major`
|
||||
- Nation name
|
||||
@ -68,11 +68,11 @@ Allowed values:
|
||||
- `non-air` for non-air non-missile units
|
||||
- `Military`, `military units`
|
||||
- `Civilian`, `civilian units`
|
||||
- `All`
|
||||
- `All`, `all`
|
||||
- `Melee`
|
||||
- `Ranged`
|
||||
- `Nuclear Weapon`
|
||||
- `Great Person`, `Great`
|
||||
- `Great Person`
|
||||
- `Embarked`
|
||||
- Matching [technologyfilter](#technologyfilter) for the tech this unit requires - e.g. `Modern Era`
|
||||
- Any exact unique the unit has
|
||||
@ -88,11 +88,12 @@ Allowed values:
|
||||
- Any matching [baseUnitFilter](#baseunitfilter)
|
||||
- Any [civFilter](#civfilter) matching the owner
|
||||
- Any unique the unit has - also includes uniques not caught by the [baseUnitFilter](#baseunitfilter), for example promotions
|
||||
- Any promotion name
|
||||
- Any promotion name, or an exact unique a promotion has
|
||||
- `Wounded`
|
||||
- `Embarked`
|
||||
- `City-State`
|
||||
- `Barbarians`, `Barbarian`
|
||||
- `Non-City`
|
||||
- Again, any combination of the above is also allowed, e.g. `[{Wounded} {Water}]` units.
|
||||
|
||||
You can check this in-game using the console with the `unit checkfilter <filter>` command
|
||||
@ -103,7 +104,7 @@ Allows to only activate a unique for certain buildings.
|
||||
|
||||
Allowed values:
|
||||
|
||||
- `All`
|
||||
- `All`, `all`
|
||||
- `Buildings`, `Building`
|
||||
- `Wonder`, `Wonders`
|
||||
- `National Wonder`, `National`
|
||||
@ -124,7 +125,7 @@ Allowed values:
|
||||
cityFilters allow us to choose the range of cities affected by this unique:
|
||||
|
||||
- `in this city`
|
||||
- `in all cities`
|
||||
- `in all cities`, `All`, `all` - Generally applies to all cities owned by the relevant civ
|
||||
- `in your cities`, `Your`
|
||||
- `in all coastal cities`, `Coastal`
|
||||
- `in capital`, `Capital`
|
||||
@ -137,6 +138,7 @@ cityFilters allow us to choose the range of cities affected by this unique:
|
||||
- `in foreign cities`, `Foreign`
|
||||
- `in annexed cities`, `Annexed`
|
||||
- `in puppeted cities`, `Puppeted`
|
||||
- `in resisting cities`, `Resisting`
|
||||
- `in cities being razed`, `Razing`
|
||||
- `in holy cities`, `Holy`
|
||||
- `in City-State cities`
|
||||
@ -155,8 +157,10 @@ For filtering a specific improvement.
|
||||
Allowed values:
|
||||
|
||||
- improvement name
|
||||
- `All`
|
||||
- `Great Improvements`, `Great`
|
||||
- An exact unique the improvement has (e.g.: `spaceship improvement`)
|
||||
- `Improvement`
|
||||
- `All`, `all`
|
||||
- `Great Improvement`, `Great`
|
||||
- `All Road` - for Roads & Railroads
|
||||
|
||||
## populationFilter
|
||||
@ -189,7 +193,7 @@ For filtering specific relgions
|
||||
|
||||
Allowed values:
|
||||
|
||||
- `All` or `all`
|
||||
- `All`, `all`
|
||||
- `[policyBranchName] branch`
|
||||
- The name of the policy
|
||||
- A unique the Policy has (verbatim, no placeholders)
|
||||
@ -238,7 +242,8 @@ These can be strung together with ", " between them, for example: `+2 Production
|
||||
Allowed values:
|
||||
|
||||
- Resource name
|
||||
- `any`, `all`
|
||||
- `any`
|
||||
- `All`, `all`
|
||||
- Resource type: `Strategic`, `Luxury`, `Bonus`
|
||||
- Stat provided by the resource when improved (e.g. `Food`)
|
||||
|
||||
@ -270,7 +275,7 @@ At the moment only implemented for [ModOptions.techsToRemove](Mod-file-structure
|
||||
|
||||
Allowed values:
|
||||
|
||||
- `All`
|
||||
- `All`, `all`
|
||||
- The name of an Era
|
||||
- The name of a Technology
|
||||
- A unique a Technology has (verbatim, no placeholders)
|
||||
@ -290,19 +295,23 @@ Allowed values:
|
||||
- Natural wonder
|
||||
- A [nationFilter](#nationfilter) matching the tile owner
|
||||
- Or the filter is a constant string choosing a derived test:
|
||||
- `All`
|
||||
- `All`, `all`
|
||||
- `Terrain`
|
||||
- `Water`, `Land`
|
||||
- `Coastal` (at least one direct neighbor is a coast)
|
||||
- `River` (as in all 'river on tile' contexts, it means 'adjacent to a river on at least one side')
|
||||
- `Open terrain`, `Rough terrain` (note all terrain not having the rough unique is counted as open)
|
||||
- `Friendly Land` - land belonging to you, or other civs with open borders to you
|
||||
- `Friendly Land`, `Friendly` - land belonging to you, or other civs with open borders to you
|
||||
- `Foreign Land` - any land that isn't friendly land
|
||||
- `Enemy Land` - any land belonging to a civ you are at war with
|
||||
- `Enemy Land`, `Enemy` - any land belonging to a civ you are at war with
|
||||
- `your` - land belonging to you
|
||||
- `unowned` - land that is not owned by any civ
|
||||
- `Unowned` - land that is not owned by any civ
|
||||
- `Water resource`, `Strategic resource`, `Luxury resource`, `Bonus resource`, `resource`
|
||||
- `Natural Wonder` (as opposed to above which means testing for a specific Natural Wonder by name, this tests for any of them)
|
||||
- `Featureless`
|
||||
- `Fresh Water`
|
||||
- `non-fresh water`
|
||||
- `Impassible`
|
||||
|
||||
Please note all of these are _case-sensitive_.
|
||||
|
||||
@ -316,6 +325,7 @@ Allowed values:
|
||||
|
||||
- [terrainFilter](#terrainfilter) for this tile
|
||||
- [improvementFilter](#improvementfilter) for this tile
|
||||
- [civFilter](#civfilter) of the civilization who owns this tile
|
||||
- `Improvement` or `improved` for tiles with any improvements
|
||||
- `unimproved` for tiles with no improvement
|
||||
- `pillaged` for pillaged tiles
|
||||
|
@ -1523,6 +1523,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
|
||||
Applicable to: Nation, Tech, Policy, FounderBelief, FollowerBelief, Building, Unit, UnitType, Promotion, Terrain, Improvement, Resource, Ruins, Speed, Difficulty, EventChoice
|
||||
|
||||
## Building uniques
|
||||
??? example "[positiveAmount]% of [stat] from every [improvementFilter/buildingFilter] in the city added to [resource]"
|
||||
Example: "[3]% of [Culture] from every [All Road] in the city added to [Iron]"
|
||||
|
||||
Applicable to: Building
|
||||
|
||||
??? example "Consumes [amount] [resource]"
|
||||
Example: "Consumes [3] [Iron]"
|
||||
|
||||
|
@ -166,6 +166,26 @@ class ResourceTests {
|
||||
assertEquals("4 Iron from Buildings", resources[0].toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should handle StatPercentFromObjectToResource with a buildingFilter`() {
|
||||
city.cityConstructions.addBuilding("Monument")
|
||||
var building = game.createBuilding("[300]% of [Culture] from every [Monument] in the city added to [Iron]")
|
||||
city.cityConstructions.addBuilding(building)
|
||||
assertEquals(6, city.getAvailableResourceAmount("Iron")) // 2 Culture * 3
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should handle StatPercentFromObjectToResource with a improvementFilter`() {
|
||||
val tile = game.tileMap[1,1]
|
||||
tile.resource = "Wheat"
|
||||
tile.resourceAmount = 1
|
||||
tile.setImprovement("Farm")
|
||||
city.population.addPopulation(5) // Add population, since the tile needs to be worked
|
||||
var building = game.createBuilding("[300]% of [Food] from every [Farm] in the city added to [Iron]")
|
||||
city.cityConstructions.addBuilding(building)
|
||||
assertEquals(3, city.getAvailableResourceAmount("Iron"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should reduce resources due to buildings`() {
|
||||
// given
|
||||
|
Loading…
x
Reference in New Issue
Block a user