Resolved #409 - rewrite line-of-sight rules

This commit is contained in:
Yair Morgenstern
2019-01-21 22:41:22 +02:00
parent d1de589e4f
commit d7067d2835
4 changed files with 30 additions and 10 deletions

View File

@ -154,14 +154,14 @@ class UnitAutomation{
// and then later we round it off to a whole.
// So the poor unit thought it could attack from the tile, but when it comes to do so it has no movement points!
// Silly floats, basically
var tilesToAttackFrom = unitDistanceToTiles.asSequence()
val tilesToAttackFrom = unitDistanceToTiles.asSequence()
.filter { unit.currentMovement - it.value >= minMovementBeforeAttack }
.map { it.key }
.filter { unit.canMoveTo(it) || it==unit.getTile() }
for(reachableTile in tilesToAttackFrom){ // tiles we'll still have energy after we reach there
val tilesInAttackRange = if (unit.hasUnique("Indirect Fire")) reachableTile.getTilesInDistance(rangeOfAttack)
else reachableTile.getViewableTiles(rangeOfAttack)
else reachableTile.getViewableTiles(rangeOfAttack, unit.type.isWaterUnit())
attackableTiles += tilesInAttackRange.asSequence().filter { it in tilesWithEnemies }
.map { AttackableTile(reachableTile,it) }
}

View File

@ -110,7 +110,7 @@ class MapUnit {
visibilityRange += 1
val tile = getTile()
if (tile.baseTerrain == "Hill" && type.isLandUnit()) visibilityRange += 1
return tile.getViewableTiles(visibilityRange)
return tile.getViewableTiles(visibilityRange, type.isWaterUnit())
}
fun isFortified(): Boolean {

View File

@ -210,8 +210,8 @@ open class TileInfo {
return getUnits().any{it.isIdle()}
}
fun getViewableTiles(distance:Int): MutableList<TileInfo> {
return tileMap.getViewableTiles(this.position,distance)
fun getViewableTiles(distance:Int, ignoreCurrentTileHeight:Boolean = false): MutableList<TileInfo> {
return tileMap.getViewableTiles(this.position,distance,ignoreCurrentTileHeight)
}
fun getTilesInDistance(distance:Int): List<TileInfo> {

View File

@ -3,10 +3,8 @@ package com.unciv.logic.map
import com.badlogic.gdx.math.Vector2
import com.unciv.logic.GameInfo
import com.unciv.logic.HexMath
import com.unciv.logic.map.MapType
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.gamebasics.GameBasics
import com.unciv.ui.NewGameScreen
class TileMap {
@ -90,18 +88,40 @@ class TileMap {
return unit
}
fun getViewableTiles(position: Vector2, sightDistance: Int): MutableList<TileInfo> {
fun getViewableTiles(position: Vector2, sightDistance: Int, ignoreCurrentTileHeight:Boolean=false): MutableList<TileInfo> {
val viewableTiles = getTilesInDistance(position, 1).toMutableList()
val currentTileHeight = if(ignoreCurrentTileHeight) 0 else get(position).getHeight()
for (i in 1..sightDistance) { // in each layer,
// This is so we don't use tiles in the same distance to "see over",
// that is to say, the "viewableTiles.contains(it) check will return false for neighbors from the same distance
val tilesToAddInDistanceI = ArrayList<TileInfo>()
for (tile in getTilesAtDistance(position, i)) { // for each tile in that layer,
val tileHeight = tile.getHeight()
val targetTileHeight = tile.getHeight()
/*
Okay so, if we're looking at a tile from a to c with b in the middle,
we have several scenarios:
1. a>b - - I can see everything, b does not hide c
2. a==b
2.1 a==b==0, all flat ground, no hiding
2.2 a>0, b>=c - b hides c from view (say I am in a forest/jungle and b is a forest/jungle, or hill)
2.3 a>0, c>b - c is tall enough I can see it over b!
3. a<b
3.1 b>=c - b hides c
3.2 b<c - c is tall enough I can see it over b!
This can all be summed up as "I can see c if a>b || c>b || b==0 "
*/
val containsViewableNeighborThatCanSeeOver = tile.neighbors.any {
val neighborHeight = it.getHeight()
viewableTiles.contains(it) && (neighborHeight == 0 || neighborHeight < tileHeight)
viewableTiles.contains(it) && (
currentTileHeight > neighborHeight // a>b
|| targetTileHeight > neighborHeight // c>b
|| neighborHeight == 0) // b==0
}
if (containsViewableNeighborThatCanSeeOver) tilesToAddInDistanceI.add(tile)
}