All improvement placing units are automated in the same way - this allows for the AI to control modded units that place other improvements!

This commit is contained in:
Yair Morgenstern 2020-07-28 19:26:02 +03:00
parent 9d2cc90ccd
commit 5fbfa637f2
4 changed files with 45 additions and 35 deletions

View file

@ -1290,32 +1290,32 @@
{
"name": "Great Artist",
"unitType": "Civilian",
"uniques": ["Can start an 8-turn golden age","Can build improvement: Landmark", "Unbuildable"],
"uniques": ["Can start an 8-turn golden age","Can construct [Landmark]", "Unbuildable"],
"movement": 2
},
{
"name": "Great Scientist",
"unitType": "Civilian",
"uniques": ["Can hurry technology research","Can build improvement: Academy", "Unbuildable"],
"uniques": ["Can hurry technology research","Can construct [Academy]", "Unbuildable"],
"movement": 2
},
{
"name": "Great Merchant",
"unitType": "Civilian",
"uniques": ["Can undertake a trade mission with City-State, giving a large sum of gold and [30] Influence",
"Can build improvement: Customs house", "Unbuildable"],
"Can construct [Customs house]", "Unbuildable"],
"movement": 2
},
{
"name": "Great Engineer",
"unitType": "Civilian",
"uniques": ["Can speed up construction of a wonder","Can build improvement: Manufactory", "Unbuildable"],
"uniques": ["Can speed up construction of a wonder","Can construct [Manufactory]", "Unbuildable"],
"movement": 2
},
{
"name": "Great General",
"unitType": "Civilian",
"uniques": ["Can start an 8-turn golden age","Bonus for units in 2 tile radius 15%", "Can build improvement: Citadel", "Unbuildable"],
"uniques": ["Can start an 8-turn golden age","Bonus for units in 2 tile radius 15%", "Can construct [Citadel]", "Unbuildable"],
"movement": 2
},
{

View file

@ -10,6 +10,8 @@ import com.unciv.logic.map.TileInfo
import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.ruleset.tile.TileResource
import com.unciv.models.stats.Stats
import com.unciv.models.translations.equalsPlaceholderText
import com.unciv.models.translations.getPlaceholderParameters
import com.unciv.ui.worldscreen.unit.UnitActions
object SpecificUnitAutomation {
@ -79,18 +81,18 @@ object SpecificUnitAutomation {
if (owner != null)
distance - WorkerAutomation(unit).getPriority(it, owner)
else distance }
.firstOrNull{ unit.movement.canReach(it) } // canReach is perfrmance-heavy and always a last resort
.firstOrNull{ unit.movement.canReach(it) } // canReach is performance-heavy and always a last resort
// if there is a good tile to steal - go there
if (tileToSteal != null) {
unit.movement.headTowards(tileToSteal)
if (unit.currentMovement > 0 && unit.currentTile == tileToSteal)
UnitActions.getBuildImprovementAction(unit)?.action?.invoke()
UnitActions.getImprovementConstructionActions(unit, unit.currentTile).firstOrNull()?.action?.invoke()
return
}
// try to build a citadel
// try to build a citadel for defensive purposes
if (WorkerAutomation(unit).evaluateFortPlacement(unit.currentTile, unit.civInfo, true)) {
UnitActions.getBuildImprovementAction(unit)?.action?.invoke()
UnitActions.getImprovementConstructionActions(unit,unit.currentTile).firstOrNull()?.action?.invoke()
return
}
@ -110,7 +112,7 @@ object SpecificUnitAutomation {
if (tileForCitadel != null) {
unit.movement.headTowards(tileForCitadel)
if (unit.currentMovement > 0 && unit.currentTile == tileForCitadel)
UnitActions.getBuildImprovementAction(unit)?.action?.invoke()
UnitActions.getImprovementConstructionActions(unit,unit.currentTile).firstOrNull()?.action?.invoke()
} else
unit.movement.headTowards(cityToGarrison)
return
@ -190,10 +192,13 @@ object SpecificUnitAutomation {
foundCityAction.action.invoke()
}
fun automateGreatPerson(unit: MapUnit) {
fun automateImprovementPlacer(unit: MapUnit) {
if (unit.getTile().militaryUnit == null) return // Don't move until you're accompanied by a military unit
val relatedStat = GreatPersonManager().statToGreatPersonMapping.entries.first { it.value == unit.name }.key
val improvementName = unit.getUniques().first { it.equalsPlaceholderText("Can construct []") }
.getPlaceholderParameters()[0]
val improvement = unit.civInfo.gameInfo.ruleSet.tileImprovements[improvementName]!!
val relatedStat = improvement.toHashMap().maxBy { it.value }!!.key
val citiesByStatBoost = unit.civInfo.cities.sortedByDescending {
val stats = Stats()
@ -221,7 +226,7 @@ object SpecificUnitAutomation {
unit.movement.headTowards(chosenTile)
if (unit.currentTile == chosenTile)
UnitActions.getBuildImprovementAction(unit)?.action?.invoke()
UnitActions.getImprovementConstructionActions(unit, unit.currentTile).firstOrNull()?.action?.invoke()
return
}
}

View file

@ -4,12 +4,12 @@ import com.badlogic.gdx.graphics.Color
import com.unciv.Constants
import com.unciv.logic.battle.*
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.GreatPersonManager
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo
import com.unciv.models.ruleset.unit.UnitType
import com.unciv.models.translations.equalsPlaceholderText
import com.unciv.ui.worldscreen.unit.UnitActions
object UnitAutomation {
@ -90,17 +90,24 @@ object UnitAutomation {
if (unit.civInfo.isBarbarian())
throw IllegalStateException("Barbarians is not allowed here.")
if (unit.name == Constants.settler)
return SpecificUnitAutomation.automateSettlerActions(unit)
if(unit.type==UnitType.Civilian) {
if (unit.name == Constants.settler)
return SpecificUnitAutomation.automateSettlerActions(unit)
if (unit.hasUnique(Constants.workerUnique))
return WorkerAutomation(unit).automateWorkerAction()
if (unit.hasUnique(Constants.workerUnique))
return WorkerAutomation(unit).automateWorkerAction()
if (unit.name == "Work Boats")
return SpecificUnitAutomation.automateWorkBoats(unit)
if (unit.name == "Work Boats")
return SpecificUnitAutomation.automateWorkBoats(unit)
if (unit.name == Constants.greatGeneral || unit.baseUnit.replaces == Constants.greatGeneral)
return SpecificUnitAutomation.automateGreatGeneral(unit)
if (unit.name == Constants.greatGeneral || unit.baseUnit.replaces == Constants.greatGeneral)
return SpecificUnitAutomation.automateGreatGeneral(unit)
if (unit.getUniques().any { it.equalsPlaceholderText("Can construct []") })
return SpecificUnitAutomation.automateImprovementPlacer(unit) // includes great people plus moddable units
return // The AI doesn't know how to handle unknown civilian units
}
if (unit.type == UnitType.Fighter)
return SpecificUnitAutomation.automateFighter(unit)
@ -112,10 +119,6 @@ object UnitAutomation {
return SpecificUnitAutomation.automateMissile(unit)
if (unit.name.startsWith("Great")
&& unit.name in GreatPersonManager().statToGreatPersonMapping.values)// So "Great War Infantry" isn't caught here
return SpecificUnitAutomation.automateGreatPerson(unit)
if (tryGoToRuinAndEncampment(unit)) {
if (unit.currentMovement == 0f) return
}

View file

@ -15,6 +15,8 @@ import com.unciv.models.UncivSound
import com.unciv.models.UnitAction
import com.unciv.models.UnitActionType
import com.unciv.models.ruleset.Building
import com.unciv.models.translations.equalsPlaceholderText
import com.unciv.models.translations.getPlaceholderParameters
import com.unciv.models.translations.tr
import com.unciv.ui.pickerscreens.ImprovementPickerScreen
import com.unciv.ui.pickerscreens.PromotionPickerScreen
@ -67,11 +69,13 @@ object UnitActions {
addConstructRoadsAction(unit, tile, actionList)
addCreateWaterImprovements(unit, actionList)
addGreatPersonActions(unit, actionList, tile)
actionList += getImprovementConstructionActions(unit, tile)
addDisbandAction(actionList, unit, worldScreen)
return actionList
}
private fun addDisbandAction(actionList: ArrayList<UnitAction>, unit: MapUnit, worldScreen: WorldScreen) {
actionList += UnitAction(
type = UnitActionType.DisbandUnit,
@ -347,16 +351,14 @@ object UnitActions {
unit.destroy()
}.takeIf { canConductTradeMission })
}
val buildImprovementAction = getBuildImprovementAction(unit)
if (buildImprovementAction != null) actionList += buildImprovementAction
}
fun getBuildImprovementAction(unit: MapUnit): UnitAction? {
val tile = unit.currentTile
for (unique in unit.getUniques().filter { it.startsWith("Can build improvement: ") }) {
val improvementName = unique.replace("Can build improvement: ", "")
return UnitAction(
fun getImprovementConstructionActions(unit: MapUnit, tile: TileInfo): ArrayList<UnitAction> {
val finalActions = ArrayList<UnitAction>()
for (unique in unit.getUniques().filter { it.equalsPlaceholderText("Can construct []") }) {
val improvementName = unique.getPlaceholderParameters()[0]
finalActions += UnitAction(
type = UnitActionType.Create,
title = "Create [$improvementName]",
uncivSound = UncivSound.Chimes,
@ -384,7 +386,7 @@ object UnitActions {
(improvementName != Constants.citadel ||
tile.neighbors.any { it.getOwner() == unit.civInfo })})
}
return null
return finalActions
}
private fun takeOverTilesAround(unit: MapUnit) {