Enemy civs now pick technologies and advance!

Fixed bug where workers would try to move and improve unreachable tiles, crashing the game
This commit is contained in:
Yair Morgenstern 2018-04-24 23:00:58 +03:00
parent c6136acbec
commit 9d7399dd48
8 changed files with 47 additions and 22 deletions

View File

@ -8,6 +8,7 @@ import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
import com.unciv.logic.map.UnitMovementAlgorithms
import com.unciv.logic.map.UnitType import com.unciv.logic.map.UnitType
import com.unciv.models.gamebasics.Building import com.unciv.models.gamebasics.Building
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
@ -24,6 +25,8 @@ class Automation {
&& it.improvement == null && it.improvement == null
&& (it.getCity()==null || it.getCity()!!.civInfo == civInfo) // don't work tiles belonging to another civ && (it.getCity()==null || it.getCity()!!.civInfo == civInfo) // don't work tiles belonging to another civ
&& it.canBuildImprovement(chooseImprovement(it), civInfo) && it.canBuildImprovement(chooseImprovement(it), civInfo)
&& UnitMovementAlgorithms(currentTile.tileMap) // the tile is actually reachable - more difficult than it seems!
.getShortestPath(currentTile.position, it.position, 2f, 2, civInfo).isNotEmpty()
} }
.maxBy { getPriority(it, civInfo) } .maxBy { getPriority(it, civInfo) }
if (selectedTile != null && getPriority(selectedTile, civInfo) > 1) return selectedTile if (selectedTile != null && getPriority(selectedTile, civInfo) > 1) return selectedTile
@ -129,24 +132,7 @@ class Automation {
fun automateUnitMoves(unit: MapUnit) { fun automateUnitMoves(unit: MapUnit) {
if (unit.name == "Settler") { if (unit.name == "Settler") {
automateSettlerActions(unit)
val tileMap = unit.civInfo.gameInfo.tileMap
// find best city location within 5 tiles
val bestCityLocation = tileMap.getTilesInDistance(unit.getTile().position, 5)
.filterNot { it.isCityCenter || it.neighbors.any { it.isCityCenter } }
.sortedByDescending { rankTileAsCityCenter(it, unit.civInfo) }
.first()
if(unit.getTile() == bestCityLocation)
UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen!!).first { it.name == "Found city" }.action()
else {
unit.headTowards(bestCityLocation.position)
if(unit.currentMovement>0 && unit.getTile()==bestCityLocation)
UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen!!).first { it.name == "Found city" }.action()
}
return return
} }
@ -235,6 +221,24 @@ class Automation {
unit.moveToTile(distanceToTiles.keys.filter { it.unit == null }.toList().getRandom()) unit.moveToTile(distanceToTiles.keys.filter { it.unit == null }.toList().getRandom())
} }
private fun automateSettlerActions(unit: MapUnit) {
val tileMap = unit.civInfo.gameInfo.tileMap
// find best city location within 5 tiles
val bestCityLocation = tileMap.getTilesInDistance(unit.getTile().position, 7)
.filterNot { tileMap.getTilesInDistance(it.position,2).any { tid -> tid.isCityCenter } }
.sortedByDescending { rankTileAsCityCenter(it, unit.civInfo) }
.first()
if (unit.getTile() == bestCityLocation)
UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen!!).first { it.name == "Found city" }.action()
else {
unit.headTowards(bestCityLocation.position)
if (unit.currentMovement > 0 && unit.getTile() == bestCityLocation)
UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen!!).first { it.name == "Found city" }.action()
}
}
fun chooseNextConstruction(cityConstructions: CityConstructions) { fun chooseNextConstruction(cityConstructions: CityConstructions) {
cityConstructions.run { cityConstructions.run {

View File

@ -3,6 +3,7 @@ package com.unciv.logic
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.TileMap import com.unciv.logic.map.TileMap
import com.unciv.models.gamebasics.GameBasics
import com.unciv.ui.utils.getRandom import com.unciv.ui.utils.getRandom
class GameInfo { class GameInfo {
@ -21,7 +22,16 @@ class GameInfo {
fun nextTurn() { fun nextTurn() {
notifications.clear() notifications.clear()
for (civInfo in civilizations) civInfo.nextTurn() for (civInfo in civilizations){
if(civInfo.tech.techsToResearch.isEmpty()){
val researchableTechs = GameBasics.Technologies.values
.filter { !civInfo.tech.isResearched(it.name) && civInfo.tech.canBeResearched(it.name) }
civInfo.tech.techsToResearch.add(researchableTechs.minBy { it.cost }!!.name)
}
}
for (civInfo in civilizations)
civInfo.nextTurn()
tileMap.values.filter { it.unit!=null }.map { it.unit!! }.forEach { it.nextTurn() } tileMap.values.filter { it.unit!=null }.map { it.unit!! }.forEach { it.nextTurn() }

View File

@ -38,4 +38,8 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
else -> throw Exception("Should never get here!") else -> throw Exception("Should never get here!")
} }
} }
override fun toString(): String {
return unit.name+" of "+unit.civInfo.civName
}
} }

View File

@ -131,4 +131,6 @@ class CityInfo {
internal fun getMaxHealth(): Int { internal fun getMaxHealth(): Int {
return 200 // add more later when walls citadl etc. return 200 // add more later when walls citadl etc.
} }
override fun toString(): String {return name} // for debug
} }

View File

@ -180,4 +180,6 @@ class CivilizationInfo {
if(isPlayerCivilization()) if(isPlayerCivilization())
gameInfo.notifications.add(Notification(text, location)) gameInfo.notifications.add(Notification(text, location))
} }
override fun toString(): String {return civName} // for debug
} }

View File

@ -47,7 +47,8 @@ class TileMap {
unit.owner = civInfo.civName unit.owner = civInfo.civName
unit.civInfo = civInfo unit.civInfo = civInfo
val tilesInDistance = getTilesInDistance(position, 2) val tilesInDistance = getTilesInDistance(position, 2)
tilesInDistance.first { it.unit == null }.unit = unit // And if there's none, then kill me. val unitToPlaceTile = tilesInDistance.firstOrNull { it.unit == null }
if(unitToPlaceTile!=null) unitToPlaceTile.unit = unit // And if there's none, then kill me.
} }
fun getViewableTiles(position: Vector2, sightDistance: Int): MutableList<TileInfo> { fun getViewableTiles(position: Vector2, sightDistance: Int): MutableList<TileInfo> {

View File

@ -77,6 +77,8 @@ class UnitMovementAlgorithms(val tileMap: TileMap){
return path.reversed() // and reverse in order to get the list in chronological order return path.reversed() // and reverse in order to get the list in chronological order
} }
if(newTilesToCheck.isEmpty()) return emptyList() // there is NO PATH (eg blocked by enemy units)
tilesToCheck = newTilesToCheck tilesToCheck = newTilesToCheck
distance++ distance++
} }

View File

@ -53,8 +53,8 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
open fun update(isViewable: Boolean) { open fun update(isViewable: Boolean) {
if (!tileInfo.explored) { if (!tileInfo.explored) {
hexagon.color = Color.BLACK //hexagon.color = Color.BLACK
return //return
} }
updateTerrainFeatureImage() updateTerrainFeatureImage()