diff --git a/core/src/com/unciv/logic/city/City.kt b/core/src/com/unciv/logic/city/City.kt index f31c1c2ac7..6c4b84b4f0 100644 --- a/core/src/com/unciv/logic/city/City.kt +++ b/core/src/com/unciv/logic/city/City.kt @@ -18,8 +18,6 @@ import com.unciv.logic.map.tile.Tile import com.unciv.models.Counter import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.ModOptionsConstants -import com.unciv.models.ruleset.tile.ResourceSupplyList -import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.unique.StateForConditionals import com.unciv.models.ruleset.unique.Unique import com.unciv.models.ruleset.unique.UniqueType @@ -200,103 +198,8 @@ class City : IsPartOfGameInfoSerialization { fun getRuleset() = civ.gameInfo.ruleset - fun getCityResources(): ResourceSupplyList { - val cityResources = ResourceSupplyList() - - val resourceModifer = HashMap() - for (resource in civ.gameInfo.ruleset.tileResources.values) - resourceModifer[resource.name] = civ.getResourceModifier(resource) - - getResourcesFromTiles(resourceModifer, cityResources) - - getResourceFromUniqueImprovedTiles(cityResources, resourceModifer) - - manageCityResourcesRequiredByBuildings(cityResources) - - getCityResourcesFromUniqueBuildings(cityResources, resourceModifer) - - if (civ.isCityState() && isCapital() && civ.cityStateResource != null) { - cityResources.add( - getRuleset().tileResources[civ.cityStateResource]!!, - "Mercantile City-State" - ) - } - - return cityResources - } - - private fun getResourcesFromTiles(resourceModifer: HashMap, cityResources: ResourceSupplyList) { - for (tileInfo in getTiles().filter { it.resource != null }) { - val resource = tileInfo.tileResource - val amount = getTileResourceAmount(tileInfo) * resourceModifer[resource.name]!! - if (amount > 0) cityResources.add(resource, "Tiles", amount.toInt()) - } - } - - private fun getResourceFromUniqueImprovedTiles(cityResources: ResourceSupplyList, resourceModifer: HashMap) { - for (tileInfo in getTiles().filter { it.getUnpillagedImprovement() != null }) { - val stateForConditionals = StateForConditionals(civ, this, tile = tileInfo) - val tileImprovement = tileInfo.getUnpillagedTileImprovement() - for (unique in tileImprovement!!.getMatchingUniques(UniqueType.ProvidesResources, stateForConditionals)) { - val resource = getRuleset().tileResources[unique.params[1]] ?: continue - cityResources.add( - resource, "Improvements", - (unique.params[0].toFloat() * resourceModifer[resource.name]!!).toInt() - ) - } - for (unique in tileImprovement.getMatchingUniques(UniqueType.ConsumesResources, stateForConditionals)) { - val resource = getRuleset().tileResources[unique.params[1]] ?: continue - cityResources.add( - resource, "Improvements", - -1 * unique.params[0].toInt() - ) - } - } - } - - private fun manageCityResourcesRequiredByBuildings(cityResources: ResourceSupplyList) { - val freeBuildings = civ.civConstructions.getFreeBuildingNames(this) - for (building in cityConstructions.getBuiltBuildings()) { - // Free buildings cost no resources - if (building.name in freeBuildings) continue - cityResources.subtractResourceRequirements(building.getResourceRequirementsPerTurn(), getRuleset(), "Buildings") - } - } - - private fun getCityResourcesFromUniqueBuildings(cityResources: ResourceSupplyList, resourceModifer: HashMap) { - for (unique in cityConstructions.builtBuildingUniqueMap.getMatchingUniques(UniqueType.ProvidesResources, StateForConditionals(civ, this))) { // E.G "Provides [1] [Iron]" - val resource = getRuleset().tileResources[unique.params[1]] - ?: continue - cityResources.add( - resource, "Buildings", - (unique.params[0].toFloat() * resourceModifer[resource.name]!!).toInt() - ) - } - } - - /** Gets the number of resources available to this city - * Accommodates both city-wide and civ-wide resources */ - fun getResourceAmount(resourceName: String): Int { - val resource = getRuleset().tileResources[resourceName] ?: return 0 - - if (resource.hasUnique(UniqueType.CityResource)) - return getCityResources().asSequence().filter { it.resource == resource }.sumOf { it.amount } - return civ.getResourceAmount(resourceName) - } - - private fun getTileResourceAmount(tile: Tile): Int { - if (tile.resource == null) return 0 - if (!tile.providesResources(civ)) return 0 - - val resource = tile.tileResource - var amountToAdd = if (resource.resourceType == ResourceType.Strategic) tile.resourceAmount - else 1 - if (resource.resourceType == ResourceType.Luxury - && containsBuildingUnique(UniqueType.ProvidesExtraLuxuryFromCityResources)) - amountToAdd += 1 - - return amountToAdd - } + fun getCityResources() = CityResources.getCityResources(this) + fun getResourceAmount(resourceName:String) = CityResources.getResourceAmount(this, resourceName) fun isGrowing() = foodForNextTurn() > 0 fun isStarving() = foodForNextTurn() < 0 diff --git a/core/src/com/unciv/logic/city/CityResources.kt b/core/src/com/unciv/logic/city/CityResources.kt new file mode 100644 index 0000000000..bdd832ab88 --- /dev/null +++ b/core/src/com/unciv/logic/city/CityResources.kt @@ -0,0 +1,110 @@ +package com.unciv.logic.city + +import com.unciv.logic.map.tile.Tile +import com.unciv.models.ruleset.tile.ResourceSupplyList +import com.unciv.models.ruleset.tile.ResourceType +import com.unciv.models.ruleset.unique.StateForConditionals +import com.unciv.models.ruleset.unique.UniqueType + +object CityResources { + + fun getCityResources(city: City): ResourceSupplyList { + val cityResources = ResourceSupplyList() + + val resourceModifer = HashMap() + for (resource in city.civ.gameInfo.ruleset.tileResources.values) + resourceModifer[resource.name] = city.civ.getResourceModifier(resource) + + getResourcesFromTiles(city, resourceModifer, cityResources) + + getResourceFromUniqueImprovedTiles(city, cityResources, resourceModifer) + + manageCityResourcesRequiredByBuildings(city, cityResources) + + getCityResourcesFromUniqueBuildings(city, cityResources, resourceModifer) + + if (city.civ.isCityState() && city.isCapital() && city.civ.cityStateResource != null) { + cityResources.add( + city.getRuleset().tileResources[city.civ.cityStateResource]!!, + "Mercantile City-State" + ) + } + + return cityResources + } + + + /** Gets the number of resources available to this city + * Accommodates both city-wide and civ-wide resources */ + fun getResourceAmount(city: City, resourceName: String): Int { + val resource = city.getRuleset().tileResources[resourceName] ?: return 0 + + if (resource.hasUnique(UniqueType.CityResource)) + return getCityResources(city).asSequence().filter { it.resource == resource }.sumOf { it.amount } + return city.civ.getResourceAmount(resourceName) + } + + private fun getResourcesFromTiles(city: City, resourceModifer: HashMap, cityResources: ResourceSupplyList) { + for (tileInfo in city.getTiles().filter { it.resource != null }) { + val resource = tileInfo.tileResource + val amount = getTileResourceAmount(city, tileInfo) * resourceModifer[resource.name]!! + if (amount > 0) cityResources.add(resource, "Tiles", amount.toInt()) + } + } + + private fun getResourceFromUniqueImprovedTiles(city: City, cityResources: ResourceSupplyList, resourceModifer: HashMap) { + for (tileInfo in city.getTiles().filter { it.getUnpillagedImprovement() != null }) { + val stateForConditionals = StateForConditionals(city.civ, city, tile = tileInfo) + val tileImprovement = tileInfo.getUnpillagedTileImprovement() + for (unique in tileImprovement!!.getMatchingUniques(UniqueType.ProvidesResources, stateForConditionals)) { + val resource = city.getRuleset().tileResources[unique.params[1]] ?: continue + cityResources.add( + resource, "Improvements", + (unique.params[0].toFloat() * resourceModifer[resource.name]!!).toInt() + ) + } + for (unique in tileImprovement.getMatchingUniques(UniqueType.ConsumesResources, stateForConditionals)) { + val resource = city.getRuleset().tileResources[unique.params[1]] ?: continue + cityResources.add( + resource, "Improvements", + -1 * unique.params[0].toInt() + ) + } + } + } + + private fun manageCityResourcesRequiredByBuildings(city: City, cityResources: ResourceSupplyList) { + val freeBuildings = city.civ.civConstructions.getFreeBuildingNames(city) + for (building in city.cityConstructions.getBuiltBuildings()) { + // Free buildings cost no resources + if (building.name in freeBuildings) continue + cityResources.subtractResourceRequirements(building.getResourceRequirementsPerTurn(), city.getRuleset(), "Buildings") + } + } + + private fun getCityResourcesFromUniqueBuildings(city: City, cityResources: ResourceSupplyList, resourceModifer: HashMap) { + for (unique in city.cityConstructions.builtBuildingUniqueMap + .getMatchingUniques(UniqueType.ProvidesResources, StateForConditionals(city.civ, city))) { // E.G "Provides [1] [Iron]" + val resource = city.getRuleset().tileResources[unique.params[1]] + ?: continue + cityResources.add( + resource, "Buildings", + (unique.params[0].toFloat() * resourceModifer[resource.name]!!).toInt() + ) + } + } + + private fun getTileResourceAmount(city: City, tile: Tile): Int { + if (tile.resource == null) return 0 + if (!tile.providesResources(city.civ)) return 0 + + val resource = tile.tileResource + var amountToAdd = if (resource.resourceType == ResourceType.Strategic) tile.resourceAmount + else 1 + if (resource.resourceType == ResourceType.Luxury + && city.containsBuildingUnique(UniqueType.ProvidesExtraLuxuryFromCityResources)) + amountToAdd += 1 + + return amountToAdd + } +}