mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-24 18:06:04 +07:00
Cities referenced by UUID (#1638)
* Cities referenced by UUID * UUID defaulted in CityInfo Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
parent
065e944896
commit
036d4058f1
@ -5,16 +5,17 @@ import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.automation.NextTurnAutomation
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.LocationAction
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.civilization.*
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.logic.trade.TradeOffer
|
||||
import com.unciv.logic.trade.TradeType
|
||||
import com.unciv.models.metadata.GameParameters
|
||||
import com.unciv.models.ruleset.Difficulty
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class GameInfo {
|
||||
@Transient lateinit var difficultyObject: Difficulty // Since this is static game-wide, and was taking a large part of nextTurn
|
||||
@ -58,6 +59,7 @@ class GameInfo {
|
||||
fun getCurrentPlayerCivilization() = currentPlayerCiv
|
||||
fun getBarbarianCivilization() = getCivilization("Barbarians")
|
||||
fun getDifficulty() = difficultyObject
|
||||
fun getCities() = civilizations.flatMap { it.cities }
|
||||
//endregion
|
||||
|
||||
fun nextTurn() {
|
||||
@ -265,11 +267,62 @@ class GameInfo {
|
||||
// This doesn't HAVE to go here, but why not.
|
||||
// As of version 3.1.3, trade offers of "Declare war on X" and "Introduction to X" were changed to X,
|
||||
// with the extra text being added only on UI display (solved a couple of problems).
|
||||
for(trade in civInfo.tradeRequests.map { it.trade })
|
||||
for(offer in trade.theirOffers.union(trade.ourOffers)){
|
||||
for(trade in civInfo.tradeRequests.map { it.trade }) {
|
||||
for (offer in trade.theirOffers.union(trade.ourOffers)) {
|
||||
offer.name = offer.name.removePrefix("Declare war on ")
|
||||
offer.name = offer.name.removePrefix("Introduction to ")
|
||||
}
|
||||
}
|
||||
|
||||
// As of 3.4.9 cities are referenced by id, not by name
|
||||
// So try to update every tradeRequest (if there are no conflicting names)
|
||||
for(tradeRequest in civInfo.tradeRequests) {
|
||||
val trade = tradeRequest.trade
|
||||
val toRemove = ArrayList<TradeOffer>()
|
||||
for (offer in trade.ourOffers) {
|
||||
if (offer.type == TradeType.City) {
|
||||
val countNames = civInfo.cities.count { it.name == offer.name}
|
||||
|
||||
if (countNames == 1)
|
||||
offer.name = civInfo.cities.first { it.name == offer.name}.id
|
||||
// There are conflicting names: we can't guess what city was being offered
|
||||
else if (countNames > 1)
|
||||
toRemove.add(offer)
|
||||
}
|
||||
}
|
||||
|
||||
trade.ourOffers.removeAll(toRemove)
|
||||
toRemove.clear()
|
||||
|
||||
val themCivInfo = getCivilization(tradeRequest.requestingCiv)
|
||||
for (offer in trade.theirOffers) {
|
||||
if (offer.type == TradeType.City) {
|
||||
val countNames = themCivInfo.cities.count { it.name == offer.name}
|
||||
|
||||
if (countNames == 1)
|
||||
offer.name = themCivInfo.cities.first { it.name == offer.name}.id
|
||||
// There are conflicting names: we can't guess what city was being offered
|
||||
else if (countNames > 1)
|
||||
toRemove.add(offer)
|
||||
}
|
||||
}
|
||||
|
||||
trade.theirOffers.removeAll(toRemove)
|
||||
}
|
||||
|
||||
// As of 3.4.9 cities are referenced by id, not by name
|
||||
val toRemove = ArrayList<PopupAlert>()
|
||||
for (popupAlert in civInfo.popupAlerts.filter { it.type == AlertType.CityConquered }) {
|
||||
val countNames = getCities().count { it.name == popupAlert.value }
|
||||
|
||||
if (countNames == 1)
|
||||
popupAlert.value = getCities().first { it.name == popupAlert.value }.id
|
||||
else if (countNames > 1) {
|
||||
// Sorry again, conflicting names: who knows what city you conquered?
|
||||
toRemove.add(popupAlert)
|
||||
}
|
||||
}
|
||||
civInfo.popupAlerts.removeAll(toRemove)
|
||||
}
|
||||
|
||||
for (civInfo in civilizations) civInfo.setNationTransient()
|
||||
|
@ -93,7 +93,7 @@ class SpecificUnitAutomation{
|
||||
fun automateSettlerActions(unit: MapUnit) {
|
||||
if(unit.getTile().militaryUnit==null) return // Don't move until you're accompanied by a military unit
|
||||
|
||||
val tilesNearCities = unit.civInfo.gameInfo.civilizations.flatMap { it.cities }
|
||||
val tilesNearCities = unit.civInfo.gameInfo.getCities()
|
||||
.flatMap {
|
||||
val distanceAwayFromCity =
|
||||
if (unit.civInfo.knows(it.civInfo)
|
||||
|
@ -45,14 +45,14 @@ class WorkerAutomation(val unit: MapUnit) {
|
||||
|
||||
val citiesToNumberOfUnimprovedTiles = HashMap<String, Int>()
|
||||
for (city in unit.civInfo.cities) {
|
||||
citiesToNumberOfUnimprovedTiles[city.name] =
|
||||
citiesToNumberOfUnimprovedTiles[city.id] =
|
||||
city.getTiles().count { it.isLand && it.civilianUnit == null
|
||||
&& tileCanBeImproved(it, unit.civInfo) }
|
||||
}
|
||||
|
||||
val mostUndevelopedCity = unit.civInfo.cities
|
||||
.filter { citiesToNumberOfUnimprovedTiles[it.name]!! > 0 }
|
||||
.sortedByDescending { citiesToNumberOfUnimprovedTiles[it.name] }
|
||||
.filter { citiesToNumberOfUnimprovedTiles[it.id]!! > 0 }
|
||||
.sortedByDescending { citiesToNumberOfUnimprovedTiles[it.id] }
|
||||
.firstOrNull { unit.movement.canReach(it.getCenterTile()) } //goto most undeveloped city
|
||||
if (mostUndevelopedCity != null && mostUndevelopedCity != unit.currentTile.owningCity) {
|
||||
val reachedTile = unit.movement.headTowards(mostUndevelopedCity.getCenterTile())
|
||||
|
@ -256,7 +256,7 @@ class Battle(val gameInfo:GameInfo) {
|
||||
}
|
||||
|
||||
if (attackerCiv.isPlayerCivilization()) {
|
||||
attackerCiv.popupAlerts.add(PopupAlert(AlertType.CityConquered, city.name))
|
||||
attackerCiv.popupAlerts.add(PopupAlert(AlertType.CityConquered, city.id))
|
||||
UncivGame.Current.settings.addCompletedTutorialTask("Conquer a city")
|
||||
}
|
||||
else {
|
||||
|
@ -19,8 +19,10 @@ import com.unciv.models.ruleset.tile.ResourceSupplyList
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.ui.utils.withoutItem
|
||||
import kotlin.math.*
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.collections.HashSet
|
||||
import kotlin.math.*
|
||||
|
||||
class CityInfo {
|
||||
@Transient lateinit var civInfo: CivilizationInfo
|
||||
@ -31,6 +33,7 @@ class CityInfo {
|
||||
@Transient var hasJustBeenConquered = false // this is so that military units can enter the city, even before we decide what to do with it
|
||||
|
||||
var location: Vector2 = Vector2.Zero
|
||||
var id: String = UUID.randomUUID().toString()
|
||||
var name: String = ""
|
||||
var foundingCiv = ""
|
||||
var turnAcquired = 0
|
||||
@ -99,15 +102,16 @@ class CityInfo {
|
||||
//region pure functions
|
||||
fun clone(): CityInfo {
|
||||
val toReturn = CityInfo()
|
||||
toReturn.location=location
|
||||
toReturn.name=name
|
||||
toReturn.health=health
|
||||
toReturn.location = location
|
||||
toReturn.id = id
|
||||
toReturn.name = name
|
||||
toReturn.health = health
|
||||
toReturn.population = population.clone()
|
||||
toReturn.cityConstructions=cityConstructions.clone()
|
||||
toReturn.cityConstructions = cityConstructions.clone()
|
||||
toReturn.expansion = expansion.clone()
|
||||
toReturn.tiles = tiles
|
||||
toReturn.workedTiles = workedTiles
|
||||
toReturn.isBeingRazed=isBeingRazed
|
||||
toReturn.isBeingRazed = isBeingRazed
|
||||
toReturn.attackedThisTurn = attackedThisTurn
|
||||
toReturn.resistanceCounter = resistanceCounter
|
||||
toReturn.foundingCiv = foundingCiv
|
||||
|
@ -128,7 +128,7 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo){
|
||||
val citiesReachedToMediums = HashMap<CityInfo, ArrayList<String>>()
|
||||
var citiesToCheck = mutableListOf(civInfo.getCapital())
|
||||
citiesReachedToMediums[civInfo.getCapital()] = arrayListOf("Start")
|
||||
val allCivCities = civInfo.gameInfo.civilizations.flatMap { it.cities }
|
||||
val allCivCities = civInfo.gameInfo.getCities()
|
||||
|
||||
val theWheelIsResearched = civInfo.tech.isResearched("The Wheel")
|
||||
|
||||
|
@ -38,7 +38,7 @@ class TradeEvaluation{
|
||||
TradeType.Technology -> return true
|
||||
TradeType.Introduction -> return true
|
||||
TradeType.WarDeclaration -> return true
|
||||
TradeType.City -> return offerer.cities.any { it.name==tradeOffer.name }
|
||||
TradeType.City -> return offerer.cities.any { it.id == tradeOffer.name }
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ class TradeEvaluation{
|
||||
else return 0 // why should we pay you to go fight someone...?
|
||||
}
|
||||
TradeType.City -> {
|
||||
val city = tradePartner.cities.first { it.name==offer.name }
|
||||
val city = tradePartner.cities.first { it.id==offer.name }
|
||||
val stats = city.cityStats.currentCityStats
|
||||
if(civInfo.getHappiness() + city.cityStats.happinessList.values.sum() < 0)
|
||||
return 0 // we can't really afford to go into negative happiness because of buying a city
|
||||
@ -204,7 +204,7 @@ class TradeEvaluation{
|
||||
}
|
||||
|
||||
TradeType.City -> {
|
||||
val city = civInfo.cities.first { it.name==offer.name }
|
||||
val city = civInfo.cities.first { it.id == offer.name }
|
||||
val stats = city.cityStats.currentCityStats
|
||||
val sumOfStats = stats.culture+stats.gold+stats.science+stats.production+stats.happiness+stats.food
|
||||
return sumOfStats.toInt() * 100
|
||||
|
@ -48,7 +48,7 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci
|
||||
if (!civInfo.isOneCityChallenger() && !otherCivilization.isOneCityChallenger()
|
||||
&& !civInfo.isCityState() && !otherCivilization.isCityState()) {
|
||||
for (city in civInfo.cities.filterNot { it.isCapital() })
|
||||
offers.add(TradeOffer(city.name, TradeType.City, 0))
|
||||
offers.add(TradeOffer(city.id, TradeType.City, 0))
|
||||
}
|
||||
|
||||
val otherCivsWeKnow = civInfo.getKnownCivs()
|
||||
@ -94,7 +94,7 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci
|
||||
to.tech.addTechnology(offer.name)
|
||||
}
|
||||
if (offer.type == TradeType.City) {
|
||||
val city = from.cities.first { it.name == offer.name }
|
||||
val city = from.cities.first { it.id == offer.name }
|
||||
city.moveToCiv(to)
|
||||
city.getCenterTile().getUnits().forEach { it.movement.teleportToClosestMoveableTile() }
|
||||
to.updateViewableTiles()
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.unciv.logic.trade
|
||||
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.translations.tr
|
||||
|
||||
data class TradeOffer(var name:String, var type: TradeType,
|
||||
@ -18,6 +19,7 @@ data class TradeOffer(var name:String, var type: TradeType,
|
||||
var offerText = when(type){
|
||||
TradeType.WarDeclaration -> "Declare war on [$name]"
|
||||
TradeType.Introduction -> "Introduction to [$name]"
|
||||
TradeType.City -> UncivGame.Current.gameInfo.getCities().first{ it.id == name }.name
|
||||
else -> name
|
||||
}.tr()
|
||||
if (type !in tradesToNotHaveNumbers) offerText += " ($amount)"
|
||||
|
@ -256,7 +256,7 @@ class Building : NamedStats(), IConstruction{
|
||||
|
||||
// Regular wonders
|
||||
if (isWonder){
|
||||
if(civInfo.gameInfo.civilizations.flatMap { it.cities }
|
||||
if(civInfo.gameInfo.getCities()
|
||||
.any {it.cityConstructions.isBuilt(name)})
|
||||
return "Wonder is already built"
|
||||
|
||||
|
@ -58,7 +58,7 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu
|
||||
}
|
||||
}
|
||||
AlertType.CityConquered -> {
|
||||
val city = worldScreen.gameInfo.civilizations.flatMap { it.cities }.first { it.name == popupAlert.value}
|
||||
val city = worldScreen.gameInfo.getCities().first { it.id == popupAlert.value }
|
||||
addGoodSizedLabel("What would you like to do with the city?",24)
|
||||
.padBottom(20f).row()
|
||||
val conqueringCiv = worldScreen.gameInfo.currentPlayerCiv
|
||||
|
Loading…
Reference in New Issue
Block a user