introduce UnitActionsType (#1633)

This commit is contained in:
Vladimir Tanakov 2020-01-09 21:17:13 +03:00 committed by Yair Morgenstern
parent 036d4058f1
commit 9776029376
5 changed files with 83 additions and 48 deletions

View File

@ -7,6 +7,7 @@ import com.unciv.logic.civilization.GreatPersonManager
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
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.UnitActionType
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
@ -29,7 +30,7 @@ class SpecificUnitAutomation{
unit.movement.headTowards(closestReachableResource) unit.movement.headTowards(closestReachableResource)
if (unit.currentMovement > 0 && unit.currentTile == closestReachableResource) { if (unit.currentMovement > 0 && unit.currentTile == closestReachableResource) {
val createImprovementAction = UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen) val createImprovementAction = UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen)
.firstOrNull { it.name.startsWith("Create") }?.action // could be either fishing boats or oil well .firstOrNull { it.type == UnitActionType.Create }?.action // could be either fishing boats or oil well
if (createImprovementAction != null) // If it's null, then unit is already gone if (createImprovementAction != null) // If it's null, then unit is already gone
return createImprovementAction() return createImprovementAction()
} }
@ -134,11 +135,11 @@ class SpecificUnitAutomation{
throw Exception("City within distance") throw Exception("City within distance")
if (unit.getTile() == bestCityLocation) if (unit.getTile() == bestCityLocation)
UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen).first { it.name == "Found city" }.action?.invoke() UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen).first { it.type == UnitActionType.FoundCity }.action?.invoke()
else { else {
unit.movement.headTowards(bestCityLocation) unit.movement.headTowards(bestCityLocation)
if (unit.currentMovement > 0 && unit.getTile() == bestCityLocation) if (unit.currentMovement > 0 && unit.getTile() == bestCityLocation)
UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen).first { it.name == "Found city" }.action?.invoke() UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen).first { it.type == UnitActionType.FoundCity }.action?.invoke()
} }
} }
@ -173,7 +174,7 @@ class SpecificUnitAutomation{
unit.movement.headTowards(chosenTile) unit.movement.headTowards(chosenTile)
if(unit.currentTile==chosenTile && unit.currentMovement > 0) if(unit.currentTile==chosenTile && unit.currentMovement > 0)
UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen) UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen)
.first { it.name.startsWith("Create") }.action?.invoke() .first { it.type == UnitActionType.Create }.action?.invoke()
return return
} }

View File

@ -11,6 +11,7 @@ import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.PathsToTilesWithinTurn import com.unciv.logic.map.PathsToTilesWithinTurn
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
import com.unciv.models.UnitAction import com.unciv.models.UnitAction
import com.unciv.models.UnitActionType
import com.unciv.models.ruleset.unit.UnitType import com.unciv.models.ruleset.unit.UnitType
import com.unciv.ui.worldscreen.unit.UnitActions import com.unciv.ui.worldscreen.unit.UnitActions
@ -166,7 +167,7 @@ class UnitAutomation{
unit.movement.moveToTile(tileToPillage) unit.movement.moveToTile(tileToPillage)
UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen) UnitActions().getUnitActions(unit, UncivGame.Current.worldScreen)
.first { it.name == "Pillage" }.action?.invoke() .first { it.type == UnitActionType.Pillage }.action?.invoke()
return true return true
} }
@ -297,7 +298,7 @@ class UnitAutomation{
if (unit.baseUnit().upgradesTo != null) { if (unit.baseUnit().upgradesTo != null) {
val upgradedUnit = unit.civInfo.gameInfo.ruleSet.units[unit.baseUnit().upgradesTo!!]!! val upgradedUnit = unit.civInfo.gameInfo.ruleSet.units[unit.baseUnit().upgradesTo!!]!!
if (upgradedUnit.isBuildable(unit.civInfo)) { if (upgradedUnit.isBuildable(unit.civInfo)) {
val upgradeAction = unitActions.firstOrNull { it.name.startsWith("Upgrade to") } val upgradeAction = unitActions.firstOrNull { it.type == UnitActionType.Upgrade }
if (upgradeAction != null && upgradeAction.canAct) { if (upgradeAction != null && upgradeAction.canAct) {
upgradeAction.action?.invoke() upgradeAction.action?.invoke()
return true return true

View File

@ -1,10 +1,33 @@
package com.unciv.models package com.unciv.models
data class UnitAction( data class UnitAction(
var name: String, // TODO make it enum or sealed class var type: UnitActionType,
var canAct: Boolean, var canAct: Boolean,
var title: String = name, var title: String = type.value,
var isCurrentAction: Boolean = false, var isCurrentAction: Boolean = false,
var uncivSound: UncivSound = UncivSound.Click, var uncivSound: UncivSound = UncivSound.Click,
var action: (() -> Unit)? = null var action: (() -> Unit)? = null
) )
enum class UnitActionType(val value: String) {
Automate("Automate"),
StopMovement("Stop movement"),
StopAutomation("Stop automation"),
StopExploration("Stop exploration"),
Sleep("Sleep"),
Fortify("Fortify"),
Explore("Explore"),
Promote("Promote"),
Upgrade("Upgrade"),
Pillage("Pillage"),
SetUp("Set up"),
FoundCity("Found city"),
ConstructImprovement("Construct improvement"),
ConstructRoad("Construct road"),
Create("Create"),
HurryResearch("Hurry Research"),
StartGoldenAge("Start Golden Age"),
HurryWonder("Hurry Wonder"),
ConductTradeMission("Conduct Trade Mission"),
DisbandUnit("Disband unit")
}

View File

@ -10,6 +10,7 @@ import com.unciv.logic.map.RoadStatus
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
import com.unciv.models.UncivSound import com.unciv.models.UncivSound
import com.unciv.models.UnitAction import com.unciv.models.UnitAction
import com.unciv.models.UnitActionType
import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Building
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.pickerscreens.ImprovementPickerScreen import com.unciv.ui.pickerscreens.ImprovementPickerScreen
@ -26,18 +27,19 @@ class UnitActions {
if (unit.action != null && unit.action!!.startsWith("moveTo")) { if (unit.action != null && unit.action!!.startsWith("moveTo")) {
actionList += UnitAction( actionList += UnitAction(
name = "Stop movement", type = UnitActionType.StopMovement,
canAct = true, canAct = true,
action = { unit.action = null } action = { unit.action = null }
) )
} }
val workingOnImprovement = unit.hasUnique("Can build improvements on tiles") && unit.currentTile.hasImprovementInProgress() val workingOnImprovement = unit.hasUnique("Can build improvements on tiles")
&& unit.currentTile.hasImprovementInProgress()
if (!unit.isFortified() && (!unit.canFortify() || unit.health < 100) && unit.currentMovement > 0 if (!unit.isFortified() && (!unit.canFortify() || unit.health < 100) && unit.currentMovement > 0
&& !workingOnImprovement) { && !workingOnImprovement) {
val isSleeping = unit.action == Constants.unitActionSleep val isSleeping = unit.action == Constants.unitActionSleep
actionList += UnitAction( actionList += UnitAction(
name = "Sleep", type = UnitActionType.Sleep,
canAct = !isSleeping, canAct = !isSleeping,
isCurrentAction = isSleeping, isCurrentAction = isSleeping,
action = { action = {
@ -48,7 +50,7 @@ class UnitActions {
if (unit.canFortify()) { if (unit.canFortify()) {
actionList += UnitAction( actionList += UnitAction(
name = "Fortify", type = UnitActionType.Fortify,
canAct = unit.currentMovement > 0, canAct = unit.currentMovement > 0,
uncivSound = UncivSound.Fortify, uncivSound = UncivSound.Fortify,
action = { action = {
@ -57,7 +59,7 @@ class UnitActions {
}) })
} else if (unit.isFortified()) { } else if (unit.isFortified()) {
actionList += UnitAction( actionList += UnitAction(
name = "Fortify", type = UnitActionType.Fortify,
canAct = false, canAct = false,
isCurrentAction = true, isCurrentAction = true,
title = "${"Fortification".tr()} ${unit.getFortificationTurns() * 20}%" title = "${"Fortification".tr()} ${unit.getFortificationTurns() * 20}%"
@ -67,7 +69,7 @@ class UnitActions {
if (!unit.type.isAirUnit()) { if (!unit.type.isAirUnit()) {
if (unit.action != Constants.unitActionExplore) { if (unit.action != Constants.unitActionExplore) {
actionList += UnitAction( actionList += UnitAction(
name = "Explore", type = UnitActionType.Explore,
canAct = true, canAct = true,
action = { action = {
UnitAutomation().automatedExplore(unit) UnitAutomation().automatedExplore(unit)
@ -75,7 +77,7 @@ class UnitActions {
}) })
} else { } else {
actionList += UnitAction( actionList += UnitAction(
name = "Stop exploration", type = UnitActionType.StopExploration,
canAct = true, canAct = true,
action = { unit.action = null } action = { unit.action = null }
) )
@ -85,7 +87,7 @@ class UnitActions {
if (!unit.type.isCivilian() && unit.promotions.canBePromoted()) { if (!unit.type.isCivilian() && unit.promotions.canBePromoted()) {
// promotion does not consume movement points, so we can do it always // promotion does not consume movement points, so we can do it always
actionList += UnitAction( actionList += UnitAction(
name = "Promote", type = UnitActionType.Promote,
canAct = true, canAct = true,
uncivSound = UncivSound.Promote, uncivSound = UncivSound.Promote,
action = { action = {
@ -99,7 +101,8 @@ class UnitActions {
val upgradedUnit = unit.getUnitToUpgradeTo() val upgradedUnit = unit.getUnitToUpgradeTo()
actionList += UnitAction( actionList += UnitAction(
name = "Upgrade to [${upgradedUnit.name}] ([$goldCostOfUpgrade] gold)", type = UnitActionType.Upgrade,
title = "Upgrade to [${upgradedUnit.name}] ([$goldCostOfUpgrade] gold)",
canAct = unit.civInfo.gold >= goldCostOfUpgrade && !unit.isEmbarked() && unit.currentMovement == unit.getMaxMovement().toFloat(), canAct = unit.civInfo.gold >= goldCostOfUpgrade && !unit.isEmbarked() && unit.currentMovement == unit.getMaxMovement().toFloat(),
uncivSound = UncivSound.Upgrade, uncivSound = UncivSound.Upgrade,
action = { action = {
@ -123,8 +126,10 @@ class UnitActions {
} }
if (!unit.type.isCivilian() && tile.improvement != null) { if (!unit.type.isCivilian() && tile.improvement != null) {
actionList += UnitAction("Pillage", unit.currentMovement > 0 && canPillage(unit, tile)) actionList += UnitAction(
{ type = UnitActionType.Pillage,
canAct = unit.currentMovement > 0 && canPillage(unit, tile),
action = {
// http://well-of-souls.com/civ/civ5_improvements.html says that naval improvements are destroyed upon pilllage // http://well-of-souls.com/civ/civ5_improvements.html says that naval improvements are destroyed upon pilllage
// and I can't find any other sources so I'll go with that // and I can't find any other sources so I'll go with that
if (tile.isLand) { if (tile.isLand) {
@ -134,13 +139,13 @@ class UnitActions {
tile.improvement = null tile.improvement = null
if (!unit.hasUnique("No movement cost to pillage")) unit.useMovementPoints(1f) if (!unit.hasUnique("No movement cost to pillage")) unit.useMovementPoints(1f)
unit.healBy(25) unit.healBy(25)
} })
} }
if (unit.hasUnique("Must set up to ranged attack") && !unit.isEmbarked()) { if (unit.hasUnique("Must set up to ranged attack") && !unit.isEmbarked()) {
val setUp = unit.action == "Set Up" val setUp = unit.action == "Set Up"
actionList += UnitAction( actionList += UnitAction(
name = "Set up", type = UnitActionType.SetUp,
canAct = unit.currentMovement > 0 && !setUp, canAct = unit.currentMovement > 0 && !setUp,
isCurrentAction = setUp, isCurrentAction = setUp,
uncivSound = UncivSound.Setup, uncivSound = UncivSound.Setup,
@ -152,7 +157,7 @@ class UnitActions {
if (unit.hasUnique("Founds a new city") && !unit.isEmbarked()) { if (unit.hasUnique("Founds a new city") && !unit.isEmbarked()) {
actionList += UnitAction( actionList += UnitAction(
name = "Found city", type = UnitActionType.FoundCity,
canAct = unit.currentMovement > 0 && !tile.getTilesInDistance(3).any { it.isCityCenter() }, canAct = unit.currentMovement > 0 && !tile.getTilesInDistance(3).any { it.isCityCenter() },
uncivSound = UncivSound.Chimes, uncivSound = UncivSound.Chimes,
action = { action = {
@ -165,7 +170,7 @@ class UnitActions {
if (unit.hasUnique("Can build improvements on tiles") && !unit.isEmbarked()) { if (unit.hasUnique("Can build improvements on tiles") && !unit.isEmbarked()) {
actionList += UnitAction( actionList += UnitAction(
name = "Construct improvement", type = UnitActionType.ConstructImprovement,
canAct = unit.currentMovement > 0 canAct = unit.currentMovement > 0
&& !tile.isCityCenter() && !tile.isCityCenter()
&& unit.civInfo.gameInfo.ruleSet.tileImprovements.values.any { tile.canBuildImprovement(it, unit.civInfo) }, && unit.civInfo.gameInfo.ruleSet.tileImprovements.values.any { tile.canBuildImprovement(it, unit.civInfo) },
@ -176,13 +181,13 @@ class UnitActions {
if (Constants.unitActionAutomation == unit.action) { if (Constants.unitActionAutomation == unit.action) {
actionList += UnitAction( actionList += UnitAction(
name = "Stop automation", type = UnitActionType.StopAutomation,
canAct = true, canAct = true,
action = { unit.action = null } action = { unit.action = null }
) )
} else { } else {
actionList += UnitAction( actionList += UnitAction(
name = "Automate", type = UnitActionType.Automate,
canAct = unit.currentMovement > 0, canAct = unit.currentMovement > 0,
action = { action = {
unit.action = Constants.unitActionAutomation unit.action = Constants.unitActionAutomation
@ -196,10 +201,13 @@ class UnitActions {
&& tile.improvementInProgress != "Road" && tile.improvementInProgress != "Road"
&& tile.isLand && tile.isLand
&& unit.civInfo.tech.isResearched(RoadStatus.Road.improvement(unit.civInfo.gameInfo.ruleSet)!!.techRequired!!)) && unit.civInfo.tech.isResearched(RoadStatus.Road.improvement(unit.civInfo.gameInfo.ruleSet)!!.techRequired!!))
actionList += UnitAction("Construct road", unit.currentMovement > 0) { actionList += UnitAction(
type = UnitActionType.ConstructRoad,
canAct = unit.currentMovement > 0,
action = {
tile.improvementInProgress = "Road" tile.improvementInProgress = "Road"
tile.turnsToImprovement = 4 tile.turnsToImprovement = 4
} })
for (improvement in listOf("Fishing Boats", "Oil well")) { for (improvement in listOf("Fishing Boats", "Oil well")) {
if (unit.hasUnique("May create improvements on water resources") && tile.resource != null if (unit.hasUnique("May create improvements on water resources") && tile.resource != null
@ -209,7 +217,8 @@ class UnitActions {
&& unit.civInfo.tech.isResearched(unit.civInfo.gameInfo.ruleSet.tileImprovements[improvement]!!.techRequired!!) && unit.civInfo.tech.isResearched(unit.civInfo.gameInfo.ruleSet.tileImprovements[improvement]!!.techRequired!!)
) )
actionList += UnitAction( actionList += UnitAction(
name = "Create [$improvement]", type = UnitActionType.Create,
title = "Create [$improvement]",
canAct = unit.currentMovement > 0, canAct = unit.currentMovement > 0,
action = { action = {
tile.improvement = improvement tile.improvement = improvement
@ -220,7 +229,8 @@ class UnitActions {
for (unique in unit.getUniques().filter { it.startsWith("Can build improvement: ") }) { for (unique in unit.getUniques().filter { it.startsWith("Can build improvement: ") }) {
val improvementName = unique.replace("Can build improvement: ", "") val improvementName = unique.replace("Can build improvement: ", "")
actionList += UnitAction( actionList += UnitAction(
name = "Create [$improvementName]", type = UnitActionType.Create,
title = "Create [$improvementName]",
canAct = unit.currentMovement > 0f && !tile.isWater && !tile.isCityCenter() && !tile.getLastTerrain().unbuildable, canAct = unit.currentMovement > 0f && !tile.isWater && !tile.isCityCenter() && !tile.getLastTerrain().unbuildable,
uncivSound = UncivSound.Chimes, uncivSound = UncivSound.Chimes,
action = { action = {
@ -235,7 +245,7 @@ class UnitActions {
if (unit.name == "Great Scientist" && !unit.isEmbarked()) { if (unit.name == "Great Scientist" && !unit.isEmbarked()) {
actionList += UnitAction( actionList += UnitAction(
name = "Hurry Research", type = UnitActionType.HurryResearch,
canAct = unit.civInfo.tech.currentTechnologyName() != null && unit.currentMovement > 0, canAct = unit.civInfo.tech.currentTechnologyName() != null && unit.currentMovement > 0,
uncivSound = UncivSound.Chimes, uncivSound = UncivSound.Chimes,
action = { action = {
@ -246,7 +256,7 @@ class UnitActions {
if (unit.hasUnique("Can start an 8-turn golden age") && !unit.isEmbarked()) { if (unit.hasUnique("Can start an 8-turn golden age") && !unit.isEmbarked()) {
actionList += UnitAction( actionList += UnitAction(
name = "Start Golden Age", type = UnitActionType.StartGoldenAge,
canAct = unit.currentMovement > 0, canAct = unit.currentMovement > 0,
uncivSound = UncivSound.Chimes, uncivSound = UncivSound.Chimes,
action = { action = {
@ -263,7 +273,7 @@ class UnitActions {
else currentConstruction.isWonder || currentConstruction.isNationalWonder else currentConstruction.isWonder || currentConstruction.isNationalWonder
} }
actionList += UnitAction( actionList += UnitAction(
name = "Hurry Wonder", type = UnitActionType.HurryWonder,
canAct = canHurryWonder, canAct = canHurryWonder,
uncivSound = UncivSound.Chimes, uncivSound = UncivSound.Chimes,
action = { action = {
@ -280,7 +290,7 @@ class UnitActions {
&& tile.owningCity?.civInfo?.isAtWarWith(unit.civInfo) == false && tile.owningCity?.civInfo?.isAtWarWith(unit.civInfo) == false
&& unit.currentMovement > 0 && unit.currentMovement > 0
actionList += UnitAction( actionList += UnitAction(
name = "Conduct Trade Mission", type = UnitActionType.ConductTradeMission,
canAct = canConductTradeMission, canAct = canConductTradeMission,
uncivSound = UncivSound.Chimes, uncivSound = UncivSound.Chimes,
action = { action = {
@ -298,7 +308,7 @@ class UnitActions {
} }
actionList += UnitAction( actionList += UnitAction(
name = "Disband unit", type = UnitActionType.DisbandUnit,
canAct = unit.currentMovement > 0, canAct = unit.currentMovement > 0,
action = { action = {
val disbandText = if (unit.currentTile.getOwner() == unit.civInfo) val disbandText = if (unit.currentTile.getOwner() == unit.civInfo)

View File

@ -67,9 +67,9 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
private fun getUnitActionButton(unitAction: UnitAction): Button { private fun getUnitActionButton(unitAction: UnitAction): Button {
val actionButton = Button(CameraStageBaseScreen.skin) val actionButton = Button(CameraStageBaseScreen.skin)
actionButton.add(getIconForUnitAction(unitAction.name)).size(20f).pad(5f) actionButton.add(getIconForUnitAction(unitAction.title)).size(20f).pad(5f)
val fontColor = if(unitAction.isCurrentAction) Color.YELLOW else Color.WHITE val fontColor = if(unitAction.isCurrentAction) Color.YELLOW else Color.WHITE
actionButton.add(unitAction.name.toLabel(fontColor)).pad(5f) actionButton.add(unitAction.title.toLabel(fontColor)).pad(5f)
actionButton.pack() actionButton.pack()
actionButton.onClick(unitAction.uncivSound) { unitAction.action?.invoke(); UncivGame.Current.worldScreen.shouldUpdate=true } actionButton.onClick(unitAction.uncivSound) { unitAction.action?.invoke(); UncivGame.Current.worldScreen.shouldUpdate=true }
if (!unitAction.canAct) actionButton.disable() if (!unitAction.canAct) actionButton.disable()