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
This commit is contained in:
Yair Morgenstern
2018-08-22 13:30:37 +03:00
parent 5e1bccdc47
commit 6b5c1e62da
8 changed files with 51 additions and 32 deletions

View File

@ -25,7 +25,7 @@ class GameStarter(){
val distanceAroundStartingPointNoOneElseWillStartIn = 5 val distanceAroundStartingPointNoOneElseWillStartIn = 5
val freeTiles = gameInfo.tileMap.values.toMutableList().filter { vectorIsWithinNTilesOfEdge(it.position,3)}.toMutableList() val freeTiles = gameInfo.tileMap.values.toMutableList().filter { vectorIsWithinNTilesOfEdge(it.position,3)}.toMutableList()
val playerPosition = freeTiles.getRandom().position val playerPosition = freeTiles.getRandom().position
val playerCiv = CivilizationInfo(civilization, playerPosition, gameInfo) val playerCiv = CivilizationInfo(civilization, gameInfo)
playerCiv.difficulty=difficulty playerCiv.difficulty=difficulty
gameInfo.civilizations.add(playerCiv) // first one is player civ gameInfo.civilizations.add(playerCiv) // first one is player civ
@ -35,18 +35,28 @@ class GameStarter(){
gameInfo.civilizations.add(barbarianCivilization)// second is barbarian civ gameInfo.civilizations.add(barbarianCivilization)// second is barbarian civ
for (civname in GameBasics.Nations.keys.filterNot { it=="Barbarians" || it==civilization }.take(numberOfCivs)) { 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 civ = CivilizationInfo(civname, gameInfo)
val startingLocation = freeTiles.toList().getRandom().position
val civ = CivilizationInfo(civname, startingLocation, gameInfo)
civ.tech.techsResearched.addAll(playerCiv.getDifficulty().aiFreeTechs) civ.tech.techsResearched.addAll(playerCiv.getDifficulty().aiFreeTechs)
gameInfo.civilizations.add(civ) gameInfo.civilizations.add(civ)
freeTiles.removeAll(gameInfo.tileMap.getTilesInDistance(startingLocation, distanceAroundStartingPointNoOneElseWillStartIn ))
} }
barbarianCivilization.civName = "Barbarians" barbarianCivilization.civName = "Barbarians"
gameInfo.setTransients() // needs to be before placeBarbarianUnit because it depends on the tilemap having its gameinfo set 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 { (1..5).forEach {
val freeTilesList = freeTiles.toList() val freeTilesList = freeTiles.toList()
if(freeTilesList.isNotEmpty()){ if(freeTilesList.isNotEmpty()){

View File

@ -2,7 +2,6 @@ package com.unciv.logic
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.unciv.logic.automation.Automation import com.unciv.logic.automation.Automation
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.Notification import com.unciv.logic.civilization.Notification
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
@ -11,8 +10,6 @@ import com.unciv.models.gamebasics.GameBasics
import com.unciv.ui.utils.getRandom import com.unciv.ui.utils.getRandom
class GameInfo { class GameInfo {
@Transient var tilesToCities = HashMap<TileInfo,CityInfo>()
var notifications = mutableListOf<Notification>() var notifications = mutableListOf<Notification>()
@Deprecated("As of 2.6.9") var tutorial = mutableListOf<String>() @Deprecated("As of 2.6.9") var tutorial = mutableListOf<String>()
var civilizations = mutableListOf<CivilizationInfo>() var civilizations = mutableListOf<CivilizationInfo>()
@ -100,15 +97,7 @@ class GameInfo {
for (civInfo in civilizations) for (civInfo in civilizations)
for (cityInfo in civInfo.cities) for (cityInfo in civInfo.cities)
cityInfo.cityStats.update() cityInfo.cityStats.update()
updateTilesToCities()
} }
fun updateTilesToCities(){
tilesToCities.clear()
for (city in civilizations.flatMap { it.cities }){
for (tile in city.getTiles()) tilesToCities.put(tile,city)
}
}
} }

View File

@ -31,7 +31,7 @@ class CityExpansionManager {
} }
fun getNewTile(): TileInfo? { fun chooseNewTileToOwn(): TileInfo? {
for (i in 2..5) { for (i in 2..5) {
val tiles = cityInfo.getCenterTile().getTilesInDistance(i).filter { val tiles = cityInfo.getCenterTile().getTilesInDistance(i).filter {
it.getOwner() != cityInfo.civInfo it.getOwner() != cityInfo.civInfo
@ -46,24 +46,40 @@ class CityExpansionManager {
//region state-changing functions //region state-changing functions
fun reset() { 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) } cityInfo.getCenterTile().getTilesInDistance(1).forEach { takeOwnership(it) }
} }
private fun addNewTileWithCulture() { private fun addNewTileWithCulture() {
cultureStored -= getCultureToNextTile() cultureStored -= getCultureToNextTile()
val chosenTile = getNewTile() val chosenTile = chooseNewTileToOwn()
if(chosenTile!=null){ if(chosenTile!=null){
takeOwnership(chosenTile) takeOwnership(chosenTile)
} }
} }
fun takeOwnership(tileInfo: TileInfo){ fun relinquishOwnership(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) cityInfo.tiles.remove(tileInfo.position)
if(cityInfo.workedTiles.contains(tileInfo.position))
cityInfo.workedTiles.remove(tileInfo.position)
tileInfo.owningCity=null
}
fun takeOwnership(tileInfo: TileInfo){
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) cityInfo.tiles.add(tileInfo.position)
tileInfo.owningCity = cityInfo
cityInfo.population.autoAssignPopulation()
for(unit in tileInfo.getUnits()) for(unit in tileInfo.getUnits())
if(!unit.civInfo.canEnterTiles(cityInfo.civInfo)) if(!unit.civInfo.canEnterTiles(cityInfo.civInfo))
unit.movementAlgs().teleportToClosestMoveableTile() unit.movementAlgs().teleportToClosestMoveableTile()
@ -77,5 +93,10 @@ class CityExpansionManager {
cityInfo.civInfo.addNotification(cityInfo.name + " {has expanded its borders}!", cityInfo.location, Color.PURPLE) 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 //endregion
} }

View File

@ -52,7 +52,6 @@ class CityInfo {
} }
expansion.reset() expansion.reset()
civInfo.gameInfo.updateTilesToCities()
val tile = getCenterTile() val tile = getCenterTile()
tile.roadStatus = RoadStatus.Railroad tile.roadStatus = RoadStatus.Railroad
@ -141,6 +140,7 @@ class CityInfo {
fun setTransients() { fun setTransients() {
population.cityInfo = this population.cityInfo = this
expansion.cityInfo = this expansion.cityInfo = this
expansion.setTransients()
cityStats.cityInfo = this cityStats.cityInfo = this
cityConstructions.cityInfo = this cityConstructions.cityInfo = this
} }
@ -186,7 +186,6 @@ class CityInfo {
for(building in cityConstructions.getBuiltBuildings().filter { it.requiredBuildingInAllCities!=null }) for(building in cityConstructions.getBuiltBuildings().filter { it.requiredBuildingInAllCities!=null })
cityConstructions.builtBuildings.remove(building.name) cityConstructions.builtBuildings.remove(building.name)
civInfo.gameInfo.updateTilesToCities()
} }
//endregion //endregion
} }

View File

@ -74,6 +74,7 @@ class PopulationManager {
} }
internal fun autoAssignPopulation() { internal fun autoAssignPopulation() {
if(getFreePopulation()==0) return
val toWork: TileInfo? = cityInfo.getTiles() val toWork: TileInfo? = cityInfo.getTiles()
.filterNot { cityInfo.workedTiles.contains(it.position) || cityInfo.location==it.position} .filterNot { cityInfo.workedTiles.contains(it.position) || cityInfo.location==it.position}
.maxBy { Automation().rankTile(it,cityInfo.civInfo) } .maxBy { Automation().rankTile(it,cityInfo.civInfo) }
@ -83,7 +84,7 @@ class PopulationManager {
fun unassignExtraPopulation() { fun unassignExtraPopulation() {
for(tile in cityInfo.workedTiles.map { cityInfo.tileMap[it] }) for(tile in cityInfo.workedTiles.map { cityInfo.tileMap[it] })
if(tile.getOwner()!=cityInfo.civInfo) if(tile.getCity()!=cityInfo)
cityInfo.workedTiles.remove(tile.position) cityInfo.workedTiles.remove(tile.position)
while (cityInfo.workedTiles.size > population) { while (cityInfo.workedTiles.size > population) {

View File

@ -40,12 +40,10 @@ class CivilizationInfo {
constructor() constructor()
constructor(civName: String, startingLocation: Vector2, gameInfo: GameInfo) { constructor(civName: String, gameInfo: GameInfo) {
this.civName = civName this.civName = civName
this.gameInfo = gameInfo // this.gameInfo = gameInfo // already happens in setTransients
tech.techsResearched.add("Agriculture") tech.techsResearched.add("Agriculture")
this.placeUnitNearTile(startingLocation, "Settler")
this.placeUnitNearTile(startingLocation, "Scout")
} }
fun clone(): CivilizationInfo { fun clone(): CivilizationInfo {
@ -240,8 +238,8 @@ class CivilizationInfo {
} }
for (cityInfo in cities) { 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.setTransients()
cityInfo.civInfo = this
} }
} }
@ -280,7 +278,6 @@ class CivilizationInfo {
goldenAges.endTurn(happiness) goldenAges.endTurn(happiness)
getCivUnits().forEach { it.endTurn() } getCivUnits().forEach { it.endTurn() }
diplomacy.values.forEach{it.nextTurn()} diplomacy.values.forEach{it.nextTurn()}
gameInfo.updateTilesToCities()
} }
fun startTurn(){ fun startTurn(){

View File

@ -14,6 +14,7 @@ import kotlin.math.abs
open class TileInfo { open class TileInfo {
@Transient lateinit var tileMap: TileMap @Transient lateinit var tileMap: TileMap
@Transient var owningCity:CityInfo?=null
var militaryUnit:MapUnit?=null var militaryUnit:MapUnit?=null
var civilianUnit:MapUnit?=null var civilianUnit:MapUnit?=null
@ -48,7 +49,8 @@ open class TileInfo {
fun getUnits()= listOf(militaryUnit,civilianUnit).filterNotNull() fun getUnits()= listOf(militaryUnit,civilianUnit).filterNotNull()
fun getCity(): CityInfo? { 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)} //return tileMap.gameInfo.civilizations.flatMap { it.cities }.firstOrNull{it.tiles.contains(position)}
} }

View File

@ -101,7 +101,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() {
private fun updateTileGroups() { private fun updateTileGroups() {
val nextTile = city.expansion.getNewTile() val nextTile = city.expansion.chooseNewTileToOwn()
for (HG in tileGroups) { for (HG in tileGroups) {
HG.update() HG.update()
if(HG.tileInfo == nextTile){ if(HG.tileInfo == nextTile){