From 6b5c1e62dada34fabaf8c1fc4d52c9eb6c17ba53 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Wed, 22 Aug 2018 13:30:37 +0300 Subject: [PATCH] City-to-tile ownership is more efficient Fixed bug where when starting a new game your initial units would get an extra turn until you reloaded the game --- core/src/com/unciv/GameStarter.kt | 20 +++++++++--- core/src/com/unciv/logic/GameInfo.kt | 11 ------- .../unciv/logic/city/CityExpansionManager.kt | 31 ++++++++++++++++--- core/src/com/unciv/logic/city/CityInfo.kt | 3 +- .../com/unciv/logic/city/PopulationManager.kt | 3 +- .../logic/civilization/CivilizationInfo.kt | 9 ++---- core/src/com/unciv/logic/map/TileInfo.kt | 4 ++- .../src/com/unciv/ui/cityscreen/CityScreen.kt | 2 +- 8 files changed, 51 insertions(+), 32 deletions(-) diff --git a/core/src/com/unciv/GameStarter.kt b/core/src/com/unciv/GameStarter.kt index e1bd537234..1d6f31a61f 100644 --- a/core/src/com/unciv/GameStarter.kt +++ b/core/src/com/unciv/GameStarter.kt @@ -25,7 +25,7 @@ class GameStarter(){ val distanceAroundStartingPointNoOneElseWillStartIn = 5 val freeTiles = gameInfo.tileMap.values.toMutableList().filter { vectorIsWithinNTilesOfEdge(it.position,3)}.toMutableList() val playerPosition = freeTiles.getRandom().position - val playerCiv = CivilizationInfo(civilization, playerPosition, gameInfo) + val playerCiv = CivilizationInfo(civilization, gameInfo) playerCiv.difficulty=difficulty gameInfo.civilizations.add(playerCiv) // first one is player civ @@ -35,18 +35,28 @@ class GameStarter(){ gameInfo.civilizations.add(barbarianCivilization)// second is barbarian civ for (civname in GameBasics.Nations.keys.filterNot { it=="Barbarians" || it==civilization }.take(numberOfCivs)) { - if(freeTiles.isEmpty()) break // we can't add any more civs. - val startingLocation = freeTiles.toList().getRandom().position - val civ = CivilizationInfo(civname, startingLocation, gameInfo) + val civ = CivilizationInfo(civname, gameInfo) civ.tech.techsResearched.addAll(playerCiv.getDifficulty().aiFreeTechs) gameInfo.civilizations.add(civ) - freeTiles.removeAll(gameInfo.tileMap.getTilesInDistance(startingLocation, distanceAroundStartingPointNoOneElseWillStartIn )) } + barbarianCivilization.civName = "Barbarians" gameInfo.setTransients() // needs to be before placeBarbarianUnit because it depends on the tilemap having its gameinfo set + // and only now do we add units for everyone, because otherwise both the gameIngo.setTransients() and the placeUnit will both add the unit to the civ's unit list! + + for (civ in gameInfo.civilizations.toList().filter { !it.isBarbarianCivilization() }) { + if(freeTiles.isEmpty()) gameInfo.civilizations.remove(civ) // we can't add any more civs. + val startingLocation = freeTiles.toList().getRandom().position + + civ.placeUnitNearTile(startingLocation, "Settler") + civ.placeUnitNearTile(startingLocation, "Scout") + + freeTiles.removeAll(gameInfo.tileMap.getTilesInDistance(startingLocation, distanceAroundStartingPointNoOneElseWillStartIn )) + } + (1..5).forEach { val freeTilesList = freeTiles.toList() if(freeTilesList.isNotEmpty()){ diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 60d92aeaa8..abd63a0b60 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -2,7 +2,6 @@ package com.unciv.logic import com.badlogic.gdx.graphics.Color import com.unciv.logic.automation.Automation -import com.unciv.logic.city.CityInfo import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.Notification import com.unciv.logic.map.TileInfo @@ -11,8 +10,6 @@ import com.unciv.models.gamebasics.GameBasics import com.unciv.ui.utils.getRandom class GameInfo { - @Transient var tilesToCities = HashMap() - var notifications = mutableListOf() @Deprecated("As of 2.6.9") var tutorial = mutableListOf() var civilizations = mutableListOf() @@ -100,15 +97,7 @@ class GameInfo { for (civInfo in civilizations) for (cityInfo in civInfo.cities) cityInfo.cityStats.update() - - updateTilesToCities() } - fun updateTilesToCities(){ - tilesToCities.clear() - for (city in civilizations.flatMap { it.cities }){ - for (tile in city.getTiles()) tilesToCities.put(tile,city) - } - } } diff --git a/core/src/com/unciv/logic/city/CityExpansionManager.kt b/core/src/com/unciv/logic/city/CityExpansionManager.kt index c553055aac..072f4204bd 100644 --- a/core/src/com/unciv/logic/city/CityExpansionManager.kt +++ b/core/src/com/unciv/logic/city/CityExpansionManager.kt @@ -31,7 +31,7 @@ class CityExpansionManager { } - fun getNewTile(): TileInfo? { + fun chooseNewTileToOwn(): TileInfo? { for (i in 2..5) { val tiles = cityInfo.getCenterTile().getTilesInDistance(i).filter { it.getOwner() != cityInfo.civInfo @@ -46,24 +46,40 @@ class CityExpansionManager { //region state-changing functions fun reset() { - cityInfo.tiles.clear() + for(tile in cityInfo.tiles.map { cityInfo.tileMap[it] }) + relinquishOwnership(tile) + +// cityInfo.tiles.clear() // this should be deleted after we change systems cityInfo.getCenterTile().getTilesInDistance(1).forEach { takeOwnership(it) } } private fun addNewTileWithCulture() { cultureStored -= getCultureToNextTile() - val chosenTile = getNewTile() + val chosenTile = chooseNewTileToOwn() if(chosenTile!=null){ takeOwnership(chosenTile) } } + fun relinquishOwnership(tileInfo: TileInfo){ + cityInfo.tiles.remove(tileInfo.position) + if(cityInfo.workedTiles.contains(tileInfo.position)) + cityInfo.workedTiles.remove(tileInfo.position) + tileInfo.owningCity=null + } + fun takeOwnership(tileInfo: TileInfo){ - for(city in cityInfo.civInfo.gameInfo.civilizations.flatMap { it.cities }) // Remove this tile from any other cities - should stop SO many problems! - cityInfo.tiles.remove(tileInfo.position) + if(tileInfo.getCity()!=null) tileInfo.getCity()!!.expansion.relinquishOwnership(tileInfo) + + // this shuold be deleted ater we move to the new caching system +// for(city in cityInfo.civInfo.gameInfo.civilizations.flatMap { it.cities }) // Remove this tile from any other cities - should stop SO many problems! +// cityInfo.tiles.remove(tileInfo.position) cityInfo.tiles.add(tileInfo.position) + tileInfo.owningCity = cityInfo + cityInfo.population.autoAssignPopulation() + for(unit in tileInfo.getUnits()) if(!unit.civInfo.canEnterTiles(cityInfo.civInfo)) unit.movementAlgs().teleportToClosestMoveableTile() @@ -77,5 +93,10 @@ class CityExpansionManager { cityInfo.civInfo.addNotification(cityInfo.name + " {has expanded its borders}!", cityInfo.location, Color.PURPLE) } } + + fun setTransients(){ + for(tile in cityInfo.tiles.map { cityInfo.tileMap[it] }) + tile.owningCity=cityInfo + } //endregion } \ No newline at end of file diff --git a/core/src/com/unciv/logic/city/CityInfo.kt b/core/src/com/unciv/logic/city/CityInfo.kt index c0d8a7a97f..0c2bee939b 100644 --- a/core/src/com/unciv/logic/city/CityInfo.kt +++ b/core/src/com/unciv/logic/city/CityInfo.kt @@ -52,7 +52,6 @@ class CityInfo { } expansion.reset() - civInfo.gameInfo.updateTilesToCities() val tile = getCenterTile() tile.roadStatus = RoadStatus.Railroad @@ -141,6 +140,7 @@ class CityInfo { fun setTransients() { population.cityInfo = this expansion.cityInfo = this + expansion.setTransients() cityStats.cityInfo = this cityConstructions.cityInfo = this } @@ -186,7 +186,6 @@ class CityInfo { for(building in cityConstructions.getBuiltBuildings().filter { it.requiredBuildingInAllCities!=null }) cityConstructions.builtBuildings.remove(building.name) - civInfo.gameInfo.updateTilesToCities() } //endregion } \ No newline at end of file diff --git a/core/src/com/unciv/logic/city/PopulationManager.kt b/core/src/com/unciv/logic/city/PopulationManager.kt index 29484a8b2d..d8068157e9 100644 --- a/core/src/com/unciv/logic/city/PopulationManager.kt +++ b/core/src/com/unciv/logic/city/PopulationManager.kt @@ -74,6 +74,7 @@ class PopulationManager { } internal fun autoAssignPopulation() { + if(getFreePopulation()==0) return val toWork: TileInfo? = cityInfo.getTiles() .filterNot { cityInfo.workedTiles.contains(it.position) || cityInfo.location==it.position} .maxBy { Automation().rankTile(it,cityInfo.civInfo) } @@ -83,7 +84,7 @@ class PopulationManager { fun unassignExtraPopulation() { for(tile in cityInfo.workedTiles.map { cityInfo.tileMap[it] }) - if(tile.getOwner()!=cityInfo.civInfo) + if(tile.getCity()!=cityInfo) cityInfo.workedTiles.remove(tile.position) while (cityInfo.workedTiles.size > population) { diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 6388bb46f7..56b52deb0a 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -40,12 +40,10 @@ class CivilizationInfo { constructor() - constructor(civName: String, startingLocation: Vector2, gameInfo: GameInfo) { + constructor(civName: String, gameInfo: GameInfo) { this.civName = civName - this.gameInfo = gameInfo +// this.gameInfo = gameInfo // already happens in setTransients tech.techsResearched.add("Agriculture") - this.placeUnitNearTile(startingLocation, "Settler") - this.placeUnitNearTile(startingLocation, "Scout") } fun clone(): CivilizationInfo { @@ -240,8 +238,8 @@ class CivilizationInfo { } for (cityInfo in cities) { + cityInfo.civInfo = this // must be before the city's setTransients because it depends on the tilemap, that comes from the civInfo cityInfo.setTransients() - cityInfo.civInfo = this } } @@ -280,7 +278,6 @@ class CivilizationInfo { goldenAges.endTurn(happiness) getCivUnits().forEach { it.endTurn() } diplomacy.values.forEach{it.nextTurn()} - gameInfo.updateTilesToCities() } fun startTurn(){ diff --git a/core/src/com/unciv/logic/map/TileInfo.kt b/core/src/com/unciv/logic/map/TileInfo.kt index d3317ecd69..33420ac409 100644 --- a/core/src/com/unciv/logic/map/TileInfo.kt +++ b/core/src/com/unciv/logic/map/TileInfo.kt @@ -14,6 +14,7 @@ import kotlin.math.abs open class TileInfo { @Transient lateinit var tileMap: TileMap + @Transient var owningCity:CityInfo?=null var militaryUnit:MapUnit?=null var civilianUnit:MapUnit?=null @@ -48,7 +49,8 @@ open class TileInfo { fun getUnits()= listOf(militaryUnit,civilianUnit).filterNotNull() fun getCity(): CityInfo? { - return tileMap.gameInfo.tilesToCities.get(this) + return owningCity +// return tileMap.gameInfo.tilesToCities.get(this) //return tileMap.gameInfo.civilizations.flatMap { it.cities }.firstOrNull{it.tiles.contains(position)} } diff --git a/core/src/com/unciv/ui/cityscreen/CityScreen.kt b/core/src/com/unciv/ui/cityscreen/CityScreen.kt index e1e4230be3..f3b4450902 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreen.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreen.kt @@ -101,7 +101,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() { private fun updateTileGroups() { - val nextTile = city.expansion.getNewTile() + val nextTile = city.expansion.chooseNewTileToOwn() for (HG in tileGroups) { HG.update() if(HG.tileInfo == nextTile){