mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-11 03:18:18 +07:00
Performance: Removed map lookup for getLastTerrain
This was used in isImpassible which was used in canPassThrough, which means it was called A LOT
This commit is contained in:
parent
f0ee25dcac
commit
9c121086ea
@ -387,7 +387,7 @@ class WorkerAutomation(
|
||||
.filter { it.second > 0f }
|
||||
.maxByOrNull { it.second }?.first
|
||||
|
||||
val lastTerrain = tile.getLastTerrain()
|
||||
val lastTerrain = tile.lastTerrain
|
||||
|
||||
fun isUnbuildableAndRemovable(terrain: Terrain): Boolean = terrain.unbuildable
|
||||
&& ruleSet.tileImprovements.containsKey(Constants.remove + terrain.name)
|
||||
|
@ -220,7 +220,7 @@ class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineSc
|
||||
.firstOrNull { tile.isAdjacentTo(it.params[1]) }
|
||||
?: continue
|
||||
val terrain = ruleset.terrains[conversionUnique.params[0]] ?: continue
|
||||
if (!terrain.occursOn.contains(tile.getLastTerrain().name)) continue
|
||||
if (!terrain.occursOn.contains(tile.lastTerrain.name)) continue
|
||||
|
||||
if (terrain.type == TerrainType.TerrainFeature)
|
||||
tile.addTerrainFeature(terrain.name)
|
||||
@ -316,7 +316,7 @@ class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineSc
|
||||
val suitableTiles = candidateTiles
|
||||
.filterNot { it.baseTerrain == Constants.snow && it.isHill() }
|
||||
.filter { it.resource == null
|
||||
&& resource.terrainsCanBeFoundOn.contains(it.getLastTerrain().name) }
|
||||
&& resource.terrainsCanBeFoundOn.contains(it.lastTerrain.name) }
|
||||
|
||||
val locations = randomness.chooseSpreadOutLocations(resourcesPerType, suitableTiles, mapRadius)
|
||||
|
||||
@ -335,7 +335,7 @@ class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineSc
|
||||
val suitableTiles = tileMap.values
|
||||
.filterNot { it.baseTerrain == Constants.snow && it.isHill() }
|
||||
.filter { it.resource == null && it.neighbors.none { neighbor -> neighbor.isNaturalWonder() }
|
||||
&& resourcesOfType.any { r -> r.terrainsCanBeFoundOn.contains(it.getLastTerrain().name) } }
|
||||
&& resourcesOfType.any { r -> r.terrainsCanBeFoundOn.contains(it.lastTerrain.name) } }
|
||||
val numberOfResources = tileMap.values.count { it.isLand && !it.isImpassible() } *
|
||||
tileMap.mapParameters.resourceRichness
|
||||
val locations = randomness.chooseSpreadOutLocations(numberOfResources.toInt(), suitableTiles, mapRadius)
|
||||
@ -344,7 +344,7 @@ class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineSc
|
||||
|
||||
for (tile in locations) {
|
||||
val possibleResources = resourcesOfType
|
||||
.filter { it.terrainsCanBeFoundOn.contains(tile.getLastTerrain().name) }
|
||||
.filter { it.terrainsCanBeFoundOn.contains(tile.lastTerrain.name) }
|
||||
if (possibleResources.isEmpty()) continue
|
||||
val resourceWithLeastAssignments = possibleResources.minByOrNull { resourceToNumber[it.name]!! }!!
|
||||
resourceToNumber.add(resourceWithLeastAssignments.name, 1)
|
||||
@ -635,13 +635,13 @@ class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineSc
|
||||
val candidateTerrains = vegetationTerrains.flatMap{ it.occursOn }
|
||||
// Checking it.baseTerrain in candidateTerrains to make sure forest does not spawn on desert hill
|
||||
for (tile in tileMap.values.asSequence().filter { it.baseTerrain in candidateTerrains
|
||||
&& it.getLastTerrain().name in candidateTerrains }) {
|
||||
&& it.lastTerrain.name in candidateTerrains }) {
|
||||
|
||||
val vegetation = (randomness.getPerlinNoise(tile, vegetationSeed, scale = 3.0, nOctaves = 1) + 1.0) / 2.0
|
||||
|
||||
if (vegetation <= tileMap.mapParameters.vegetationRichness) {
|
||||
val possibleVegetation = vegetationTerrains.filter { vegetationTerrain ->
|
||||
vegetationTerrain.occursOn.contains(tile.getLastTerrain().name)
|
||||
vegetationTerrain.occursOn.contains(tile.lastTerrain.name)
|
||||
&& vegetationTerrain.getMatchingUniques(UniqueType.TileGenerationConditions).none {
|
||||
tile.temperature!! < it.params[0].toDouble() || tile.temperature!! > it.params[1].toDouble()
|
||||
|| tile.humidity!! < it.params[2].toDouble() || tile.humidity!! > it.params[3].toDouble()
|
||||
@ -714,7 +714,7 @@ class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineSc
|
||||
val candidates = iceEquivalents
|
||||
.filter {
|
||||
it.matches(temperature, 1.0) &&
|
||||
tile.getLastTerrain().name in it.terrain.occursOn
|
||||
tile.lastTerrain.name in it.terrain.occursOn
|
||||
}.map { it.terrain.name }
|
||||
when (candidates.size) {
|
||||
1 -> tile.addTerrainFeature(candidates.first())
|
||||
|
@ -646,9 +646,9 @@ class MapRegions (val ruleset: Ruleset){
|
||||
val validBonuses = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Bonus &&
|
||||
it.food >= 1 &&
|
||||
plot.getLastTerrain().name in it.terrainsCanBeFoundOn
|
||||
plot.lastTerrain.name in it.terrainsCanBeFoundOn
|
||||
}
|
||||
val goodPlotForOasis = canPlaceOasis && plot.getLastTerrain().name in oasisEquivalent!!.occursOn
|
||||
val goodPlotForOasis = canPlaceOasis && plot.lastTerrain.name in oasisEquivalent!!.occursOn
|
||||
|
||||
if (validBonuses.isNotEmpty() || goodPlotForOasis) {
|
||||
if (goodPlotForOasis) {
|
||||
@ -699,7 +699,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
|
||||
if (plot.resource != null) continue
|
||||
|
||||
val bonusToPlace = stoneTypeBonuses.filter { plot.getLastTerrain().name in it.terrainsCanBeFoundOn }.randomOrNull()
|
||||
val bonusToPlace = stoneTypeBonuses.filter { plot.lastTerrain.name in it.terrainsCanBeFoundOn }.randomOrNull()
|
||||
if (bonusToPlace != null) {
|
||||
plot.resource = bonusToPlace.name
|
||||
stoneNeeded--
|
||||
@ -715,7 +715,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
val bestImprovementYield = tile.tileMap.ruleset!!.tileImprovements.values
|
||||
.filter { !it.hasUnique(UniqueType.GreatImprovement) &&
|
||||
it.uniqueTo == null &&
|
||||
tile.getLastTerrain().name in it.terrainsCanBeBuiltOn }
|
||||
tile.lastTerrain.name in it.terrainsCanBeBuiltOn }
|
||||
.maxOfOrNull { it[stat] }
|
||||
return baseYield + (bestImprovementYield ?: 0f)
|
||||
}
|
||||
@ -1334,7 +1334,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
continue
|
||||
val weightings = strategicResources.map {
|
||||
if (fallbackStrategic) {
|
||||
if (tile.getLastTerrain().name in it.terrainsCanBeFoundOn) 1f else 0f
|
||||
if (tile.lastTerrain.name in it.terrainsCanBeFoundOn) 1f else 0f
|
||||
} else {
|
||||
val uniques = it.getMatchingUniques(UniqueType.MinorDepositWeighting, conditionalTerrain).toList()
|
||||
uniques.sumOf { unique -> unique.params[0].toInt() }.toFloat()
|
||||
@ -1391,7 +1391,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
if(fallbackBonuses && resource.resourceType == ResourceType.Bonus) {
|
||||
// Since we haven't been able to generate any rule-based lists, just generate new ones on the fly
|
||||
// Increase impact to avoid clustering since there is no terrain type stratification.
|
||||
val fallbackList = tileMap.values.filter { it.getLastTerrain().name in resource.terrainsCanBeFoundOn }.shuffled()
|
||||
val fallbackList = tileMap.values.filter { it.lastTerrain.name in resource.terrainsCanBeFoundOn }.shuffled()
|
||||
placeResourcesInTiles((20 * bonusMultiplier).toInt(), fallbackList, listOf(resource), 2 + extraImpact, 2 + extraImpact, false)
|
||||
}
|
||||
}
|
||||
@ -1440,7 +1440,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
for (tile in tiles) {
|
||||
val conditionalTerrain = StateForConditionals(attackedTile = tile)
|
||||
if (tile.resource == null &&
|
||||
tile.getLastTerrain().name in resource.terrainsCanBeFoundOn &&
|
||||
tile.lastTerrain.name in resource.terrainsCanBeFoundOn &&
|
||||
!tile.getBaseTerrain().hasUnique(UniqueType.BlocksResources, conditionalTerrain) &&
|
||||
!resource.hasUnique(UniqueType.NoNaturalGeneration, conditionalTerrain) &&
|
||||
resource.getMatchingUniques(UniqueType.TileGenerationConditions).none {
|
||||
@ -1515,7 +1515,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
for (tile in tileList) {
|
||||
if (tile.resource != null ||
|
||||
(testTerrains &&
|
||||
(tile.getLastTerrain().name !in resourceOptions.first().terrainsCanBeFoundOn ||
|
||||
(tile.lastTerrain.name !in resourceOptions.first().terrainsCanBeFoundOn ||
|
||||
resourceOptions.first().hasUnique(UniqueType.NoNaturalGeneration, conditionalTerrain)) ) ||
|
||||
tile.getBaseTerrain().hasUnique(UniqueType.BlocksResources, conditionalTerrain))
|
||||
continue // Can't place here, can't be a fallback tile
|
||||
|
@ -99,7 +99,7 @@ class NaturalWonderGenerator(val ruleset: Ruleset, val randomness: MapGeneration
|
||||
|
||||
val suitableLocations = tileMap.values.filter { tile->
|
||||
tile.resource == null &&
|
||||
naturalWonder.occursOn.contains(tile.getLastTerrain().name) &&
|
||||
naturalWonder.occursOn.contains(tile.lastTerrain.name) &&
|
||||
naturalWonder.uniqueObjects.all { unique ->
|
||||
when (unique.type) {
|
||||
UniqueType.NaturalWonderNeighborCount -> {
|
||||
@ -215,7 +215,7 @@ class NaturalWonderGenerator(val ruleset: Ruleset, val randomness: MapGeneration
|
||||
"Land" -> isLand
|
||||
Constants.hill -> isHill()
|
||||
naturalWonder -> true
|
||||
in allTerrainFeatures -> getLastTerrain().name == filter
|
||||
in allTerrainFeatures -> lastTerrain.name == filter
|
||||
else -> baseTerrain == filter
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ class UnitMovement(val unit: MapUnit) {
|
||||
if (unit.cache.ignoresTerrainCost) return 1f + extraCost
|
||||
if (areConnectedByRiver) return 100f // Rivers take the entire turn to cross
|
||||
|
||||
val terrainCost = to.getLastTerrain().movementCost.toFloat()
|
||||
val terrainCost = to.lastTerrain.movementCost.toFloat()
|
||||
|
||||
if (unit.cache.noTerrainMovementUniques)
|
||||
return terrainCost + extraCost
|
||||
@ -704,7 +704,7 @@ class UnitMovement(val unit: MapUnit) {
|
||||
// helicopters can pass through impassable tiles like mountains
|
||||
if (!unit.cache.canPassThroughImpassableTiles && !(unit.cache.canEnterIceTiles && tile.terrainFeatures.contains(Constants.ice))
|
||||
// carthage-like uniques sometimes allow passage through impassible tiles
|
||||
&& !(unit.civ.passThroughImpassableUnlocked && unit.civ.passableImpassables.contains(tile.getLastTerrain().name)))
|
||||
&& !(unit.civ.passThroughImpassableUnlocked && unit.civ.passableImpassables.contains(tile.lastTerrain.name)))
|
||||
return false
|
||||
}
|
||||
if (tile.isLand
|
||||
|
@ -96,6 +96,11 @@ open class Tile : IsPartOfGameInfoSerialization {
|
||||
var allTerrains: Sequence<Terrain> = sequenceOf()
|
||||
private set
|
||||
|
||||
@Transient
|
||||
/** Saves a sequence of a list */
|
||||
lateinit var lastTerrain: Terrain
|
||||
private set
|
||||
|
||||
@Transient
|
||||
var terrainUniqueMap = UniqueMap()
|
||||
private set
|
||||
@ -205,13 +210,6 @@ open class Tile : IsPartOfGameInfoSerialization {
|
||||
|
||||
fun getCity(): City? = owningCity
|
||||
|
||||
fun getLastTerrain(): Terrain = when {
|
||||
terrainFeatures.isNotEmpty() -> ruleset.terrains[terrainFeatures.last()]
|
||||
?: getBaseTerrain() // defense against rare edge cases involving baseTerrain Hill deprecation
|
||||
naturalWonder != null -> getNaturalWonder()
|
||||
else -> getBaseTerrain()
|
||||
}
|
||||
|
||||
@Transient
|
||||
private var tileResourceCache: TileResource? = null
|
||||
val tileResource: TileResource
|
||||
@ -257,7 +255,7 @@ open class Tile : IsPartOfGameInfoSerialization {
|
||||
|
||||
fun isCityCenter(): Boolean = isCityCenterInternal
|
||||
fun isNaturalWonder(): Boolean = naturalWonder != null
|
||||
fun isImpassible() = getLastTerrain().impassable
|
||||
fun isImpassible() = lastTerrain.impassable
|
||||
|
||||
fun getTileImprovement(): TileImprovement? = if (improvement == null) null else ruleset.tileImprovements[improvement!!]
|
||||
fun getUnpillagedTileImprovement(): TileImprovement? = if (getUnpillagedImprovement() == null) null else ruleset.tileImprovements[improvement!!]
|
||||
@ -826,6 +824,13 @@ open class Tile : IsPartOfGameInfoSerialization {
|
||||
val newUniqueMap = UniqueMap()
|
||||
for (terrain in allTerrains)
|
||||
newUniqueMap.addUniques(terrain.uniqueObjects)
|
||||
|
||||
lastTerrain = when {
|
||||
terrainFeatures.isNotEmpty() -> ruleset.terrains[terrainFeatures.last()]
|
||||
?: getBaseTerrain() // defense against rare edge cases involving baseTerrain Hill deprecation
|
||||
naturalWonder != null -> getNaturalWonder()
|
||||
else -> getBaseTerrain()
|
||||
}
|
||||
terrainUniqueMap = newUniqueMap
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ class TileInfoImprovementFunctions(val tile: Tile) {
|
||||
fun TileImprovement.canBeBuildOnThisUnbuildableTerrain(
|
||||
knownFeatureRemovals: List<TileImprovement>? = null,
|
||||
): Boolean {
|
||||
val topTerrain = tile.getLastTerrain()
|
||||
val topTerrain = tile.lastTerrain
|
||||
// We can build if we are specifically allowed to build on this terrain
|
||||
if (isAllowedOnFeature(topTerrain.name)) return true
|
||||
|
||||
@ -115,7 +115,7 @@ class TileInfoImprovementFunctions(val tile: Tile) {
|
||||
tile.improvement != null && tile.getTileImprovement()!!.hasUnique(UniqueType.Irremovable, stateForConditionals) -> false
|
||||
|
||||
// Can't build if this terrain is unbuildable, except when we are specifically allowed to
|
||||
tile.getLastTerrain().unbuildable && !improvement.canBeBuildOnThisUnbuildableTerrain(knownFeatureRemovals) -> false
|
||||
tile.lastTerrain.unbuildable && !improvement.canBeBuildOnThisUnbuildableTerrain(knownFeatureRemovals) -> false
|
||||
|
||||
// Can't build if any terrain specifically prevents building this improvement
|
||||
tile.getTerrainMatchingUniques(UniqueType.RestrictedBuildableImprovements, stateForConditionals).any {
|
||||
@ -146,7 +146,7 @@ class TileInfoImprovementFunctions(val tile: Tile) {
|
||||
// At this point we know this is a normal improvement and that there is no reason not to allow it to be built.
|
||||
|
||||
// Lastly we check if the improvement may be built on this terrain or resource
|
||||
improvement.canBeBuiltOn(tile.getLastTerrain().name) -> true
|
||||
improvement.canBeBuiltOn(tile.lastTerrain.name) -> true
|
||||
tile.isLand && improvement.canBeBuiltOn("Land") -> true
|
||||
tile.isWater && improvement.canBeBuiltOn("Water") -> true
|
||||
// DO NOT reverse this &&. isAdjacentToFreshwater() is a lazy which calls a function, and reversing it breaks the tests.
|
||||
|
@ -79,8 +79,8 @@ class ImprovementPickerScreen(
|
||||
// clone tileInfo without "top" feature if it could be removed
|
||||
// Keep this copy around for speed
|
||||
val tileWithoutLastTerrain: Tile = tile.clone()
|
||||
if (Constants.remove + tileWithoutLastTerrain.getLastTerrain().name in ruleSet.tileImprovements) {
|
||||
tileWithoutLastTerrain.removeTerrainFeature(tileWithoutLastTerrain.getLastTerrain().name)
|
||||
if (Constants.remove + tileWithoutLastTerrain.lastTerrain.name in ruleSet.tileImprovements) {
|
||||
tileWithoutLastTerrain.removeTerrainFeature(tileWithoutLastTerrain.lastTerrain.name)
|
||||
}
|
||||
|
||||
val cityUniqueCache = LocalUniqueCache()
|
||||
@ -133,7 +133,7 @@ class ImprovementPickerScreen(
|
||||
val proposedSolutions = mutableListOf<String>()
|
||||
|
||||
if (suggestRemoval)
|
||||
proposedSolutions.add("${Constants.remove}[${tile.getLastTerrain().name}] first")
|
||||
proposedSolutions.add("${Constants.remove}[${tile.lastTerrain.name}] first")
|
||||
if (ImprovementBuildingProblem.MissingTech in unbuildableBecause)
|
||||
proposedSolutions.add("Research [${improvement.techRequired}] first")
|
||||
if (ImprovementBuildingProblem.NotJustOutsideBorders in unbuildableBecause)
|
||||
|
Loading…
Reference in New Issue
Block a user