mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-20 12:48:56 +07:00
Readability helpers for Map of Sets: add, contains (#10116)
This commit is contained in:
@ -31,6 +31,7 @@ import com.unciv.models.stats.Stat
|
|||||||
import com.unciv.models.stats.Stats
|
import com.unciv.models.stats.Stats
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.components.Fonts
|
import com.unciv.ui.components.Fonts
|
||||||
|
import com.unciv.ui.components.extensions.addToMapOfSets
|
||||||
import com.unciv.ui.components.extensions.withItem
|
import com.unciv.ui.components.extensions.withItem
|
||||||
import com.unciv.ui.components.extensions.withoutItem
|
import com.unciv.ui.components.extensions.withoutItem
|
||||||
import com.unciv.ui.screens.civilopediascreen.CivilopediaCategories
|
import com.unciv.ui.screens.civilopediascreen.CivilopediaCategories
|
||||||
@ -39,7 +40,6 @@ import kotlin.math.ceil
|
|||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* City constructions manager.
|
* City constructions manager.
|
||||||
*
|
*
|
||||||
@ -604,7 +604,7 @@ class CityConstructions : IsPartOfGameInfoSerialization {
|
|||||||
for (city in citiesThatApply) {
|
for (city in citiesThatApply) {
|
||||||
if (city.cityConstructions.containsBuildingOrEquivalent(freeBuilding.name)) continue
|
if (city.cityConstructions.containsBuildingOrEquivalent(freeBuilding.name)) continue
|
||||||
city.cityConstructions.addBuilding(freeBuilding)
|
city.cityConstructions.addBuilding(freeBuilding)
|
||||||
freeBuildingsProvidedFromThisCity.getOrPut(city.id) { hashSetOf() }.add(freeBuilding.name)
|
freeBuildingsProvidedFromThisCity.addToMapOfSets(city.id, freeBuilding.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,7 +612,7 @@ class CityConstructions : IsPartOfGameInfoSerialization {
|
|||||||
for (unique in city.civ.getMatchingUniques(UniqueType.GainFreeBuildings, stateForConditionals = StateForConditionals(city.civ, city))) {
|
for (unique in city.civ.getMatchingUniques(UniqueType.GainFreeBuildings, stateForConditionals = StateForConditionals(city.civ, city))) {
|
||||||
val freeBuilding = city.civ.getEquivalentBuilding(unique.params[0])
|
val freeBuilding = city.civ.getEquivalentBuilding(unique.params[0])
|
||||||
if (city.matchesFilter(unique.params[1])) {
|
if (city.matchesFilter(unique.params[1])) {
|
||||||
freeBuildingsProvidedFromThisCity.getOrPut(city.id) { hashSetOf() }.add(freeBuilding.name)
|
freeBuildingsProvidedFromThisCity.addToMapOfSets(city.id, freeBuilding.name)
|
||||||
if (!isBuilt(freeBuilding.name))
|
if (!isBuilt(freeBuilding.name))
|
||||||
addBuilding(freeBuilding)
|
addBuilding(freeBuilding)
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ import com.unciv.models.ruleset.INonPerpetualConstruction
|
|||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.models.ruleset.unit.BaseUnit
|
import com.unciv.models.ruleset.unit.BaseUnit
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
|
import com.unciv.ui.components.extensions.addToMapOfSets
|
||||||
|
import com.unciv.ui.components.extensions.contains
|
||||||
import com.unciv.ui.components.extensions.yieldAllNotNull
|
import com.unciv.ui.components.extensions.yieldAllNotNull
|
||||||
|
|
||||||
class CivConstructions : IsPartOfGameInfoSerialization {
|
class CivConstructions : IsPartOfGameInfoSerialization {
|
||||||
@ -88,8 +90,7 @@ class CivConstructions : IsPartOfGameInfoSerialization {
|
|||||||
getFreeBuildingNamesSequence(cityId).contains(buildingName)
|
getFreeBuildingNamesSequence(cityId).contains(buildingName)
|
||||||
|
|
||||||
private fun addFreeBuilding(cityId: String, building: String) {
|
private fun addFreeBuilding(cityId: String, building: String) {
|
||||||
freeBuildings.getOrPut(cityId) { hashSetOf() }
|
freeBuildings.addToMapOfSets(cityId, civInfo.getEquivalentBuilding(building).name)
|
||||||
.add(civInfo.getEquivalentBuilding(building).name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addFreeStatsBuildings() {
|
private fun addFreeStatsBuildings() {
|
||||||
@ -105,12 +106,12 @@ class CivConstructions : IsPartOfGameInfoSerialization {
|
|||||||
|
|
||||||
private fun addFreeStatBuildings(stat: Stat, amount: Int) {
|
private fun addFreeStatBuildings(stat: Stat, amount: Int) {
|
||||||
for (city in civInfo.cities.take(amount)) {
|
for (city in civInfo.cities.take(amount)) {
|
||||||
if (freeStatBuildingsProvided[stat.name]?.contains(city.id) == true) continue
|
if (freeStatBuildingsProvided.contains(stat.name, city.id)) continue
|
||||||
if (!city.cityConstructions.hasBuildableStatBuildings(stat)) continue
|
if (!city.cityConstructions.hasBuildableStatBuildings(stat)) continue
|
||||||
|
|
||||||
val builtBuilding = city.cityConstructions.addCheapestBuildableStatBuilding(stat)
|
val builtBuilding = city.cityConstructions.addCheapestBuildableStatBuilding(stat)
|
||||||
if (builtBuilding != null) {
|
if (builtBuilding != null) {
|
||||||
freeStatBuildingsProvided.getOrPut(stat.name) { hashSetOf() }.add(city.id)
|
freeStatBuildingsProvided.addToMapOfSets(stat.name, city.id)
|
||||||
addFreeBuilding(city.id, builtBuilding)
|
addFreeBuilding(city.id, builtBuilding)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,12 +131,12 @@ class CivConstructions : IsPartOfGameInfoSerialization {
|
|||||||
private fun addFreeBuildings(building: Building, amount: Int) {
|
private fun addFreeBuildings(building: Building, amount: Int) {
|
||||||
|
|
||||||
for (city in civInfo.cities.take(amount)) {
|
for (city in civInfo.cities.take(amount)) {
|
||||||
if (freeSpecificBuildingsProvided[building.name]?.contains(city.id) == true
|
if (freeSpecificBuildingsProvided.contains(building.name, city.id)
|
||||||
|| city.cityConstructions.containsBuildingOrEquivalent(building.name)) continue
|
|| city.cityConstructions.containsBuildingOrEquivalent(building.name)) continue
|
||||||
|
|
||||||
building.postBuildEvent(city.cityConstructions)
|
building.postBuildEvent(city.cityConstructions)
|
||||||
|
|
||||||
freeSpecificBuildingsProvided.getOrPut(building.name) { hashSetOf() }.add(city.id)
|
freeSpecificBuildingsProvided.addToMapOfSets(building.name, city.id)
|
||||||
addFreeBuilding(city.id, building.name)
|
addFreeBuilding(city.id, building.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@ import com.unciv.models.ruleset.tile.TerrainType
|
|||||||
import com.unciv.models.ruleset.unique.UniqueMap
|
import com.unciv.models.ruleset.unique.UniqueMap
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.models.ruleset.unit.BaseUnit
|
import com.unciv.models.ruleset.unit.BaseUnit
|
||||||
|
import com.unciv.ui.components.extensions.addToMapOfSets
|
||||||
|
import com.unciv.ui.components.extensions.contains
|
||||||
import java.lang.Integer.max
|
import java.lang.Integer.max
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
@ -92,7 +94,7 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization {
|
|||||||
get() = tileList
|
get() = tileList
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
val startingLocationsByNation = HashMap<String,HashSet<Tile>>()
|
val startingLocationsByNation = HashMap<String, HashSet<Tile>>()
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
/** Continent ID to Continent size */
|
/** Continent ID to Continent size */
|
||||||
@ -646,8 +648,7 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization {
|
|||||||
return translateStartingLocationsFromMap()
|
return translateStartingLocationsFromMap()
|
||||||
startingLocationsByNation.clear()
|
startingLocationsByNation.clear()
|
||||||
for ((position, nationName) in startingLocations) {
|
for ((position, nationName) in startingLocations) {
|
||||||
val nationSet = startingLocationsByNation[nationName] ?: hashSetOf<Tile>().also { startingLocationsByNation[nationName] = it }
|
startingLocationsByNation.addToMapOfSets(nationName, get(position))
|
||||||
nationSet.add(get(position))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,16 +671,15 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization {
|
|||||||
/** Adds a starting position, maintaining the transients
|
/** Adds a starting position, maintaining the transients
|
||||||
* @return true if the starting position was not already stored as per [Collection]'s add */
|
* @return true if the starting position was not already stored as per [Collection]'s add */
|
||||||
fun addStartingLocation(nationName: String, tile: Tile): Boolean {
|
fun addStartingLocation(nationName: String, tile: Tile): Boolean {
|
||||||
if (startingLocationsByNation[nationName]?.contains(tile) == true) return false
|
if (startingLocationsByNation.contains(nationName, tile)) return false
|
||||||
startingLocations.add(StartingLocation(tile.position, nationName))
|
startingLocations.add(StartingLocation(tile.position, nationName))
|
||||||
val nationSet = startingLocationsByNation[nationName] ?: hashSetOf<Tile>().also { startingLocationsByNation[nationName] = it }
|
return startingLocationsByNation.addToMapOfSets(nationName, tile)
|
||||||
return nationSet.add(tile)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes a starting position, maintaining the transients
|
/** Removes a starting position, maintaining the transients
|
||||||
* @return true if the starting position was removed as per [Collection]'s remove */
|
* @return true if the starting position was removed as per [Collection]'s remove */
|
||||||
fun removeStartingLocation(nationName: String, tile: Tile): Boolean {
|
fun removeStartingLocation(nationName: String, tile: Tile): Boolean {
|
||||||
if (startingLocationsByNation[nationName]?.contains(tile) != true) return false
|
if (startingLocationsByNation.contains(nationName, tile)) return false
|
||||||
startingLocations.remove(StartingLocation(tile.position, nationName))
|
startingLocations.remove(StartingLocation(tile.position, nationName))
|
||||||
return startingLocationsByNation[nationName]!!.remove(tile)
|
return startingLocationsByNation[nationName]!!.remove(tile)
|
||||||
// we do not clean up an empty startingLocationsByNation[nationName] set - not worth it
|
// we do not clean up an empty startingLocationsByNation[nationName] set - not worth it
|
||||||
|
@ -83,3 +83,18 @@ suspend fun <T> SequenceScope<T>.yieldAllNotNull(elements: Iterable<T?>?) {
|
|||||||
if (elements == null) return
|
if (elements == null) return
|
||||||
for (element in elements) yieldIfNotNull(element)
|
for (element in elements) yieldIfNotNull(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplifies adding to a map of sets where the map entry where the new element belongs is not
|
||||||
|
* guaranteed to be already present in the map (sparse map).
|
||||||
|
*
|
||||||
|
* @param key The key identifying the Set to add [element] to
|
||||||
|
* @param element The new element to be added to the Set for [key]
|
||||||
|
* @return `false` if the element was already present, `true` if it was new (same as `Set.add()`)
|
||||||
|
*/
|
||||||
|
fun <KT, ET> HashMap<KT, HashSet<ET>>.addToMapOfSets(key: KT, element: ET) =
|
||||||
|
getOrPut(key) { hashSetOf() }.add(element)
|
||||||
|
|
||||||
|
/** Simplifies testing whether in a sparse map of sets the [element] exists for [key]. */
|
||||||
|
fun <KT, ET> HashMap<KT, HashSet<ET>>.contains(key: KT, element: ET) =
|
||||||
|
get(key)?.contains(element) == true
|
||||||
|
Reference in New Issue
Block a user