mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-21 05:09:25 +07:00
City tiles are always contiguous, otherwise loads of wierd bugs happen
Also, better calculation of the number of claimed tiles In retrospect this has been plaguing us for a long time
This commit is contained in:
@ -6,6 +6,7 @@ import com.unciv.logic.automation.Automation
|
|||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.ui.utils.withItem
|
import com.unciv.ui.utils.withItem
|
||||||
import com.unciv.ui.utils.withoutItem
|
import com.unciv.ui.utils.withoutItem
|
||||||
|
import kotlin.math.max
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -16,12 +17,16 @@ class CityExpansionManager {
|
|||||||
|
|
||||||
fun clone(): CityExpansionManager {
|
fun clone(): CityExpansionManager {
|
||||||
val toReturn = CityExpansionManager()
|
val toReturn = CityExpansionManager()
|
||||||
toReturn.cultureStored=cultureStored
|
toReturn.cultureStored = cultureStored
|
||||||
return toReturn
|
return toReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tilesClaimed() = cityInfo.tiles.size - 7
|
fun tilesClaimed(): Int {
|
||||||
fun isAreaMaxed(): Boolean = (cityInfo.tiles.size >= 90)
|
val tilesAroundCity = cityInfo.getCenterTile().getTilesInDistance(1)
|
||||||
|
.map { it.position }
|
||||||
|
return cityInfo.tiles.filterNot { it in tilesAroundCity }.size
|
||||||
|
}
|
||||||
|
fun isAreaMaxed(): Boolean = cityInfo.tiles.size >= 90
|
||||||
|
|
||||||
// This one has conflicting sources -
|
// This one has conflicting sources -
|
||||||
// http://civilization.wikia.com/wiki/Mathematics_of_Civilization_V says it's 20+(10(t-1))^1.1
|
// http://civilization.wikia.com/wiki/Mathematics_of_Civilization_V says it's 20+(10(t-1))^1.1
|
||||||
@ -29,19 +34,20 @@ class CityExpansionManager {
|
|||||||
// (per game XML files) at 6*(t+0.4813)^1.3
|
// (per game XML files) at 6*(t+0.4813)^1.3
|
||||||
// The second seems to be more based, so I'll go with that
|
// The second seems to be more based, so I'll go with that
|
||||||
fun getCultureToNextTile(): Int {
|
fun getCultureToNextTile(): Int {
|
||||||
var cultureToNextTile = 6 * (kotlin.math.max(0, tilesClaimed()) + 1.4813).pow(1.3)
|
var cultureToNextTile = 6 * (max(0, tilesClaimed()) + 1.4813).pow(1.3)
|
||||||
if (cityInfo.civInfo.containsBuildingUnique("Cost of acquiring new tiles reduced by 25%"))
|
if (cityInfo.civInfo.containsBuildingUnique("Cost of acquiring new tiles reduced by 25%"))
|
||||||
cultureToNextTile *= 0.75 //Speciality of Angkor Wat
|
cultureToNextTile *= 0.75 //Speciality of Angkor Wat
|
||||||
if(cityInfo.containsBuildingUnique("Culture and Gold costs of acquiring new tiles reduced by 25% in this city"))
|
if (cityInfo.containsBuildingUnique("Culture and Gold costs of acquiring new tiles reduced by 25% in this city"))
|
||||||
cultureToNextTile *= 0.75 // Specialty of Krepost
|
cultureToNextTile *= 0.75 // Specialty of Krepost
|
||||||
if (cityInfo.civInfo.policies.isAdopted("Tradition")) cultureToNextTile *= 0.75
|
if (cityInfo.civInfo.policies.isAdopted("Tradition")) cultureToNextTile *= 0.75
|
||||||
return cultureToNextTile.roundToInt()
|
return cultureToNextTile.roundToInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buyTile(tileInfo: TileInfo){
|
fun buyTile(tileInfo: TileInfo) {
|
||||||
val goldCost = getGoldCostOfTile(tileInfo)
|
val goldCost = getGoldCostOfTile(tileInfo)
|
||||||
|
|
||||||
class NotEnoughGoldToBuyTileException : Exception()
|
class NotEnoughGoldToBuyTileException : Exception()
|
||||||
if(cityInfo.civInfo.gold<goldCost) throw NotEnoughGoldToBuyTileException()
|
if (cityInfo.civInfo.gold < goldCost) throw NotEnoughGoldToBuyTileException()
|
||||||
cityInfo.civInfo.gold -= goldCost
|
cityInfo.civInfo.gold -= goldCost
|
||||||
takeOwnership(tileInfo)
|
takeOwnership(tileInfo)
|
||||||
}
|
}
|
||||||
@ -49,14 +55,14 @@ class CityExpansionManager {
|
|||||||
fun getGoldCostOfTile(tileInfo: TileInfo): Int {
|
fun getGoldCostOfTile(tileInfo: TileInfo): Int {
|
||||||
val baseCost = 50
|
val baseCost = 50
|
||||||
val distanceFromCenter = tileInfo.aerialDistanceTo(cityInfo.getCenterTile())
|
val distanceFromCenter = tileInfo.aerialDistanceTo(cityInfo.getCenterTile())
|
||||||
var cost = baseCost * (distanceFromCenter-1) + tilesClaimed()*5.0
|
var cost = baseCost * (distanceFromCenter - 1) + tilesClaimed() * 5.0
|
||||||
|
|
||||||
if (cityInfo.civInfo.containsBuildingUnique("Cost of acquiring new tiles reduced by 25%"))
|
if (cityInfo.civInfo.containsBuildingUnique("Cost of acquiring new tiles reduced by 25%"))
|
||||||
cost *= 0.75 //Speciality of Angkor Wat
|
cost *= 0.75 //Speciality of Angkor Wat
|
||||||
if(cityInfo.containsBuildingUnique("Culture and Gold costs of acquiring new tiles reduced by 25% in this city"))
|
if (cityInfo.containsBuildingUnique("Culture and Gold costs of acquiring new tiles reduced by 25% in this city"))
|
||||||
cost *= 0.75 // Specialty of Krepost
|
cost *= 0.75 // Specialty of Krepost
|
||||||
|
|
||||||
if(cityInfo.civInfo.nation.unique == UniqueAbility.MANIFEST_DESTINY)
|
if (cityInfo.civInfo.nation.unique == UniqueAbility.MANIFEST_DESTINY)
|
||||||
cost /= 2
|
cost /= 2
|
||||||
return cost.toInt()
|
return cost.toInt()
|
||||||
}
|
}
|
||||||
@ -65,8 +71,10 @@ class CityExpansionManager {
|
|||||||
fun chooseNewTileToOwn(): TileInfo? {
|
fun chooseNewTileToOwn(): TileInfo? {
|
||||||
for (i in 2..5) {
|
for (i in 2..5) {
|
||||||
val tiles = cityInfo.getCenterTile().getTilesInDistance(i)
|
val tiles = cityInfo.getCenterTile().getTilesInDistance(i)
|
||||||
.filter { it.getOwner() == null
|
.filter {
|
||||||
&& it.neighbors.any { tile -> tile.getOwner() == cityInfo.civInfo } }
|
it.getOwner() == null
|
||||||
|
&& it.neighbors.any { tile -> tile.getCity() == cityInfo }
|
||||||
|
}
|
||||||
val chosenTile = tiles.maxBy { Automation.rankTile(it, cityInfo.civInfo) }
|
val chosenTile = tiles.maxBy { Automation.rankTile(it, cityInfo.civInfo) }
|
||||||
if (chosenTile != null)
|
if (chosenTile != null)
|
||||||
return chosenTile
|
return chosenTile
|
||||||
@ -90,12 +98,12 @@ class CityExpansionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun addNewTileWithCulture(): Boolean {
|
private fun addNewTileWithCulture(): Boolean {
|
||||||
if ( isAreaMaxed() ) {
|
if (isAreaMaxed()) {
|
||||||
cultureStored = 0
|
cultureStored = 0
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val chosenTile = chooseNewTileToOwn()
|
val chosenTile = chooseNewTileToOwn()
|
||||||
if (chosenTile!=null) {
|
if (chosenTile != null) {
|
||||||
cultureStored -= getCultureToNextTile()
|
cultureStored -= getCultureToNextTile()
|
||||||
takeOwnership(chosenTile)
|
takeOwnership(chosenTile)
|
||||||
return true
|
return true
|
||||||
@ -103,19 +111,19 @@ class CityExpansionManager {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun relinquishOwnership(tileInfo: TileInfo){
|
fun relinquishOwnership(tileInfo: TileInfo) {
|
||||||
cityInfo.tiles = cityInfo.tiles.withoutItem(tileInfo.position)
|
cityInfo.tiles = cityInfo.tiles.withoutItem(tileInfo.position)
|
||||||
if(cityInfo.workedTiles.contains(tileInfo.position))
|
if (cityInfo.workedTiles.contains(tileInfo.position))
|
||||||
cityInfo.workedTiles = cityInfo.workedTiles.withoutItem(tileInfo.position)
|
cityInfo.workedTiles = cityInfo.workedTiles.withoutItem(tileInfo.position)
|
||||||
tileInfo.owningCity=null
|
tileInfo.owningCity = null
|
||||||
|
|
||||||
cityInfo.civInfo.updateDetailedCivResources()
|
cityInfo.civInfo.updateDetailedCivResources()
|
||||||
cityInfo.cityStats.update()
|
cityInfo.cityStats.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun takeOwnership(tileInfo: TileInfo){
|
fun takeOwnership(tileInfo: TileInfo) {
|
||||||
if(tileInfo.isCityCenter()) throw Exception("What?!")
|
if (tileInfo.isCityCenter()) throw Exception("What?!")
|
||||||
if(tileInfo.getCity()!=null)
|
if (tileInfo.getCity() != null)
|
||||||
tileInfo.getCity()!!.expansion.relinquishOwnership(tileInfo)
|
tileInfo.getCity()!!.expansion.relinquishOwnership(tileInfo)
|
||||||
|
|
||||||
cityInfo.tiles = cityInfo.tiles.withItem(tileInfo.position)
|
cityInfo.tiles = cityInfo.tiles.withItem(tileInfo.position)
|
||||||
@ -124,8 +132,8 @@ class CityExpansionManager {
|
|||||||
cityInfo.civInfo.updateDetailedCivResources()
|
cityInfo.civInfo.updateDetailedCivResources()
|
||||||
cityInfo.cityStats.update()
|
cityInfo.cityStats.update()
|
||||||
|
|
||||||
for(unit in tileInfo.getUnits())
|
for (unit in tileInfo.getUnits())
|
||||||
if(!unit.civInfo.canEnterTiles(cityInfo.civInfo))
|
if (!unit.civInfo.canEnterTiles(cityInfo.civInfo))
|
||||||
unit.movement.teleportToClosestMoveableTile()
|
unit.movement.teleportToClosestMoveableTile()
|
||||||
|
|
||||||
cityInfo.civInfo.updateViewableTiles()
|
cityInfo.civInfo.updateViewableTiles()
|
||||||
@ -135,14 +143,14 @@ class CityExpansionManager {
|
|||||||
cultureStored += culture.toInt()
|
cultureStored += culture.toInt()
|
||||||
if (cultureStored >= getCultureToNextTile()) {
|
if (cultureStored >= getCultureToNextTile()) {
|
||||||
if (addNewTileWithCulture())
|
if (addNewTileWithCulture())
|
||||||
cityInfo.civInfo.addNotification("["+cityInfo.name + "] has expanded its borders!", cityInfo.location, Color.PURPLE)
|
cityInfo.civInfo.addNotification("[" + cityInfo.name + "] has expanded its borders!", cityInfo.location, Color.PURPLE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTransients(){
|
fun setTransients() {
|
||||||
val tiles = cityInfo.getTiles()
|
val tiles = cityInfo.getTiles()
|
||||||
for(tile in tiles )
|
for (tile in tiles)
|
||||||
tile.owningCity=cityInfo
|
tile.owningCity = cityInfo
|
||||||
}
|
}
|
||||||
//endregion
|
//endregion
|
||||||
}
|
}
|
Reference in New Issue
Block a user