mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-27 16:10:55 +07:00
Fix Denunceation typo, reorg compatibility code (#5156)
* Fix Denunceation typo, reorg compatibility code * Fix Denunceation typo - lint
This commit is contained in:
parent
cbd3c2910e
commit
f1f4def7f0
131
core/src/com/unciv/logic/BackwardCompatibility.kt
Normal file
131
core/src/com/unciv/logic/BackwardCompatibility.kt
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
package com.unciv.logic
|
||||||
|
|
||||||
|
import com.unciv.logic.city.CityConstructions
|
||||||
|
import com.unciv.logic.city.PerpetualConstruction
|
||||||
|
import com.unciv.logic.civilization.TechManager
|
||||||
|
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
|
||||||
|
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
|
||||||
|
import com.unciv.models.ruleset.Ruleset
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for all temporarily used code managing transitions from deprecated elements to their replacements.
|
||||||
|
*
|
||||||
|
* Please place ***all*** such code here and call it _only_ from [GameInfo.setTransients].
|
||||||
|
* Functions are allowed to remain once no longer used if you think they might serve as template for
|
||||||
|
* similar usecases in the future. Please comment sufficiently :)
|
||||||
|
*/
|
||||||
|
@Suppress("unused") // as mentioned above
|
||||||
|
object BackwardCompatibility {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mods can change, leading to things on the map that are no longer defined in the mod.
|
||||||
|
* This function removes them so the game doesn't crash when it tries to access them.
|
||||||
|
*/
|
||||||
|
fun GameInfo.removeMissingModReferences() {
|
||||||
|
for (tile in tileMap.values) {
|
||||||
|
for (terrainFeature in tile.terrainFeatures.filter{ !ruleSet.terrains.containsKey(it) })
|
||||||
|
tile.terrainFeatures.remove(terrainFeature)
|
||||||
|
if (tile.resource != null && !ruleSet.tileResources.containsKey(tile.resource!!))
|
||||||
|
tile.resource = null
|
||||||
|
if (tile.improvement != null && !ruleSet.tileImprovements.containsKey(tile.improvement!!))
|
||||||
|
tile.improvement = null
|
||||||
|
|
||||||
|
for (unit in tile.getUnits()) {
|
||||||
|
if (!ruleSet.units.containsKey(unit.name)) tile.removeUnit(unit)
|
||||||
|
|
||||||
|
for (promotion in unit.promotions.promotions.toList())
|
||||||
|
if (!ruleSet.unitPromotions.containsKey(promotion))
|
||||||
|
unit.promotions.promotions.remove(promotion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (city in civilizations.asSequence().flatMap { it.cities.asSequence() }) {
|
||||||
|
|
||||||
|
for (building in city.cityConstructions.builtBuildings.toHashSet())
|
||||||
|
if (!ruleSet.buildings.containsKey(building))
|
||||||
|
city.cityConstructions.builtBuildings.remove(building)
|
||||||
|
|
||||||
|
fun isInvalidConstruction(construction: String) =
|
||||||
|
!ruleSet.buildings.containsKey(construction)
|
||||||
|
&& !ruleSet.units.containsKey(construction)
|
||||||
|
&& !PerpetualConstruction.perpetualConstructionsMap.containsKey(construction)
|
||||||
|
|
||||||
|
// Remove invalid buildings or units from the queue - don't just check buildings and units because it might be a special construction as well
|
||||||
|
for (construction in city.cityConstructions.constructionQueue.toList()) {
|
||||||
|
if (isInvalidConstruction(construction))
|
||||||
|
city.cityConstructions.constructionQueue.remove(construction)
|
||||||
|
}
|
||||||
|
// And from being in progress
|
||||||
|
for (construction in city.cityConstructions.inProgressConstructions.keys.toList())
|
||||||
|
if (isInvalidConstruction(construction))
|
||||||
|
city.cityConstructions.inProgressConstructions.remove(construction)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (civInfo in civilizations) {
|
||||||
|
for (tech in civInfo.tech.techsResearched.toList())
|
||||||
|
if (!ruleSet.technologies.containsKey(tech))
|
||||||
|
civInfo.tech.techsResearched.remove(tech)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces all occurrences of [oldBuildingName] in [cityConstructions] with [newBuildingName]
|
||||||
|
* if the former is not contained in the ruleset.
|
||||||
|
*/
|
||||||
|
private fun changeBuildingNameIfNotInRuleset(
|
||||||
|
ruleSet: Ruleset,
|
||||||
|
cityConstructions: CityConstructions,
|
||||||
|
oldBuildingName: String,
|
||||||
|
newBuildingName: String
|
||||||
|
) {
|
||||||
|
if (ruleSet.buildings.containsKey(oldBuildingName))
|
||||||
|
return
|
||||||
|
// Replace in built buildings
|
||||||
|
if (cityConstructions.builtBuildings.contains(oldBuildingName)) {
|
||||||
|
cityConstructions.builtBuildings.remove(oldBuildingName)
|
||||||
|
cityConstructions.builtBuildings.add(newBuildingName)
|
||||||
|
}
|
||||||
|
// Replace in construction queue
|
||||||
|
if (!cityConstructions.builtBuildings.contains(newBuildingName) && !cityConstructions.constructionQueue.contains(newBuildingName))
|
||||||
|
cityConstructions.constructionQueue = cityConstructions.constructionQueue
|
||||||
|
.map { if (it == oldBuildingName) newBuildingName else it }
|
||||||
|
.toMutableList()
|
||||||
|
else
|
||||||
|
cityConstructions.constructionQueue.remove(oldBuildingName)
|
||||||
|
// Replace in in-progress constructions
|
||||||
|
if (cityConstructions.inProgressConstructions.containsKey(oldBuildingName)) {
|
||||||
|
if (!cityConstructions.builtBuildings.contains(newBuildingName) && !cityConstructions.inProgressConstructions.containsKey(newBuildingName))
|
||||||
|
cityConstructions.inProgressConstructions[newBuildingName] = cityConstructions.inProgressConstructions[oldBuildingName]!!
|
||||||
|
cityConstructions.inProgressConstructions.remove(oldBuildingName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Replace a changed tech name */
|
||||||
|
private fun TechManager.replaceUpdatedTechName(oldTechName: String, newTechName: String) {
|
||||||
|
if (oldTechName in techsResearched) {
|
||||||
|
techsResearched.remove(oldTechName)
|
||||||
|
techsResearched.add(newTechName)
|
||||||
|
}
|
||||||
|
val index = techsToResearch.indexOf(oldTechName)
|
||||||
|
if (index >= 0) {
|
||||||
|
techsToResearch[index] = newTechName
|
||||||
|
}
|
||||||
|
if (oldTechName in techsInProgress) {
|
||||||
|
techsInProgress[newTechName] = researchOfTech(oldTechName)
|
||||||
|
techsInProgress.remove(oldTechName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Replace a deprecated DiplomacyFlags instance */
|
||||||
|
fun GameInfo.replaceDiplomacyFlag(old: DiplomacyFlags, new: DiplomacyFlags) {
|
||||||
|
fun DiplomacyManager.replaceFlag() {
|
||||||
|
if (hasFlag(old)) {
|
||||||
|
val value = getFlag(old)
|
||||||
|
removeFlag(old)
|
||||||
|
setFlag(new, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
civilizations.flatMap { civ -> civ.diplomacy.values }.forEach { it.replaceFlag() }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,10 +2,11 @@ package com.unciv.logic
|
|||||||
|
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
|
import com.unciv.logic.BackwardCompatibility.removeMissingModReferences
|
||||||
|
import com.unciv.logic.BackwardCompatibility.replaceDiplomacyFlag
|
||||||
import com.unciv.logic.automation.NextTurnAutomation
|
import com.unciv.logic.automation.NextTurnAutomation
|
||||||
import com.unciv.logic.city.CityConstructions
|
|
||||||
import com.unciv.logic.city.PerpetualConstruction
|
|
||||||
import com.unciv.logic.civilization.*
|
import com.unciv.logic.civilization.*
|
||||||
|
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.logic.map.TileMap
|
import com.unciv.logic.map.TileMap
|
||||||
import com.unciv.models.Religion
|
import com.unciv.models.Religion
|
||||||
@ -18,20 +19,7 @@ import java.util.*
|
|||||||
class UncivShowableException(missingMods: String) : Exception(missingMods)
|
class UncivShowableException(missingMods: String) : Exception(missingMods)
|
||||||
|
|
||||||
class GameInfo {
|
class GameInfo {
|
||||||
@Transient
|
//region Fields - Serialized
|
||||||
lateinit var difficultyObject: Difficulty // Since this is static game-wide, and was taking a large part of nextTurn
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
lateinit var currentPlayerCiv: CivilizationInfo // this is called thousands of times, no reason to search for it with a find{} every time
|
|
||||||
|
|
||||||
/** This is used in multiplayer games, where I may have a saved game state on my phone
|
|
||||||
* that is inconsistent with the saved game on the cloud */
|
|
||||||
@Transient
|
|
||||||
var isUpToDate = false
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
lateinit var ruleSet: Ruleset
|
|
||||||
|
|
||||||
var civilizations = mutableListOf<CivilizationInfo>()
|
var civilizations = mutableListOf<CivilizationInfo>()
|
||||||
var religions: HashMap<String, Religion> = hashMapOf()
|
var religions: HashMap<String, Religion> = hashMapOf()
|
||||||
var difficulty = "Chieftain" // difficulty is game-wide, think what would happen if 2 human players could play on different difficulties?
|
var difficulty = "Chieftain" // difficulty is game-wide, think what would happen if 2 human players could play on different difficulties?
|
||||||
@ -54,15 +42,36 @@ class GameInfo {
|
|||||||
@Volatile
|
@Volatile
|
||||||
var customSaveLocation: String? = null
|
var customSaveLocation: String? = null
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
//region Fields - Transient
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
lateinit var difficultyObject: Difficulty // Since this is static game-wide, and was taking a large part of nextTurn
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
lateinit var currentPlayerCiv: CivilizationInfo // this is called thousands of times, no reason to search for it with a find{} every time
|
||||||
|
|
||||||
|
/** This is used in multiplayer games, where I may have a saved game state on my phone
|
||||||
|
* that is inconsistent with the saved game on the cloud */
|
||||||
|
@Transient
|
||||||
|
var isUpToDate = false
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
lateinit var ruleSet: Ruleset
|
||||||
|
|
||||||
/** Simulate until any player wins,
|
/** Simulate until any player wins,
|
||||||
* or turns exceeds indicated number
|
* or turns exceeds indicated number
|
||||||
* Does not update World View until finished.
|
* Does not update World View until finished.
|
||||||
* Should be set manually on each new game start.
|
* Should be set manually on each new game start.
|
||||||
*/
|
*/
|
||||||
|
@Transient
|
||||||
var simulateMaxTurns: Int = 1000
|
var simulateMaxTurns: Int = 1000
|
||||||
|
@Transient
|
||||||
var simulateUntilWin = false
|
var simulateUntilWin = false
|
||||||
|
|
||||||
//region pure functions
|
//endregion
|
||||||
|
//region Pure functions
|
||||||
|
|
||||||
fun clone(): GameInfo {
|
fun clone(): GameInfo {
|
||||||
val toReturn = GameInfo()
|
val toReturn = GameInfo()
|
||||||
toReturn.tileMap = tileMap.clone()
|
toReturn.tileMap = tileMap.clone()
|
||||||
@ -103,7 +112,14 @@ class GameInfo {
|
|||||||
fun getCities() = civilizations.asSequence().flatMap { it.cities }
|
fun getCities() = civilizations.asSequence().flatMap { it.cities }
|
||||||
fun getAliveCityStates() = civilizations.filter { it.isAlive() && it.isCityState() }
|
fun getAliveCityStates() = civilizations.filter { it.isAlive() && it.isCityState() }
|
||||||
fun getAliveMajorCivs() = civilizations.filter { it.isAlive() && it.isMajorCiv() }
|
fun getAliveMajorCivs() = civilizations.filter { it.isAlive() && it.isMajorCiv() }
|
||||||
|
|
||||||
|
fun hasReligionEnabled() =
|
||||||
|
// Temporary function to check whether religion should be used for this game
|
||||||
|
(gameParameters.religionEnabled || ruleSet.hasReligion())
|
||||||
|
&& (ruleSet.eras.isEmpty() || !ruleSet.eras[gameParameters.startingEra]!!.hasUnique("Starting in this era disables religion"))
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
//region State changing functions
|
||||||
|
|
||||||
fun nextTurn() {
|
fun nextTurn() {
|
||||||
val previousHumanPlayer = getCurrentPlayerCivilization()
|
val previousHumanPlayer = getCurrentPlayerCivilization()
|
||||||
@ -236,7 +252,7 @@ class GameInfo {
|
|||||||
return tile
|
return tile
|
||||||
}
|
}
|
||||||
|
|
||||||
fun placeBarbarianUnit(tileToPlace: TileInfo) {
|
private fun placeBarbarianUnit(tileToPlace: TileInfo) {
|
||||||
// if we don't make this into a separate list then the retain() will happen on the Tech keys,
|
// if we don't make this into a separate list then the retain() will happen on the Tech keys,
|
||||||
// which effectively removes those techs from the game and causes all sorts of problems
|
// which effectively removes those techs from the game and causes all sorts of problems
|
||||||
val allResearchedTechs = ruleSet.technologies.keys.toMutableList()
|
val allResearchedTechs = ruleSet.technologies.keys.toMutableList()
|
||||||
@ -252,10 +268,9 @@ class GameInfo {
|
|||||||
val landUnits = unitList.filter { it.isLandUnit() }
|
val landUnits = unitList.filter { it.isLandUnit() }
|
||||||
val waterUnits = unitList.filter { it.isWaterUnit() }
|
val waterUnits = unitList.filter { it.isWaterUnit() }
|
||||||
|
|
||||||
val unit: String
|
val unit: String = if (waterUnits.isNotEmpty() && tileToPlace.isCoastalTile() && Random().nextBoolean())
|
||||||
if (waterUnits.isNotEmpty() && tileToPlace.isCoastalTile() && Random().nextBoolean())
|
waterUnits.random().name
|
||||||
unit = waterUnits.random().name
|
else landUnits.random().name
|
||||||
else unit = landUnits.random().name
|
|
||||||
|
|
||||||
tileMap.placeUnitNearTile(tileToPlace.position, unit, getBarbarianCivilization())
|
tileMap.placeUnitNearTile(tileToPlace.position, unit, getBarbarianCivilization())
|
||||||
}
|
}
|
||||||
@ -264,7 +279,7 @@ class GameInfo {
|
|||||||
* [CivilizationInfo.addNotification][Add a notification] to every civilization that have
|
* [CivilizationInfo.addNotification][Add a notification] to every civilization that have
|
||||||
* adopted Honor policy and have explored the [tile] where the Barbarian Encampment has spawned.
|
* adopted Honor policy and have explored the [tile] where the Barbarian Encampment has spawned.
|
||||||
*/
|
*/
|
||||||
fun notifyCivsOfBarbarianEncampment(tile: TileInfo) {
|
private fun notifyCivsOfBarbarianEncampment(tile: TileInfo) {
|
||||||
civilizations.filter {
|
civilizations.filter {
|
||||||
it.hasUnique("Notified of new Barbarian encampments")
|
it.hasUnique("Notified of new Barbarian encampments")
|
||||||
&& it.exploredTiles.contains(tile.position)
|
&& it.exploredTiles.contains(tile.position)
|
||||||
@ -289,6 +304,8 @@ class GameInfo {
|
|||||||
|
|
||||||
removeMissingModReferences()
|
removeMissingModReferences()
|
||||||
|
|
||||||
|
replaceDiplomacyFlag(DiplomacyFlags.Denunceation, DiplomacyFlags.Denunciation)
|
||||||
|
|
||||||
for (baseUnit in ruleSet.units.values)
|
for (baseUnit in ruleSet.units.values)
|
||||||
baseUnit.ruleset = ruleSet
|
baseUnit.ruleset = ruleSet
|
||||||
|
|
||||||
@ -296,14 +313,14 @@ class GameInfo {
|
|||||||
// the nation of their civilization when setting transients
|
// the nation of their civilization when setting transients
|
||||||
for (civInfo in civilizations) civInfo.gameInfo = this
|
for (civInfo in civilizations) civInfo.gameInfo = this
|
||||||
for (civInfo in civilizations) civInfo.setNationTransient()
|
for (civInfo in civilizations) civInfo.setNationTransient()
|
||||||
|
|
||||||
tileMap.setTransients(ruleSet)
|
tileMap.setTransients(ruleSet)
|
||||||
|
|
||||||
if (currentPlayer == "") currentPlayer = civilizations.first { it.isPlayerCivilization() }.civName
|
if (currentPlayer == "") currentPlayer = civilizations.first { it.isPlayerCivilization() }.civName
|
||||||
currentPlayerCiv = getCivilization(currentPlayer)
|
currentPlayerCiv = getCivilization(currentPlayer)
|
||||||
|
|
||||||
difficultyObject = ruleSet.difficulties[difficulty]!!
|
difficultyObject = ruleSet.difficulties[difficulty]!!
|
||||||
|
|
||||||
for (religion in religions.values) religion.setTransients(this)
|
for (religion in religions.values) religion.setTransients(this)
|
||||||
|
|
||||||
for (civInfo in civilizations) civInfo.setTransients()
|
for (civInfo in civilizations) civInfo.setTransients()
|
||||||
@ -338,105 +355,7 @@ class GameInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
// Mods can change, leading to things on the map that are no longer defined in the mod.
|
|
||||||
// So we remove them so the game doesn't crash when it tries to access them.
|
|
||||||
private fun removeMissingModReferences() {
|
|
||||||
for (tile in tileMap.values) {
|
|
||||||
for (terrainFeature in tile.terrainFeatures.filter{ !ruleSet.terrains.containsKey(it) })
|
|
||||||
tile.terrainFeatures.remove(terrainFeature)
|
|
||||||
if (tile.resource != null && !ruleSet.tileResources.containsKey(tile.resource!!))
|
|
||||||
tile.resource = null
|
|
||||||
if (tile.improvement != null && !ruleSet.tileImprovements.containsKey(tile.improvement!!))
|
|
||||||
tile.improvement = null
|
|
||||||
|
|
||||||
for (unit in tile.getUnits()) {
|
|
||||||
if (!ruleSet.units.containsKey(unit.name)) tile.removeUnit(unit)
|
|
||||||
|
|
||||||
for (promotion in unit.promotions.promotions.toList())
|
|
||||||
if (!ruleSet.unitPromotions.containsKey(promotion))
|
|
||||||
unit.promotions.promotions.remove(promotion)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (city in civilizations.asSequence().flatMap { it.cities.asSequence() }) {
|
|
||||||
|
|
||||||
for (building in city.cityConstructions.builtBuildings.toHashSet())
|
|
||||||
if (!ruleSet.buildings.containsKey(building))
|
|
||||||
city.cityConstructions.builtBuildings.remove(building)
|
|
||||||
|
|
||||||
fun isInvalidConstruction(construction: String) =
|
|
||||||
!ruleSet.buildings.containsKey(construction)
|
|
||||||
&& !ruleSet.units.containsKey(construction)
|
|
||||||
&& !PerpetualConstruction.perpetualConstructionsMap.containsKey(construction)
|
|
||||||
|
|
||||||
// Remove invalid buildings or units from the queue - don't just check buildings and units because it might be a special construction as well
|
|
||||||
for (construction in city.cityConstructions.constructionQueue.toList()) {
|
|
||||||
if (isInvalidConstruction(construction))
|
|
||||||
city.cityConstructions.constructionQueue.remove(construction)
|
|
||||||
}
|
|
||||||
// And from being in progress
|
|
||||||
for (construction in city.cityConstructions.inProgressConstructions.keys.toList())
|
|
||||||
if (isInvalidConstruction(construction))
|
|
||||||
city.cityConstructions.inProgressConstructions.remove(construction)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (civinfo in civilizations) {
|
|
||||||
for (tech in civinfo.tech.techsResearched.toList())
|
|
||||||
if (!ruleSet.technologies.containsKey(tech))
|
|
||||||
civinfo.tech.techsResearched.remove(tech)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replaces all occurrences of [oldBuildingName] in [cityConstructions] with [newBuildingName]
|
|
||||||
* if the former is not contained in the ruleset.
|
|
||||||
* This function can be used for backwards compatibility with older save files when a building
|
|
||||||
* name is changed.
|
|
||||||
*/
|
|
||||||
@Suppress("unused") // it's OK if there's no deprecation currently needing this
|
|
||||||
private fun changeBuildingNameIfNotInRuleset(cityConstructions: CityConstructions, oldBuildingName: String, newBuildingName: String) {
|
|
||||||
if (ruleSet.buildings.containsKey(oldBuildingName))
|
|
||||||
return
|
|
||||||
// Replace in built buildings
|
|
||||||
if (cityConstructions.builtBuildings.contains(oldBuildingName)) {
|
|
||||||
cityConstructions.builtBuildings.remove(oldBuildingName)
|
|
||||||
cityConstructions.builtBuildings.add(newBuildingName)
|
|
||||||
}
|
|
||||||
// Replace in construction queue
|
|
||||||
if (!cityConstructions.builtBuildings.contains(newBuildingName) && !cityConstructions.constructionQueue.contains(newBuildingName))
|
|
||||||
cityConstructions.constructionQueue = cityConstructions.constructionQueue.map{ if (it == oldBuildingName) newBuildingName else it }.toMutableList()
|
|
||||||
else
|
|
||||||
cityConstructions.constructionQueue.remove(oldBuildingName)
|
|
||||||
// Replace in in-progress constructions
|
|
||||||
if (cityConstructions.inProgressConstructions.containsKey(oldBuildingName)) {
|
|
||||||
if (!cityConstructions.builtBuildings.contains(newBuildingName) && !cityConstructions.inProgressConstructions.containsKey(newBuildingName))
|
|
||||||
cityConstructions.inProgressConstructions[newBuildingName] = cityConstructions.inProgressConstructions[oldBuildingName]!!
|
|
||||||
cityConstructions.inProgressConstructions.remove(oldBuildingName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replace a changed tech name, only temporarily used for breaking ruleset updates */
|
|
||||||
private fun TechManager.replaceUpdatedTechName(oldTechName: String, newTechName: String) {
|
|
||||||
if (oldTechName in techsResearched) {
|
|
||||||
techsResearched.remove(oldTechName)
|
|
||||||
techsResearched.add(newTechName)
|
|
||||||
}
|
|
||||||
val index = techsToResearch.indexOf(oldTechName)
|
|
||||||
if (index >= 0) {
|
|
||||||
techsToResearch[index] = newTechName
|
|
||||||
}
|
|
||||||
if (oldTechName in techsInProgress) {
|
|
||||||
techsInProgress[newTechName] = researchOfTech(oldTechName)
|
|
||||||
techsInProgress.remove(oldTechName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun hasReligionEnabled() =
|
|
||||||
// Temporary function to check whether religion should be used for this game
|
|
||||||
(gameParameters.religionEnabled || ruleSet.hasReligion())
|
|
||||||
&& (ruleSet.eras.isEmpty() || !ruleSet.eras[gameParameters.startingEra]!!.hasUnique("Starting in this era disables religion"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reduced variant only for load preview
|
// reduced variant only for load preview
|
||||||
|
@ -63,7 +63,7 @@ object NextTurnAutomation {
|
|||||||
// Can only be done now, as the prophet first has to decide to found/enhance a religion
|
// Can only be done now, as the prophet first has to decide to found/enhance a religion
|
||||||
chooseReligiousBeliefs(civInfo)
|
chooseReligiousBeliefs(civInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
reassignWorkedTiles(civInfo) // second most expensive
|
reassignWorkedTiles(civInfo) // second most expensive
|
||||||
trainSettler(civInfo)
|
trainSettler(civInfo)
|
||||||
tryVoteForDiplomaticVictory(civInfo)
|
tryVoteForDiplomaticVictory(civInfo)
|
||||||
@ -103,7 +103,7 @@ object NextTurnAutomation {
|
|||||||
val requestingCiv = civInfo.gameInfo.getCivilization(popupAlert.value)
|
val requestingCiv = civInfo.gameInfo.getCivilization(popupAlert.value)
|
||||||
val diploManager = civInfo.getDiplomacyManager(requestingCiv)
|
val diploManager = civInfo.getDiplomacyManager(requestingCiv)
|
||||||
if (diploManager.relationshipLevel() > RelationshipLevel.Neutral
|
if (diploManager.relationshipLevel() > RelationshipLevel.Neutral
|
||||||
&& !diploManager.otherCivDiplomacy().hasFlag(DiplomacyFlags.Denunceation)) {
|
&& !diploManager.otherCivDiplomacy().hasFlag(DiplomacyFlags.Denunciation)) {
|
||||||
diploManager.signDeclarationOfFriendship()
|
diploManager.signDeclarationOfFriendship()
|
||||||
requestingCiv.addNotification("We have signed a Declaration of Friendship with [${civInfo.civName}]!", NotificationIcon.Diplomacy, civInfo.civName)
|
requestingCiv.addNotification("We have signed a Declaration of Friendship with [${civInfo.civName}]!", NotificationIcon.Diplomacy, civInfo.civName)
|
||||||
} else requestingCiv.addNotification("[${civInfo.civName}] has denied our Declaration of Friendship!", NotificationIcon.Diplomacy, civInfo.civName)
|
} else requestingCiv.addNotification("[${civInfo.civName}] has denied our Declaration of Friendship!", NotificationIcon.Diplomacy, civInfo.civName)
|
||||||
@ -206,8 +206,9 @@ object NextTurnAutomation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bonus for luxury resources we can get from them
|
// Bonus for luxury resources we can get from them
|
||||||
value += cityState.detailedCivResources.count { it.resource.resourceType == ResourceType.Luxury
|
value += cityState.detailedCivResources.count {
|
||||||
&& it.resource !in civInfo.detailedCivResources.map { it.resource }
|
it.resource.resourceType == ResourceType.Luxury
|
||||||
|
&& it.resource !in civInfo.detailedCivResources.map { supply -> supply.resource }
|
||||||
}
|
}
|
||||||
|
|
||||||
return value
|
return value
|
||||||
@ -298,13 +299,13 @@ object NextTurnAutomation {
|
|||||||
civInfo.policies.adopt(policyToAdopt)
|
civInfo.policies.adopt(policyToAdopt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun chooseReligiousBeliefs(civInfo: CivilizationInfo) {
|
private fun chooseReligiousBeliefs(civInfo: CivilizationInfo) {
|
||||||
choosePantheon(civInfo)
|
choosePantheon(civInfo)
|
||||||
foundReligion(civInfo)
|
foundReligion(civInfo)
|
||||||
enhanceReligion(civInfo)
|
enhanceReligion(civInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun choosePantheon(civInfo: CivilizationInfo) {
|
private fun choosePantheon(civInfo: CivilizationInfo) {
|
||||||
if (!civInfo.religionManager.canFoundPantheon()) return
|
if (!civInfo.religionManager.canFoundPantheon()) return
|
||||||
// So looking through the source code of the base game available online,
|
// So looking through the source code of the base game available online,
|
||||||
@ -319,7 +320,7 @@ object NextTurnAutomation {
|
|||||||
val chosenPantheon = availablePantheons.random() // Why calculate stuff?
|
val chosenPantheon = availablePantheons.random() // Why calculate stuff?
|
||||||
civInfo.religionManager.choosePantheonBelief(chosenPantheon)
|
civInfo.religionManager.choosePantheonBelief(chosenPantheon)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun foundReligion(civInfo: CivilizationInfo) {
|
private fun foundReligion(civInfo: CivilizationInfo) {
|
||||||
if (civInfo.religionManager.religionState != ReligionState.FoundingReligion) return
|
if (civInfo.religionManager.religionState != ReligionState.FoundingReligion) return
|
||||||
val religionIcon = civInfo.gameInfo.ruleSet.religions
|
val religionIcon = civInfo.gameInfo.ruleSet.religions
|
||||||
@ -329,7 +330,7 @@ object NextTurnAutomation {
|
|||||||
val chosenBeliefs = chooseBeliefs(civInfo, civInfo.religionManager.getBeliefsToChooseAtFounding()).toList()
|
val chosenBeliefs = chooseBeliefs(civInfo, civInfo.religionManager.getBeliefsToChooseAtFounding()).toList()
|
||||||
civInfo.religionManager.chooseBeliefs(religionIcon, religionIcon, chosenBeliefs)
|
civInfo.religionManager.chooseBeliefs(religionIcon, religionIcon, chosenBeliefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun enhanceReligion(civInfo: CivilizationInfo) {
|
private fun enhanceReligion(civInfo: CivilizationInfo) {
|
||||||
civInfo.religionManager.chooseBeliefs(
|
civInfo.religionManager.chooseBeliefs(
|
||||||
null,
|
null,
|
||||||
@ -337,11 +338,11 @@ object NextTurnAutomation {
|
|||||||
chooseBeliefs(civInfo, civInfo.religionManager.getBeliefsToChooseAtEnhancing()).toList()
|
chooseBeliefs(civInfo, civInfo.religionManager.getBeliefsToChooseAtEnhancing()).toList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun chooseBeliefs(civInfo: CivilizationInfo, beliefContainer: BeliefContainer): HashSet<Belief> {
|
private fun chooseBeliefs(civInfo: CivilizationInfo, beliefContainer: BeliefContainer): HashSet<Belief> {
|
||||||
val chosenBeliefs = hashSetOf<Belief>()
|
val chosenBeliefs = hashSetOf<Belief>()
|
||||||
// The 'continues' should never be reached, but just in case I'd rather have AI have a
|
// The `continue`s should never be reached, but just in case I'd rather have the AI have a
|
||||||
// belief less than make the game crash. The 'continue's should only be reached whenever
|
// belief less than make the game crash. The `continue`s should only be reached whenever
|
||||||
// there are not enough beliefs to choose, but there should be, as otherwise we could
|
// there are not enough beliefs to choose, but there should be, as otherwise we could
|
||||||
// not have used a great prophet to found/enhance our religion.
|
// not have used a great prophet to found/enhance our religion.
|
||||||
for (counter in 0 until beliefContainer.pantheonBeliefCount)
|
for (counter in 0 until beliefContainer.pantheonBeliefCount)
|
||||||
@ -362,7 +363,7 @@ object NextTurnAutomation {
|
|||||||
)
|
)
|
||||||
return chosenBeliefs
|
return chosenBeliefs
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun chooseBeliefOfType(civInfo: CivilizationInfo, beliefType: BeliefType, additionalBeliefsToExclude: HashSet<Belief> = hashSetOf()): Belief? {
|
private fun chooseBeliefOfType(civInfo: CivilizationInfo, beliefType: BeliefType, additionalBeliefsToExclude: HashSet<Belief> = hashSetOf()): Belief? {
|
||||||
return civInfo.gameInfo.ruleSet.beliefs
|
return civInfo.gameInfo.ruleSet.beliefs
|
||||||
.filter {
|
.filter {
|
||||||
@ -436,7 +437,7 @@ object NextTurnAutomation {
|
|||||||
it.isMajorCiv() && !it.isAtWarWith(civInfo)
|
it.isMajorCiv() && !it.isAtWarWith(civInfo)
|
||||||
&& it.getDiplomacyManager(civInfo).relationshipLevel() > RelationshipLevel.Neutral
|
&& it.getDiplomacyManager(civInfo).relationshipLevel() > RelationshipLevel.Neutral
|
||||||
&& !civInfo.getDiplomacyManager(it).hasFlag(DiplomacyFlags.DeclarationOfFriendship)
|
&& !civInfo.getDiplomacyManager(it).hasFlag(DiplomacyFlags.DeclarationOfFriendship)
|
||||||
&& !civInfo.getDiplomacyManager(it).hasFlag(DiplomacyFlags.Denunceation)
|
&& !civInfo.getDiplomacyManager(it).hasFlag(DiplomacyFlags.Denunciation)
|
||||||
}
|
}
|
||||||
.sortedByDescending { it.getDiplomacyManager(civInfo).relationshipLevel() }
|
.sortedByDescending { it.getDiplomacyManager(civInfo).relationshipLevel() }
|
||||||
for (civ in civsThatWeCanDeclareFriendshipWith) {
|
for (civ in civsThatWeCanDeclareFriendshipWith) {
|
||||||
@ -682,20 +683,20 @@ object NextTurnAutomation {
|
|||||||
private fun tryVoteForDiplomaticVictory(civInfo: CivilizationInfo) {
|
private fun tryVoteForDiplomaticVictory(civInfo: CivilizationInfo) {
|
||||||
if (!civInfo.mayVoteForDiplomaticVictory()) return
|
if (!civInfo.mayVoteForDiplomaticVictory()) return
|
||||||
val chosenCiv: String? = if (civInfo.isMajorCiv()) {
|
val chosenCiv: String? = if (civInfo.isMajorCiv()) {
|
||||||
|
|
||||||
val knownMajorCivs = civInfo.getKnownCivs().filter { it.isMajorCiv() }
|
val knownMajorCivs = civInfo.getKnownCivs().filter { it.isMajorCiv() }
|
||||||
val highestOpinion = knownMajorCivs
|
val highestOpinion = knownMajorCivs
|
||||||
.maxOfOrNull {
|
.maxOfOrNull {
|
||||||
civInfo.getDiplomacyManager(it).opinionOfOtherCiv()
|
civInfo.getDiplomacyManager(it).opinionOfOtherCiv()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highestOpinion == null) null
|
if (highestOpinion == null) null
|
||||||
else knownMajorCivs.filter { civInfo.getDiplomacyManager(it).opinionOfOtherCiv() == highestOpinion}.random().civName
|
else knownMajorCivs.filter { civInfo.getDiplomacyManager(it).opinionOfOtherCiv() == highestOpinion}.random().civName
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
civInfo.getAllyCiv()
|
civInfo.getAllyCiv()
|
||||||
}
|
}
|
||||||
|
|
||||||
civInfo.diplomaticVoteForCiv(chosenCiv)
|
civInfo.diplomaticVoteForCiv(chosenCiv)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,4 +743,4 @@ object NextTurnAutomation {
|
|||||||
|
|
||||||
return cityDistances.minByOrNull { it.aerialDistance }!!
|
return cityDistances.minByOrNull { it.aerialDistance }!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ enum class DiplomacyFlags {
|
|||||||
DeclaredWar,
|
DeclaredWar,
|
||||||
DeclarationOfFriendship,
|
DeclarationOfFriendship,
|
||||||
ResearchAgreement,
|
ResearchAgreement,
|
||||||
|
@Deprecated("Deprecated after 3.16.13", ReplaceWith("Denunciation"))
|
||||||
Denunceation,
|
Denunceation,
|
||||||
BorderConflict,
|
BorderConflict,
|
||||||
SettledCitiesNearUs,
|
SettledCitiesNearUs,
|
||||||
@ -43,7 +44,8 @@ enum class DiplomacyFlags {
|
|||||||
NotifiedAfraid,
|
NotifiedAfraid,
|
||||||
RecentlyPledgedProtection,
|
RecentlyPledgedProtection,
|
||||||
RecentlyWithdrewProtection,
|
RecentlyWithdrewProtection,
|
||||||
AngerFreeIntrusion
|
AngerFreeIntrusion,
|
||||||
|
Denunciation
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class DiplomaticModifiers {
|
enum class DiplomaticModifiers {
|
||||||
@ -107,7 +109,7 @@ class DiplomacyManager() {
|
|||||||
get() = if (civInfo.isAtWarWith(otherCiv())) MINIMUM_INFLUENCE else field
|
get() = if (civInfo.isAtWarWith(otherCiv())) MINIMUM_INFLUENCE else field
|
||||||
|
|
||||||
/** Total of each turn Science during Research Agreement */
|
/** Total of each turn Science during Research Agreement */
|
||||||
var totalOfScienceDuringRA = 0
|
private var totalOfScienceDuringRA = 0
|
||||||
|
|
||||||
fun clone(): DiplomacyManager {
|
fun clone(): DiplomacyManager {
|
||||||
val toReturn = DiplomacyManager()
|
val toReturn = DiplomacyManager()
|
||||||
@ -188,6 +190,7 @@ class DiplomacyManager() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("unused") //todo Finish original intent or remove
|
||||||
fun matchesCityStateRelationshipFilter(filter: String): Boolean {
|
fun matchesCityStateRelationshipFilter(filter: String): Boolean {
|
||||||
val relationshipLevel = relationshipLevel()
|
val relationshipLevel = relationshipLevel()
|
||||||
return when (filter) {
|
return when (filter) {
|
||||||
@ -210,7 +213,7 @@ class DiplomacyManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// To be run from City-State DiplomacyManager, which holds the influence. Resting point for every major civ can be different.
|
// To be run from City-State DiplomacyManager, which holds the influence. Resting point for every major civ can be different.
|
||||||
fun getCityStateInfluenceRestingPoint(): Float {
|
private fun getCityStateInfluenceRestingPoint(): Float {
|
||||||
var restingPoint = 0f
|
var restingPoint = 0f
|
||||||
|
|
||||||
for (unique in otherCiv().getMatchingUniques("Resting point for Influence with City-States is increased by []"))
|
for (unique in otherCiv().getMatchingUniques("Resting point for Influence with City-States is increased by []"))
|
||||||
@ -287,7 +290,7 @@ class DiplomacyManager() {
|
|||||||
return goldPerTurnForUs
|
return goldPerTurnForUs
|
||||||
}
|
}
|
||||||
|
|
||||||
fun scienceFromResearchAgreement() {
|
private fun scienceFromResearchAgreement() {
|
||||||
// https://forums.civfanatics.com/resources/research-agreements-bnw.25568/
|
// https://forums.civfanatics.com/resources/research-agreements-bnw.25568/
|
||||||
val scienceFromResearchAgreement = min(totalOfScienceDuringRA, otherCivDiplomacy().totalOfScienceDuringRA)
|
val scienceFromResearchAgreement = min(totalOfScienceDuringRA, otherCivDiplomacy().totalOfScienceDuringRA)
|
||||||
civInfo.tech.scienceFromResearchAgreements += scienceFromResearchAgreement
|
civInfo.tech.scienceFromResearchAgreements += scienceFromResearchAgreement
|
||||||
@ -696,16 +699,16 @@ class DiplomacyManager() {
|
|||||||
diplomaticModifiers[modifier.name] = amount
|
diplomaticModifiers[modifier.name] = amount
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getModifier(modifier: DiplomaticModifiers): Float {
|
private fun getModifier(modifier: DiplomaticModifiers): Float {
|
||||||
if (!hasModifier(modifier)) return 0f
|
if (!hasModifier(modifier)) return 0f
|
||||||
return diplomaticModifiers[modifier.name]!!
|
return diplomaticModifiers[modifier.name]!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeModifier(modifier: DiplomaticModifiers) = diplomaticModifiers.remove(modifier.name)
|
private fun removeModifier(modifier: DiplomaticModifiers) = diplomaticModifiers.remove(modifier.name)
|
||||||
fun hasModifier(modifier: DiplomaticModifiers) = diplomaticModifiers.containsKey(modifier.name)
|
fun hasModifier(modifier: DiplomaticModifiers) = diplomaticModifiers.containsKey(modifier.name)
|
||||||
|
|
||||||
/** @param amount always positive, so you don't need to think about it */
|
/** @param amount always positive, so you don't need to think about it */
|
||||||
fun revertToZero(modifier: DiplomaticModifiers, amount: Float) {
|
private fun revertToZero(modifier: DiplomaticModifiers, amount: Float) {
|
||||||
if (!hasModifier(modifier)) return
|
if (!hasModifier(modifier)) return
|
||||||
val currentAmount = getModifier(modifier)
|
val currentAmount = getModifier(modifier)
|
||||||
if (currentAmount > 0) addModifier(modifier, -amount)
|
if (currentAmount > 0) addModifier(modifier, -amount)
|
||||||
@ -728,7 +731,7 @@ class DiplomacyManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setFriendshipBasedModifier() {
|
private fun setFriendshipBasedModifier() {
|
||||||
removeModifier(DiplomaticModifiers.DeclaredFriendshipWithOurAllies)
|
removeModifier(DiplomaticModifiers.DeclaredFriendshipWithOurAllies)
|
||||||
removeModifier(DiplomaticModifiers.DeclaredFriendshipWithOurEnemies)
|
removeModifier(DiplomaticModifiers.DeclaredFriendshipWithOurEnemies)
|
||||||
for (thirdCiv in getCommonKnownCivs()
|
for (thirdCiv in getCommonKnownCivs()
|
||||||
@ -747,8 +750,8 @@ class DiplomacyManager() {
|
|||||||
fun denounce() {
|
fun denounce() {
|
||||||
setModifier(DiplomaticModifiers.Denunciation, -35f)
|
setModifier(DiplomaticModifiers.Denunciation, -35f)
|
||||||
otherCivDiplomacy().setModifier(DiplomaticModifiers.Denunciation, -35f)
|
otherCivDiplomacy().setModifier(DiplomaticModifiers.Denunciation, -35f)
|
||||||
setFlag(DiplomacyFlags.Denunceation, 30)
|
setFlag(DiplomacyFlags.Denunciation, 30)
|
||||||
otherCivDiplomacy().setFlag(DiplomacyFlags.Denunceation, 30)
|
otherCivDiplomacy().setFlag(DiplomacyFlags.Denunciation, 30)
|
||||||
|
|
||||||
otherCiv().addNotification("[${civInfo.civName}] has denounced us!", NotificationIcon.Diplomacy, civInfo.civName)
|
otherCiv().addNotification("[${civInfo.civName}] has denounced us!", NotificationIcon.Diplomacy, civInfo.civName)
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
|||||||
import com.unciv.logic.trade.TradeLogic
|
import com.unciv.logic.trade.TradeLogic
|
||||||
import com.unciv.logic.trade.TradeOffer
|
import com.unciv.logic.trade.TradeOffer
|
||||||
import com.unciv.logic.trade.TradeType
|
import com.unciv.logic.trade.TradeType
|
||||||
import com.unciv.models.ruleset.Era
|
|
||||||
import com.unciv.models.ruleset.ModOptionsConstants
|
import com.unciv.models.ruleset.ModOptionsConstants
|
||||||
import com.unciv.models.ruleset.Quest
|
import com.unciv.models.ruleset.Quest
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
@ -593,7 +592,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
|
|||||||
diplomacyTable.add(researchAgreementButton).row()
|
diplomacyTable.add(researchAgreementButton).row()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!diplomacyManager.hasFlag(DiplomacyFlags.Denunceation)
|
if (!diplomacyManager.hasFlag(DiplomacyFlags.Denunciation)
|
||||||
&& !diplomacyManager.hasFlag(DiplomacyFlags.DeclarationOfFriendship)
|
&& !diplomacyManager.hasFlag(DiplomacyFlags.DeclarationOfFriendship)
|
||||||
) {
|
) {
|
||||||
val denounceButton = "Denounce ([30] turns)".toTextButton()
|
val denounceButton = "Denounce ([30] turns)".toTextButton()
|
||||||
|
Loading…
Reference in New Issue
Block a user