River adjacency functions and gold bonus for tiles adjacent to rivers

This commit is contained in:
Yair Morgenstern 2020-05-17 21:29:12 +03:00
parent 8a43d5c5d6
commit 3032ba9c73

View file

@ -24,9 +24,9 @@ open class TileInfo {
@Transient var isWater = false
@Transient var isOcean = false
var militaryUnit:MapUnit?=null
var civilianUnit:MapUnit?=null
var airUnits=ArrayList<MapUnit>()
var militaryUnit: MapUnit? = null
var civilianUnit: MapUnit? = null
var airUnits = ArrayList<MapUnit>()
var position: Vector2 = Vector2.Zero
lateinit var baseTerrain: String
@ -50,18 +50,18 @@ open class TileInfo {
fun clone(): TileInfo {
val toReturn = TileInfo()
if(militaryUnit!=null) toReturn.militaryUnit=militaryUnit!!.clone()
if(civilianUnit!=null) toReturn.civilianUnit=civilianUnit!!.clone()
for(airUnit in airUnits) toReturn.airUnits.add(airUnit.clone())
toReturn.position=position.cpy()
toReturn.baseTerrain=baseTerrain
toReturn.terrainFeature=terrainFeature
toReturn.naturalWonder=naturalWonder
toReturn.resource=resource
toReturn.improvement=improvement
toReturn.improvementInProgress=improvementInProgress
toReturn.roadStatus=roadStatus
toReturn.turnsToImprovement=turnsToImprovement
if (militaryUnit != null) toReturn.militaryUnit = militaryUnit!!.clone()
if (civilianUnit != null) toReturn.civilianUnit = civilianUnit!!.clone()
for (airUnit in airUnits) toReturn.airUnits.add(airUnit.clone())
toReturn.position = position.cpy()
toReturn.baseTerrain = baseTerrain
toReturn.terrainFeature = terrainFeature
toReturn.naturalWonder = naturalWonder
toReturn.resource = resource
toReturn.improvement = improvement
toReturn.improvementInProgress = improvementInProgress
toReturn.roadStatus = roadStatus
toReturn.turnsToImprovement = turnsToImprovement
return toReturn
}
@ -96,18 +96,18 @@ open class TileInfo {
fun getCity(): CityInfo? = owningCity
fun getLastTerrain(): Terrain = if (terrainFeature != null) getTerrainFeature()!! else if(naturalWonder != null) getNaturalWonder() else getBaseTerrain()
fun getLastTerrain(): Terrain = if (terrainFeature != null) getTerrainFeature()!! else if (naturalWonder != null) getNaturalWonder() else getBaseTerrain()
fun getTileResource(): TileResource =
if (resource == null) throw Exception("No resource exists for this tile!")
else ruleset.tileResources[resource!!]!!
fun getNaturalWonder() : Terrain =
fun getNaturalWonder(): Terrain =
if (naturalWonder == null) throw Exception("No natural wonder exists for this tile!")
else ruleset.terrains[naturalWonder!!]!!
fun isCityCenter(): Boolean = getCity()?.location == position
fun isNaturalWonder() : Boolean = naturalWonder != null
fun isNaturalWonder(): Boolean = naturalWonder != null
fun getTileImprovement(): TileImprovement? = if (improvement == null) null else ruleset.tileImprovements[improvement!!]
@ -130,7 +130,7 @@ open class TileInfo {
fun getOwner(): CivilizationInfo? {
val containingCity = getCity()
if(containingCity==null) return null
if (containingCity == null) return null
return containingCity.civInfo
}
@ -147,7 +147,7 @@ open class TileInfo {
fun getTerrainFeature(): Terrain? =
if (terrainFeature == null) null else ruleset.terrains[terrainFeature!!]
fun getWorkingCity():CityInfo? {
fun getWorkingCity(): CityInfo? {
val civInfo = getOwner()
if (civInfo == null) return null
return civInfo.cities.firstOrNull { it.workedTiles.contains(position) }
@ -157,9 +157,9 @@ open class TileInfo {
return getWorkingCity() != null
}
fun isLocked(): Boolean{
fun isLocked(): Boolean {
val workingCity = getWorkingCity()
return workingCity!=null && workingCity.lockedTiles.contains(position)
return workingCity != null && workingCity.lockedTiles.contains(position)
}
fun getTileStats(observingCiv: CivilizationInfo): Stats = getTileStats(getCity(), observingCiv)
@ -167,7 +167,7 @@ open class TileInfo {
fun getTileStats(city: CityInfo?, observingCiv: CivilizationInfo): Stats {
var stats = getBaseTerrain().clone()
if((baseTerrain== Constants.ocean||baseTerrain==Constants.coast) && city!=null
if ((baseTerrain == Constants.ocean || baseTerrain == Constants.coast) && city != null
&& city.containsBuildingUnique("+1 food from Ocean and Coast tiles"))
stats.food += 1
@ -206,7 +206,7 @@ open class TileInfo {
val resourceBuilding = tileMap.gameInfo.ruleSet.buildings[resource.building!!]!!
stats.add(resourceBuilding.resourceBonusStats!!) // resource-specific building (eg forge, stable) bonus
}
if (resource.resourceType==ResourceType.Strategic
if (resource.resourceType == ResourceType.Strategic
&& observingCiv.nation.unique == UniqueAbility.SIBERIAN_RICHES)
stats.production += 1
if (city != null) {
@ -217,9 +217,9 @@ open class TileInfo {
&& city.containsBuildingUnique("+2 Gold for each source of Marble and Stone"))
stats.gold += 2
if (isWater) {
if(city.containsBuildingUnique("+1 production from all sea resources worked by the city"))
if (city.containsBuildingUnique("+1 production from all sea resources worked by the city"))
stats.production += 1
if(city.containsBuildingUnique("+1 production and gold from all sea resources worked by the city")){
if (city.containsBuildingUnique("+1 production and gold from all sea resources worked by the city")) {
stats.production += 1
stats.gold += 1
}
@ -231,7 +231,7 @@ open class TileInfo {
if (improvement != null)
stats.add(getImprovementStats(improvement, observingCiv, city))
if(city!=null && isWater && city.containsBuildingUnique("+1 gold from worked water tiles in city"))
if (city != null && isWater && city.containsBuildingUnique("+1 gold from worked water tiles in city"))
stats.gold += 1
if (isCityCenter()) {
@ -242,6 +242,8 @@ open class TileInfo {
if (stats.gold != 0f && observingCiv.goldenAges.isGoldenAge())
stats.gold++
if (isAdjacentToRiver()) stats.gold++
if (stats.production < 0) stats.production = 0f
return stats
@ -297,72 +299,87 @@ open class TileInfo {
}
}
fun hasImprovementInProgress() = improvementInProgress!=null
fun hasImprovementInProgress() = improvementInProgress != null
@delegate:Transient
private val _isCoastalTile: Boolean by lazy { neighbors.any { it.baseTerrain==Constants.coast } }
private val _isCoastalTile: Boolean by lazy { neighbors.any { it.baseTerrain == Constants.coast } }
fun isCoastalTile() = _isCoastalTile
fun hasViewableResource(civInfo: CivilizationInfo): Boolean =
resource != null && (getTileResource().revealedBy == null || civInfo.tech.isResearched(getTileResource().revealedBy!!))
fun getViewableTilesList(distance:Int): List<TileInfo> =
fun getViewableTilesList(distance: Int): List<TileInfo> =
tileMap.getViewableTiles(position, distance)
fun getTilesInDistance(distance: Int): Sequence<TileInfo> =
tileMap.getTilesInDistance(position,distance)
tileMap.getTilesInDistance(position, distance)
fun getTilesInDistanceRange(range: IntRange): Sequence<TileInfo> =
tileMap.getTilesInDistanceRange(position, range)
fun getTilesAtDistance(distance:Int): Sequence<TileInfo> =
fun getTilesAtDistance(distance: Int): Sequence<TileInfo> =
tileMap.getTilesAtDistance(position, distance)
fun getDefensiveBonus(): Float {
var bonus = getBaseTerrain().defenceBonus
if(terrainFeature!=null) bonus += getTerrainFeature()!!.defenceBonus
if (terrainFeature != null) bonus += getTerrainFeature()!!.defenceBonus
return bonus
}
fun aerialDistanceTo(otherTile:TileInfo): Int {
val xDelta = position.x-otherTile.position.x
val yDelta = position.y-otherTile.position.y
return listOf(abs(xDelta),abs(yDelta), abs(xDelta-yDelta)).max()!!.toInt()
fun aerialDistanceTo(otherTile: TileInfo): Int {
val xDelta = position.x - otherTile.position.x
val yDelta = position.y - otherTile.position.y
return listOf(abs(xDelta), abs(yDelta), abs(xDelta - yDelta)).max()!!.toInt()
}
fun isRoughTerrain() = getBaseTerrain().rough || getTerrainFeature()?.rough == true
override fun toString():String { // for debugging, it helps to see what you're doing
override fun toString(): String { // for debugging, it helps to see what you're doing
return toString(null)
}
fun isConnectedByRiver(otherTile:TileInfo): Boolean {
if(otherTile !in neighbors) throw Exception("Should never call this function on a non-neighbor!")
val xDifference = this.position.x - otherTile.position.x
val yDifference = this.position.y - otherTile.position.y
return when {
xDifference == 1f && yDifference == 1f -> hasBottomRiver // we're directly above it
xDifference == 1f -> hasBottomRightRiver // we're to the top-left of it
yDifference == 1f -> hasBottomLeftRiver // we're to the top-right of it
else -> otherTile.isConnectedByRiver(this) // we're below it, check the other tile
}
}
fun isAdjacentToRiver() = neighbors.any { isConnectedByRiver(it) }
fun toString(viewingCiv: CivilizationInfo?): String {
val lineList = ArrayList<String>() // more readable than StringBuilder, with same performance for our use-case
val isViewableToPlayer = viewingCiv==null || UncivGame.Current.viewEntireMapForDebug
val isViewableToPlayer = viewingCiv == null || UncivGame.Current.viewEntireMapForDebug
|| viewingCiv.viewableTiles.contains(this)
if (isCityCenter()) {
val city = getCity()!!
var cityString = city.name.tr()
if(isViewableToPlayer) cityString += " ("+city.health+")"
if (isViewableToPlayer) cityString += " (" + city.health + ")"
lineList += cityString
if(UncivGame.Current.viewEntireMapForDebug || city.civInfo == viewingCiv)
if (UncivGame.Current.viewEntireMapForDebug || city.civInfo == viewingCiv)
lineList += city.cityConstructions.getProductionForTileInfo()
}
lineList += baseTerrain.tr()
if (terrainFeature != null) lineList += terrainFeature!!.tr()
if (resource!=null && (viewingCiv==null || hasViewableResource(viewingCiv))) lineList += resource!!.tr()
if (resource != null && (viewingCiv == null || hasViewableResource(viewingCiv))) lineList += resource!!.tr()
if (naturalWonder != null) lineList += naturalWonder!!.tr()
if (roadStatus !== RoadStatus.None && !isCityCenter()) lineList += roadStatus.toString().tr()
if (improvement != null) lineList += improvement!!.tr()
if (improvementInProgress != null && isViewableToPlayer)
lineList += "{$improvementInProgress}\r\n{in} $turnsToImprovement {turns}".tr() // todo change to [] translation notation
if (civilianUnit != null && isViewableToPlayer)
lineList += civilianUnit!!.name.tr()+" - "+civilianUnit!!.civInfo.civName.tr()
if(militaryUnit!=null && isViewableToPlayer){
lineList += civilianUnit!!.name.tr() + " - " + civilianUnit!!.civInfo.civName.tr()
if (militaryUnit != null && isViewableToPlayer) {
var milUnitString = militaryUnit!!.name.tr()
if(militaryUnit!!.health<100) milUnitString += "(" + militaryUnit!!.health + ")"
milUnitString += " - "+militaryUnit!!.civInfo.civName.tr()
if (militaryUnit!!.health < 100) milUnitString += "(" + militaryUnit!!.health + ")"
milUnitString += " - " + militaryUnit!!.civInfo.civName.tr()
lineList += milUnitString
}
var defenceBonus = getDefensiveBonus()
@ -374,12 +391,12 @@ open class TileInfo {
else -> 0.0f
}
}
if(defenceBonus != 0.0f){
var defencePercentString = (defenceBonus*100).toInt().toString()+"%"
if(!defencePercentString.startsWith("-")) defencePercentString = "+$defencePercentString"
if (defenceBonus != 0.0f) {
var defencePercentString = (defenceBonus * 100).toInt().toString() + "%"
if (!defencePercentString.startsWith("-")) defencePercentString = "+$defencePercentString"
lineList += "[$defencePercentString] to unit defence".tr()
}
if(getBaseTerrain().impassable) lineList += Constants.impassable.tr()
if (getBaseTerrain().impassable) lineList += Constants.impassable.tr()
return lineList.joinToString("\n")
}
@ -387,23 +404,23 @@ open class TileInfo {
//endregion
//region state-changing functions
fun setTransients(){
fun setTransients() {
setTerrainTransients()
setUnitTransients(true)
}
fun setTerrainTransients(){
fun setTerrainTransients() {
baseTerrainObject = ruleset.terrains[baseTerrain]!! // This is a HACK.
isWater = getBaseTerrain().type==TerrainType.Water
isLand = getBaseTerrain().type==TerrainType.Land
isWater = getBaseTerrain().type == TerrainType.Water
isLand = getBaseTerrain().type == TerrainType.Land
isOcean = baseTerrain == Constants.ocean
}
fun setUnitTransients(unitCivTransients: Boolean) {
for (unit in getUnits()) {
unit.currentTile = this
if(unitCivTransients)
unit.assignOwner(tileMap.gameInfo.getCivilization(unit.owner),false)
if (unitCivTransients)
unit.assignOwner(tileMap.gameInfo.getCivilization(unit.owner), false)
unit.setTransients(ruleset)
}
}
@ -412,15 +429,16 @@ open class TileInfo {
improvementInProgress = improvement.name
turnsToImprovement = improvement.getTurnsToBuild(civInfo)
}
fun stopWorkingOnImprovement() {
improvementInProgress = null
turnsToImprovement = 0
}
fun hasEnemySubmarine(viewingCiv:CivilizationInfo): Boolean {
fun hasEnemySubmarine(viewingCiv: CivilizationInfo): Boolean {
val unitsInTile = getUnits()
if (unitsInTile.none()) return false
if (unitsInTile.first().civInfo!=viewingCiv &&
if (unitsInTile.first().civInfo != viewingCiv &&
unitsInTile.firstOrNull { it.isInvisible() } != null) {
return true
}