mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-20 09:17:47 +07:00
AI now accompanies settlers with military units
AI now picks promotions for promotable units
This commit is contained in:
parent
3f87cfa3db
commit
05b37dc660
@ -12,6 +12,14 @@ class UnCivGame : Game() {
|
||||
var gameInfo: GameInfo = GameInfo()
|
||||
lateinit var settings : GameSettings
|
||||
|
||||
/**
|
||||
* This exists so that when debugging we can see the entire map.
|
||||
* Remember to turn this to false before commit and upload!
|
||||
*/
|
||||
val viewEntireMapForDebug = false
|
||||
|
||||
|
||||
|
||||
lateinit var worldScreen: WorldScreen
|
||||
|
||||
override fun create() {
|
||||
|
@ -81,14 +81,6 @@ class GameInfo {
|
||||
civInfo.setTransients()
|
||||
}
|
||||
|
||||
val civNameToCiv = civilizations.associateBy ({ it.civName},{it})
|
||||
|
||||
for (tile in tileMap.values) {
|
||||
if (tile.militaryUnit != null) tile.militaryUnit!!.civInfo = civNameToCiv[tile.militaryUnit!!.owner]!!
|
||||
if (tile.civilianUnit!= null) tile.civilianUnit!!.civInfo = civNameToCiv[tile.civilianUnit!!.owner]!!
|
||||
}
|
||||
|
||||
|
||||
for (civInfo in civilizations)
|
||||
for (cityInfo in civInfo.cities)
|
||||
cityInfo.cityStats.update()
|
||||
|
@ -47,19 +47,25 @@ class Automation {
|
||||
val civilianUnits = mutableListOf<MapUnit>()
|
||||
|
||||
for (unit in civInfo.getCivUnits()) {
|
||||
if(unit.promotions.canBePromoted()){
|
||||
val availablePromotions = unit.promotions.getAvailablePromotions()
|
||||
if(availablePromotions.isNotEmpty())
|
||||
unit.promotions.addPromotion(availablePromotions.getRandom().name)
|
||||
}
|
||||
|
||||
val unitType = unit.getBaseUnit().unitType
|
||||
if(unitType.isRanged()) rangedUnits.add(unit)
|
||||
else if(unitType.isMelee()) meleeUnits.add(unit)
|
||||
else civilianUnits.add(unit)
|
||||
}
|
||||
|
||||
for (unit in civilianUnits) UnitAutomation().automateUnitMoves(unit) // They move first so that combat units can accompany a settler
|
||||
for (unit in rangedUnits) UnitAutomation().automateUnitMoves(unit)
|
||||
for (unit in meleeUnits) UnitAutomation().automateUnitMoves(unit)
|
||||
for (unit in civilianUnits) UnitAutomation().automateUnitMoves(unit)
|
||||
|
||||
// train settler?
|
||||
if (civInfo.cities.any()
|
||||
&& civInfo.happiness > 2*civInfo.cities.size +5
|
||||
&& civInfo.happiness > civInfo.cities.size +5
|
||||
&& civInfo.getCivUnits().none { it.name == "Settler" }
|
||||
&& civInfo.cities.none { it.cityConstructions.currentConstruction == "Settler" }) {
|
||||
|
||||
|
@ -76,7 +76,16 @@ class UnitAutomation{
|
||||
return
|
||||
}
|
||||
|
||||
if(unit.name.startsWith("Great")) return // DON'T MOVE A MUSCLE
|
||||
if(unit.name.startsWith("Great")) return // I don't know what to do with you yet.
|
||||
|
||||
|
||||
// Accompany settlers
|
||||
val closeTileWithSettler = unit.getDistanceToTiles().keys.firstOrNull{
|
||||
it.civilianUnit!=null && it.civilianUnit!!.name=="Settler"}
|
||||
if(closeTileWithSettler != null && unit.canMoveTo(closeTileWithSettler)){
|
||||
unit.movementAlgs().headTowards(closeTileWithSettler)
|
||||
return
|
||||
}
|
||||
|
||||
if (unit.health < 50) {
|
||||
healUnit(unit)
|
||||
@ -87,7 +96,7 @@ class UnitAutomation{
|
||||
val enemyTileToAttack = getAttackableEnemies(unit).firstOrNull()
|
||||
|
||||
if (enemyTileToAttack != null) {
|
||||
val setupAction = UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen!!).firstOrNull{ it.name == "Set up" }
|
||||
val setupAction = UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen).firstOrNull{ it.name == "Set up" }
|
||||
if(setupAction!=null) setupAction.action()
|
||||
|
||||
val enemy = Battle().getMapCombatantOfTile(enemyTileToAttack)!!
|
||||
@ -160,6 +169,8 @@ class UnitAutomation{
|
||||
}
|
||||
|
||||
private fun automateSettlerActions(unit: MapUnit) {
|
||||
if(unit.getTile().militaryUnit==null) return // Don;t move until you're accompanied by a military unit
|
||||
|
||||
// find best city location within 5 tiles
|
||||
val tilesNearCities = unit.civInfo.gameInfo.civilizations.flatMap { it.cities }
|
||||
.flatMap { it.getCenterTile().getTilesInDistance(2) }
|
||||
|
@ -127,6 +127,12 @@ class CivilizationInfo {
|
||||
policies.civInfo = this
|
||||
tech.civInfo = this
|
||||
|
||||
for (unit in getCivUnits()) {
|
||||
unit.civInfo=this
|
||||
unit.setTransients()
|
||||
}
|
||||
|
||||
|
||||
for (cityInfo in cities) {
|
||||
cityInfo.setTransients()
|
||||
cityInfo.civInfo = this
|
||||
@ -180,7 +186,7 @@ class CivilizationInfo {
|
||||
}
|
||||
|
||||
fun getCivUnits(): List<MapUnit> {
|
||||
return gameInfo.tileMap.values.flatMap { it.getUnits() }.filter { it.civInfo==this }
|
||||
return gameInfo.tileMap.values.flatMap { it.getUnits() }.filter { it.owner==civName }
|
||||
}
|
||||
|
||||
fun getViewableTiles(): List<TileInfo> {
|
||||
|
@ -21,6 +21,10 @@ class MapUnit {
|
||||
var attacksThisTurn = 0
|
||||
var promotions = UnitPromotions()
|
||||
|
||||
init{
|
||||
promotions.unit=this
|
||||
}
|
||||
|
||||
fun getBaseUnit(): Unit = GameBasics.Units[name]!!
|
||||
fun getMovementString(): String = DecimalFormat("0.#").format(currentMovement.toDouble()) + "/" + maxMovement
|
||||
fun getTile(): TileInfo {
|
||||
@ -190,4 +194,8 @@ class MapUnit {
|
||||
if(hasUnique("Must set up to ranged attack") && action != "Set Up") return false
|
||||
return true
|
||||
}
|
||||
|
||||
fun setTransients(){
|
||||
promotions.unit=this
|
||||
}
|
||||
}
|
@ -67,7 +67,7 @@ class TileMap {
|
||||
fun setTransients() {
|
||||
for (tileInfo in values){
|
||||
tileInfo.tileMap = this
|
||||
if(tileInfo.unit!=null){
|
||||
if(tileInfo.unit!=null){ // thi is for the old "unit" field which has been replaced.
|
||||
tileInfo.unit!!.putInTile(tileInfo)
|
||||
tileInfo.unit=null
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
package com.unciv.logic.map
|
||||
|
||||
import com.unciv.models.gamebasics.GameBasics
|
||||
import com.unciv.models.gamebasics.unit.Promotion
|
||||
|
||||
class UnitPromotions{
|
||||
@Transient lateinit var unit:MapUnit
|
||||
var XP=0
|
||||
var promotions = HashSet<String>()
|
||||
var numberOfPromotions = 0 // The number of times this unit has been promoted - some promotions don't come from being promoted but from other things!
|
||||
@ -13,4 +17,10 @@ class UnitPromotions{
|
||||
promotions.add(promotionName)
|
||||
numberOfPromotions++
|
||||
}
|
||||
|
||||
fun getAvailablePromotions(): List<Promotion> {
|
||||
return GameBasics.UnitPromotions.values
|
||||
.filter { unit.getBaseUnit().unitType.toString() in it.unitTypes && it.name !in promotions }
|
||||
.filter { it.prerequisites.isEmpty() || it.prerequisites.all { p->p in promotions } }
|
||||
}
|
||||
}
|
@ -21,13 +21,13 @@ class PromotionPickerScreen(mapUnit: MapUnit) : PickerScreen() {
|
||||
dispose()
|
||||
}
|
||||
|
||||
val availablePromotions = VerticalGroup()
|
||||
availablePromotions.space(10f)
|
||||
val availablePromotionsGroup = VerticalGroup()
|
||||
availablePromotionsGroup.space(10f)
|
||||
val unitType = mapUnit.getBaseUnit().unitType
|
||||
val promotionsForUnitType = GameBasics.UnitPromotions.values.filter { it.unitTypes.contains(unitType.toString()) }
|
||||
val unitAvailablePromotions = mapUnit.promotions.getAvailablePromotions()
|
||||
for (promotion in promotionsForUnitType) {
|
||||
val isPromotionAvailable = promotion.prerequisites.isEmpty()
|
||||
|| promotion.prerequisites.any { mapUnit.promotions.promotions.contains(it) }
|
||||
val isPromotionAvailable = promotion in unitAvailablePromotions
|
||||
val unitHasPromotion = mapUnit.promotions.promotions.contains(promotion.name)
|
||||
val promotionButton = Button(skin)
|
||||
|
||||
@ -48,8 +48,8 @@ class PromotionPickerScreen(mapUnit: MapUnit) : PickerScreen() {
|
||||
.joinToString(" OR ")
|
||||
descriptionLabel.setText(descriptionText)
|
||||
}
|
||||
availablePromotions.addActor(promotionButton)
|
||||
availablePromotionsGroup.addActor(promotionButton)
|
||||
}
|
||||
topTable.add(availablePromotions)
|
||||
topTable.add(availablePromotionsGroup)
|
||||
}
|
||||
}
|
@ -15,13 +15,6 @@ import com.unciv.ui.utils.center
|
||||
import com.unciv.ui.utils.colorFromRGB
|
||||
|
||||
open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
/**
|
||||
* This exists so that when debugging we can see the entire map.
|
||||
* Remember to turn this to false before commit and upload!
|
||||
*/
|
||||
protected val viewEntireMapForDebug = false
|
||||
|
||||
|
||||
protected val hexagon = ImageGetter.getImage("TerrainIcons/Hexagon.png")
|
||||
protected var terrainFeatureImage:Image?=null
|
||||
|
||||
@ -90,7 +83,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
open fun update(isViewable: Boolean) {
|
||||
hideCircle()
|
||||
if (!tileInfo.tileMap.gameInfo.getPlayerCivilization().exploredTiles.contains(tileInfo.position)
|
||||
&& !viewEntireMapForDebug) {
|
||||
&& !UnCivGame.Current.viewEntireMapForDebug) {
|
||||
hexagon.color = Color.BLACK
|
||||
return
|
||||
}
|
||||
@ -109,7 +102,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
updateBorderImages()
|
||||
|
||||
fogImage.toFront()
|
||||
fogImage.isVisible=!isViewable
|
||||
fogImage.isVisible=!(isViewable || UnCivGame.Current.viewEntireMapForDebug)
|
||||
}
|
||||
|
||||
private fun updateBorderImages() {
|
||||
@ -256,7 +249,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
currentImage.remove()
|
||||
}
|
||||
|
||||
if (unit != null && (isViewable || viewEntireMapForDebug)) { // Tile is visible
|
||||
if (unit != null && isViewable) { // Tile is visible
|
||||
newImage = getUnitImage(unit, unit.civInfo.getCivilization().getColor(), 25f)
|
||||
addActor(newImage)
|
||||
newImage.center(this)
|
||||
|
@ -44,9 +44,9 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
|
||||
addPopulationIcon()
|
||||
|
||||
if (tileInfo.tileMap.gameInfo.getPlayerCivilization().exploredTiles.contains(tileInfo.position)
|
||||
|| viewEntireMapForDebug) updateCityButton(city, isViewable) // needs to be before the update so the units will be above the city button
|
||||
|| UnCivGame.Current.viewEntireMapForDebug) updateCityButton(city, isViewable) // needs to be before the update so the units will be above the city button
|
||||
|
||||
super.update(isViewable)
|
||||
super.update(isViewable || UnCivGame.Current.viewEntireMapForDebug)
|
||||
|
||||
yieldGroup.isVisible = !UnCivGame.Current.settings.showResourcesAndImprovements
|
||||
if(yieldGroup.isVisible)
|
||||
|
@ -6,6 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.Group
|
||||
import com.badlogic.gdx.scenes.scene2d.InputListener
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.HexMath
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.ui.utils.ImageGetter
|
||||
@ -74,7 +75,7 @@ class Minimap(val tileMapHolder: TileMapHolder) : ScrollPane(null){
|
||||
for(tileInfo in tileMapHolder.tileMap.values) {
|
||||
val RGB = tileInfo.getBaseTerrain().RGB!!
|
||||
val hex = tileImages[tileInfo]!!
|
||||
if (!exploredTiles.contains(tileInfo.position)) hex.color = Color.BLACK
|
||||
if (!(exploredTiles.contains(tileInfo.position) || UnCivGame.Current.viewEntireMapForDebug)) hex.color = Color.BLACK
|
||||
else if (tileInfo.isCityCenter()) hex.color = Color.WHITE
|
||||
else if (tileInfo.getCity() != null) hex.color = tileInfo.getOwner()!!.getCivilization().getColor()
|
||||
else hex.color = colorFromRGB(RGB[0], RGB[1], RGB[2]).lerp(Color.GRAY, 0.5f) // Todo add to baseterrain as function
|
||||
|
@ -3,6 +3,7 @@ package com.unciv.ui.worldscreen.bottombar
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.ui.utils.CameraStageBaseScreen
|
||||
import com.unciv.ui.utils.ImageGetter
|
||||
@ -18,7 +19,7 @@ class TileInfoTable(private val worldScreen: WorldScreen) : Table() {
|
||||
val civInfo = worldScreen.civInfo
|
||||
columnDefaults(0).padRight(10f)
|
||||
|
||||
if (civInfo.exploredTiles.contains(tile.position)) {
|
||||
if (civInfo.exploredTiles.contains(tile.position) || UnCivGame.Current.viewEntireMapForDebug) {
|
||||
add(getStatsTable(tile)).pad(10f)
|
||||
add(Label(tile.toString(), skin)).colspan(2)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user