We no longer "downgrade" tiles from Railroad to Road when we try to build a Road somewhere

Fixed error where if intermediate tiles were full (o e.g. other workers) it would try to "jump" to a tile that was out of its reach
This commit is contained in:
Yair Morgenstern 2019-05-22 22:55:24 +03:00
parent 98803f0454
commit 29647896ce
2 changed files with 18 additions and 15 deletions

View File

@ -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"

View File

@ -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<TileInfo> {
@ -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
}