mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 05:46:43 -04:00
Performance improvement - Moved all autosaving to save a *clone* of the current game in another thread, thus allowing the user to continue his game without having to wait for the game to save
This commit is contained in:
parent
b4fece29e0
commit
fe67fda906
@ -98,5 +98,14 @@ class GameInfo {
|
|||||||
for (tile in city.getTiles()) tilesToCities.put(tile,city)
|
for (tile in city.getTiles()) tilesToCities.put(tile,city)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone():GameInfo{
|
||||||
|
val toReturn = GameInfo()
|
||||||
|
toReturn.civilizations.addAll(civilizations.map { it.clone() })
|
||||||
|
toReturn.tileMap=tileMap.clone()
|
||||||
|
toReturn.notifications.addAll(notifications)
|
||||||
|
toReturn.turns=turns
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ class GameSaver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun loadGame(GameName: String) : GameInfo {
|
fun loadGame(GameName: String) : GameInfo {
|
||||||
val game = Json().fromJson(GameInfo::class.java, getSave(GameName).readString())
|
val game = UnCivGame.Current.json.fromJson(GameInfo::class.java, getSave(GameName).readString())
|
||||||
game.setTransients()
|
game.setTransients()
|
||||||
return game
|
return game
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,7 @@ class UnitAutomation{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun tryAdvanceTowardsCloseEnemy(unit: MapUnit): Boolean {
|
private fun tryAdvanceTowardsCloseEnemy(unit: MapUnit): Boolean {
|
||||||
|
// this can be sped up if we check each layer separately
|
||||||
var closeEnemies = unit.getTile().getTilesInDistance(5)
|
var closeEnemies = unit.getTile().getTilesInDistance(5)
|
||||||
.filter{ containsAttackableEnemy(it, unit.civInfo) && unit.movementAlgs().canReach(it)}
|
.filter{ containsAttackableEnemy(it, unit.civInfo) && unit.movementAlgs().canReach(it)}
|
||||||
if(unit.baseUnit().unitType.isRanged())
|
if(unit.baseUnit().unitType.isRanged())
|
||||||
@ -171,8 +172,8 @@ class UnitAutomation{
|
|||||||
|
|
||||||
private fun tryHeadTowardsEnemyCity(unit: MapUnit): Boolean {
|
private fun tryHeadTowardsEnemyCity(unit: MapUnit): Boolean {
|
||||||
if(unit.civInfo.cities.isEmpty()) return false
|
if(unit.civInfo.cities.isEmpty()) return false
|
||||||
var enemyCities = unit.civInfo.exploredTiles.map { unit.civInfo.gameInfo.tileMap[it] }
|
var enemyCities = unit.civInfo.gameInfo.civilizations.filter { unit.civInfo.isAtWarWith(it) }
|
||||||
.filter { it.isCityCenter() && it.getOwner() != unit.civInfo }
|
.flatMap { it.cities }.filter { it.location in unit.civInfo.exploredTiles }.map { it.getCenterTile() }
|
||||||
if(unit.baseUnit().unitType.isRanged())
|
if(unit.baseUnit().unitType.isRanged())
|
||||||
enemyCities = enemyCities.filterNot { it.getCity()!!.health==1 }
|
enemyCities = enemyCities.filterNot { it.getCity()!!.health==1 }
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class CityConstructions {
|
|||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
for (building in getBuiltBuildings())
|
for (building in getBuiltBuildings())
|
||||||
stats.add(building.getStats(cityInfo.civInfo.policies.adoptedPolicies))
|
stats.add(building.getStats(cityInfo.civInfo.policies.adoptedPolicies))
|
||||||
stats.science += (cityInfo.buildingUniques.count({ it == "+1 Science Per 2 Population" }) * cityInfo.population.population / 2).toFloat()
|
stats.science += (cityInfo.getBuildingUniques().count({ it == "+1 Science Per 2 Population" }) * cityInfo.population.population / 2).toFloat()
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,4 +170,12 @@ class CityConstructions {
|
|||||||
Automation().chooseNextConstruction(this)
|
Automation().chooseNextConstruction(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): CityConstructions {
|
||||||
|
val toReturn = CityConstructions()
|
||||||
|
toReturn.currentConstruction=currentConstruction
|
||||||
|
toReturn.builtBuildings.addAll(builtBuildings)
|
||||||
|
toReturn.inProgressConstructions.putAll(inProgressConstructions)
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
} // for json parsing, we need to have a default constructor
|
} // for json parsing, we need to have a default constructor
|
@ -24,7 +24,7 @@ class CityExpansionManager {
|
|||||||
fun getCultureToNextTile(): Int {
|
fun getCultureToNextTile(): Int {
|
||||||
val numTilesClaimed = cityInfo.tiles.size - 7
|
val numTilesClaimed = cityInfo.tiles.size - 7
|
||||||
var cultureToNextTile = 6 * Math.pow(numTilesClaimed + 1.4813, 1.3)
|
var cultureToNextTile = 6 * Math.pow(numTilesClaimed + 1.4813, 1.3)
|
||||||
if (cityInfo.civInfo.buildingUniques.contains("Cost of acquiring new tiles reduced by 25%")) cultureToNextTile *= 0.75 //Speciality of Angkor Wat
|
if (cityInfo.civInfo.getBuildingUniques().contains("Cost of acquiring new tiles reduced by 25%")) cultureToNextTile *= 0.75 //Speciality of Angkor Wat
|
||||||
if (cityInfo.civInfo.policies.isAdopted("Tradition")) cultureToNextTile *= 0.75
|
if (cityInfo.civInfo.policies.isAdopted("Tradition")) cultureToNextTile *= 0.75
|
||||||
return Math.round(cultureToNextTile).toInt()
|
return Math.round(cultureToNextTile).toInt()
|
||||||
}
|
}
|
||||||
@ -69,4 +69,10 @@ class CityExpansionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): CityExpansionManager {
|
||||||
|
val toReturn = CityExpansionManager()
|
||||||
|
toReturn.cultureStored=cultureStored
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -58,8 +58,7 @@ class CityInfo {
|
|||||||
return cityResources
|
return cityResources
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildingUniques: List<String?>
|
fun getBuildingUniques(): List<String?> = cityConstructions.getBuiltBuildings().filter { it.unique != null }.map { it.unique }
|
||||||
get() = cityConstructions.getBuiltBuildings().filter { it.unique!=null }.map { it.unique }
|
|
||||||
|
|
||||||
fun getGreatPersonPoints(): Stats {
|
fun getGreatPersonPoints(): Stats {
|
||||||
var greatPersonPoints = population.getSpecialists().times(3f)
|
var greatPersonPoints = population.getSpecialists().times(3f)
|
||||||
@ -68,7 +67,7 @@ class CityInfo {
|
|||||||
if (building.greatPersonPoints != null)
|
if (building.greatPersonPoints != null)
|
||||||
greatPersonPoints.add(building.greatPersonPoints!!)
|
greatPersonPoints.add(building.greatPersonPoints!!)
|
||||||
|
|
||||||
if (civInfo.buildingUniques.contains("+33% great person generation in all cities"))
|
if (civInfo.getBuildingUniques().contains("+33% great person generation in all cities"))
|
||||||
greatPersonPoints = greatPersonPoints.times(1.33f)
|
greatPersonPoints = greatPersonPoints.times(1.33f)
|
||||||
if (civInfo.policies.isAdopted("Entrepreneurship"))
|
if (civInfo.policies.isAdopted("Entrepreneurship"))
|
||||||
greatPersonPoints.gold *= 1.25f
|
greatPersonPoints.gold *= 1.25f
|
||||||
@ -173,4 +172,18 @@ class CityInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {return name} // for debug
|
override fun toString(): String {return name} // for debug
|
||||||
|
|
||||||
|
fun clone(): CityInfo {
|
||||||
|
val toReturn = CityInfo()
|
||||||
|
toReturn.population = population.clone()
|
||||||
|
toReturn.health=health
|
||||||
|
toReturn.name=name
|
||||||
|
toReturn.tiles.addAll(tiles)
|
||||||
|
toReturn.workedTiles.addAll(workedTiles)
|
||||||
|
toReturn.cityConstructions=cityConstructions.clone()
|
||||||
|
toReturn.expansion = expansion.clone()
|
||||||
|
toReturn.isBeingRazed=isBeingRazed
|
||||||
|
toReturn.location=location
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
@ -32,7 +32,7 @@ class CityStats {
|
|||||||
val civInfo = cityInfo.civInfo
|
val civInfo = cityInfo.civInfo
|
||||||
var goldFromTradeRoute = civInfo.getCapital().population.population * 0.15 + cityInfo.population.population * 1.1 - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5)
|
var goldFromTradeRoute = civInfo.getCapital().population.population * 0.15 + cityInfo.population.population * 1.1 - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5)
|
||||||
if (civInfo.policies.isAdopted("Trade Unions")) goldFromTradeRoute += 2.0
|
if (civInfo.policies.isAdopted("Trade Unions")) goldFromTradeRoute += 2.0
|
||||||
if (civInfo.buildingUniques.contains("Gold from all trade routes +25%")) goldFromTradeRoute *= 1.25 // Machu Pichu speciality
|
if (civInfo.getBuildingUniques().contains("Gold from all trade routes +25%")) goldFromTradeRoute *= 1.25 // Machu Pichu speciality
|
||||||
stats.gold += goldFromTradeRoute.toFloat()
|
stats.gold += goldFromTradeRoute.toFloat()
|
||||||
}
|
}
|
||||||
return stats
|
return stats
|
||||||
@ -46,7 +46,7 @@ class CityStats {
|
|||||||
"Gold" -> stats.gold += production / 4
|
"Gold" -> stats.gold += production / 4
|
||||||
"Science" -> {
|
"Science" -> {
|
||||||
var scienceProduced = production / 4
|
var scienceProduced = production / 4
|
||||||
if (cityInfo.civInfo.buildingUniques.contains("ScienceConversionIncrease")) scienceProduced *= 1.33f
|
if (cityInfo.civInfo.getBuildingUniques().contains("ScienceConversionIncrease")) scienceProduced *= 1.33f
|
||||||
if (cityInfo.civInfo.policies.isAdopted("Rationalism")) scienceProduced *= 1.33f
|
if (cityInfo.civInfo.policies.isAdopted("Rationalism")) scienceProduced *= 1.33f
|
||||||
stats.science += scienceProduced
|
stats.science += scienceProduced
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ class CityStats {
|
|||||||
var unhappinessFromCitizens = cityInfo.population.population.toFloat()
|
var unhappinessFromCitizens = cityInfo.population.population.toFloat()
|
||||||
if (civInfo.policies.isAdopted("Democracy"))
|
if (civInfo.policies.isAdopted("Democracy"))
|
||||||
unhappinessFromCitizens -= cityInfo.population.getNumberOfSpecialists() * 0.5f
|
unhappinessFromCitizens -= cityInfo.population.getNumberOfSpecialists() * 0.5f
|
||||||
if (civInfo.buildingUniques.contains("Unhappiness from population decreased by 10%"))
|
if (civInfo.getBuildingUniques().contains("Unhappiness from population decreased by 10%"))
|
||||||
unhappinessFromCitizens *= 0.9f
|
unhappinessFromCitizens *= 0.9f
|
||||||
if (civInfo.policies.isAdopted("Meritocracy"))
|
if (civInfo.policies.isAdopted("Meritocracy"))
|
||||||
unhappinessFromCitizens *= 0.95f
|
unhappinessFromCitizens *= 0.95f
|
||||||
@ -181,7 +181,7 @@ class CityStats {
|
|||||||
|
|
||||||
private fun getStatPercentBonusesFromWonders(): Stats {
|
private fun getStatPercentBonusesFromWonders(): Stats {
|
||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
val civUniques = cityInfo.civInfo.buildingUniques
|
val civUniques = cityInfo.civInfo.getBuildingUniques()
|
||||||
if (civUniques.contains("Culture in all cities increased by 25%")) stats.culture += 25f
|
if (civUniques.contains("Culture in all cities increased by 25%")) stats.culture += 25f
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ class PopulationManager {
|
|||||||
// growth!
|
// growth!
|
||||||
{
|
{
|
||||||
foodStored -= getFoodToNextPopulation()
|
foodStored -= getFoodToNextPopulation()
|
||||||
if (cityInfo.buildingUniques.contains("40% of food is carried over after a new citizen is born")) foodStored += (0.4f * getFoodToNextPopulation()).toInt() // Aqueduct special
|
if (cityInfo.getBuildingUniques().contains("40% of food is carried over after a new citizen is born")) foodStored += (0.4f * getFoodToNextPopulation()).toInt() // Aqueduct special
|
||||||
population++
|
population++
|
||||||
autoAssignPopulation()
|
autoAssignPopulation()
|
||||||
cityInfo.civInfo.addNotification(cityInfo.name + " {has grown}!", cityInfo.location, Color.GREEN)
|
cityInfo.civInfo.addNotification(cityInfo.name + " {has grown}!", cityInfo.location, Color.GREEN)
|
||||||
@ -89,4 +89,11 @@ class PopulationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): PopulationManager {
|
||||||
|
val toReturn = PopulationManager()
|
||||||
|
toReturn.population=population
|
||||||
|
toReturn.foodStored=foodStored
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -136,7 +136,7 @@ class CivilizationInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buildingUniques.contains("Provides 1 happiness per social policy"))
|
if (getBuildingUniques().contains("Provides 1 happiness per social policy"))
|
||||||
statMap["Policies"] = policies.getAdoptedPolicies().count { !it.endsWith("Complete") }.toFloat()
|
statMap["Policies"] = policies.getAdoptedPolicies().count { !it.endsWith("Complete") }.toFloat()
|
||||||
|
|
||||||
return statMap
|
return statMap
|
||||||
@ -151,8 +151,7 @@ class CivilizationInfo {
|
|||||||
return civResources
|
return civResources
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildingUniques: List<String>
|
fun getBuildingUniques(): List<String> = cities.flatMap { it.cityConstructions.getBuiltBuildings().map { it.unique }.filterNotNull() }.distinct()
|
||||||
get() = cities.flatMap{ it.cityConstructions.getBuiltBuildings().map { it.unique }.filterNotNull() }.distinct()
|
|
||||||
|
|
||||||
|
|
||||||
constructor()
|
constructor()
|
||||||
@ -305,6 +304,22 @@ class CivilizationInfo {
|
|||||||
if(isAtWarWith(otherCiv)) return true
|
if(isAtWarWith(otherCiv)) return true
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): CivilizationInfo {
|
||||||
|
val toReturn = CivilizationInfo()
|
||||||
|
toReturn.exploredTiles=exploredTiles.toHashSet()
|
||||||
|
toReturn.diplomacy.putAll(diplomacy.values.map { it.clone() }.associateBy { it.otherCivName })
|
||||||
|
toReturn.cities.addAll(cities.map { it.clone() })
|
||||||
|
toReturn.tech = tech.clone()
|
||||||
|
toReturn.difficulty=difficulty
|
||||||
|
toReturn.policies = policies.clone()
|
||||||
|
toReturn.happiness=happiness
|
||||||
|
toReturn.greatPeople=greatPeople.clone()
|
||||||
|
toReturn.gold = gold
|
||||||
|
toReturn.goldenAges = goldenAges.clone()
|
||||||
|
toReturn.civName=civName
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,4 +94,11 @@ class DiplomacyManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun canDeclareWar() = turnsToPeaceTreaty()==0
|
fun canDeclareWar() = turnsToPeaceTreaty()==0
|
||||||
|
fun clone(): DiplomacyManager {
|
||||||
|
val toReturn = DiplomacyManager()
|
||||||
|
toReturn.otherCivName=otherCivName
|
||||||
|
toReturn.diplomaticStatus=diplomaticStatus
|
||||||
|
toReturn.trades.addAll(trades.map { it.clone() })
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
@ -2,7 +2,7 @@ package com.unciv.logic.civilization
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
|
||||||
class GoldenAgeManager {
|
class GoldenAgeManager{
|
||||||
@Transient
|
@Transient
|
||||||
lateinit var civInfo: CivilizationInfo
|
lateinit var civInfo: CivilizationInfo
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ class GoldenAgeManager {
|
|||||||
|
|
||||||
fun enterGoldenAge() {
|
fun enterGoldenAge() {
|
||||||
var turnsToGoldenAge = 10.0
|
var turnsToGoldenAge = 10.0
|
||||||
if (civInfo.buildingUniques.contains("Golden Age length increases +50%")) turnsToGoldenAge *= 1.5
|
if (civInfo.getBuildingUniques().contains("Golden Age length increases +50%")) turnsToGoldenAge *= 1.5
|
||||||
if (civInfo.policies.isAdopted("Freedom Complete")) turnsToGoldenAge *= 1.5
|
if (civInfo.policies.isAdopted("Freedom Complete")) turnsToGoldenAge *= 1.5
|
||||||
turnsLeftForCurrentGoldenAge += turnsToGoldenAge.toInt()
|
turnsLeftForCurrentGoldenAge += turnsToGoldenAge.toInt()
|
||||||
civInfo.addNotification("{You have entered a golden age}!", null, Color.GOLD)
|
civInfo.addNotification("{You have entered a golden age}!", null, Color.GOLD)
|
||||||
@ -35,4 +35,12 @@ class GoldenAgeManager {
|
|||||||
numberOfGoldenAges++
|
numberOfGoldenAges++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): GoldenAgeManager {
|
||||||
|
val toReturn = GoldenAgeManager()
|
||||||
|
toReturn.numberOfGoldenAges=numberOfGoldenAges
|
||||||
|
toReturn.storedHappiness=storedHappiness
|
||||||
|
toReturn.turnsLeftForCurrentGoldenAge=turnsLeftForCurrentGoldenAge
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import com.unciv.models.stats.Stats
|
|||||||
|
|
||||||
class GreatPersonManager {
|
class GreatPersonManager {
|
||||||
private var pointsForNextGreatPerson = 100
|
private var pointsForNextGreatPerson = 100
|
||||||
private val greatPersonPoints = Stats()
|
private var greatPersonPoints = Stats()
|
||||||
var freeGreatPeople=0
|
var freeGreatPeople=0
|
||||||
|
|
||||||
fun getNewGreatPerson(): String? {
|
fun getNewGreatPerson(): String? {
|
||||||
@ -27,4 +27,12 @@ class GreatPersonManager {
|
|||||||
greatPersonPoints.add(greatPersonPoints)
|
greatPersonPoints.add(greatPersonPoints)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): GreatPersonManager {
|
||||||
|
val toReturn = GreatPersonManager()
|
||||||
|
toReturn.freeGreatPeople=freeGreatPeople
|
||||||
|
toReturn.greatPersonPoints=greatPersonPoints.clone()
|
||||||
|
toReturn.pointsForNextGreatPerson=pointsForNextGreatPerson
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ class PolicyManager {
|
|||||||
var cityModifier = 0.3 * (civInfo.cities.size - 1)
|
var cityModifier = 0.3 * (civInfo.cities.size - 1)
|
||||||
if (isAdopted("Representation")) cityModifier *= (2 / 3f).toDouble()
|
if (isAdopted("Representation")) cityModifier *= (2 / 3f).toDouble()
|
||||||
if (isAdopted("Piety Complete")) baseCost *= 0.9
|
if (isAdopted("Piety Complete")) baseCost *= 0.9
|
||||||
if (civInfo.buildingUniques.contains("Culture cost of adopting new Policies reduced by 10%")) baseCost *= 0.9
|
if (civInfo.getBuildingUniques().contains("Culture cost of adopting new Policies reduced by 10%")) baseCost *= 0.9
|
||||||
val cost: Int = Math.round(baseCost * (1 + cityModifier)).toInt()
|
val cost: Int = Math.round(baseCost * (1 + cityModifier)).toInt()
|
||||||
return cost - (cost % 5)
|
return cost - (cost % 5)
|
||||||
}
|
}
|
||||||
@ -84,4 +84,14 @@ class PolicyManager {
|
|||||||
shouldOpenPolicyPicker = true
|
shouldOpenPolicyPicker = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): PolicyManager {
|
||||||
|
val toReturn = PolicyManager()
|
||||||
|
toReturn.numberOfAdoptedPolicies=numberOfAdoptedPolicies
|
||||||
|
toReturn.adoptedPolicies.addAll(adoptedPolicies)
|
||||||
|
toReturn.freePolicies=freePolicies
|
||||||
|
toReturn.shouldOpenPolicyPicker=shouldOpenPolicyPicker
|
||||||
|
toReturn.storedCulture=storedCulture
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -92,6 +92,15 @@ class TechManager {
|
|||||||
city.cityConstructions.currentConstruction = currentConstructionUnit.upgradesTo!!
|
city.cityConstructions.currentConstruction = currentConstructionUnit.upgradesTo!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): TechManager {
|
||||||
|
val toReturn = TechManager()
|
||||||
|
toReturn.techsResearched.addAll(techsResearched)
|
||||||
|
toReturn.freeTechs=freeTechs
|
||||||
|
toReturn.techsInProgress.putAll(techsInProgress)
|
||||||
|
toReturn.techsToResearch.addAll(techsToResearch)
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ class MapUnit {
|
|||||||
|
|
||||||
lateinit var owner: String
|
lateinit var owner: String
|
||||||
lateinit var name: String
|
lateinit var name: String
|
||||||
var maxMovement: Int = 0
|
|
||||||
var currentMovement: Float = 0f
|
var currentMovement: Float = 0f
|
||||||
var health:Int = 100
|
var health:Int = 100
|
||||||
var action: String? = null // work, automation, fortifying, I dunno what.
|
var action: String? = null // work, automation, fortifying, I dunno what.
|
||||||
@ -23,11 +22,12 @@ class MapUnit {
|
|||||||
|
|
||||||
@Transient lateinit var baseUnit: BaseUnit
|
@Transient lateinit var baseUnit: BaseUnit
|
||||||
fun baseUnit(): BaseUnit = baseUnit
|
fun baseUnit(): BaseUnit = baseUnit
|
||||||
fun getMovementString(): String = DecimalFormat("0.#").format(currentMovement.toDouble()) + "/" + maxMovement
|
fun getMovementString(): String = DecimalFormat("0.#").format(currentMovement.toDouble()) + "/" + getMaxMovement()
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
internal lateinit var currentTile :TileInfo
|
internal lateinit var currentTile :TileInfo
|
||||||
fun getTile(): TileInfo = currentTile
|
fun getTile(): TileInfo = currentTile
|
||||||
|
fun getMaxMovement() = baseUnit.movement
|
||||||
|
|
||||||
fun getDistanceToTiles(): HashMap<TileInfo, Float> {
|
fun getDistanceToTiles(): HashMap<TileInfo, Float> {
|
||||||
val tile = getTile()
|
val tile = getTile()
|
||||||
@ -63,7 +63,7 @@ class MapUnit {
|
|||||||
|
|
||||||
private fun doPostTurnAction() {
|
private fun doPostTurnAction() {
|
||||||
if (name == "Worker" && getTile().improvementInProgress != null) workOnImprovement()
|
if (name == "Worker" && getTile().improvementInProgress != null) workOnImprovement()
|
||||||
if(currentMovement==maxMovement.toFloat()
|
if(currentMovement== getMaxMovement().toFloat()
|
||||||
&& isFortified()){
|
&& isFortified()){
|
||||||
val currentTurnsFortified = getFortificationTurns()
|
val currentTurnsFortified = getFortificationTurns()
|
||||||
if(currentTurnsFortified<2) action = "Fortify ${currentTurnsFortified+1}"
|
if(currentTurnsFortified<2) action = "Fortify ${currentTurnsFortified+1}"
|
||||||
@ -76,7 +76,7 @@ class MapUnit {
|
|||||||
if (tile.turnsToImprovement != 0) return
|
if (tile.turnsToImprovement != 0) return
|
||||||
when {
|
when {
|
||||||
tile.improvementInProgress!!.startsWith("Remove") -> {
|
tile.improvementInProgress!!.startsWith("Remove") -> {
|
||||||
val tileImprovement = tile.tileImprovement
|
val tileImprovement = tile.getTileImprovement()
|
||||||
if(tileImprovement!=null
|
if(tileImprovement!=null
|
||||||
&& tileImprovement.terrainsCanBeBuiltOn.contains(tile.terrainFeature)
|
&& tileImprovement.terrainsCanBeBuiltOn.contains(tile.terrainFeature)
|
||||||
&& !tileImprovement.terrainsCanBeBuiltOn.contains(tile.baseTerrain)) {
|
&& !tileImprovement.terrainsCanBeBuiltOn.contains(tile.baseTerrain)) {
|
||||||
@ -124,14 +124,14 @@ class MapUnit {
|
|||||||
|
|
||||||
fun endTurn() {
|
fun endTurn() {
|
||||||
doPostTurnAction()
|
doPostTurnAction()
|
||||||
if(currentMovement==maxMovement.toFloat() // didn't move this turn
|
if(currentMovement== getMaxMovement().toFloat() // didn't move this turn
|
||||||
|| getSpecialAbilities().contains("Unit will heal every turn, even if it performs an action")){
|
|| getSpecialAbilities().contains("Unit will heal every turn, even if it performs an action")){
|
||||||
heal()
|
heal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startTurn(){
|
fun startTurn(){
|
||||||
currentMovement = maxMovement.toFloat()
|
currentMovement = getMaxMovement().toFloat()
|
||||||
attacksThisTurn=0
|
attacksThisTurn=0
|
||||||
val tileOwner = getTile().getOwner()
|
val tileOwner = getTile().getOwner()
|
||||||
if(tileOwner!=null && !civInfo.canEnterTiles(tileOwner)) // if an enemy city expanded onto this tile while I was in it
|
if(tileOwner!=null && !civInfo.canEnterTiles(tileOwner)) // if an enemy city expanded onto this tile while I was in it
|
||||||
@ -226,4 +226,16 @@ class MapUnit {
|
|||||||
if(hasUnique("+1 Range")) range++
|
if(hasUnique("+1 Range")) range++
|
||||||
return range
|
return range
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): MapUnit {
|
||||||
|
val toReturn = MapUnit()
|
||||||
|
toReturn.action=action
|
||||||
|
toReturn.currentMovement=currentMovement
|
||||||
|
toReturn.name=name
|
||||||
|
toReturn.promotions=promotions.clone()
|
||||||
|
toReturn.health=health
|
||||||
|
toReturn.attacksThisTurn=attacksThisTurn
|
||||||
|
toReturn.owner=owner
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
@ -43,8 +43,7 @@ open class TileInfo {
|
|||||||
|
|
||||||
fun isCityCenter(): Boolean = getCity()?.location == position
|
fun isCityCenter(): Boolean = getCity()?.location == position
|
||||||
|
|
||||||
val tileImprovement: TileImprovement?
|
fun getTileImprovement(): TileImprovement? = if (improvement == null) null else GameBasics.TileImprovements[improvement!!]
|
||||||
get() = if (improvement == null) null else GameBasics.TileImprovements[improvement!!]
|
|
||||||
|
|
||||||
|
|
||||||
// This is for performance - since we access the neighbors of a tile ALL THE TIME,
|
// This is for performance - since we access the neighbors of a tile ALL THE TIME,
|
||||||
@ -103,7 +102,7 @@ open class TileInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val improvement = tileImprovement
|
val improvement = getTileImprovement()
|
||||||
if (improvement != null) {
|
if (improvement != null) {
|
||||||
if (resource != null && getTileResource().improvement == improvement.name)
|
if (resource != null && getTileResource().improvement == improvement.name)
|
||||||
stats.add(getTileResource().improvementStats!!) // resource-specifc improvement
|
stats.add(getTileResource().improvementStats!!) // resource-specifc improvement
|
||||||
@ -125,7 +124,7 @@ open class TileInfo {
|
|||||||
if (stats.production < 0) stats.production = 0f
|
if (stats.production < 0) stats.production = 0f
|
||||||
|
|
||||||
if ("Jungle" == terrainFeature && city != null
|
if ("Jungle" == terrainFeature && city != null
|
||||||
&& city.buildingUniques.contains("Jungles provide +2 science"))
|
&& city.getBuildingUniques().contains("Jungles provide +2 science"))
|
||||||
stats.science += 2f
|
stats.science += 2f
|
||||||
if (stats.gold != 0f && observingCiv.goldenAges.isGoldenAge())
|
if (stats.gold != 0f && observingCiv.goldenAges.isGoldenAge())
|
||||||
stats.gold++
|
stats.gold++
|
||||||
@ -211,4 +210,18 @@ open class TileInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun arialDistanceTo(otherTile:TileInfo) = abs(position.x-otherTile.position.x) + abs(position.y-otherTile.position.y)
|
fun arialDistanceTo(otherTile:TileInfo) = abs(position.x-otherTile.position.x) + abs(position.y-otherTile.position.y)
|
||||||
|
fun clone(): TileInfo {
|
||||||
|
val toReturn = TileInfo()
|
||||||
|
if(civilianUnit!=null) toReturn.civilianUnit=civilianUnit!!.clone()
|
||||||
|
if(militaryUnit!=null) toReturn.militaryUnit=militaryUnit!!.clone()
|
||||||
|
toReturn.improvement=improvement
|
||||||
|
toReturn.position=position
|
||||||
|
toReturn.baseTerrain=baseTerrain
|
||||||
|
toReturn.terrainFeature=terrainFeature
|
||||||
|
toReturn.improvementInProgress=improvementInProgress
|
||||||
|
toReturn.resource=resource
|
||||||
|
toReturn.roadStatus=roadStatus
|
||||||
|
toReturn.turnsToImprovement=turnsToImprovement
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
@ -81,4 +81,10 @@ class TileMap {
|
|||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): TileMap {
|
||||||
|
val toReturn = TileMap()
|
||||||
|
toReturn.tiles.putAll(tiles.values.map { it.clone() }.associateBy{it.position.toString()})
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -78,7 +78,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
|||||||
while (true) {
|
while (true) {
|
||||||
val newTilesToCheck = ArrayList<TileInfo>()
|
val newTilesToCheck = ArrayList<TileInfo>()
|
||||||
val distanceToDestination = HashMap<TileInfo, Float>()
|
val distanceToDestination = HashMap<TileInfo, Float>()
|
||||||
val movementThisTurn = if (distance == 1) unit.currentMovement else unit.maxMovement.toFloat()
|
val movementThisTurn = if (distance == 1) unit.currentMovement else unit.getMaxMovement().toFloat()
|
||||||
for (tileToCheck in tilesToCheck) {
|
for (tileToCheck in tilesToCheck) {
|
||||||
val distanceToTilesThisTurn = getDistanceToTilesWithinTurn(tileToCheck.position, movementThisTurn)
|
val distanceToTilesThisTurn = getDistanceToTilesWithinTurn(tileToCheck.position, movementThisTurn)
|
||||||
for (reachableTile in distanceToTilesThisTurn.keys) {
|
for (reachableTile in distanceToTilesThisTurn.keys) {
|
||||||
|
@ -23,4 +23,12 @@ class UnitPromotions{
|
|||||||
.filter { unit.baseUnit().unitType.toString() in it.unitTypes && it.name !in promotions }
|
.filter { unit.baseUnit().unitType.toString() in it.unitTypes && it.name !in promotions }
|
||||||
.filter { it.prerequisites.isEmpty() || it.prerequisites.any { p->p in promotions } }
|
.filter { it.prerequisites.isEmpty() || it.prerequisites.any { p->p in promotions } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): UnitPromotions {
|
||||||
|
val toReturn = UnitPromotions()
|
||||||
|
toReturn.XP=XP
|
||||||
|
toReturn.promotions.addAll(promotions)
|
||||||
|
toReturn.numberOfPromotions=numberOfPromotions
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
@ -24,4 +24,11 @@ class Trade{
|
|||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone():Trade{
|
||||||
|
val toReturn = Trade()
|
||||||
|
toReturn.theirOffers.addAll(theirOffers)
|
||||||
|
toReturn.ourOffers.addAll(ourOffers)
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
@ -13,4 +13,5 @@ class TradeOffersList: ArrayList<TradeOffer>(){
|
|||||||
if(equivalentOffer.amount==0) remove(equivalentOffer)
|
if(equivalentOffer.amount==0) remove(equivalentOffer)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -186,7 +186,7 @@ class Building : NamedStats(), IConstruction{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ("Spaceship part" == unique) {
|
if ("Spaceship part" == unique) {
|
||||||
if (!civInfo.buildingUniques.contains("Enables construction of Spaceship parts")) return false
|
if (!civInfo.getBuildingUniques().contains("Enables construction of Spaceship parts")) return false
|
||||||
if (civInfo.scienceVictory.unconstructedParts()[name] == 0) return false // Don't need to build any more of these!
|
if (civInfo.scienceVictory.unconstructedParts()[name] == 0) return false // Don't need to build any more of these!
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -18,7 +18,7 @@ class TileImprovement : NamedStats(), ICivilopedia {
|
|||||||
private val turnsToBuild: Int = 0 // This is the base cost.
|
private val turnsToBuild: Int = 0 // This is the base cost.
|
||||||
fun getTurnsToBuild(civInfo: CivilizationInfo): Int {
|
fun getTurnsToBuild(civInfo: CivilizationInfo): Int {
|
||||||
var realTurnsToBuild = turnsToBuild.toFloat()
|
var realTurnsToBuild = turnsToBuild.toFloat()
|
||||||
if (civInfo.buildingUniques.contains("Worker construction increased 25%, provides 2 free workers"))
|
if (civInfo.getBuildingUniques().contains("Worker construction increased 25%, provides 2 free workers"))
|
||||||
realTurnsToBuild *= 0.75f
|
realTurnsToBuild *= 0.75f
|
||||||
if (civInfo.policies.isAdopted("Citizenship"))
|
if (civInfo.policies.isAdopted("Citizenship"))
|
||||||
realTurnsToBuild *= 0.75f
|
realTurnsToBuild *= 0.75f
|
||||||
|
@ -76,7 +76,6 @@ class BaseUnit : INamed, IConstruction, ICivilopedia {
|
|||||||
fun getMapUnit(): MapUnit {
|
fun getMapUnit(): MapUnit {
|
||||||
val unit = MapUnit()
|
val unit = MapUnit()
|
||||||
unit.name = name
|
unit.name = name
|
||||||
unit.maxMovement = movement
|
|
||||||
unit.currentMovement = movement.toFloat()
|
unit.currentMovement = movement.toFloat()
|
||||||
unit.setTransients()
|
unit.setTransients()
|
||||||
return unit
|
return unit
|
||||||
|
@ -213,7 +213,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
|
|||||||
table.add(unit.name.tr())
|
table.add(unit.name.tr())
|
||||||
if(baseUnit.strength>0) table.add(baseUnit.strength.toString()) else table.add()
|
if(baseUnit.strength>0) table.add(baseUnit.strength.toString()) else table.add()
|
||||||
if(baseUnit.rangedStrength>0) table.add(baseUnit.rangedStrength.toString()) else table.add()
|
if(baseUnit.rangedStrength>0) table.add(baseUnit.rangedStrength.toString()) else table.add()
|
||||||
table.add(unit.currentMovement.toString()+"/"+unit.maxMovement)
|
table.add(unit.currentMovement.toString()+"/"+unit.getMaxMovement())
|
||||||
val closestCity = unit.getTile().getTilesInDistance(3).firstOrNull{it.isCityCenter()}
|
val closestCity = unit.getTile().getTilesInDistance(3).firstOrNull{it.isCityCenter()}
|
||||||
if (closestCity!=null) table.add(closestCity.getCity()!!.name) else table.add()
|
if (closestCity!=null) table.add(closestCity.getCity()!!.name) else table.add()
|
||||||
table.row()
|
table.row()
|
||||||
|
@ -58,7 +58,7 @@ class VictoryScreen : PickerScreen() {
|
|||||||
fun scienceVictoryColumn():Table{
|
fun scienceVictoryColumn():Table{
|
||||||
val t = Table()
|
val t = Table()
|
||||||
t.defaults().pad(5f)
|
t.defaults().pad(5f)
|
||||||
t.add(getMilestone("Built Apollo Program",civInfo.buildingUniques.contains("Enables construction of Spaceship parts"))).row()
|
t.add(getMilestone("Built Apollo Program",civInfo.getBuildingUniques().contains("Enables construction of Spaceship parts"))).row()
|
||||||
|
|
||||||
val scienceVictory = civInfo.scienceVictory
|
val scienceVictory = civInfo.scienceVictory
|
||||||
|
|
||||||
|
@ -177,15 +177,23 @@ class WorldScreen : CameraStageBaseScreen() {
|
|||||||
|
|
||||||
kotlin.concurrent.thread {
|
kotlin.concurrent.thread {
|
||||||
try {
|
try {
|
||||||
game.gameInfo.nextTurn()
|
gameInfo.nextTurn()
|
||||||
GameSaver().saveGame(game.gameInfo, "Autosave")
|
|
||||||
}
|
}
|
||||||
catch (ex:Exception){
|
catch (ex:Exception){
|
||||||
UnCivGame.Current.settings.hasCrashedRecently=true
|
game.settings.hasCrashedRecently=true
|
||||||
UnCivGame.Current.settings.save()
|
game.settings.save()
|
||||||
throw ex
|
throw ex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val gameInfoClone = gameInfo.clone()
|
||||||
|
kotlin.concurrent.thread {
|
||||||
|
// the save takes a long time( up to a second!) and we can do it while the player continues his game.
|
||||||
|
// On the other hand if we alter the game data while it's being serialized we could get a concurrent modification exception.
|
||||||
|
// So what we do is we clone all the game data and serialize the clone.
|
||||||
|
GameSaver().saveGame(gameInfoClone, "Autosave")
|
||||||
|
nextTurnButton.enable() // only enable the user to next turn once we've saved the current one
|
||||||
|
}
|
||||||
|
|
||||||
// If we put this BEFORE the save game, then we try to save the game...
|
// If we put this BEFORE the save game, then we try to save the game...
|
||||||
// but the main thread does other stuff, including showing tutorials which guess what? Changes the game data
|
// but the main thread does other stuff, including showing tutorials which guess what? Changes the game data
|
||||||
// BOOM! Exception!
|
// BOOM! Exception!
|
||||||
@ -193,7 +201,6 @@ class WorldScreen : CameraStageBaseScreen() {
|
|||||||
shouldUpdate=true
|
shouldUpdate=true
|
||||||
|
|
||||||
nextTurnButton.setText("Next turn".tr())
|
nextTurnButton.setText("Next turn".tr())
|
||||||
nextTurnButton.enable()
|
|
||||||
Gdx.input.inputProcessor = stage
|
Gdx.input.inputProcessor = stage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ class UnitActions {
|
|||||||
newunit.currentMovement=0f
|
newunit.currentMovement=0f
|
||||||
},
|
},
|
||||||
unit.civInfo.gold >= goldCostOfUpgrade
|
unit.civInfo.gold >= goldCostOfUpgrade
|
||||||
&& unit.currentMovement == unit.maxMovement.toFloat() )
|
&& unit.currentMovement == unit.getMaxMovement().toFloat() )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user