diff --git a/android/assets/jsons/Civilizations.json b/android/assets/jsons/Civilizations.json index 69c8167e9b..8bd24bb502 100644 --- a/android/assets/jsons/Civilizations.json +++ b/android/assets/jsons/Civilizations.json @@ -11,6 +11,11 @@ cities:["Athens","Sparta","Corinth","Argos","Knossos","Mycenae","Pharsalos","Ephesus","Halicarnassus","Rhodes", "Eretria","Pergamon","Miletos","Megara","Phocaea"] }, + { + name:"Chinese", + RGB:[ 101, 253, 155], + cities:["Beijing","Shanghai","Guangzhou","Nanjing","Xian","Chengdu","Hangzhou","Tianjin","Macau","Shandong"] + }, { name:"Barbarians", RGB:[200,200,200] diff --git a/core/src/com/unciv/logic/Automation.kt b/core/src/com/unciv/logic/Automation.kt index 019def4a23..1f7823e537 100644 --- a/core/src/com/unciv/logic/Automation.kt +++ b/core/src/com/unciv/logic/Automation.kt @@ -8,31 +8,14 @@ import com.unciv.logic.city.CityInfo import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.map.MapUnit import com.unciv.logic.map.TileInfo -import com.unciv.logic.map.UnitMovementAlgorithms import com.unciv.logic.map.UnitType import com.unciv.models.gamebasics.Building import com.unciv.models.gamebasics.GameBasics -import com.unciv.models.gamebasics.TileImprovement import com.unciv.ui.utils.getRandom import com.unciv.ui.worldscreen.unit.UnitActions class Automation { - private fun findTileToWork(currentTile: TileInfo, civInfo: CivilizationInfo): TileInfo { - val selectedTile = currentTile.tileMap.getTilesInDistance(currentTile.position, 4) - .filter { - (it.unit == null || it == currentTile) - && it.improvement == null - && (it.getCity()==null || it.getCity()!!.civInfo == civInfo) // don't work tiles belonging to another civ - && 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) } - if (selectedTile != null && getPriority(selectedTile, civInfo) > 1) return selectedTile - else return currentTile - } - internal fun rankTile(tile: TileInfo, civInfo: CivilizationInfo): Float { val stats = tile.getTileStats(null, civInfo) @@ -48,46 +31,6 @@ class Automation { return rank } - private fun getPriority(tileInfo: TileInfo, civInfo: CivilizationInfo): Int { - var priority = 0 - if (tileInfo.isWorked()) priority += 3 - if (tileInfo.getOwner() == civInfo) priority += 2 - if (tileInfo.hasViewableResource(civInfo)) priority += 1 - else if (tileInfo.neighbors.any { it.getOwner() != null }) priority += 1 - return priority - } - - private fun chooseImprovement(tile: TileInfo): TileImprovement { - val improvementString = when { - tile.improvementInProgress != null -> tile.improvementInProgress - tile.terrainFeature == "Forest" -> "Lumber mill" - tile.terrainFeature == "Jungle" -> "Trading post" - tile.terrainFeature == "Marsh" -> "Remove Marsh" - tile.resource != null -> tile.tileResource.improvement - tile.baseTerrain == "Hill" -> "Mine" - tile.baseTerrain == "Grassland" || tile.baseTerrain == "Desert" || tile.baseTerrain == "Plains" -> "Farm" - tile.baseTerrain == "Tundra" -> "Trading post" - else -> null - } - return GameBasics.TileImprovements[improvementString]!! - } - - fun automateWorkerAction(unit: MapUnit) { - var tile = unit.getTile() - val tileToWork = findTileToWork(tile, unit.civInfo) - if (tileToWork != tile) { - tile = unit.headTowards(tileToWork.position) - unit.doPreTurnAction(tile) - return - } - if (tile.improvementInProgress == null) { - val improvement = chooseImprovement(tile) - if (tile.canBuildImprovement(improvement, unit.civInfo)) - // What if we're stuck on this tile but can't build there? - tile.startWorkingOnImprovement(improvement, unit.civInfo) - } - } - fun rankTileAsCityCenter(tileInfo: TileInfo, civInfo: CivilizationInfo): Float { val bestTilesFromOuterLayer = tileInfo.tileMap.getTilesAtDistance(tileInfo.position,2) .sortedByDescending { rankTile(it,civInfo) }.take(2) @@ -137,7 +80,7 @@ class Automation { } if (unit.name == "Worker") { - Automation().automateWorkerAction(unit) + WorkerAutomation().automateWorkerAction(unit) return } @@ -258,4 +201,5 @@ class Automation { } } -} \ No newline at end of file +} + diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index c67bdccd8d..5d484912bc 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -39,6 +39,7 @@ class GameInfo { // maybe one of them has a wonder that affects the stats of all the rest of the cities for (civInfo in civilizations){ + civInfo.getViewableTiles() // adds explored tiles for auto civs if(!civInfo.isPlayerCivilization()) Automation().automateCivMoves(civInfo) for (city in civInfo.cities) diff --git a/core/src/com/unciv/logic/WorkerAutomation.kt b/core/src/com/unciv/logic/WorkerAutomation.kt new file mode 100644 index 0000000000..d983c0c304 --- /dev/null +++ b/core/src/com/unciv/logic/WorkerAutomation.kt @@ -0,0 +1,68 @@ +package com.unciv.logic + +import com.unciv.logic.civilization.CivilizationInfo +import com.unciv.logic.map.MapUnit +import com.unciv.logic.map.TileInfo +import com.unciv.logic.map.UnitMovementAlgorithms +import com.unciv.models.gamebasics.GameBasics +import com.unciv.models.gamebasics.TileImprovement + +public class WorkerAutomation(){ + + fun automateWorkerAction(unit: MapUnit) { + var tile = unit.getTile() + val tileToWork = findTileToWork(tile, unit.civInfo) + if (tileToWork != tile) { + tile = unit.headTowards(tileToWork.position) + unit.doPreTurnAction(tile) + return + } + if (tile.improvementInProgress == null) { + val improvement = chooseImprovement(tile) + if (tile.canBuildImprovement(improvement, unit.civInfo)) + // What if we're stuck on this tile but can't build there? + tile.startWorkingOnImprovement(improvement, unit.civInfo) + } + } + + private fun findTileToWork(currentTile: TileInfo, civInfo: CivilizationInfo): TileInfo { + val selectedTile = currentTile.tileMap.getTilesInDistance(currentTile.position, 4) + .filter { + (it.unit == null || it == currentTile) + && it.improvement == null + && (it.getCity()==null || it.getCity()!!.civInfo == civInfo) // don't work tiles belonging to another civ + && 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) } + if (selectedTile != null && getPriority(selectedTile, civInfo) > 1) return selectedTile + else return currentTile + } + + + private fun getPriority(tileInfo: TileInfo, civInfo: CivilizationInfo): Int { + var priority = 0 + if (tileInfo.isWorked()) priority += 3 + if (tileInfo.getOwner() == civInfo) priority += 2 + if (tileInfo.hasViewableResource(civInfo)) priority += 1 + else if (tileInfo.neighbors.any { it.getOwner() != null }) priority += 1 + return priority + } + + private fun chooseImprovement(tile: TileInfo): TileImprovement { + val improvementString = when { + tile.improvementInProgress != null -> tile.improvementInProgress + tile.terrainFeature == "Forest" -> "Lumber mill" + tile.terrainFeature == "Jungle" -> "Trading post" + tile.terrainFeature == "Marsh" -> "Remove Marsh" + tile.resource != null -> tile.tileResource.improvement + tile.baseTerrain == "Hill" -> "Mine" + tile.baseTerrain == "Grassland" || tile.baseTerrain == "Desert" || tile.baseTerrain == "Plains" -> "Farm" + tile.baseTerrain == "Tundra" -> "Trading post" + else -> null + } + return GameBasics.TileImprovements[improvementString]!! + } + +} \ No newline at end of file diff --git a/core/src/com/unciv/logic/battle/CityCombatant.kt b/core/src/com/unciv/logic/battle/CityCombatant.kt index a75970ffed..e33488df23 100644 --- a/core/src/com/unciv/logic/battle/CityCombatant.kt +++ b/core/src/com/unciv/logic/battle/CityCombatant.kt @@ -21,7 +21,8 @@ class CityCombatant(val city: CityInfo) : ICombatant { override fun getAttackingStrength(defender: ICombatant): Int = getCityStrength() override fun getDefendingStrength(attacker: ICombatant): Int = getCityStrength() - fun getCityStrength(): Int { + private fun + getCityStrength(): Int { val baseStrength = 10 // as tech progresses so does city strength val techsPercentKnown: Float = city.civInfo.tech.techsResearched.count().toFloat() / @@ -37,9 +38,9 @@ class CityCombatant(val city: CityInfo) : ICombatant { // 10% bonus foreach pop val strengthWithPop = (baseStrength + strengthFromTechs) * (1 + 0.1*city.population.population) - - return strengthWithPop.toInt() * 100 // *100 because a city is always at 100% strength } + override fun toString(): String {return city.name} // for debug + } \ No newline at end of file diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 73fd0ac4bc..d6b1b59152 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -33,6 +33,7 @@ class CivilizationInfo { var scienceVictory = ScienceVictoryManager() var cities = ArrayList() + var exploredTiles = ArrayList() fun getCivilization(): Civilization {return GameBasics.Civilizations[civName]!!} @@ -173,6 +174,7 @@ class CivilizationInfo { viewablePositions += gameInfo.tileMap.values .filter { it.unit != null && it.unit!!.owner == civName } .flatMap { it.getViewableTiles(2)} // Tiles within 2 tiles of units + viewablePositions.map { it.position }.filterNot { exploredTiles.contains(it) }.toCollection(exploredTiles) return viewablePositions } diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index c08d3f2238..81a9c16265 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -1,7 +1,7 @@ package com.unciv.logic.map import com.badlogic.gdx.math.Vector2 -import com.unciv.logic.Automation +import com.unciv.logic.WorkerAutomation import com.unciv.logic.civilization.CivilizationInfo import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.Unit @@ -50,7 +50,7 @@ class MapUnit { return } - if (action == "automation") Automation().automateWorkerAction(this) + if (action == "automation") WorkerAutomation().automateWorkerAction(this) } private fun doPostTurnAction(tile: TileInfo) { diff --git a/core/src/com/unciv/logic/map/TileInfo.kt b/core/src/com/unciv/logic/map/TileInfo.kt index d464f4953d..c5c498526b 100644 --- a/core/src/com/unciv/logic/map/TileInfo.kt +++ b/core/src/com/unciv/logic/map/TileInfo.kt @@ -22,7 +22,6 @@ class TileInfo { var improvementInProgress: String? = null var roadStatus = RoadStatus.None - var explored = false var turnsToImprovement: Int = 0 fun getCity(): CityInfo? = tileMap.gameInfo.civilizations.flatMap { it.cities }.firstOrNull{it.tiles.contains(position)} diff --git a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt index ec7dba03fb..0112e6e049 100644 --- a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt +++ b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt @@ -44,6 +44,8 @@ class UnitMovementAlgorithms(val tileMap: TileMap){ fun getShortestPath(origin: Vector2, destination: Vector2, currentMovement: Float, maxMovement: Int, civInfo: CivilizationInfo): List { + if(origin.equals(destination)) return listOf(tileMap[origin]) // edge case that's needed, so that workers will know that they can reach their own tile. *sigh* + var tilesToCheck: List = listOf(tileMap[origin]) val movementTreeParents = HashMap() // contains a map of "you can get from X to Y in that turn" movementTreeParents[tileMap[origin]] = null diff --git a/core/src/com/unciv/ui/cityscreen/CityScreen.kt b/core/src/com/unciv/ui/cityscreen/CityScreen.kt index dc9e894906..d751d6a032 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreen.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreen.kt @@ -153,7 +153,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() { val allTiles = Group() for (tileInfo in game.gameInfo.tileMap.getTilesInDistance(cityInfo.location, 5)) { - if (!tileInfo.explored) continue // Don't even bother to display it. + if (!city.civInfo.exploredTiles.contains(tileInfo.position)) continue // Don't even bother to display it. val group = CityTileGroup(cityInfo, tileInfo) group.addClickListener { selectedTile = tileInfo diff --git a/core/src/com/unciv/ui/tilegroups/TileGroup.kt b/core/src/com/unciv/ui/tilegroups/TileGroup.kt index 03277d8eca..713c60eafd 100644 --- a/core/src/com/unciv/ui/tilegroups/TileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/TileGroup.kt @@ -52,9 +52,9 @@ open class TileGroup(var tileInfo: TileInfo) : Group() { open fun update(isViewable: Boolean) { - if (!tileInfo.explored) { - //hexagon.color = Color.BLACK - //return + if (!tileInfo.tileMap.gameInfo.getPlayerCivilization().exploredTiles.contains(tileInfo.position)) { +// hexagon.color = Color.BLACK +// return } updateTerrainFeatureImage() diff --git a/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt b/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt index 390982906d..fe052f95b5 100644 --- a/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt @@ -47,7 +47,7 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) { override fun update(isViewable: Boolean) { super.update(isViewable) - if (!tileInfo.explored) return + //if (!tileInfo.explored) return if (populationImage != null) removePopulationIcon() @@ -94,7 +94,7 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) { unitImage = null } - if (tileInfo.unit != null && isViewable) { // Tile is visible + if (tileInfo.unit != null /*&& isViewable*/) { // Tile is visible val unit = tileInfo.unit!! unitImage = getUnitImage(unit.name, unit.civInfo.getCivilization().getColor()) addActor(unitImage!!) diff --git a/core/src/com/unciv/ui/worldscreen/BattleTable.kt b/core/src/com/unciv/ui/worldscreen/BattleTable.kt index 16422e778b..3516cacd04 100644 --- a/core/src/com/unciv/ui/worldscreen/BattleTable.kt +++ b/core/src/com/unciv/ui/worldscreen/BattleTable.kt @@ -31,7 +31,8 @@ class BattleTable(val worldScreen: WorldScreen): Table() { if (worldScreen.tileMapHolder.selectedTile == null) return val selectedTile = worldScreen.tileMapHolder.selectedTile!! val defender: ICombatant - if (selectedTile.explored && selectedTile.isCityCenter && selectedTile.getOwner() != worldScreen.civInfo) + if (attacker.getCivilization().exploredTiles.contains(selectedTile.position) + && selectedTile.isCityCenter && selectedTile.getOwner() != worldScreen.civInfo) defender = CityCombatant(selectedTile.getCity()!!) else if (selectedTile.unit != null && selectedTile.unit!!.owner != worldScreen.civInfo.civName // enemy unit on selected tile, diff --git a/core/src/com/unciv/ui/worldscreen/TileInfoTable.kt b/core/src/com/unciv/ui/worldscreen/TileInfoTable.kt index 0cad80f332..8924453106 100644 --- a/core/src/com/unciv/ui/worldscreen/TileInfoTable.kt +++ b/core/src/com/unciv/ui/worldscreen/TileInfoTable.kt @@ -27,7 +27,7 @@ class TileInfoTable(private val worldScreen: WorldScreen, internal val civInfo: val skin = CameraStageBaseScreen.skin - if (tile.explored) { + if (civInfo.exploredTiles.contains(tile.position)) { add(Label(tile.toString(), skin)).colspan(2) row() diff --git a/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt b/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt index 8877f5a780..7a4006fa13 100644 --- a/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt +++ b/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt @@ -94,7 +94,6 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: .filter { tileGroups.containsKey(it) }) { tileGroups[string]!!.run { - tileInfo.explored = true update(true) } }