Added helper function MapUnit.hasMovement()

This commit is contained in:
yairm210 2024-07-25 00:35:43 +03:00
parent 5e10698abc
commit 5d8316abac
25 changed files with 65 additions and 64 deletions

View File

@ -49,7 +49,7 @@ class BarbarianAutomation(val civInfo: Civilization) {
private fun automateCombatUnit(unit: MapUnit) { private fun automateCombatUnit(unit: MapUnit) {
// 1 - Try pillaging to restore health (barbs don't auto-heal) // 1 - Try pillaging to restore health (barbs don't auto-heal)
if (unit.health < 50 && UnitAutomation.tryPillageImprovement(unit, true) && unit.currentMovement == 0f) return if (unit.health < 50 && UnitAutomation.tryPillageImprovement(unit, true) && !unit.hasMovement()) return
// 2 - trying to upgrade // 2 - trying to upgrade
if (UnitAutomation.tryUpgradeUnit(unit)) return if (UnitAutomation.tryUpgradeUnit(unit)) return
@ -61,7 +61,7 @@ class BarbarianAutomation(val civInfo: Civilization) {
// 4 - trying to pillage tile or route // 4 - trying to pillage tile or route
while (UnitAutomation.tryPillageImprovement(unit)) { while (UnitAutomation.tryPillageImprovement(unit)) {
if (unit.currentMovement == 0f) return if (!unit.hasMovement()) return
} }
// 6 - wander // 6 - wander

View File

@ -85,8 +85,7 @@ object AirUnitAutomation {
|| (tile.isCityCenter() && tile.getCity()!!.civ.isAtWarWith(unit.civ)) } || (tile.isCityCenter() && tile.getCity()!!.civ.isAtWarWith(unit.civ)) }
}.minByOrNull { it.aerialDistanceTo(unit.getTile()) } ?: return false }.minByOrNull { it.aerialDistanceTo(unit.getTile()) } ?: return false
AirInterception.airSweep(MapUnitCombatant(unit),targetTile) AirInterception.airSweep(MapUnitCombatant(unit),targetTile)
if (unit.currentMovement > 0) return false return !unit.hasMovement()
return true
} }
fun automateBomber(unit: MapUnit) { fun automateBomber(unit: MapUnit) {

View File

@ -37,7 +37,7 @@ object BattleHelper {
Battle.moveAndAttack(MapUnitCombatant(unit), enemyTileToAttack) Battle.moveAndAttack(MapUnitCombatant(unit), enemyTileToAttack)
} }
} }
return unit.currentMovement == 0f return !unit.hasMovement()
} }
fun tryDisembarkUnitToAttackPosition(unit: MapUnit): Boolean { fun tryDisembarkUnitToAttackPosition(unit: MapUnit): Boolean {

View File

@ -238,9 +238,9 @@ class RoadBetweenCitiesAutomation(val civInfo: Civilization, cachedForTurn: Int,
unit.movement.canMoveTo(it.first) && unit.movement.canReach(it.first) unit.movement.canMoveTo(it.first) && unit.movement.canReach(it.first)
}?.first ?: continue // Apparently we can't reach any of these tiles at all }?.first ?: continue // Apparently we can't reach any of these tiles at all
if (bestTile != currentTile && unit.currentMovement > 0) if (bestTile != currentTile && unit.hasMovement())
unit.movement.headTowards(bestTile) unit.movement.headTowards(bestTile)
if (unit.currentMovement > 0 && bestTile == currentTile if (unit.hasMovement() && bestTile == currentTile
&& currentTile.improvementInProgress != bestRoadAvailable.name) { && currentTile.improvementInProgress != bestRoadAvailable.name) {
val improvement = bestRoadAvailable.improvement(civInfo.gameInfo.ruleset)!! val improvement = bestRoadAvailable.improvement(civInfo.gameInfo.ruleset)!!
bestTile.startWorkingOnImprovement(improvement, civInfo, unit) bestTile.startWorkingOnImprovement(improvement, civInfo, unit)

View File

@ -81,7 +81,7 @@ class RoadToAutomation(val civInfo: Civilization) {
* - It can move to * - It can move to
* - Can be improved/upgraded * - Can be improved/upgraded
* */ * */
if (unit.currentMovement > 0 && !shouldBuildRoadOnTile(currentTile)) { if (unit.hasMovement() && !shouldBuildRoadOnTile(currentTile)) {
if (currTileIndex == pathToDest.size - 1) { // The last tile in the path is unbuildable or has a road. if (currTileIndex == pathToDest.size - 1) { // The last tile in the path is unbuildable or has a road.
stopAndCleanAutomation(unit) stopAndCleanAutomation(unit)
unit.civ.addNotification("Connect road completed!", MapUnitAction(unit), NotificationCategory.Units, unit.name) unit.civ.addNotification("Connect road completed!", MapUnitAction(unit), NotificationCategory.Units, unit.name)
@ -115,7 +115,7 @@ class RoadToAutomation(val civInfo: Civilization) {
} }
// We need to check current movement again after we've (potentially) moved // We need to check current movement again after we've (potentially) moved
if (unit.currentMovement > 0) { if (unit.hasMovement()) {
// Repair pillaged roads first // Repair pillaged roads first
if (currentTile.roadStatus != RoadStatus.None && currentTile.roadIsPillaged){ if (currentTile.roadStatus != RoadStatus.None && currentTile.roadIsPillaged){
currentTile.setRepaired() currentTile.setRepaired()

View File

@ -57,7 +57,7 @@ object SpecificUnitAutomation {
// 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.hasMovement() && unit.currentTile == tileToSteal)
UnitActionsFromUniques.getImprovementConstructionActionsFromGeneralUnique(unit, unit.currentTile).firstOrNull()?.action?.invoke() UnitActionsFromUniques.getImprovementConstructionActionsFromGeneralUnique(unit, unit.currentTile).firstOrNull()?.action?.invoke()
return true return true
} }
@ -97,7 +97,7 @@ object SpecificUnitAutomation {
return return
} }
unit.movement.headTowards(tileForCitadel) unit.movement.headTowards(tileForCitadel)
if (unit.currentMovement > 0 && unit.currentTile == tileForCitadel) if (unit.hasMovement() && unit.currentTile == tileForCitadel)
UnitActionsFromUniques.getImprovementConstructionActionsFromGeneralUnique(unit, unit.currentTile) UnitActionsFromUniques.getImprovementConstructionActionsFromGeneralUnique(unit, unit.currentTile)
.firstOrNull()?.action?.invoke() .firstOrNull()?.action?.invoke()
} }
@ -118,7 +118,7 @@ object SpecificUnitAutomation {
if (unit.civ.gameInfo.turns == 0 && unit.civ.cities.isEmpty() && bestTilesInfo.tileRankMap.containsKey(unit.getTile())) { // Special case, we want AI to settle in place on turn 1. if (unit.civ.gameInfo.turns == 0 && unit.civ.cities.isEmpty() && bestTilesInfo.tileRankMap.containsKey(unit.getTile())) { // Special case, we want AI to settle in place on turn 1.
val foundCityAction = UnitActionsFromUniques.getFoundCityAction(unit, unit.getTile()) val foundCityAction = UnitActionsFromUniques.getFoundCityAction(unit, unit.getTile())
// Depending on era and difficulty we might start with more than one settler. In that case settle the one with the best location // Depending on era and difficulty we might start with more than one settler. In that case settle the one with the best location
val allUnsettledSettlers = unit.civ.units.getCivUnits().filter { it.currentMovement > 0 && it.baseUnit == unit.baseUnit } val allUnsettledSettlers = unit.civ.units.getCivUnits().filter { it.hasMovement() && it.baseUnit == unit.baseUnit }
// Don't settle immediately if we only have one settler, look for a better location // Don't settle immediately if we only have one settler, look for a better location
val bestSettlerInRange = allUnsettledSettlers.maxByOrNull { val bestSettlerInRange = allUnsettledSettlers.maxByOrNull {
@ -186,13 +186,13 @@ object SpecificUnitAutomation {
val foundCityAction = UnitActionsFromUniques.getFoundCityAction(unit, bestCityLocation) val foundCityAction = UnitActionsFromUniques.getFoundCityAction(unit, bestCityLocation)
if (foundCityAction?.action == null) { // this means either currentMove == 0 or city within 3 tiles if (foundCityAction?.action == null) { // this means either currentMove == 0 or city within 3 tiles
if (unit.currentMovement > 0 && !unit.civ.isOneCityChallenger()) // therefore, city within 3 tiles if (unit.hasMovement() && !unit.civ.isOneCityChallenger()) // therefore, city within 3 tiles
throw Exception("City within distance") throw Exception("City within distance")
return return
} }
unit.movement.headTowards(bestCityLocation) unit.movement.headTowards(bestCityLocation)
if (unit.getTile() == bestCityLocation && unit.currentMovement > 0) if (unit.getTile() == bestCityLocation && unit.hasMovement())
foundCityAction.action.invoke() foundCityAction.action.invoke()
} }

View File

@ -41,7 +41,7 @@ object UnitAutomation {
} }
internal fun tryExplore(unit: MapUnit): Boolean { internal fun tryExplore(unit: MapUnit): Boolean {
if (tryGoToRuinAndEncampment(unit) && (unit.currentMovement == 0f || unit.isDestroyed)) return true if (tryGoToRuinAndEncampment(unit) && (!unit.hasMovement() || unit.isDestroyed)) return true
val explorableTilesThisTurn = val explorableTilesThisTurn =
unit.movement.getDistanceToTiles().keys.filter { isGoodTileToExplore(unit, it) } unit.movement.getDistanceToTiles().keys.filter { isGoodTileToExplore(unit, it) }
@ -216,7 +216,7 @@ object UnitAutomation {
// Accompany settlers // Accompany settlers
if (tryAccompanySettlerOrGreatPerson(unit)) return if (tryAccompanySettlerOrGreatPerson(unit)) return
if (tryGoToRuinAndEncampment(unit) && unit.currentMovement == 0f) return if (tryGoToRuinAndEncampment(unit) && !unit.hasMovement()) return
if (tryUpgradeUnit(unit)) return if (tryUpgradeUnit(unit)) return
@ -350,7 +350,7 @@ object UnitAutomation {
// Try pillage improvements until healed // Try pillage improvements until healed
while(tryPillageImprovement(unit, false)) { while(tryPillageImprovement(unit, false)) {
// If we are fully healed and can still do things, lets keep on going by returning false // If we are fully healed and can still do things, lets keep on going by returning false
if (unit.currentMovement == 0f || unit.health == 100) return unit.currentMovement == 0f if (!unit.hasMovement() || unit.health == 100) return !unit.hasMovement()
} }
val unitDistanceToTiles = unit.movement.getDistanceToTiles() val unitDistanceToTiles = unit.movement.getDistanceToTiles()
@ -566,7 +566,7 @@ object UnitAutomation {
if (reachableTileNearSiegedCity != null) { if (reachableTileNearSiegedCity != null) {
unit.movement.headTowards(reachableTileNearSiegedCity) unit.movement.headTowards(reachableTileNearSiegedCity)
} }
return unit.currentMovement == 0f return !unit.hasMovement()
} }
@ -714,7 +714,7 @@ object UnitAutomation {
/** This is what a unit with the 'explore' action does. /** This is what a unit with the 'explore' action does.
It also explores, but also has other functions, like healing if necessary. */ It also explores, but also has other functions, like healing if necessary. */
fun automatedExplore(unit: MapUnit) { fun automatedExplore(unit: MapUnit) {
if (tryGoToRuinAndEncampment(unit) && (unit.currentMovement == 0f || unit.isDestroyed)) return if (tryGoToRuinAndEncampment(unit) && (!unit.hasMovement() || unit.isDestroyed)) return
if (unit.health < 80 && tryHealUnit(unit)) return if (unit.health < 80 && tryHealUnit(unit)) return
if (tryExplore(unit)) return if (tryExplore(unit)) return
unit.civ.addNotification("${unit.shortDisplayName()} finished exploring.", MapUnitAction(unit), NotificationCategory.Units, unit.name, "OtherIcons/Sleep") unit.civ.addNotification("${unit.shortDisplayName()} finished exploring.", MapUnitAction(unit), NotificationCategory.Units, unit.name, "OtherIcons/Sleep")

View File

@ -101,7 +101,7 @@ class WorkerAutomation(
// If there's move still left, perform action // If there's move still left, perform action
// Unit may stop due to Enemy Unit within walking range during doAction() call // Unit may stop due to Enemy Unit within walking range during doAction() call
if (unit.currentMovement > 0 && reachedTile == tileToWork) { if (unit.hasMovement() && reachedTile == tileToWork) {
if (reachedTile.isPillaged()) { if (reachedTile.isPillaged()) {
debug("WorkerAutomation: $unit -> repairs $reachedTile") debug("WorkerAutomation: $unit -> repairs $reachedTile")
UnitActionsFromUniques.getRepairAction(unit)?.action?.invoke() UnitActionsFromUniques.getRepairAction(unit)?.action?.invoke()

View File

@ -71,7 +71,7 @@ object Battle {
* so we expended all of our movement points! */ * so we expended all of our movement points! */
if (attacker.hasUnique(UniqueType.MustSetUp) if (attacker.hasUnique(UniqueType.MustSetUp)
&& !attacker.unit.isSetUpForSiege() && !attacker.unit.isSetUpForSiege()
&& attacker.unit.currentMovement > 0f && attacker.unit.hasMovement()
) { ) {
attacker.unit.action = UnitActionType.SetUp.value attacker.unit.action = UnitActionType.SetUp.value
attacker.unit.useMovementPoints(1f) attacker.unit.useMovementPoints(1f)
@ -89,7 +89,7 @@ object Battle {
} }
} }
} }
return (attacker.unit.currentMovement > 0f) return (attacker.unit.hasMovement())
} }
/** /**

View File

@ -245,11 +245,11 @@ class MapUnit : IsPartOfGameInfoSerialization {
fun isSetUpForSiege() = action == UnitActionType.SetUp.value fun isSetUpForSiege() = action == UnitActionType.SetUp.value
/** /**
* @param includeOtherEscortUnit determines whether or not this method will also check if it's other escort unit is idle if it has one * @param includeOtherEscortUnit determines whether this method will also check if it's other escort unit is idle if it has one
* Leave it as default unless you know what [isIdle] does. * Leave it as default unless you know what [isIdle] does.
*/ */
fun isIdle(includeOtherEscortUnit: Boolean = true): Boolean { fun isIdle(includeOtherEscortUnit: Boolean = true): Boolean {
if (currentMovement == 0f) return false if (!hasMovement()) return false
val tile = getTile() val tile = getTile()
if (tile.improvementInProgress != null && if (tile.improvementInProgress != null &&
canBuildImprovement(tile.getTileImprovementInProgress()!!) && canBuildImprovement(tile.getTileImprovementInProgress()!!) &&
@ -309,6 +309,8 @@ class MapUnit : IsPartOfGameInfoSerialization {
return false return false
} }
fun hasMovement() = currentMovement > 0
fun getMaxMovement(ignoreOtherUnit: Boolean = false): Int { fun getMaxMovement(ignoreOtherUnit: Boolean = false): Int {
var movement = var movement =
if (isEmbarked()) 2 if (isEmbarked()) 2
@ -364,7 +366,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
} }
fun canAttack(): Boolean { fun canAttack(): Boolean {
if (currentMovement == 0f) return false if (!hasMovement()) return false
if (isCivilian()) return false if (isCivilian()) return false
return attacksThisTurn < maxAttacksPerTurn() return attacksThisTurn < maxAttacksPerTurn()
} }
@ -483,7 +485,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
fun canIntercept(): Boolean { fun canIntercept(): Boolean {
if (interceptChance() == 0) return false if (interceptChance() == 0) return false
// Air Units can only Intercept if they didn't move this turn // Air Units can only Intercept if they didn't move this turn
if (baseUnit.isAirUnit() && currentMovement == 0f) return false if (baseUnit.isAirUnit() && !hasMovement()) return false
val maxAttacksPerTurn = 1 + val maxAttacksPerTurn = 1 +
getMatchingUniques(UniqueType.ExtraInterceptionsPerTurn) getMatchingUniques(UniqueType.ExtraInterceptionsPerTurn)
.sumOf { it.params[0].toInt() } .sumOf { it.params[0].toInt() }
@ -727,8 +729,8 @@ class MapUnit : IsPartOfGameInfoSerialization {
fun doAction() { fun doAction() {
if (action == null && !isAutomated()) return if (action == null && !isAutomated()) return
if (currentMovement == 0f) return // We've already done stuff this turn, and can't do any more stuff if (!hasMovement()) return // We've already done stuff this turn, and can't do any more stuff
if (isEscorting() && getOtherEscortUnit()!!.currentMovement == 0f) return if (isEscorting() && !getOtherEscortUnit()!!.hasMovement()) return
val enemyUnitsInWalkingDistance = movement.getDistanceToTiles().keys val enemyUnitsInWalkingDistance = movement.getDistanceToTiles().keys
.filter { it.militaryUnit != null && civ.isAtWarWith(it.militaryUnit!!.civ) } .filter { it.militaryUnit != null && civ.isAtWarWith(it.militaryUnit!!.civ) }
@ -755,7 +757,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
return return
} }
if (gotTo.position == destinationTile.position) action = null if (gotTo.position == destinationTile.position) action = null
if (currentMovement > 0) doAction() if (hasMovement()) doAction()
return return
} }

View File

@ -15,7 +15,7 @@ class UnitTurnManager(val unit: MapUnit) {
for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponTurnEnd)) for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponTurnEnd))
UniqueTriggerActivation.triggerUnique(unique, unit) UniqueTriggerActivation.triggerUnique(unique, unit)
if (unit.currentMovement > 0 if (unit.hasMovement()
&& unit.getTile().improvementInProgress != null && unit.getTile().improvementInProgress != null
&& unit.canBuildImprovement(unit.getTile().getTileImprovementInProgress()!!) && unit.canBuildImprovement(unit.getTile().getTileImprovementInProgress()!!)
) { ) {

View File

@ -543,7 +543,7 @@ class CityButton(val city: City, private val tileGroup: TileGroup) : Table(BaseS
enterCityOrInfoPopup() enterCityOrInfoPopup()
} else { } else {
moveButtonDown() moveButtonDown()
if ((unitTable.selectedUnit == null || unitTable.selectedUnit!!.currentMovement == 0f) && belongsToViewingCiv()) if ((unitTable.selectedUnit == null || !unitTable.selectedUnit!!.hasMovement()) && belongsToViewingCiv())
unitTable.citySelected(city) unitTable.citySelected(city)
} }
} }

View File

@ -72,7 +72,7 @@ class TileLayerUnitFlag(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup
newIcon.actionGroup?.color?.a = 0.5f newIcon.actionGroup?.color?.a = 0.5f
// Fade out flag for own out-of-moves units // Fade out flag for own out-of-moves units
if (unit.civ == viewingCiv && unit.currentMovement == 0f) if (unit.civ == viewingCiv && !unit.hasMovement())
newIcon.color.a = 0.5f * UncivGame.Current.settings.unitIconOpacity newIcon.color.a = 0.5f * UncivGame.Current.settings.unitIconOpacity
} }

View File

@ -210,7 +210,7 @@ class UnitIconGroup(val unit: MapUnit, val size: Float) : Group() {
// Unit base icon is faded out only if out of moves // Unit base icon is faded out only if out of moves
// Foreign unit icons are never faded! // Foreign unit icons are never faded!
val shouldBeFaded = (unit.owner == GUI.getSelectedPlayer().civName val shouldBeFaded = (unit.owner == GUI.getSelectedPlayer().civName
&& unit.currentMovement == 0f && GUI.getSettings().unitIconOpacity == 1f) && !unit.hasMovement() && GUI.getSettings().unitIconOpacity == 1f)
val alpha = if (shouldBeFaded) opacity * 0.5f else opacity val alpha = if (shouldBeFaded) opacity * 0.5f else opacity
flagIcon.color.a = alpha flagIcon.color.a = alpha
flagBg.color.a = alpha flagBg.color.a = alpha

View File

@ -49,7 +49,7 @@ class UnitUpgradeMenu(
unit.civ.units.getCivUnits() unit.civ.units.getCivUnits()
.filter { .filter {
it.baseUnit.name == unit.baseUnit.name it.baseUnit.name == unit.baseUnit.name
&& it.currentMovement > 0f && it.hasMovement()
&& it.currentTile.getOwner() == unit.civ && it.currentTile.getOwner() == unit.civ
&& !it.isEmbarked() && !it.isEmbarked()
&& it.upgrade.canUpgrade(unitToUpgradeTo, ignoreResources = true) && it.upgrade.canUpgrade(unitToUpgradeTo, ignoreResources = true)

View File

@ -46,7 +46,7 @@ open class UnitOverviewTabHelpers {
private fun getWorkerActionText(unit: MapUnit): String? = when { private fun getWorkerActionText(unit: MapUnit): String? = when {
// See UnitTurnManager.endTurn, if..workOnImprovement or UnitGroup.getActionImage: similar logic // See UnitTurnManager.endTurn, if..workOnImprovement or UnitGroup.getActionImage: similar logic
!unit.cache.hasUniqueToBuildImprovements -> null !unit.cache.hasUniqueToBuildImprovements -> null
unit.currentMovement == 0f -> null !unit.hasMovement() -> null
unit.currentTile.improvementInProgress == null -> null unit.currentTile.improvementInProgress == null -> null
!unit.canBuildImprovement(unit.getTile().getTileImprovementInProgress()!!) -> null !unit.canBuildImprovement(unit.getTile().getTileImprovementInProgress()!!) -> null
else -> unit.currentTile.improvementInProgress else -> unit.currentTile.improvementInProgress
@ -142,7 +142,7 @@ open class UnitOverviewTabHelpers {
if (!showPromoteStar) return if (!showPromoteStar) return
table.add( table.add(
ImageGetter.getImage("OtherIcons/Star").apply { ImageGetter.getImage("OtherIcons/Star").apply {
color = if (canEnable && unit.currentMovement > 0f && unit.attacksThisTurn == 0) color = if (canEnable && unit.hasMovement() && unit.attacksThisTurn == 0)
Color.GOLDENROD Color.GOLDENROD
else Color.GOLDENROD.darken(0.25f) else Color.GOLDENROD.darken(0.25f)
} }

View File

@ -59,7 +59,7 @@ class PromotionPickerScreen private constructor(
private val canChangeState = GUI.isAllowedChangeState() private val canChangeState = GUI.isAllowedChangeState()
private val canPromoteNow = canChangeState && private val canPromoteNow = canChangeState &&
unit.promotions.canBePromoted() && unit.promotions.canBePromoted() &&
unit.currentMovement > 0 && unit.attacksThisTurn == 0 unit.hasMovement() && unit.attacksThisTurn == 0
// Logic // Logic
private val tree = PromotionTree(unit) private val tree = PromotionTree(unit)

View File

@ -242,7 +242,7 @@ object UnitActions {
worldScreen.switchToNextUnit() worldScreen.switchToNextUnit()
}.open() }.open()
} }
}.takeIf { unit.currentMovement > 0 } }.takeIf { unit.hasMovement() }
)) ))
} }
@ -253,7 +253,7 @@ object UnitActions {
useFrequency = 150f, // We want to show the player that they can promote useFrequency = 150f, // We want to show the player that they can promote
action = { action = {
UncivGame.Current.pushScreen(PromotionPickerScreen(unit)) UncivGame.Current.pushScreen(PromotionPickerScreen(unit))
}.takeIf { unit.currentMovement > 0 && unit.attacksThisTurn == 0 } }.takeIf { unit.hasMovement() && unit.attacksThisTurn == 0 }
)) ))
} }
@ -262,7 +262,7 @@ object UnitActions {
if (unit.isExploring()) return if (unit.isExploring()) return
yield(UnitAction(UnitActionType.Explore, 5f) { yield(UnitAction(UnitActionType.Explore, 5f) {
unit.action = UnitActionType.Explore.value unit.action = UnitActionType.Explore.value
if (unit.currentMovement > 0) UnitAutomation.automatedExplore(unit) if (unit.hasMovement()) UnitAutomation.automatedExplore(unit)
}) })
} }
@ -279,7 +279,7 @@ object UnitActions {
return return
} }
if (!unit.canFortify() || unit.currentMovement == 0f) return if (!unit.canFortify() || !unit.hasMovement()) return
yield(UnitAction(UnitActionType.Fortify, yield(UnitAction(UnitActionType.Fortify,
action = { unit.fortify() }.takeIf { !unit.isFortified() || unit.isFortifyingUntilHealed() }, action = { unit.fortify() }.takeIf { !unit.isFortified() || unit.isFortifyingUntilHealed() },
@ -295,7 +295,7 @@ object UnitActions {
} }
private suspend fun SequenceScope<UnitAction>.addSleepActions(unit: MapUnit, tile: Tile) { private suspend fun SequenceScope<UnitAction>.addSleepActions(unit: MapUnit, tile: Tile) {
if (unit.isFortified() || unit.canFortify() || unit.currentMovement == 0f) return if (unit.isFortified() || unit.canFortify() || !unit.hasMovement()) return
if (tile.hasImprovementInProgress() && unit.canBuildImprovement(tile.getTileImprovementInProgress()!!)) return if (tile.hasImprovementInProgress() && unit.canBuildImprovement(tile.getTileImprovementInProgress()!!)) return
yield(UnitAction(UnitActionType.Sleep, yield(UnitAction(UnitActionType.Sleep,
@ -333,7 +333,7 @@ object UnitActions {
// Transported units can't be gifted // Transported units can't be gifted
if (unit.isTransported) return@sequence if (unit.isTransported) return@sequence
if (unit.currentMovement <= 0) { if (!unit.hasMovement()) {
yield(UnitAction(UnitActionType.GiftUnit, 1f, action = null)) yield(UnitAction(UnitActionType.GiftUnit, 1f, action = null))
return@sequence return@sequence
} }
@ -372,7 +372,7 @@ object UnitActions {
action = { action = {
unit.automated = true unit.automated = true
UnitAutomation.automateUnitMoves(unit) UnitAutomation.automateUnitMoves(unit)
}.takeIf { unit.currentMovement > 0 } }.takeIf { unit.hasMovement() }
)) ))
} }

View File

@ -46,7 +46,7 @@ object UnitActionsFromUniques {
// Spain should still be able to build Conquistadors in a one city challenge - but can't settle them // Spain should still be able to build Conquistadors in a one city challenge - but can't settle them
if (unit.civ.isOneCityChallenger() && unit.civ.hasEverOwnedOriginalCapital) return null if (unit.civ.isOneCityChallenger() && unit.civ.hasEverOwnedOriginalCapital) return null
if (unit.currentMovement <= 0 || !tile.canBeSettled()) if (!unit.hasMovement() || !tile.canBeSettled())
return UnitAction(UnitActionType.FoundCity, 80f, action = null) return UnitAction(UnitActionType.FoundCity, 80f, action = null)
val hasActionModifiers = unique.conditionals.any { it.type?.targetTypes?.contains( val hasActionModifiers = unique.conditionals.any { it.type?.targetTypes?.contains(
@ -126,7 +126,7 @@ object UnitActionsFromUniques {
action = { action = {
unit.action = UnitActionType.SetUp.value unit.action = UnitActionType.SetUp.value
unit.useMovementPoints(1f) unit.useMovementPoints(1f)
}.takeIf { unit.currentMovement > 0 && !isSetUp }) }.takeIf { unit.hasMovement() && !isSetUp })
) )
} }
@ -204,7 +204,7 @@ object UnitActionsFromUniques {
val title = UnitActionModifiers.actionTextWithSideEffects(baseTitle, unique, unit) val title = UnitActionModifiers.actionTextWithSideEffects(baseTitle, unique, unit)
val unitAction = fun (): (()->Unit)? { val unitAction = fun (): (()->Unit)? {
if (unit.currentMovement == 0f) return null if (!unit.hasMovement()) return null
val triggerFunction = UniqueTriggerActivation.getTriggerFunction(unique, unit.civ, unit = unit, tile = unit.currentTile) val triggerFunction = UniqueTriggerActivation.getTriggerFunction(unique, unit.civ, unit = unit, tile = unit.currentTile)
?: return null ?: return null
return { // This is the *action* that will be triggered! return { // This is the *action* that will be triggered!
@ -256,7 +256,7 @@ object UnitActionsFromUniques {
action = { action = {
tile.setImprovement(improvementName, unit.civ, unit) tile.setImprovement(improvementName, unit.civ, unit)
unit.destroy() // Modders may wish for a nondestructive way, but that should be another Unique unit.destroy() // Modders may wish for a nondestructive way, but that should be another Unique
}.takeIf { unit.currentMovement > 0 }) }.takeIf { unit.hasMovement() })
} }
// Not internal: Used in SpecificUnitAutomation // Not internal: Used in SpecificUnitAutomation
@ -294,7 +294,7 @@ object UnitActionsFromUniques {
UnitActionModifiers.activateSideEffects(unit, unique) UnitActionModifiers.activateSideEffects(unit, unique)
}.takeIf { }.takeIf {
resourcesAvailable resourcesAvailable
&& unit.currentMovement > 0f && unit.hasMovement()
&& tile.improvementFunctions.canBuildImprovement(improvement, unit.civ) && tile.improvementFunctions.canBuildImprovement(improvement, unit.civ)
// Next test is to prevent interfering with UniqueType.CreatesOneImprovement - // Next test is to prevent interfering with UniqueType.CreatesOneImprovement -
// not pretty, but users *can* remove the building from the city queue an thus clear this: // not pretty, but users *can* remove the building from the city queue an thus clear this:
@ -401,7 +401,7 @@ object UnitActionsFromUniques {
internal fun getBuildingImprovementsActions(unit: MapUnit, tile: Tile): Sequence<UnitAction> { internal fun getBuildingImprovementsActions(unit: MapUnit, tile: Tile): Sequence<UnitAction> {
if (!unit.cache.hasUniqueToBuildImprovements) return emptySequence() if (!unit.cache.hasUniqueToBuildImprovements) return emptySequence()
val couldConstruct = unit.currentMovement > 0 val couldConstruct = unit.hasMovement()
&& !tile.isCityCenter() && !tile.isCityCenter()
&& unit.civ.gameInfo.ruleset.tileImprovements.values.any { && unit.civ.gameInfo.ruleset.tileImprovements.values.any {
ImprovementPickerScreen.canReport( ImprovementPickerScreen.canReport(
@ -447,7 +447,7 @@ object UnitActionsFromUniques {
if (tile.isCityCenter()) return null if (tile.isCityCenter()) return null
if (!tile.isPillaged()) return null if (!tile.isPillaged()) return null
val couldConstruct = unit.currentMovement > 0 val couldConstruct = unit.hasMovement()
&& !tile.isCityCenter() && tile.improvementInProgress != Constants.repair && !tile.isCityCenter() && tile.improvementInProgress != Constants.repair
&& !tile.isEnemyTerritory(unit.civ) && !tile.isEnemyTerritory(unit.civ)

View File

@ -22,7 +22,7 @@ object UnitActionsGreatPerson {
unit.civ.tech.addScience(unit.civ.tech.getScienceFromGreatScientist()) unit.civ.tech.addScience(unit.civ.tech.getScienceFromGreatScientist())
unit.consume() unit.consume()
}.takeIf { }.takeIf {
unit.currentMovement > 0 unit.hasMovement()
&& unit.civ.tech.currentTechnologyName() != null && unit.civ.tech.currentTechnologyName() != null
&& !unit.civ.tech.currentTechnology()!!.hasUnique(UniqueType.CannotBeHurried) && !unit.civ.tech.currentTechnology()!!.hasUnique(UniqueType.CannotBeHurried)
} }
@ -37,7 +37,7 @@ object UnitActionsGreatPerson {
action = { action = {
unit.civ.policies.addCulture(unit.civ.policies.getCultureFromGreatWriter()) unit.civ.policies.addCulture(unit.civ.policies.getCultureFromGreatWriter())
unit.consume() unit.consume()
}.takeIf {unit.currentMovement > 0} }.takeIf {unit.hasMovement()}
)) ))
} }
} }
@ -59,7 +59,7 @@ object UnitActionsGreatPerson {
} }
unit.consume() unit.consume()
}.takeIf { unit.currentMovement > 0 && canHurryWonder } }.takeIf { unit.hasMovement() && canHurryWonder }
)) ))
} }
} }
@ -92,7 +92,7 @@ object UnitActionsGreatPerson {
} }
unit.consume() unit.consume()
}.takeIf { unit.currentMovement > 0 && canHurryConstruction } }.takeIf { unit.hasMovement() && canHurryConstruction }
)) ))
} }
} }
@ -118,7 +118,7 @@ object UnitActionsGreatPerson {
unit.civ.addNotification("Your trade mission to [$tileOwningCiv] has earned you [$goldEarned] gold and [$influenceEarned] influence!", unit.civ.addNotification("Your trade mission to [$tileOwningCiv] has earned you [$goldEarned] gold and [$influenceEarned] influence!",
NotificationCategory.General, tileOwningCiv.civName, NotificationIcon.Gold, NotificationIcon.Culture) NotificationCategory.General, tileOwningCiv.civName, NotificationIcon.Gold, NotificationIcon.Culture)
unit.consume() unit.consume()
}.takeIf { unit.currentMovement > 0 && canConductTradeMission } }.takeIf { unit.hasMovement() && canConductTradeMission }
)) ))
} }
} }

View File

@ -65,7 +65,7 @@ object UnitActionsPillage {
if (pillagingImprovement) // only Improvements heal HP if (pillagingImprovement) // only Improvements heal HP
unit.healBy(25) unit.healBy(25)
}.takeIf { unit.currentMovement > 0 && canPillage(unit, tile) } }.takeIf { unit.hasMovement() && canPillage(unit, tile) }
) )
} }

View File

@ -179,7 +179,7 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table() {
// overlay, since the user definitely wants to interact with the new unit. // overlay, since the user definitely wants to interact with the new unit.
worldScreen.mapHolder.removeUnitActionOverlay() worldScreen.mapHolder.removeUnitActionOverlay()
if (!UncivGame.Current.settings.autoUnitCycle) return if (!UncivGame.Current.settings.autoUnitCycle) return
if (unit.isDestroyed || unitAction.type.isSkippingToNextUnit && (unit.isMoving() && unit.currentMovement == 0f || !unit.isMoving())) if (unit.isDestroyed || unitAction.type.isSkippingToNextUnit && (unit.isMoving() && !unit.hasMovement() || !unit.isMoving()))
worldScreen.switchToNextUnit() worldScreen.switchToNextUnit()
} }
} }

View File

@ -64,7 +64,7 @@ object UnitActionsUpgrade {
}.takeIf { }.takeIf {
isFree || ( isFree || (
unit.civ.gold >= goldCostOfUpgrade unit.civ.gold >= goldCostOfUpgrade
&& unit.currentMovement > 0 && unit.hasMovement()
&& unitTile.getOwner() == civInfo && unitTile.getOwner() == civInfo
&& !unit.isEmbarked() && !unit.isEmbarked()
&& unit.upgrade.canUpgrade(unitToUpgradeTo = upgradedUnit) && unit.upgrade.canUpgrade(unitToUpgradeTo = upgradedUnit)

View File

@ -63,7 +63,7 @@ class MoveHereOverlayButtonData(val unitToTurnsToDestination: HashMap<MapUnit, I
unitIcon.y = buttonSize - unitIcon.height unitIcon.y = buttonSize - unitIcon.height
moveHereButton.addActor(unitIcon) moveHereButton.addActor(unitIcon)
val unitsThatCanMove = unitToTurnsToDestination.keys.filter { it.currentMovement > 0 } val unitsThatCanMove = unitToTurnsToDestination.keys.filter { it.hasMovement() }
if (unitsThatCanMove.isEmpty()) moveHereButton.color.a = 0.5f if (unitsThatCanMove.isEmpty()) moveHereButton.color.a = 0.5f
else { else {
moveHereButton.onActivation(UncivSound.Silent) { moveHereButton.onActivation(UncivSound.Silent) {

View File

@ -305,7 +305,7 @@ class WorldMapHolder(
if (selectedUnit.currentTile != targetTile) if (selectedUnit.currentTile != targetTile)
selectedUnit.action = selectedUnit.action =
"moveTo ${targetTile.position.x.toInt()},${targetTile.position.y.toInt()}" "moveTo ${targetTile.position.x.toInt()},${targetTile.position.y.toInt()}"
if (selectedUnit.currentMovement > 0) worldScreen.bottomUnitTable.selectUnit(selectedUnit) if (selectedUnit.hasMovement()) worldScreen.bottomUnitTable.selectUnit(selectedUnit)
worldScreen.shouldUpdate = true worldScreen.shouldUpdate = true
@ -320,7 +320,7 @@ class WorldMapHolder(
moveUnitToTargetTile(selectedUnits.subList(1, selectedUnits.size), targetTile) moveUnitToTargetTile(selectedUnits.subList(1, selectedUnits.size), targetTile)
} else removeUnitActionOverlay() //we're done here } else removeUnitActionOverlay() //we're done here
if (UncivGame.Current.settings.autoUnitCycle && selectedUnit.currentMovement == 0f) if (UncivGame.Current.settings.autoUnitCycle && selected!unit.hasMovement())
worldScreen.switchToNextUnit() worldScreen.switchToNextUnit()
} catch (ex: Exception) { } catch (ex: Exception) {
@ -378,7 +378,7 @@ class WorldMapHolder(
// Play something like a swish-swoosh // Play something like a swish-swoosh
SoundPlayer.play(UncivSound.Swap) SoundPlayer.play(UncivSound.Swap)
if (selectedUnit.currentMovement > 0) worldScreen.bottomUnitTable.selectUnit(selectedUnit) if (selectedunit.hasMovement()) worldScreen.bottomUnitTable.selectUnit(selectedUnit)
worldScreen.shouldUpdate = true worldScreen.shouldUpdate = true
removeUnitActionOverlay() removeUnitActionOverlay()
@ -500,7 +500,7 @@ class WorldMapHolder(
for (unit in unitList) { for (unit in unitList) {
val unitIconGroup = UnitIconGroup(unit, 48f).surroundWithCircle(68f, resizeActor = false) val unitIconGroup = UnitIconGroup(unit, 48f).surroundWithCircle(68f, resizeActor = false)
unitIconGroup.circle.color = Color.GRAY.cpy().apply { a = 0.5f } unitIconGroup.circle.color = Color.GRAY.cpy().apply { a = 0.5f }
if (unit.currentMovement == 0f) unitIconGroup.color.a = 0.66f if (!unit.hasMovement()) unitIconGroup.color.a = 0.66f
val clickableCircle = ClickableCircle(68f) val clickableCircle = ClickableCircle(68f)
clickableCircle.touchable = Touchable.enabled clickableCircle.touchable = Touchable.enabled
clickableCircle.onClick { clickableCircle.onClick {