diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index 2ad3794cab..3c673f8e52 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -177,7 +177,8 @@ class MapUnit { } /** - * Designates whether we can walk to the tile - without attacking + * Designates whether we can enter the tile - without attacking + * DOES NOT designate whether we can reach that tile in the current turn */ fun canMoveTo(tile: TileInfo): Boolean { if(!canPassThrough(tile)) return false @@ -380,9 +381,6 @@ class MapUnit { } } - /** - * @return The tile that we reached this turn - */ fun moveToTile(otherTile: TileInfo) { if(otherTile==getTile()) return // already here! val distanceToTiles = getDistanceToTiles() @@ -394,7 +392,8 @@ class MapUnit { class CantEnterThisTileException(msg: String) : Exception(msg) if(!canMoveTo(otherTile)) throw CantEnterThisTileException("$this can't enter $otherTile") - if(otherTile.isCityCenter() && otherTile.getOwner()!=civInfo) throw Exception("This is an enemy city, you can't go here!") + if(otherTile.isCityCenter() && otherTile.getOwner()!=civInfo) + throw Exception("This is an enemy city, you can't go here!") currentMovement -= distanceToTiles[otherTile]!! if (currentMovement < 0.1) currentMovement = 0f // silly floats which are "almost zero" diff --git a/core/src/com/unciv/logic/map/action/BuildLongRoadAction.kt b/core/src/com/unciv/logic/map/action/BuildLongRoadAction.kt index f22370f567..43d7a06cf4 100644 --- a/core/src/com/unciv/logic/map/action/BuildLongRoadAction.kt +++ b/core/src/com/unciv/logic/map/action/BuildLongRoadAction.kt @@ -20,9 +20,10 @@ class BuildLongRoadAction( // we're working! if (unit.currentTile.improvementInProgress != null) return - else if (startWorking()) { + + if (startWorkingOnRoad()) return - } + // we reached our target? And road is finished? if (unit.currentTile.position == target.position @@ -33,7 +34,7 @@ class BuildLongRoadAction( // move one step forward - and start building if (stepForward(target)) { - startWorking() + startWorkingOnRoad() } else if (unit.currentMovement > 1f) { unit.action = null return @@ -45,21 +46,24 @@ class BuildLongRoadAction( // independent of movement costs, but should respect impassable terrain like water and enemy territory private fun stepForward(destination: TileInfo): Boolean { var success = false + val tilesUnitCanCurrentlyReach = unit.getDistanceToTiles().keys for (step in getPath(destination).drop(1)) { + if(step !in tilesUnitCanCurrentlyReach) return false // we're out of tiles in reachable distance, no need to check any further + if (unit.currentMovement > 0f && unit.canMoveTo(step)) { unit.moveToTile(step) success = true - // if there is a road already, take multiple steps, otherwise break - if (!isRoadFinished(step)) { - break - } + + // if there is a road already, take multiple steps, otherwise this is where we're going to build a road + if (!isRoadFinished(step)) return true + } else break } return success } private fun isRoadFinished(tile: TileInfo): Boolean { - return tile.roadStatus == unit.civInfo.tech.getBestRoadAvailable() + return tile.roadStatus >= unit.civInfo.tech.getBestRoadAvailable() } private fun getPath(destination: TileInfo): List { @@ -71,12 +75,12 @@ class BuildLongRoadAction( private fun isRoadableTile(it: TileInfo) = it.isLand && unit.canPassThrough(it) - private fun startWorking(): Boolean { + private fun startWorkingOnRoad(): Boolean { val tile = unit.currentTile if (unit.currentMovement > 0 && isRoadableTile(tile)) { val roadToBuild = unit.civInfo.tech.getBestRoadAvailable() roadToBuild.improvement()?.let { improvement -> - if (tile.roadStatus != roadToBuild && tile.improvementInProgress != improvement.name) { + if (tile.roadStatus < roadToBuild && tile.improvementInProgress != improvement.name) { tile.startWorkingOnImprovement(improvement, unit.civInfo) return true }