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:
parent
9d2cc90ccd
commit
5fbfa637f2
4 changed files with 45 additions and 35 deletions
|
@ -1290,32 +1290,32 @@
|
||||||
{
|
{
|
||||||
"name": "Great Artist",
|
"name": "Great Artist",
|
||||||
"unitType": "Civilian",
|
"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
|
"movement": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Great Scientist",
|
"name": "Great Scientist",
|
||||||
"unitType": "Civilian",
|
"unitType": "Civilian",
|
||||||
"uniques": ["Can hurry technology research","Can build improvement: Academy", "Unbuildable"],
|
"uniques": ["Can hurry technology research","Can construct [Academy]", "Unbuildable"],
|
||||||
"movement": 2
|
"movement": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Great Merchant",
|
"name": "Great Merchant",
|
||||||
"unitType": "Civilian",
|
"unitType": "Civilian",
|
||||||
"uniques": ["Can undertake a trade mission with City-State, giving a large sum of gold and [30] Influence",
|
"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
|
"movement": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Great Engineer",
|
"name": "Great Engineer",
|
||||||
"unitType": "Civilian",
|
"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
|
"movement": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Great General",
|
"name": "Great General",
|
||||||
"unitType": "Civilian",
|
"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
|
"movement": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,8 @@ import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
import com.unciv.models.ruleset.tile.TileResource
|
import com.unciv.models.ruleset.tile.TileResource
|
||||||
import com.unciv.models.stats.Stats
|
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
|
import com.unciv.ui.worldscreen.unit.UnitActions
|
||||||
|
|
||||||
object SpecificUnitAutomation {
|
object SpecificUnitAutomation {
|
||||||
|
@ -79,18 +81,18 @@ object SpecificUnitAutomation {
|
||||||
if (owner != null)
|
if (owner != null)
|
||||||
distance - WorkerAutomation(unit).getPriority(it, owner)
|
distance - WorkerAutomation(unit).getPriority(it, owner)
|
||||||
else distance }
|
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 there is a good tile to steal - go there
|
||||||
if (tileToSteal != null) {
|
if (tileToSteal != null) {
|
||||||
unit.movement.headTowards(tileToSteal)
|
unit.movement.headTowards(tileToSteal)
|
||||||
if (unit.currentMovement > 0 && unit.currentTile == tileToSteal)
|
if (unit.currentMovement > 0 && unit.currentTile == tileToSteal)
|
||||||
UnitActions.getBuildImprovementAction(unit)?.action?.invoke()
|
UnitActions.getImprovementConstructionActions(unit, unit.currentTile).firstOrNull()?.action?.invoke()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to build a citadel
|
// try to build a citadel for defensive purposes
|
||||||
if (WorkerAutomation(unit).evaluateFortPlacement(unit.currentTile, unit.civInfo, true)) {
|
if (WorkerAutomation(unit).evaluateFortPlacement(unit.currentTile, unit.civInfo, true)) {
|
||||||
UnitActions.getBuildImprovementAction(unit)?.action?.invoke()
|
UnitActions.getImprovementConstructionActions(unit,unit.currentTile).firstOrNull()?.action?.invoke()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +112,7 @@ object SpecificUnitAutomation {
|
||||||
if (tileForCitadel != null) {
|
if (tileForCitadel != null) {
|
||||||
unit.movement.headTowards(tileForCitadel)
|
unit.movement.headTowards(tileForCitadel)
|
||||||
if (unit.currentMovement > 0 && unit.currentTile == tileForCitadel)
|
if (unit.currentMovement > 0 && unit.currentTile == tileForCitadel)
|
||||||
UnitActions.getBuildImprovementAction(unit)?.action?.invoke()
|
UnitActions.getImprovementConstructionActions(unit,unit.currentTile).firstOrNull()?.action?.invoke()
|
||||||
} else
|
} else
|
||||||
unit.movement.headTowards(cityToGarrison)
|
unit.movement.headTowards(cityToGarrison)
|
||||||
return
|
return
|
||||||
|
@ -190,10 +192,13 @@ object SpecificUnitAutomation {
|
||||||
foundCityAction.action.invoke()
|
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
|
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 citiesByStatBoost = unit.civInfo.cities.sortedByDescending {
|
||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
|
@ -221,7 +226,7 @@ object SpecificUnitAutomation {
|
||||||
|
|
||||||
unit.movement.headTowards(chosenTile)
|
unit.movement.headTowards(chosenTile)
|
||||||
if (unit.currentTile == chosenTile)
|
if (unit.currentTile == chosenTile)
|
||||||
UnitActions.getBuildImprovementAction(unit)?.action?.invoke()
|
UnitActions.getImprovementConstructionActions(unit, unit.currentTile).firstOrNull()?.action?.invoke()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@ import com.badlogic.gdx.graphics.Color
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.logic.battle.*
|
import com.unciv.logic.battle.*
|
||||||
import com.unciv.logic.city.CityInfo
|
import com.unciv.logic.city.CityInfo
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
|
||||||
import com.unciv.logic.civilization.GreatPersonManager
|
import com.unciv.logic.civilization.GreatPersonManager
|
||||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||||
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.ruleset.unit.UnitType
|
import com.unciv.models.ruleset.unit.UnitType
|
||||||
|
import com.unciv.models.translations.equalsPlaceholderText
|
||||||
import com.unciv.ui.worldscreen.unit.UnitActions
|
import com.unciv.ui.worldscreen.unit.UnitActions
|
||||||
|
|
||||||
object UnitAutomation {
|
object UnitAutomation {
|
||||||
|
@ -90,6 +90,7 @@ object UnitAutomation {
|
||||||
if (unit.civInfo.isBarbarian())
|
if (unit.civInfo.isBarbarian())
|
||||||
throw IllegalStateException("Barbarians is not allowed here.")
|
throw IllegalStateException("Barbarians is not allowed here.")
|
||||||
|
|
||||||
|
if(unit.type==UnitType.Civilian) {
|
||||||
if (unit.name == Constants.settler)
|
if (unit.name == Constants.settler)
|
||||||
return SpecificUnitAutomation.automateSettlerActions(unit)
|
return SpecificUnitAutomation.automateSettlerActions(unit)
|
||||||
|
|
||||||
|
@ -102,6 +103,12 @@ object UnitAutomation {
|
||||||
if (unit.name == Constants.greatGeneral || unit.baseUnit.replaces == Constants.greatGeneral)
|
if (unit.name == Constants.greatGeneral || unit.baseUnit.replaces == Constants.greatGeneral)
|
||||||
return SpecificUnitAutomation.automateGreatGeneral(unit)
|
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)
|
if (unit.type == UnitType.Fighter)
|
||||||
return SpecificUnitAutomation.automateFighter(unit)
|
return SpecificUnitAutomation.automateFighter(unit)
|
||||||
|
|
||||||
|
@ -112,10 +119,6 @@ object UnitAutomation {
|
||||||
return SpecificUnitAutomation.automateMissile(unit)
|
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 (tryGoToRuinAndEncampment(unit)) {
|
||||||
if (unit.currentMovement == 0f) return
|
if (unit.currentMovement == 0f) return
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ import com.unciv.models.UncivSound
|
||||||
import com.unciv.models.UnitAction
|
import com.unciv.models.UnitAction
|
||||||
import com.unciv.models.UnitActionType
|
import com.unciv.models.UnitActionType
|
||||||
import com.unciv.models.ruleset.Building
|
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.models.translations.tr
|
||||||
import com.unciv.ui.pickerscreens.ImprovementPickerScreen
|
import com.unciv.ui.pickerscreens.ImprovementPickerScreen
|
||||||
import com.unciv.ui.pickerscreens.PromotionPickerScreen
|
import com.unciv.ui.pickerscreens.PromotionPickerScreen
|
||||||
|
@ -67,11 +69,13 @@ object UnitActions {
|
||||||
addConstructRoadsAction(unit, tile, actionList)
|
addConstructRoadsAction(unit, tile, actionList)
|
||||||
addCreateWaterImprovements(unit, actionList)
|
addCreateWaterImprovements(unit, actionList)
|
||||||
addGreatPersonActions(unit, actionList, tile)
|
addGreatPersonActions(unit, actionList, tile)
|
||||||
|
actionList += getImprovementConstructionActions(unit, tile)
|
||||||
addDisbandAction(actionList, unit, worldScreen)
|
addDisbandAction(actionList, unit, worldScreen)
|
||||||
|
|
||||||
return actionList
|
return actionList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun addDisbandAction(actionList: ArrayList<UnitAction>, unit: MapUnit, worldScreen: WorldScreen) {
|
private fun addDisbandAction(actionList: ArrayList<UnitAction>, unit: MapUnit, worldScreen: WorldScreen) {
|
||||||
actionList += UnitAction(
|
actionList += UnitAction(
|
||||||
type = UnitActionType.DisbandUnit,
|
type = UnitActionType.DisbandUnit,
|
||||||
|
@ -347,16 +351,14 @@ object UnitActions {
|
||||||
unit.destroy()
|
unit.destroy()
|
||||||
}.takeIf { canConductTradeMission })
|
}.takeIf { canConductTradeMission })
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildImprovementAction = getBuildImprovementAction(unit)
|
|
||||||
if (buildImprovementAction != null) actionList += buildImprovementAction
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBuildImprovementAction(unit: MapUnit): UnitAction? {
|
|
||||||
val tile = unit.currentTile
|
fun getImprovementConstructionActions(unit: MapUnit, tile: TileInfo): ArrayList<UnitAction> {
|
||||||
for (unique in unit.getUniques().filter { it.startsWith("Can build improvement: ") }) {
|
val finalActions = ArrayList<UnitAction>()
|
||||||
val improvementName = unique.replace("Can build improvement: ", "")
|
for (unique in unit.getUniques().filter { it.equalsPlaceholderText("Can construct []") }) {
|
||||||
return UnitAction(
|
val improvementName = unique.getPlaceholderParameters()[0]
|
||||||
|
finalActions += UnitAction(
|
||||||
type = UnitActionType.Create,
|
type = UnitActionType.Create,
|
||||||
title = "Create [$improvementName]",
|
title = "Create [$improvementName]",
|
||||||
uncivSound = UncivSound.Chimes,
|
uncivSound = UncivSound.Chimes,
|
||||||
|
@ -384,7 +386,7 @@ object UnitActions {
|
||||||
(improvementName != Constants.citadel ||
|
(improvementName != Constants.citadel ||
|
||||||
tile.neighbors.any { it.getOwner() == unit.civInfo })})
|
tile.neighbors.any { it.getOwner() == unit.civInfo })})
|
||||||
}
|
}
|
||||||
return null
|
return finalActions
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun takeOverTilesAround(unit: MapUnit) {
|
private fun takeOverTilesAround(unit: MapUnit) {
|
||||||
|
|
Loading…
Reference in a new issue