mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-25 15:19:51 +07:00
Trade routes now travel between harbors over water, and are calculated once per civilization instead of per city
This commit is contained in:
@ -280,7 +280,8 @@
|
||||
name:"Harbor",
|
||||
maintenance:2,
|
||||
hurryCostModifier:25,
|
||||
uniques:["+1 production from all sea resources worked by the city","Connects trade routes over water"] // todo - trade routes over water!
|
||||
uniques:["+1 production from all sea resources worked by the city",
|
||||
"Connects trade routes over water","Can only be built in coastal cities"]
|
||||
requiredTech:"Compass"
|
||||
},
|
||||
{
|
||||
|
@ -299,7 +299,7 @@
|
||||
]
|
||||
]
|
||||
|
||||
Worker:[
|
||||
WorkerTrained:[
|
||||
[
|
||||
"You have trained a worker!",
|
||||
"Workers are vital to your cities' growth, since only they can onstruct improvements on tiles",
|
||||
|
@ -21,8 +21,8 @@ android {
|
||||
applicationId "com.unciv.game"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 26
|
||||
versionCode 152
|
||||
versionName "2.9.6"
|
||||
versionCode 153
|
||||
versionName "2.9.7"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
@ -17,7 +17,7 @@ class UnCivGame : Game() {
|
||||
* This exists so that when debugging we can see the entire map.
|
||||
* Remember to turn this to false before commit and upload!
|
||||
*/
|
||||
val viewEntireMapForDebug = true
|
||||
val viewEntireMapForDebug = false
|
||||
|
||||
lateinit var worldScreen: WorldScreen
|
||||
|
||||
|
@ -15,6 +15,7 @@ import kotlin.math.min
|
||||
|
||||
class CityInfo {
|
||||
@Transient lateinit var civInfo: CivilizationInfo
|
||||
@Transient var isConnectedToCapital = false
|
||||
var location: Vector2 = Vector2.Zero
|
||||
var name: String = ""
|
||||
var health = 200
|
||||
@ -78,6 +79,7 @@ class CityInfo {
|
||||
toReturn.tiles.addAll(tiles)
|
||||
toReturn.workedTiles.addAll(workedTiles)
|
||||
toReturn.isBeingRazed=isBeingRazed
|
||||
toReturn.isConnectedToCapital = isConnectedToCapital
|
||||
return toReturn
|
||||
}
|
||||
|
||||
|
@ -224,32 +224,14 @@ class CityStats {
|
||||
fun isConnectedToCapital(roadType: RoadStatus): Boolean {
|
||||
if (cityInfo.civInfo.cities.count() < 2) return false// first city!
|
||||
|
||||
if(roadType==RoadStatus.Road) return cityInfo.isConnectedToCapital // this transient is not applicable to connection via railroad.
|
||||
|
||||
val capitalTile = cityInfo.civInfo.getCapital().getCenterTile()
|
||||
val BFS =
|
||||
if(roadType==RoadStatus.Road) BFS(capitalTile){it.roadStatus!=RoadStatus.None}
|
||||
else BFS(capitalTile){it.roadStatus == roadType}
|
||||
val BFS = BFS(capitalTile){it.roadStatus == roadType}
|
||||
|
||||
val cityTile = cityInfo.getCenterTile()
|
||||
BFS.stepUntilDestination(cityTile)
|
||||
return BFS.tilesReached.containsKey(cityTile)
|
||||
|
||||
// val tilesReached = HashSet<TileInfo>()
|
||||
// var tilesToCheck: List<TileInfo> = listOf(cityInfo.getCenterTile())
|
||||
// while (tilesToCheck.isNotEmpty()) {
|
||||
// val newTiles = tilesToCheck
|
||||
// .flatMap { it.neighbors }.distinct()
|
||||
// .filter {
|
||||
// !tilesReached.contains(it)
|
||||
// && !tilesToCheck.contains(it)
|
||||
// && (roadType !== RoadStatus.Road || it.roadStatus !== RoadStatus.None)
|
||||
// && (roadType !== RoadStatus.Railroad || it.roadStatus === roadType)
|
||||
// }
|
||||
//
|
||||
// if (newTiles.contains(capitalTile)) return true
|
||||
// tilesReached.addAll(tilesToCheck)
|
||||
// tilesToCheck = newTiles
|
||||
// }
|
||||
// return false
|
||||
}
|
||||
//endregion
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.map.BFS
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.logic.map.TileInfo
|
||||
@ -15,6 +16,8 @@ import com.unciv.models.gamebasics.tile.TileResource
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.ui.utils.getRandom
|
||||
import com.unciv.ui.utils.tr
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.math.max
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
@ -255,6 +258,7 @@ class CivilizationInfo {
|
||||
cityInfo.civInfo = this // must be before the city's setTransients because it depends on the tilemap, that comes from the civInfo
|
||||
cityInfo.setTransients()
|
||||
}
|
||||
setCitiesConnectedToCapitalTransients()
|
||||
}
|
||||
|
||||
fun endTurn() {
|
||||
@ -296,6 +300,7 @@ class CivilizationInfo {
|
||||
|
||||
fun startTurn(){
|
||||
getViewableTiles() // adds explored tiles so that the units will be able to perform automated actions better
|
||||
setCitiesConnectedToCapitalTransients()
|
||||
for (city in cities)
|
||||
city.cityStats.update()
|
||||
happiness = getHappinessForNextTurn().values.sum().roundToInt()
|
||||
@ -328,5 +333,62 @@ class CivilizationInfo {
|
||||
newCity.cityConstructions.chooseNextConstruction()
|
||||
}
|
||||
|
||||
fun setCitiesConnectedToCapitalTransients(){
|
||||
if(cities.isEmpty()) return // eg barbarians
|
||||
|
||||
// We map which cities we've reached, to the mediums they've been reached by -
|
||||
// this is so we know that if we've seen which cities can be connected by port A, and one
|
||||
// of those is city B, then we don't need to check the cities that B can connect to by port,
|
||||
// since we'll get the same cities we got from A, since they're connected to the same sea.
|
||||
val citiesReachedToMediums = HashMap<CityInfo,ArrayList<String>>()
|
||||
var citiesToCheck = mutableListOf(getCapital())
|
||||
citiesReachedToMediums[getCapital()] = arrayListOf("Start")
|
||||
while(citiesToCheck.isNotEmpty() && citiesReachedToMediums.size<cities.size){
|
||||
val newCitiesToCheck = mutableListOf<CityInfo>()
|
||||
for(cityToConnectFrom in citiesToCheck){
|
||||
val reachedMediums = citiesReachedToMediums[cityToConnectFrom]!!
|
||||
|
||||
// This is copypasta and can be cleaned up
|
||||
if(!reachedMediums.contains("Road")){
|
||||
val roadBfs = BFS(cityToConnectFrom.getCenterTile()){it.roadStatus!=RoadStatus.None}
|
||||
roadBfs.stepToEnd()
|
||||
val reachedCities = cities.filter { roadBfs.tilesReached.containsKey(it.getCenterTile())}
|
||||
for(reachedCity in reachedCities){
|
||||
if(!citiesReachedToMediums.containsKey(reachedCity)){
|
||||
newCitiesToCheck.add(reachedCity)
|
||||
citiesReachedToMediums[reachedCity] = arrayListOf()
|
||||
}
|
||||
val cityReachedByMediums = citiesReachedToMediums[reachedCity]!!
|
||||
if(!cityReachedByMediums.contains("Road"))
|
||||
cityReachedByMediums.add("Road")
|
||||
}
|
||||
citiesReachedToMediums[cityToConnectFrom]!!.add("Road")
|
||||
}
|
||||
|
||||
if(!reachedMediums.contains("Harbor")
|
||||
&& cityToConnectFrom.cityConstructions.containsBuildingOrEquivalent("Harbor")){
|
||||
val seaBfs = BFS(cityToConnectFrom.getCenterTile()){it.isWater() || it.isCityCenter()}
|
||||
seaBfs.stepToEnd()
|
||||
val reachedCities = cities.filter { seaBfs.tilesReached.containsKey(it.getCenterTile())}
|
||||
for(reachedCity in reachedCities){
|
||||
if(!citiesReachedToMediums.containsKey(reachedCity)){
|
||||
newCitiesToCheck.add(reachedCity)
|
||||
citiesReachedToMediums[reachedCity] = arrayListOf()
|
||||
}
|
||||
val cityReachedByMediums = citiesReachedToMediums[reachedCity]!!
|
||||
if(!cityReachedByMediums.contains("Harbor"))
|
||||
cityReachedByMediums.add("Harbor")
|
||||
}
|
||||
citiesReachedToMediums[cityToConnectFrom]!!.add("Harbor")
|
||||
}
|
||||
}
|
||||
citiesToCheck = newCitiesToCheck
|
||||
}
|
||||
|
||||
for(city in cities){
|
||||
city.isConnectedToCapital = citiesReachedToMediums.containsKey(city)
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
}
|
@ -12,6 +12,11 @@ class BFS(val startingPoint: TileInfo, val predicate : (TileInfo) -> Boolean){
|
||||
tilesReached.put(startingPoint,startingPoint)
|
||||
}
|
||||
|
||||
fun stepToEnd(){
|
||||
while(tilesToCheck.isNotEmpty())
|
||||
nextStep()
|
||||
}
|
||||
|
||||
fun stepUntilDestination(destination: TileInfo){
|
||||
while(!tilesReached.containsKey(destination) && tilesToCheck.isNotEmpty())
|
||||
nextStep()
|
||||
|
@ -94,6 +94,7 @@ class WorldScreen : CameraStageBaseScreen() {
|
||||
val cloneCivilization = gameClone.getPlayerCivilization()
|
||||
kotlin.concurrent.thread {
|
||||
civInfo.happiness = gameClone.getPlayerCivilization().getHappinessForNextTurn().values.sum().toInt()
|
||||
gameInfo.civilizations.forEach { it.setCitiesConnectedToCapitalTransients() }
|
||||
}
|
||||
|
||||
if(bottomBar.unitTable.selectedUnit!=null){
|
||||
|
Reference in New Issue
Block a user