AI now uses Great People properly

Fixed bug where loading a game with a free policy would freeze everything
This commit is contained in:
Yair Morgenstern 2018-12-01 22:16:26 +02:00
parent 8c3282ddce
commit ec65268099
8 changed files with 198 additions and 159 deletions

View File

@ -2899,10 +2899,11 @@
Romanian:"Accepta" Romanian:"Accepta"
Spanish:"Aceptar" Spanish:"Aceptar"
} }
"There's nothing on the table":{ "There's nothing on the table":{
Italian:"Non c'è niente da trattare" Italian:"Non c'è niente da trattare"
Russian:"Вы ничего не предложили" //Don't know how to properly translate this one, but i think this will do okay Russian:"Вы ничего не предложили" //Don't know how to properly translate this one, but i think this will do okay
French:"Rien n'est en jeu //Don't know how to properly translate this one, I went with the figurative sens e.g. nothing is in danger of being lost French:"Rien n'est en jeu" //Don't know how to properly translate this one, I went with the figurative sens e.g. nothing is in danger of being lost
Spanish:"No hay nada sobre la mesa" Spanish:"No hay nada sobre la mesa"
} }

View File

@ -394,7 +394,7 @@
name:"Great Merchant", name:"Great Merchant",
unbuildable:true, unbuildable:true,
unitType:"Civilian", unitType:"Civilian",
uniques:["Can undertake a trade mission, giving a large sum of gold","Can build improvement: Customs House"] uniques:["Can undertake a trade mission, giving a large sum of gold","Can build improvement: Customs house"]
movement:2 movement:2
}, },
{ {

View File

@ -55,13 +55,12 @@ class UnCivGame : Game() {
worldScreen = WorldScreen() worldScreen = WorldScreen()
setWorldScreen() setWorldScreen()
} }
fun setWorldScreen() { fun setWorldScreen() {
setScreen(worldScreen) setScreen(worldScreen)
worldScreen.update()
Gdx.input.inputProcessor = worldScreen.stage Gdx.input.inputProcessor = worldScreen.stage
worldScreen.update() // This can set the screen to the policy picker or tech picker screen, so the input processor must come before
} }
override fun resume() { override fun resume() {

View File

@ -8,10 +8,12 @@ import com.unciv.logic.battle.MapUnitCombatant
import com.unciv.logic.city.CityInfo import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.DiplomaticStatus import com.unciv.logic.civilization.DiplomaticStatus
import com.unciv.logic.civilization.GreatPersonManager
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.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.tile.TerrainType import com.unciv.models.gamebasics.tile.TerrainType
import com.unciv.models.stats.Stats
import com.unciv.ui.utils.getRandom import com.unciv.ui.utils.getRandom
import com.unciv.ui.worldscreen.unit.UnitAction import com.unciv.ui.worldscreen.unit.UnitAction
import com.unciv.ui.worldscreen.unit.UnitActions import com.unciv.ui.worldscreen.unit.UnitActions
@ -21,21 +23,20 @@ class UnitAutomation{
fun automateUnitMoves(unit: MapUnit) { fun automateUnitMoves(unit: MapUnit) {
if (unit.name == "Settler") { if (unit.name == "Settler") {
automateSettlerActions(unit) return SpecificUnitAutomation().automateSettlerActions(unit)
return
} }
if (unit.name == "Worker") { if (unit.name == "Worker") {
WorkerAutomation(unit).automateWorkerAction() return WorkerAutomation(unit).automateWorkerAction()
return
} }
if(unit.name=="Work Boats"){ if(unit.name=="Work Boats"){
automateWorkBoats(unit) return SpecificUnitAutomation().automateWorkBoats(unit)
return
} }
if(unit.name.startsWith("Great")) return // I don't know what to do with you yet. if(unit.name.startsWith("Great")){
return SpecificUnitAutomation().automateGreatPerson(unit)// I don't know what to do with you yet.
}
val unitActions = UnitActions().getUnitActions(unit,UnCivGame.Current.worldScreen) val unitActions = UnitActions().getUnitActions(unit,UnCivGame.Current.worldScreen)
var unitDistanceToTiles = unit.getDistanceToTiles() var unitDistanceToTiles = unit.getDistanceToTiles()
@ -81,30 +82,6 @@ class UnitAutomation{
// if both failed, then... there aren't any reachable tiles. Which is possible. // if both failed, then... there aren't any reachable tiles. Which is possible.
} }
private fun hasWorkableSeaResource(tileInfo: TileInfo, civInfo: CivilizationInfo): Boolean {
return tileInfo.hasViewableResource(civInfo) && tileInfo.isWater() && tileInfo.improvement==null
}
private fun automateWorkBoats(unit: MapUnit) {
val seaResourcesInCities = unit.civInfo.cities.flatMap { it.getTilesInRange() }.asSequence()
.filter { hasWorkableSeaResource(it, unit.civInfo) && (unit.canMoveTo(it) || unit.currentTile == it) }
val closestReachableResource = seaResourcesInCities.sortedBy { it.arialDistanceTo(unit.currentTile) }
.firstOrNull { unit.movementAlgs().canReach(it) }
if (closestReachableResource != null) {
unit.movementAlgs().headTowards(closestReachableResource)
if (unit.currentMovement > 0 && unit.currentTile == closestReachableResource) {
val createImprovementAction = UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen)
.firstOrNull { it.name.startsWith("Create") } // could be either fishing boats or oil well
if (createImprovementAction != null) {
createImprovementAction.action()
return // unit is already gone, can't "explore"
}
}
}
else explore(unit, unit.getDistanceToTiles())
}
fun rankTileForHealing(tileInfo: TileInfo, unit: MapUnit): Int { fun rankTileForHealing(tileInfo: TileInfo, unit: MapUnit): Int {
val tileOwner = tileInfo.getOwner() val tileOwner = tileInfo.getOwner()
when{ when{
@ -322,7 +299,7 @@ class UnitAutomation{
return true return true
} }
private fun explore(unit: MapUnit, unitDistanceToTiles: HashMap<TileInfo, Float>) { internal fun explore(unit: MapUnit, unitDistanceToTiles: HashMap<TileInfo, Float>) {
val distanceToTiles:HashMap<TileInfo, Float> val distanceToTiles:HashMap<TileInfo, Float>
if(tryGoToRuin(unit,unitDistanceToTiles)) if(tryGoToRuin(unit,unitDistanceToTiles))
{ {
@ -347,6 +324,49 @@ class UnitAutomation{
else if (reachableTiles.any()) unit.moveToTile(reachableTiles.toList().getRandom().first) else if (reachableTiles.any()) unit.moveToTile(reachableTiles.toList().getRandom().first)
} }
fun automatedExplore(unit:MapUnit){
if(tryGoToRuin(unit,unit.getDistanceToTiles()) && unit.currentMovement==0f) return
for(i in 1..10){
val unexploredTilesAtDistance = unit.getTile().getTilesAtDistance(i)
.filter { unit.canMoveTo(it) && it.position !in unit.civInfo.exploredTiles
&& unit.movementAlgs().canReach(it) }
if(unexploredTilesAtDistance.isNotEmpty()){
unit.movementAlgs().headTowards(unexploredTilesAtDistance.getRandom())
return
}
}
}
}
class SpecificUnitAutomation{
private fun hasWorkableSeaResource(tileInfo: TileInfo, civInfo: CivilizationInfo): Boolean {
return tileInfo.hasViewableResource(civInfo) && tileInfo.isWater() && tileInfo.improvement==null
}
fun automateWorkBoats(unit: MapUnit) {
val seaResourcesInCities = unit.civInfo.cities.flatMap { it.getTilesInRange() }.asSequence()
.filter { hasWorkableSeaResource(it, unit.civInfo) && (unit.canMoveTo(it) || unit.currentTile == it) }
val closestReachableResource = seaResourcesInCities.sortedBy { it.arialDistanceTo(unit.currentTile) }
.firstOrNull { unit.movementAlgs().canReach(it) }
if (closestReachableResource != null) {
unit.movementAlgs().headTowards(closestReachableResource)
if (unit.currentMovement > 0 && unit.currentTile == closestReachableResource) {
val createImprovementAction = UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen)
.firstOrNull { it.name.startsWith("Create") } // could be either fishing boats or oil well
if (createImprovementAction != null) {
createImprovementAction.action()
return // unit is already gone, can't "explore"
}
}
}
else UnitAutomation().explore(unit, unit.getDistanceToTiles())
}
fun rankTileAsCityCenter(tileInfo: TileInfo, nearbyTileRankings: Map<TileInfo, Float>): Float { fun rankTileAsCityCenter(tileInfo: TileInfo, nearbyTileRankings: Map<TileInfo, Float>): Float {
val bestTilesFromOuterLayer = tileInfo.getTilesAtDistance(2) val bestTilesFromOuterLayer = tileInfo.getTilesAtDistance(2)
.asSequence() .asSequence()
@ -362,7 +382,8 @@ class UnitAutomation{
return rank return rank
} }
private fun automateSettlerActions(unit: MapUnit) {
fun automateSettlerActions(unit: MapUnit) {
if(unit.getTile().militaryUnit==null) return // Don't move until you're accompanied by a military unit if(unit.getTile().militaryUnit==null) return // Don't move until you're accompanied by a military unit
val tilesNearCities = unit.civInfo.gameInfo.civilizations.flatMap { it.cities } val tilesNearCities = unit.civInfo.gameInfo.civilizations.flatMap { it.cities }
@ -382,7 +403,7 @@ class UnitAutomation{
if(bestCityLocation==null) // We got a badass over here, all tiles within 5 are taken? Screw it, random walk. if(bestCityLocation==null) // We got a badass over here, all tiles within 5 are taken? Screw it, random walk.
{ {
explore(unit, unit.getDistanceToTiles()) UnitAutomation().explore(unit, unit.getDistanceToTiles())
return return
} }
@ -398,18 +419,39 @@ class UnitAutomation{
} }
} }
fun automatedExplore(unit:MapUnit){ fun automateGreatPerson(unit: MapUnit) {
if(tryGoToRuin(unit,unit.getDistanceToTiles()) && unit.currentMovement==0f) return val relatedStat = GreatPersonManager().statToGreatPersonMapping.entries.first { it.value==unit.name }.key
for(i in 1..10){ val citiesByStatBoost = unit.civInfo.cities.sortedByDescending{
val unexploredTilesAtDistance = unit.getTile().getTilesAtDistance(i) val stats = Stats()
.filter { unit.canMoveTo(it) && it.position !in unit.civInfo.exploredTiles for (bonus in it.cityStats.statPercentBonusList.values) stats.add(bonus)
&& unit.movementAlgs().canReach(it) } stats.toHashMap()[relatedStat]!!
if(unexploredTilesAtDistance.isNotEmpty()){ }
unit.movementAlgs().headTowards(unexploredTilesAtDistance.getRandom()) for(city in citiesByStatBoost){
val pathToCity =unit.movementAlgs().getShortestPath(city.getCenterTile())
if(pathToCity.isEmpty()) continue
if(pathToCity.size>2) {
unit.movementAlgs().headTowards(city.getCenterTile())
return return
} }
// if we got here, we're pretty close, start looking!
val tiles = city.getTiles().asSequence()
.filter { (unit.canMoveTo(it) || unit.currentTile==it)
&& it.isLand()
&& !it.isCityCenter()
&& it.resource==null }
.sortedByDescending { Automation().rankTile(it,unit.civInfo) }.toList()
val chosenTile = tiles.firstOrNull { unit.movementAlgs().canReach(it) }
if(chosenTile==null) continue // to another city
unit.movementAlgs().headTowards(chosenTile)
if(unit.currentTile==chosenTile && unit.currentMovement>0)
UnitActions().getUnitActions(unit,UnCivGame.Current.worldScreen)
.first { it.name.startsWith("Construct") }.action()
return
} }
} }
} }

View File

@ -11,14 +11,11 @@ import com.unciv.models.stats.Stats
class CityStats { class CityStats {
@Transient @Transient var baseStatList = LinkedHashMap<String, Stats>()
var baseStatList = LinkedHashMap<String, Stats>() @Transient var statPercentBonusList = LinkedHashMap<String, Stats>()
@Transient @Transient var happinessList = LinkedHashMap<String, Float>()
var happinessList = LinkedHashMap<String, Float>() @Transient var currentCityStats: Stats = Stats() // This is so we won't have to calculate this multiple times - takes a lot of time, especially on phones
@Transient @Transient lateinit var cityInfo: CityInfo
var currentCityStats: Stats = Stats() // This is so we won't have to calculate this multiple times - takes a lot of time, especially on phones
@Transient
lateinit var cityInfo: CityInfo
//region pure fuctions //region pure fuctions
private fun getStatsFromTiles(): Stats { private fun getStatsFromTiles(): Stats {
@ -28,7 +25,7 @@ class CityStats {
return stats return stats
} }
fun getStatsFromTradeRoute(): Stats { private fun getStatsFromTradeRoute(): Stats {
val stats = Stats() val stats = Stats()
if (!cityInfo.isCapital() && isConnectedToCapital(RoadStatus.Road)) { if (!cityInfo.isCapital() && isConnectedToCapital(RoadStatus.Road)) {
val civInfo = cityInfo.civInfo val civInfo = cityInfo.civInfo
@ -252,15 +249,19 @@ class CityStats {
newBaseStatList["Buildings"] = cityInfo.cityConstructions.getStats() newBaseStatList["Buildings"] = cityInfo.cityConstructions.getStats()
newBaseStatList["Policies"] = getStatsFromPolicies(civInfo.policies.adoptedPolicies) newBaseStatList["Policies"] = getStatsFromPolicies(civInfo.policies.adoptedPolicies)
val statPercentBonuses = cityInfo.cityConstructions.getStatPercentBonuses() val newStatPercentBonusList = LinkedHashMap<String,Stats>()
statPercentBonuses.add(getStatPercentBonusesFromGoldenAge(cityInfo.civInfo.goldenAges.isGoldenAge())) newStatPercentBonusList["Buildings"] = cityInfo.cityConstructions.getStatPercentBonuses()
statPercentBonuses.add(getStatPercentBonusesFromPolicies(civInfo.policies.adoptedPolicies, cityInfo.cityConstructions)) newStatPercentBonusList["Golden Age"]=getStatPercentBonusesFromGoldenAge(cityInfo.civInfo.goldenAges.isGoldenAge())
newStatPercentBonusList["Policies"]=getStatPercentBonusesFromPolicies(civInfo.policies.adoptedPolicies, cityInfo.cityConstructions)
// from wonders - Culture in all cities increased by 25% // from wonders - Culture in all cities increased by 25%
statPercentBonuses.add(getStatPercentBonusesFromWonders()) newStatPercentBonusList["Wonders"]=getStatPercentBonusesFromWonders()
statPercentBonuses.add(getStatPercentBonusesFromRailroad()) newStatPercentBonusList["Railroad"]=getStatPercentBonusesFromRailroad()
statPercentBonuses.add(getStatPercentBonusesFromMarble()) newStatPercentBonusList["Marble"]=getStatPercentBonusesFromMarble()
statPercentBonuses.add(getStatPercentBonusesFromComputers()) newStatPercentBonusList["Computers"]=getStatPercentBonusesFromComputers()
statPercentBonusList=newStatPercentBonusList
val statPercentBonuses = Stats()
for(bonus in statPercentBonusList.values) statPercentBonuses.add(bonus)
//val stats = Stats() //val stats = Stats()
for (stat in newBaseStatList.values) stat.production *= 1 + statPercentBonuses.production / 100 for (stat in newBaseStatList.values) stat.production *= 1 + statPercentBonuses.production / 100

View File

@ -6,6 +6,7 @@ import com.unciv.logic.automation.UnitAutomation
import com.unciv.logic.automation.WorkerAutomation import com.unciv.logic.automation.WorkerAutomation
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.tech.TechEra
import com.unciv.models.gamebasics.unit.BaseUnit import com.unciv.models.gamebasics.unit.BaseUnit
import com.unciv.models.gamebasics.unit.UnitType import com.unciv.models.gamebasics.unit.UnitType
import com.unciv.ui.utils.getRandom import com.unciv.ui.utils.getRandom
@ -327,34 +328,38 @@ class MapUnit {
val city = civInfo.cities.getRandom() val city = civInfo.cities.getRandom()
city.population.population++ city.population.population++
city.population.autoAssignPopulation() city.population.autoAssignPopulation()
civInfo.addNotification("We have found survivors the ruins - population added to ["+city.name+"]",city.location, Color.GREEN) civInfo.addNotification("We have found survivors the ruins - population added to ["+city.name+"]",currentTile.position, Color.GREEN)
} }
val researchableAncientEraTechs = GameBasics.Technologies.values val researchableAncientEraTechs = GameBasics.Technologies.values
.filter { !civInfo.tech.isResearched(it.name) && civInfo.tech.canBeResearched(it.name)} .filter {
!civInfo.tech.isResearched(it.name)
&& civInfo.tech.canBeResearched(it.name)
&& it.era() == TechEra.Ancient
}
if(researchableAncientEraTechs.isNotEmpty()) if(researchableAncientEraTechs.isNotEmpty())
actions.add { actions.add {
val tech = researchableAncientEraTechs.getRandom().name val tech = researchableAncientEraTechs.getRandom().name
civInfo.tech.techsResearched.add(tech) civInfo.tech.techsResearched.add(tech)
if(civInfo.tech.techsToResearch.contains(tech)) civInfo.tech.techsToResearch.remove(tech) if(civInfo.tech.techsToResearch.contains(tech)) civInfo.tech.techsToResearch.remove(tech)
civInfo.addNotification("We have discovered the lost technology of [$tech] in the ruins!",null, Color.BLUE) civInfo.addNotification("We have discovered the lost technology of [$tech] in the ruins!",currentTile.position, Color.BLUE)
} }
actions.add { actions.add {
val chosenUnit = listOf("Settler","Worker","Warrior").getRandom() val chosenUnit = listOf("Settler","Worker","Warrior").getRandom()
civInfo.placeUnitNearTile(currentTile.position,chosenUnit) civInfo.placeUnitNearTile(currentTile.position,chosenUnit)
civInfo.addNotification("A [$chosenUnit] has joined us!",null, Color.BLUE) civInfo.addNotification("A [$chosenUnit] has joined us!",currentTile.position, Color.BROWN)
} }
if(!type.isCivilian()) if(!type.isCivilian())
actions.add { actions.add {
promotions.XP+=10 promotions.XP+=10
civInfo.addNotification("An ancient tribe trains our [$name] in their ways of combat!",null, Color.RED) civInfo.addNotification("An ancient tribe trains our [$name] in their ways of combat!",currentTile.position, Color.RED)
} }
actions.add { actions.add {
val amount = listOf(25,60,100).getRandom() val amount = listOf(25,60,100).getRandom()
civInfo.gold+=amount civInfo.gold+=amount
civInfo.addNotification("We have found a stash of [$amount] gold in the ruins!!",null, Color.RED) civInfo.addNotification("We have found a stash of [$amount] gold in the ruins!!",currentTile.position, Color.GOLD)
} }
(actions.getRandom())() (actions.getRandom())()

View File

@ -76,6 +76,7 @@ object ImageGetter {
fun getImprovementIcon(improvementName:String, size:Float=20f):Actor{ fun getImprovementIcon(improvementName:String, size:Float=20f):Actor{
val iconGroup = getImage("ImprovementIcons/$improvementName").surroundWithCircle(size) val iconGroup = getImage("ImprovementIcons/$improvementName").surroundWithCircle(size)
val improvement = GameBasics.TileImprovements[improvementName]!! val improvement = GameBasics.TileImprovements[improvementName]!!
when { when {
improvement.food>0 -> iconGroup.circle.color= foodCircleColor improvement.food>0 -> iconGroup.circle.color= foodCircleColor

View File

@ -16,7 +16,7 @@ import com.unciv.ui.worldscreen.optionstable.YesNoPopupTable
import java.util.* import java.util.*
import kotlin.math.max import kotlin.math.max
class UnitAction(var name: String, var action:()->Unit, var canAct:Boolean) class UnitAction(var name: String, var canAct:Boolean, var action:()->Unit)
class UnitActions { class UnitActions {
@ -33,35 +33,34 @@ class UnitActions {
val unitTable = worldScreen.bottomBar.unitTable val unitTable = worldScreen.bottomBar.unitTable
val actionList = ArrayList<UnitAction>() val actionList = ArrayList<UnitAction>()
if(unit.action!=null && unit.action!!.startsWith("moveTo")){ if(unit.action!=null && unit.action!!.startsWith("moveTo")) {
actionList += actionList +=
UnitAction("Stop movement", { UnitAction("Stop movement", true) {
unitTable.currentlyExecutingAction = null unitTable.currentlyExecutingAction = null
unit.action=null unit.action = null
},true) }
} }
if(!unit.type.isCivilian() && !unit.isEmbarked() && !unit.type.isWaterUnit() if(!unit.type.isCivilian() && !unit.isEmbarked() && !unit.type.isWaterUnit()
&& !unit.hasUnique("No defensive terrain bonus") && !unit.isFortified()) { && !unit.hasUnique("No defensive terrain bonus") && !unit.isFortified()) {
actionList += UnitAction("Fortify", { unit.action = "Fortify 0" }, unit.currentMovement != 0f) actionList += UnitAction("Fortify", unit.currentMovement != 0f) { unit.action = "Fortify 0" }
} }
if(!unit.isFortified() && actionList.none{it.name=="Fortify"} && unit.action!="Sleep") { if(!unit.isFortified() && actionList.none{it.name=="Fortify"} && unit.action!="Sleep") {
actionList += UnitAction("Sleep", { unit.action = "Sleep" }, unit.currentMovement != 0f) actionList += UnitAction("Sleep",unit.currentMovement != 0f) { unit.action = "Sleep" }
} }
if(unit.type == UnitType.Scout){ if(unit.type == UnitType.Scout){
if(unit.action != "explore") if(unit.action != "explore")
actionList += UnitAction("Explore", { UnitAutomation().automatedExplore(unit); unit.action = "explore" }, actionList += UnitAction("Explore",unit.currentMovement != 0f)
unit.currentMovement != 0f) { UnitAutomation().automatedExplore(unit); unit.action = "explore" }
else else
actionList += UnitAction("Stop exploration", { unit.action = null }, true) actionList += UnitAction("Stop exploration", true) { unit.action = null }
} }
if(!unit.type.isCivilian() && unit.promotions.canBePromoted()){ if(!unit.type.isCivilian() && unit.promotions.canBePromoted()) {
actionList += UnitAction("Promote", actionList += UnitAction("Promote", unit.currentMovement != 0f)
{UnCivGame.Current.screen = PromotionPickerScreen(unit)}, { UnCivGame.Current.screen = PromotionPickerScreen(unit) }
unit.currentMovement != 0f)
} }
if(unit.baseUnit().upgradesTo!=null && tile.getOwner()==unit.civInfo) { if(unit.baseUnit().upgradesTo!=null && tile.getOwner()==unit.civInfo) {
@ -73,60 +72,57 @@ class UnitActions {
if (upgradedUnit.isBuildable(unit.civInfo)) { if (upgradedUnit.isBuildable(unit.civInfo)) {
var goldCostOfUpgrade = (upgradedUnit.cost - unit.baseUnit().cost) * 2 + 10 var goldCostOfUpgrade = (upgradedUnit.cost - unit.baseUnit().cost) * 2 + 10
if(unit.civInfo.policies.isAdopted("Professional Army")) goldCostOfUpgrade = (goldCostOfUpgrade* 0.66f).toInt() if (unit.civInfo.policies.isAdopted("Professional Army")) goldCostOfUpgrade = (goldCostOfUpgrade * 0.66f).toInt()
actionList += UnitAction("Upgrade to [${upgradedUnit.name}] ([$goldCostOfUpgrade] gold)", actionList += UnitAction("Upgrade to [${upgradedUnit.name}] ([$goldCostOfUpgrade] gold)",
{
unit.civInfo.gold -= goldCostOfUpgrade
val unitTile = unit.getTile()
unit.destroy()
val newunit = unit.civInfo.placeUnitNearTile(unitTile.position, upgradedUnit.name)
newunit.health = unit.health
newunit.promotions = unit.promotions
newunit.currentMovement=0f
},
unit.civInfo.gold >= goldCostOfUpgrade unit.civInfo.gold >= goldCostOfUpgrade
&& !unit.isEmbarked() && !unit.isEmbarked()
&& unit.currentMovement == unit.getMaxMovement().toFloat() ) && unit.currentMovement == unit.getMaxMovement().toFloat()
) {
unit.civInfo.gold -= goldCostOfUpgrade
val unitTile = unit.getTile()
unit.destroy()
val newunit = unit.civInfo.placeUnitNearTile(unitTile.position, upgradedUnit.name)
newunit.health = unit.health
newunit.promotions = unit.promotions
newunit.currentMovement = 0f
}
} }
} }
if(unit.hasUnique("Must set up to ranged attack") && unit.action != "Set Up" && !unit.isEmbarked()) if(unit.hasUnique("Must set up to ranged attack") && unit.action != "Set Up" && !unit.isEmbarked())
actionList+=UnitAction("Set up", actionList+=UnitAction("Set up",unit.currentMovement != 0f)
{unit.action="Set Up"; unit.currentMovement = max(0f, unit.currentMovement-1)}, {unit.action="Set Up"; unit.currentMovement = max(0f, unit.currentMovement-1)}
unit.currentMovement != 0f)
if (unit.hasUnique("Founds a new city") && !unit.isEmbarked()) { if (unit.hasUnique("Founds a new city") && !unit.isEmbarked()) {
actionList += UnitAction("Found city", actionList += UnitAction("Found city",
{
worldScreen.displayTutorials("CityFounded")
unit.civInfo.addCity(tile.position)
tile.improvement=null
unitTable.currentlyExecutingAction = null // In case the settler was in the middle of doing something and we then founded a city with it
unit.destroy()
},
unit.currentMovement != 0f && unit.currentMovement != 0f &&
!tile.getTilesInDistance(3).any { it.isCityCenter() }) !tile.getTilesInDistance(3).any { it.isCityCenter() })
{
worldScreen.displayTutorials("CityFounded")
unit.civInfo.addCity(tile.position)
tile.improvement = null
unitTable.currentlyExecutingAction = null // In case the settler was in the middle of doing something and we then founded a city with it
unit.destroy()
}
} }
if (unit.hasUnique("Can build improvements on tiles") && !unit.isEmbarked()) { if (unit.hasUnique("Can build improvements on tiles") && !unit.isEmbarked()) {
actionList += UnitAction("Construct improvement", actionList += UnitAction("Construct improvement",
{ worldScreen.game.screen = ImprovementPickerScreen(tile) },
unit.currentMovement != 0f unit.currentMovement != 0f
&& !tile.isCityCenter() && !tile.isCityCenter()
&& GameBasics.TileImprovements.values.any { tile.canBuildImprovement(it, unit.civInfo) }) && GameBasics.TileImprovements.values.any { tile.canBuildImprovement(it, unit.civInfo) }
) { worldScreen.game.screen = ImprovementPickerScreen(tile) }
if("automation" == unit.action){ if("automation" == unit.action){
actionList += UnitAction("Stop automation", actionList += UnitAction("Stop automation",true) {unit.action = null}
{unit.action = null},true)
} }
else { else {
actionList += UnitAction("Automate", actionList += UnitAction("Automate", unit.currentMovement != 0f)
{ {
unit.action = "automation" unit.action = "automation"
WorkerAutomation(unit).automateWorkerAction() WorkerAutomation(unit).automateWorkerAction()
},unit.currentMovement != 0f }
)
} }
} }
@ -135,68 +131,62 @@ class UnitActions {
&& tile.getTileResource().improvement == improvement && tile.getTileResource().improvement == improvement
&& unit.civInfo.tech.isResearched(GameBasics.TileImprovements[improvement]!!.techRequired!!) && unit.civInfo.tech.isResearched(GameBasics.TileImprovements[improvement]!!.techRequired!!)
) )
actionList += UnitAction("Create $improvement", { actionList += UnitAction("Create $improvement", unit.currentMovement != 0f) {
tile.improvement = improvement tile.improvement = improvement
unit.destroy() unit.destroy()
}, unit.currentMovement != 0f) }
} }
for(unique in unit.getUniques().filter { it.startsWith("Can build improvement: ") }){
val improvementName = unique.replace("Can build improvement: ","")
actionList += UnitAction("Construct $improvementName",
unit.currentMovement != 0f && !tile.isCityCenter(),
constructImprovementAndDestroyUnit(unit, improvementName))
}
if (unit.name == "Great Scientist" && !unit.isEmbarked()) { if (unit.name == "Great Scientist" && !unit.isEmbarked()) {
actionList += UnitAction( "Discover Technology", actionList += UnitAction( "Discover Technology",unit.currentMovement != 0f
{ ) {
unit.civInfo.tech.freeTechs += 1 unit.civInfo.tech.freeTechs += 1
unit.destroy() unit.destroy()
worldScreen.game.screen = TechPickerScreen(true, unit.civInfo) worldScreen.game.screen = TechPickerScreen(true, unit.civInfo)
},unit.currentMovement != 0f) }
actionList += UnitAction("Construct Academy",
constructImprovementAndDestroyUnit(unit, "Academy"),
unit.currentMovement != 0f && !tile.isCityCenter())
} }
if (unit.name == "Great Artist" && !unit.isEmbarked()) { if (unit.name == "Great Artist" && !unit.isEmbarked()) {
actionList += UnitAction( "Start Golden Age", actionList += UnitAction( "Start Golden Age",unit.currentMovement != 0f
{ ) {
unit.civInfo.goldenAges.enterGoldenAge() unit.civInfo.goldenAges.enterGoldenAge()
unit.destroy() unit.destroy()
},unit.currentMovement != 0f }
)
actionList += UnitAction("Construct Landmark",
constructImprovementAndDestroyUnit(unit, "Landmark"),
unit.currentMovement != 0f && !tile.isCityCenter())
} }
if (unit.name == "Great Engineer" && !unit.isEmbarked()) { if (unit.name == "Great Engineer" && !unit.isEmbarked()) {
actionList += UnitAction( "Hurry Wonder", actionList += UnitAction( "Hurry Wonder",
{
tile.getCity()!!.cityConstructions.addProduction(300 + 30 * tile.getCity()!!.population.population) //http://civilization.wikia.com/wiki/Great_engineer_(Civ5)
unit.destroy()
},
unit.currentMovement != 0f && unit.currentMovement != 0f &&
tile.isCityCenter() && tile.isCityCenter() &&
tile.getCity()!!.cityConstructions.getCurrentConstruction() is Building && tile.getCity()!!.cityConstructions.getCurrentConstruction() is Building &&
(tile.getCity()!!.cityConstructions.getCurrentConstruction() as Building).isWonder) (tile.getCity()!!.cityConstructions.getCurrentConstruction() as Building).isWonder
) {
actionList += UnitAction("Construct Manufactory", tile.getCity()!!.cityConstructions.addProduction(300 + 30 * tile.getCity()!!.population.population) //http://civilization.wikia.com/wiki/Great_engineer_(Civ5)
constructImprovementAndDestroyUnit(unit, "Manufactory"), unit.destroy()
unit.currentMovement != 0f && !tile.isCityCenter()) }
} }
if (unit.name == "Great Merchant" && !unit.isEmbarked()) { if (unit.name == "Great Merchant" && !unit.isEmbarked()) {
actionList += UnitAction("Conduct Trade Mission", actionList += UnitAction("Conduct Trade Mission", unit.currentMovement != 0f
{ ) {
unit.civInfo.gold += 350 // + 50 * era_number - todo! unit.civInfo.gold += 350 // + 50 * era_number - todo!
unit.destroy() unit.destroy()
},unit.currentMovement != 0f) }
actionList += UnitAction( "Construct Customs House",
constructImprovementAndDestroyUnit(unit, "Customs house"),
unit.currentMovement != 0f && !tile.isCityCenter())
} }
actionList += UnitAction("Disband unit", actionList += UnitAction("Disband unit",unit.currentMovement != 0f
{ ) {
YesNoPopupTable("Do you really want to disband this unit?".tr(), YesNoPopupTable("Do you really want to disband this unit?".tr(),
{unit.destroy(); worldScreen.update()} ) {unit.destroy(); worldScreen.update()} )
},unit.currentMovement != 0f) }
return actionList return actionList
} }