chore: Extract city resource functions from City file

This commit is contained in:
Yair Morgenstern 2023-10-08 13:06:48 +03:00
parent ee9f735e9f
commit dd67a7d3df
2 changed files with 112 additions and 99 deletions

View File

@ -18,8 +18,6 @@ import com.unciv.logic.map.tile.Tile
import com.unciv.models.Counter import com.unciv.models.Counter
import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.ModOptionsConstants 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.StateForConditionals
import com.unciv.models.ruleset.unique.Unique import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
@ -200,103 +198,8 @@ class City : IsPartOfGameInfoSerialization {
fun getRuleset() = civ.gameInfo.ruleset fun getRuleset() = civ.gameInfo.ruleset
fun getCityResources(): ResourceSupplyList { fun getCityResources() = CityResources.getCityResources(this)
val cityResources = ResourceSupplyList() fun getResourceAmount(resourceName:String) = CityResources.getResourceAmount(this, resourceName)
val resourceModifer = HashMap<String, Float>()
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<String, Float>, 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<String, Float>) {
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<String, Float>) {
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 isGrowing() = foodForNextTurn() > 0 fun isGrowing() = foodForNextTurn() > 0
fun isStarving() = foodForNextTurn() < 0 fun isStarving() = foodForNextTurn() < 0

View File

@ -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<String, Float>()
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<String, Float>, 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<String, Float>) {
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<String, Float>) {
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
}
}