Made resource object lazy - this should speed up all sorts, especially tile stats checking

This commit is contained in:
yairm210 2021-10-19 22:08:35 +03:00
parent 21925b920b
commit 96c69cf1e9
10 changed files with 40 additions and 37 deletions

View File

@ -476,7 +476,7 @@ object GameStarter {
val relevantTiles = spawn.getTilesInDistance(2).shuffled() val relevantTiles = spawn.getTilesInDistance(2).shuffled()
for (tile in relevantTiles) { for (tile in relevantTiles) {
if(tile.resource != null && tile.getTileResource().resourceType == ResourceType.Luxury) if(tile.resource != null && tile.tileResource.resourceType == ResourceType.Luxury)
return // At least one luxury; all set return // At least one luxury; all set
} }

View File

@ -221,7 +221,7 @@ object Automation {
var rank = rankStatsValue(stats, civInfo) var rank = rankStatsValue(stats, civInfo)
if (tile.improvement == null) rank += 0.5f // improvement potential! if (tile.improvement == null) rank += 0.5f // improvement potential!
if (tile.hasViewableResource(civInfo)) { if (tile.hasViewableResource(civInfo)) {
val resource = tile.getTileResource() val resource = tile.tileResource
if (resource.resourceType != ResourceType.Bonus) rank += 1f // for usage if (resource.resourceType != ResourceType.Bonus) rank += 1f // for usage
if (tile.improvement == null) rank += 1f // improvement potential - resources give lots when improved! if (tile.improvement == null) rank += 1f // improvement potential - resources give lots when improved!
} }
@ -243,7 +243,7 @@ object Automation {
// Resources are good: less points // Resources are good: less points
if (tile.hasViewableResource(cityInfo.civInfo)) { if (tile.hasViewableResource(cityInfo.civInfo)) {
if (tile.getTileResource().resourceType != ResourceType.Bonus) score -= 105 if (tile.tileResource.resourceType != ResourceType.Bonus) score -= 105
else if (distance <= 3) score -= 104 else if (distance <= 3) score -= 104
} else { } else {
@ -273,7 +273,7 @@ object Automation {
val adjacentDistance = cityInfo.getCenterTile().aerialDistanceTo(adjacentTile) val adjacentDistance = cityInfo.getCenterTile().aerialDistanceTo(adjacentTile)
if (adjacentTile.hasViewableResource(cityInfo.civInfo) && if (adjacentTile.hasViewableResource(cityInfo.civInfo) &&
(adjacentDistance < 3 || (adjacentDistance < 3 ||
adjacentTile.getTileResource().resourceType != ResourceType.Bonus adjacentTile.tileResource.resourceType != ResourceType.Bonus
) )
) score -= 1 ) score -= 1
if (adjacentTile.naturalWonder != null) { if (adjacentTile.naturalWonder != null) {

View File

@ -34,7 +34,7 @@ object SpecificUnitAutomation {
unit.movement.headTowards(closestReachableResource) unit.movement.headTowards(closestReachableResource)
// could be either fishing boats or oil well // could be either fishing boats or oil well
val improvement = closestReachableResource.getTileResource().improvement val improvement = closestReachableResource.tileResource.improvement
if (unit.currentTile == closestReachableResource && improvement != null) if (unit.currentTile == closestReachableResource && improvement != null)
UnitActions.getWaterImprovementAction(unit)?.action?.invoke() UnitActions.getWaterImprovementAction(unit)?.action?.invoke()
} }
@ -137,7 +137,7 @@ object SpecificUnitAutomation {
if (tileInfo.isCoastalTile()) rank += 5 if (tileInfo.isCoastalTile()) rank += 5
val luxuryResourcesInCityArea = tileInfo.getTilesAtDistance(2).filter { it.resource != null } val luxuryResourcesInCityArea = tileInfo.getTilesAtDistance(2).filter { it.resource != null }
.map { it.getTileResource() }.filter { it.resourceType == ResourceType.Luxury }.distinct() .map { it.tileResource }.filter { it.resourceType == ResourceType.Luxury }.distinct()
val luxuryResourcesAlreadyInCivArea = luxuryResourcesInCivArea.map { it.name }.toHashSet() val luxuryResourcesAlreadyInCivArea = luxuryResourcesInCivArea.map { it.name }.toHashSet()
val luxuryResourcesNotYetInCiv = luxuryResourcesInCityArea val luxuryResourcesNotYetInCiv = luxuryResourcesInCityArea
.count { it.name !in luxuryResourcesAlreadyInCivArea } .count { it.name !in luxuryResourcesAlreadyInCivArea }
@ -191,7 +191,7 @@ object SpecificUnitAutomation {
val luxuryResourcesInCivArea = unit.civInfo.cities.asSequence() val luxuryResourcesInCivArea = unit.civInfo.cities.asSequence()
.flatMap { it.getTiles().asSequence() }.filter { it.resource != null } .flatMap { it.getTiles().asSequence() }.filter { it.resource != null }
.map { it.getTileResource() }.filter { it.resourceType == ResourceType.Luxury } .map { it.tileResource }.filter { it.resourceType == ResourceType.Luxury }
.distinct() .distinct()
val citiesByRanking = possibleCityLocations val citiesByRanking = possibleCityLocations

View File

@ -301,7 +301,7 @@ class WorkerAutomation(
if (chosenImprovement != null && tile.canBuildImprovement(chosenImprovement, civInfo) && unit.canBuildImprovement(chosenImprovement, tile)) return true if (chosenImprovement != null && tile.canBuildImprovement(chosenImprovement, civInfo) && unit.canBuildImprovement(chosenImprovement, tile)) return true
} else if (!tile.containsGreatImprovement() && tile.hasViewableResource(civInfo) } else if (!tile.containsGreatImprovement() && tile.hasViewableResource(civInfo)
&& tile.getTileResource().improvement != tile.improvement && tile.tileResource.improvement != tile.improvement
&& (unit == null || chooseImprovement(unit, tile) // if the chosen improvement is not null and buildable && (unit == null || chooseImprovement(unit, tile) // if the chosen improvement is not null and buildable
.let { it != null && tile.canBuildImprovement(it, civInfo) && unit.canBuildImprovement(it, tile)})) .let { it != null && tile.canBuildImprovement(it, civInfo) && unit.canBuildImprovement(it, tile)}))
return true return true
@ -335,7 +335,7 @@ class WorkerAutomation(
tile.terrainFeatures.contains("Fallout") && !isImprovementOnFeatureAllowed(tile) -> "Remove Fallout" // for really mad modders tile.terrainFeatures.contains("Fallout") && !isImprovementOnFeatureAllowed(tile) -> "Remove Fallout" // for really mad modders
tile.terrainFeatures.contains(Constants.jungle) && !isImprovementOnFeatureAllowed(tile) -> "Remove Jungle" tile.terrainFeatures.contains(Constants.jungle) && !isImprovementOnFeatureAllowed(tile) -> "Remove Jungle"
tile.terrainFeatures.contains(Constants.forest) && !isImprovementOnFeatureAllowed(tile) -> "Remove Forest" tile.terrainFeatures.contains(Constants.forest) && !isImprovementOnFeatureAllowed(tile) -> "Remove Forest"
else -> tile.getTileResource().improvement else -> tile.tileResource.improvement
} }
// turnsToBuild is what defines them as buildable // turnsToBuild is what defines them as buildable
@ -378,7 +378,7 @@ class WorkerAutomation(
* Assumes the caller ensured that terrainFeature and resource are both present! * Assumes the caller ensured that terrainFeature and resource are both present!
*/ */
private fun isImprovementOnFeatureAllowed(tile: TileInfo): Boolean { private fun isImprovementOnFeatureAllowed(tile: TileInfo): Boolean {
val resourceImprovementName = tile.getTileResource().improvement val resourceImprovementName = tile.tileResource.improvement
?: return false ?: return false
val resourceImprovement = ruleSet.tileImprovements[resourceImprovementName] val resourceImprovement = ruleSet.tileImprovements[resourceImprovementName]
?: return false ?: return false

View File

@ -273,7 +273,7 @@ class CityInfo {
val cityResources = ResourceSupplyList() val cityResources = ResourceSupplyList()
for (tileInfo in getTiles().filter { it.resource != null }) { for (tileInfo in getTiles().filter { it.resource != null }) {
val resource = tileInfo.getTileResource() val resource = tileInfo.tileResource
val amount = getTileResourceAmount(tileInfo) * civInfo.getResourceModifier(resource) val amount = getTileResourceAmount(tileInfo) * civInfo.getResourceModifier(resource)
if (amount > 0) cityResources.add(resource, amount, "Tiles") if (amount > 0) cityResources.add(resource, amount, "Tiles")
} }
@ -336,7 +336,7 @@ class CityInfo {
fun getTileResourceAmount(tileInfo: TileInfo): Int { fun getTileResourceAmount(tileInfo: TileInfo): Int {
if (tileInfo.resource == null) return 0 if (tileInfo.resource == null) return 0
val resource = tileInfo.getTileResource() val resource = tileInfo.tileResource
if (resource.revealedBy != null && !civInfo.tech.isResearched(resource.revealedBy!!)) return 0 if (resource.revealedBy != null && !civInfo.tech.isResearched(resource.revealedBy!!)) return 0
// Even if the improvement exists (we conquered an enemy city or somesuch) or we have a city on it, we won't get the resource until the correct tech is researched // Even if the improvement exists (we conquered an enemy city or somesuch) or we have a city on it, we won't get the resource until the correct tech is researched

View File

@ -135,10 +135,12 @@ open class TileInfo {
else -> getBaseTerrain() else -> getBaseTerrain()
} }
fun getTileResource(): TileResource = @delegate:Transient
if (resource == null) throw Exception("No resource exists for this tile!") val tileResource: TileResource by lazy {
else if (!ruleset.tileResources.containsKey(resource!!)) throw Exception("Resource $resource does not exist in this ruleset!") if (resource == null) throw Exception("No resource exists for this tile!")
else ruleset.tileResources[resource!!]!! else if (!ruleset.tileResources.containsKey(resource!!)) throw Exception("Resource $resource does not exist in this ruleset!")
else ruleset.tileResources[resource!!]!!
}
private fun getNaturalWonder(): Terrain = private fun getNaturalWonder(): Terrain =
if (naturalWonder == null) throw Exception("No natural wonder exists for this tile!") if (naturalWonder == null) throw Exception("No natural wonder exists for this tile!")
@ -278,7 +280,7 @@ open class TileInfo {
} }
// resource base // resource base
if (hasViewableResource(observingCiv)) stats.add(getTileResource()) if (hasViewableResource(observingCiv)) stats.add(tileResource)
val improvement = getTileImprovement() val improvement = getTileImprovement()
if (improvement != null) if (improvement != null)
@ -332,7 +334,7 @@ open class TileInfo {
else else
stats.add(terrainFeatureBase) stats.add(terrainFeatureBase)
} }
if (resource != null) stats.add(getTileResource()) if (resource != null) stats.add(tileResource)
if (stats.production < 0) stats.production = 0f if (stats.production < 0) stats.production = 0f
if (isCenter) { if (isCenter) {
@ -345,8 +347,8 @@ open class TileInfo {
fun getImprovementStats(improvement: TileImprovement, observingCiv: CivilizationInfo, city: CityInfo?): Stats { fun getImprovementStats(improvement: TileImprovement, observingCiv: CivilizationInfo, city: CityInfo?): Stats {
val stats = improvement.clone() // clones the stats of the improvement, not the improvement itself val stats = improvement.clone() // clones the stats of the improvement, not the improvement itself
if (hasViewableResource(observingCiv) && getTileResource().improvement == improvement.name) if (hasViewableResource(observingCiv) && tileResource.improvement == improvement.name)
stats.add(getTileResource().improvementStats!!.clone()) // resource-specific improvement stats.add(tileResource.improvementStats!!.clone()) // resource-specific improvement
for (unique in improvement.uniqueObjects) for (unique in improvement.uniqueObjects)
if (unique.placeholderText == "[] once [] is discovered" && observingCiv.tech.isResearched(unique.params[1])) if (unique.placeholderText == "[] once [] is discovered" && observingCiv.tech.isResearched(unique.params[1]))
@ -460,7 +462,7 @@ open class TileInfo {
it.any() && it.all { unique -> matchesTerrainFilter(unique.params[0]) } it.any() && it.all { unique -> matchesTerrainFilter(unique.params[0]) }
} -> true } -> true
else -> resourceIsVisible && getTileResource().improvement == improvement.name else -> resourceIsVisible && tileResource.improvement == improvement.name
} }
} }
@ -499,7 +501,7 @@ open class TileInfo {
// Checks 'luxury resource', 'strategic resource' and 'bonus resource' - only those that are visible of course // Checks 'luxury resource', 'strategic resource' and 'bonus resource' - only those that are visible of course
// not using hasViewableResource as observingCiv is often not passed in, // not using hasViewableResource as observingCiv is often not passed in,
// and we want to be able to at least test for non-strategic in that case. // and we want to be able to at least test for non-strategic in that case.
val resourceObject = getTileResource() val resourceObject = tileResource
if (resourceObject.resourceType.name + " resource" != filter) return false // filter match if (resourceObject.resourceType.name + " resource" != filter) return false // filter match
if (resourceObject.revealedBy == null) return true // no need for tech if (resourceObject.revealedBy == null) return true // no need for tech
if (observingCiv == null) return false // can't check tech if (observingCiv == null) return false // can't check tech
@ -515,7 +517,8 @@ open class TileInfo {
fun isCoastalTile() = _isCoastalTile fun isCoastalTile() = _isCoastalTile
fun hasViewableResource(civInfo: CivilizationInfo): Boolean = fun hasViewableResource(civInfo: CivilizationInfo): Boolean =
resource != null && (getTileResource().revealedBy == null || civInfo.tech.isResearched(getTileResource().revealedBy!!)) resource != null && (tileResource.revealedBy == null || civInfo.tech.isResearched(
tileResource.revealedBy!!))
fun getViewableTilesList(distance: Int): List<TileInfo> = fun getViewableTilesList(distance: Int): List<TileInfo> =
tileMap.getViewableTiles(position, distance) tileMap.getViewableTiles(position, distance)
@ -564,7 +567,7 @@ open class TileInfo {
lineList += baseTerrain lineList += baseTerrain
for (terrainFeature in terrainFeatures) lineList += terrainFeature for (terrainFeature in terrainFeatures) lineList += terrainFeature
if (resource != null) { if (resource != null) {
lineList += if (getTileResource().resourceType == ResourceType.Strategic) lineList += if (tileResource.resourceType == ResourceType.Strategic)
"{$resourceAmount} {$resource}" "{$resourceAmount} {$resource}"
else else
resource!! resource!!
@ -626,12 +629,12 @@ open class TileInfo {
for (terrainFeature in terrainFeatures) for (terrainFeature in terrainFeatures)
lineList += FormattedLine(terrainFeature, link="Terrain/$terrainFeature") lineList += FormattedLine(terrainFeature, link="Terrain/$terrainFeature")
if (resource != null && (viewingCiv == null || hasViewableResource(viewingCiv))) if (resource != null && (viewingCiv == null || hasViewableResource(viewingCiv)))
lineList += if (getTileResource().resourceType == ResourceType.Strategic) lineList += if (tileResource.resourceType == ResourceType.Strategic)
FormattedLine("{$resource} ($resourceAmount)", link="Resource/$resource") FormattedLine("{$resource} ($resourceAmount)", link="Resource/$resource")
else else
FormattedLine(resource!!, link="Resource/$resource") FormattedLine(resource!!, link="Resource/$resource")
if (resource != null && viewingCiv != null && hasViewableResource(viewingCiv)) { if (resource != null && viewingCiv != null && hasViewableResource(viewingCiv)) {
val tileImprovement = ruleset.tileImprovements[getTileResource().improvement] val tileImprovement = ruleset.tileImprovements[tileResource.improvement]
if (tileImprovement?.techRequired != null if (tileImprovement?.techRequired != null
&& !viewingCiv.tech.isResearched(tileImprovement.techRequired!!)) { && !viewingCiv.tech.isResearched(tileImprovement.techRequired!!)) {
lineList += FormattedLine( lineList += FormattedLine(
@ -725,9 +728,9 @@ open class TileInfo {
isOcean = baseTerrain == Constants.ocean isOcean = baseTerrain == Constants.ocean
// Resource amounts missing - Old save or bad mapgen? // Resource amounts missing - Old save or bad mapgen?
if (resource != null && getTileResource().resourceType == ResourceType.Strategic && resourceAmount == 0) { if (resource != null && tileResource.resourceType == ResourceType.Strategic && resourceAmount == 0) {
// Let's assume it's a small deposit // Let's assume it's a small deposit
setTileResource(getTileResource(), majorDeposit = false) setTileResource(tileResource, majorDeposit = false)
} }
} }

View File

@ -620,8 +620,8 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
it.resource != null it.resource != null
&& requiredNearbyImprovedResources!!.contains(it.resource!!) && requiredNearbyImprovedResources!!.contains(it.resource!!)
&& it.getOwner() == civInfo && it.getOwner() == civInfo
&& (it.getTileResource().improvement == it.improvement || it.isCityCenter() && (it.tileResource.improvement == it.improvement || it.isCityCenter()
|| (it.getTileImprovement()?.isGreatImprovement() == true && it.getTileResource().resourceType == ResourceType.Strategic) || (it.getTileImprovement()?.isGreatImprovement() == true && it.tileResource.resourceType == ResourceType.Strategic)
) )
} }
if (!containsResourceWithImprovement) if (!containsResourceWithImprovement)

View File

@ -88,7 +88,7 @@ class ImprovementPickerScreen(val tileInfo: TileInfo, unit: MapUnit, val onAccep
val turnsToBuild = if (tileInfo.improvementInProgress == improvement.name) tileInfo.turnsToImprovement val turnsToBuild = if (tileInfo.improvementInProgress == improvement.name) tileInfo.turnsToImprovement
else improvement.getTurnsToBuild(currentPlayerCiv) else improvement.getTurnsToBuild(currentPlayerCiv)
if (turnsToBuild > 0) labelText += " - $turnsToBuild${Fonts.turn}" if (turnsToBuild > 0) labelText += " - $turnsToBuild${Fonts.turn}"
val provideResource = tileInfo.hasViewableResource(currentPlayerCiv) && tileInfo.getTileResource().improvement == improvement.name val provideResource = tileInfo.hasViewableResource(currentPlayerCiv) && tileInfo.tileResource.improvement == improvement.name
if (provideResource) labelText += "\n" + "Provides [${tileInfo.resource}]".tr() if (provideResource) labelText += "\n" + "Provides [${tileInfo.resource}]".tr()
val removeImprovement = (improvement.name != RoadStatus.Road.name val removeImprovement = (improvement.name != RoadStatus.Road.name
&& improvement.name != RoadStatus.Railroad.name && !improvement.name.startsWith("Remove") && improvement.name != Constants.cancelImprovementOrder) && improvement.name != RoadStatus.Railroad.name && !improvement.name.startsWith("Remove") && improvement.name != Constants.cancelImprovementOrder)
@ -149,7 +149,7 @@ class ImprovementPickerScreen(val tileInfo: TileInfo, unit: MapUnit, val onAccep
statIcons.add(ImageGetter.getResourceImage(tileInfo.resource.toString(), 30f)).pad(3f) statIcons.add(ImageGetter.getResourceImage(tileInfo.resource.toString(), 30f)).pad(3f)
// icon for removing the resource by replacing improvement // icon for removing the resource by replacing improvement
if (removeImprovement && tileInfo.hasViewableResource(currentPlayerCiv) && tileInfo.getTileResource().improvement == tileInfo.improvement) { if (removeImprovement && tileInfo.hasViewableResource(currentPlayerCiv) && tileInfo.tileResource.improvement == tileInfo.improvement) {
val crossedResource = Group() val crossedResource = Group()
val cross = ImageGetter.getRedCross(30f, 0.8f) val cross = ImageGetter.getRedCross(30f, 0.8f)
val resourceIcon = ImageGetter.getResourceImage(tileInfo.resource.toString(), 30f) val resourceIcon = ImageGetter.getResourceImage(tileInfo.resource.toString(), 30f)

View File

@ -393,7 +393,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo): CameraStageBaseScreen()
if (improvableTile.canBuildImprovement( if (improvableTile.canBuildImprovement(
tileImprovement, tileImprovement,
otherCiv otherCiv
) && improvableTile.getTileResource().improvement == tileImprovement.name ) && improvableTile.tileResource.improvement == tileImprovement.name
) )
needsImprovements = true needsImprovements = true
@ -457,7 +457,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo): CameraStageBaseScreen()
fun getImprovableResourceTiles(otherCiv:CivilizationInfo) = otherCiv.getCapital().getTiles() fun getImprovableResourceTiles(otherCiv:CivilizationInfo) = otherCiv.getCapital().getTiles()
.filter { it.hasViewableResource(otherCiv) && it.improvement == null .filter { it.hasViewableResource(otherCiv) && it.improvement == null
&& it.getTileResource().resourceType!=ResourceType.Bonus } && it.tileResource.resourceType!=ResourceType.Bonus }
private fun getImprovementGiftTable(otherCiv: CivilizationInfo): Table { private fun getImprovementGiftTable(otherCiv: CivilizationInfo): Table {
val improvementGiftTable = getCityStateDiplomacyTableHeader(otherCiv) val improvementGiftTable = getCityStateDiplomacyTableHeader(otherCiv)
@ -470,10 +470,10 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo): CameraStageBaseScreen()
for (improvableTile in improvableResourceTiles) { for (improvableTile in improvableResourceTiles) {
for (tileImprovement in tileImprovements.values) { for (tileImprovement in tileImprovements.values) {
if (improvableTile.canBuildImprovement(tileImprovement, otherCiv) && if (improvableTile.canBuildImprovement(tileImprovement, otherCiv) &&
improvableTile.getTileResource().improvement == tileImprovement.name improvableTile.tileResource.improvement == tileImprovement.name
) { ) {
val improveTileButton = val improveTileButton =
"Build [${tileImprovement}] on [${improvableTile.getTileResource()}] (200 Gold)".toTextButton() "Build [${tileImprovement}] on [${improvableTile.tileResource}] (200 Gold)".toTextButton()
improveTileButton.onClick { improveTileButton.onClick {
viewingCiv.addGold(-200) viewingCiv.addGold(-200)
improvableTile.stopWorkingOnImprovement() improvableTile.stopWorkingOnImprovement()

View File

@ -130,7 +130,7 @@ object UnitActions {
val tile = unit.currentTile val tile = unit.currentTile
if (!tile.isWater || !unit.hasUnique(UniqueType.CreateWaterImprovements) || tile.resource == null) return null if (!tile.isWater || !unit.hasUnique(UniqueType.CreateWaterImprovements) || tile.resource == null) return null
val improvementName = tile.getTileResource().improvement ?: return null val improvementName = tile.tileResource.improvement ?: return null
val improvement = tile.ruleset.tileImprovements[improvementName] ?: return null val improvement = tile.ruleset.tileImprovements[improvementName] ?: return null
if (!tile.canBuildImprovement(improvement, unit.civInfo)) return null if (!tile.canBuildImprovement(improvement, unit.civInfo)) return null