chore: More cleanup

This commit is contained in:
Yair Morgenstern 2023-01-18 18:24:05 +02:00
parent e56d53dcd9
commit 4b9ee165b3
10 changed files with 74 additions and 73 deletions

View File

@ -291,10 +291,10 @@ object Automation {
} }
// Assume buildings remain useful // Assume buildings remain useful
val neededForBuilding = civInfo.lastEraResourceUsedForBuilding[resource] != null val neededForBuilding = civInfo.cache.lastEraResourceUsedForBuilding[resource] != null
// Don't care about old units // Don't care about old units
val neededForUnits = civInfo.lastEraResourceUsedForUnit[resource] != null val neededForUnits = civInfo.cache.lastEraResourceUsedForUnit[resource] != null
&& civInfo.lastEraResourceUsedForUnit[resource]!! >= civInfo.getEraNumber() && civInfo.cache.lastEraResourceUsedForUnit[resource]!! >= civInfo.getEraNumber()
// No need to save for both // No need to save for both
if (!neededForBuilding || !neededForUnits) { if (!neededForBuilding || !neededForUnits) {

View File

@ -697,7 +697,7 @@ object NextTurnAutomation {
// Default setting is 5, this will be changed according to different civ. // Default setting is 5, this will be changed according to different civ.
if ((1..10).random() > 5) continue if ((1..10).random() > 5) continue
val tradeLogic = TradeLogic(civInfo, otherCiv) val tradeLogic = TradeLogic(civInfo, otherCiv)
val cost = civInfo.getResearchAgreementCost() val cost = civInfo.diplomacyFunctions.getResearchAgreementCost()
tradeLogic.currentTrade.ourOffers.add(TradeOffer(Constants.researchAgreement, TradeType.Treaty, cost)) tradeLogic.currentTrade.ourOffers.add(TradeOffer(Constants.researchAgreement, TradeType.Treaty, cost))
tradeLogic.currentTrade.theirOffers.add(TradeOffer(Constants.researchAgreement, TradeType.Treaty, cost)) tradeLogic.currentTrade.theirOffers.add(TradeOffer(Constants.researchAgreement, TradeType.Treaty, cost))
@ -764,7 +764,7 @@ object NextTurnAutomation {
fun isTileCanMoveThrough(tileInfo: TileInfo): Boolean { fun isTileCanMoveThrough(tileInfo: TileInfo): Boolean {
val owner = tileInfo.getOwner() val owner = tileInfo.getOwner()
return !tileInfo.isImpassible() return !tileInfo.isImpassible()
&& (owner == otherCiv || owner == null || civInfo.canPassThroughTiles(owner)) && (owner == otherCiv || owner == null || civInfo.diplomacyFunctions.canPassThroughTiles(owner))
} }
val reachableEnemyCitiesBfs = BFS(civInfo.getCapital()!!.getCenterTile()) { isTileCanMoveThrough(it) } val reachableEnemyCitiesBfs = BFS(civInfo.getCapital()!!.getCenterTile()) { isTileCanMoveThrough(it) }

View File

@ -164,7 +164,7 @@ class CityExpansionManager : IsPartOfGameInfoSerialization {
cityInfo.cityStats.update() cityInfo.cityStats.update()
for (unit in tileInfo.getUnits().toList()) // toListed because we're modifying for (unit in tileInfo.getUnits().toList()) // toListed because we're modifying
if (!unit.civInfo.canPassThroughTiles(cityInfo.civInfo)) if (!unit.civInfo.diplomacyFunctions.canPassThroughTiles(cityInfo.civInfo))
unit.movement.teleportToClosestMoveableTile() unit.movement.teleportToClosestMoveableTile()
cityInfo.civInfo.cache.updateViewableTiles() cityInfo.civInfo.cache.updateViewableTiles()

View File

@ -12,8 +12,8 @@ import com.unciv.logic.automation.unit.WorkerAutomation
import com.unciv.logic.city.CityInfo import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.diplomacy.CityStateFunctions import com.unciv.logic.civilization.diplomacy.CityStateFunctions
import com.unciv.logic.civilization.diplomacy.CityStatePersonality import com.unciv.logic.civilization.diplomacy.CityStatePersonality
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
import com.unciv.logic.civilization.diplomacy.DiplomacyFunctions import com.unciv.logic.civilization.diplomacy.DiplomacyFunctions
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.logic.civilization.managers.EspionageManager import com.unciv.logic.civilization.managers.EspionageManager
import com.unciv.logic.civilization.managers.GoldenAgeManager import com.unciv.logic.civilization.managers.GoldenAgeManager
@ -29,7 +29,6 @@ import com.unciv.logic.civilization.transients.CivInfoStatsForNextTurn
import com.unciv.logic.civilization.transients.CivInfoTransientCache import com.unciv.logic.civilization.transients.CivInfoTransientCache
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
import com.unciv.logic.map.UnitMovementAlgorithms
import com.unciv.logic.trade.TradeRequest import com.unciv.logic.trade.TradeRequest
import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.Policy import com.unciv.models.ruleset.Policy
@ -128,11 +127,6 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
@Transient @Transient
var nonStandardTerrainDamage = false var nonStandardTerrainDamage = false
@Transient
var lastEraResourceUsedForBuilding = HashMap<String, Int>()
@Transient
val lastEraResourceUsedForUnit = HashMap<String, Int>()
@Transient @Transient
var thingsToFocusOnForVictory = setOf<Victory.Focus>() var thingsToFocusOnForVictory = setOf<Victory.Focus>()
@ -678,20 +672,6 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
nonStandardTerrainDamage = getMatchingUniques(UniqueType.DamagesContainingUnits) nonStandardTerrainDamage = getMatchingUniques(UniqueType.DamagesContainingUnits)
.any { gameInfo.ruleSet.terrains[it.params[0]]!!.damagePerTurn != it.params[1].toInt() } .any { gameInfo.ruleSet.terrains[it.params[0]]!!.damagePerTurn != it.params[1].toInt() }
// Cache the last era each resource is used for buildings or units respectively for AI building evaluation
for (resource in gameInfo.ruleSet.tileResources.values.asSequence().filter { it.resourceType == ResourceType.Strategic }.map { it.name }) {
val applicableBuildings = gameInfo.ruleSet.buildings.values.filter { it.requiresResource(resource) && getEquivalentBuilding(it) == it }
val applicableUnits = gameInfo.ruleSet.units.values.filter { it.requiresResource(resource) && getEquivalentUnit(it) == it }
val lastEraForBuilding = applicableBuildings.maxOfOrNull { gameInfo.ruleSet.eras[gameInfo.ruleSet.technologies[it.requiredTech]?.era()]?.eraNumber ?: 0 }
val lastEraForUnit = applicableUnits.maxOfOrNull { gameInfo.ruleSet.eras[gameInfo.ruleSet.technologies[it.requiredTech]?.era()]?.eraNumber ?: 0 }
if (lastEraForBuilding != null)
lastEraResourceUsedForBuilding[resource] = lastEraForBuilding
if (lastEraForUnit != null)
lastEraResourceUsedForUnit[resource] = lastEraForUnit
}
hasLongCountDisplayUnique = hasUnique(UniqueType.MayanCalendarDisplay) hasLongCountDisplayUnique = hasUnique(UniqueType.MayanCalendarDisplay)
tacticalAI.init(this) tacticalAI.init(this)
@ -704,7 +684,6 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
fun hasFlag(flag: String) = flagsCountdown.contains(flag) fun hasFlag(flag: String) = flagsCountdown.contains(flag)
fun getTurnsBetweenDiplomaticVotes() = (15 * gameInfo.speed.modifier).toInt() // Dunno the exact calculation, hidden in Lua files fun getTurnsBetweenDiplomaticVotes() = (15 * gameInfo.speed.modifier).toInt() // Dunno the exact calculation, hidden in Lua files
fun getTurnsTillNextDiplomaticVote() = flagsCountdown[CivFlags.TurnsTillNextDiplomaticVote.name] fun getTurnsTillNextDiplomaticVote() = flagsCountdown[CivFlags.TurnsTillNextDiplomaticVote.name]
fun getRecentBullyingCountdown() = flagsCountdown[CivFlags.RecentlyBullied.name] fun getRecentBullyingCountdown() = flagsCountdown[CivFlags.RecentlyBullied.name]
@ -764,27 +743,6 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
} }
} }
/**
* @returns whether units of this civilization can pass through the tiles owned by [otherCiv],
* considering only civ-wide filters.
* Use [TileInfo.canCivPassThrough] to check whether units of a civilization can pass through
* a specific tile, considering only civ-wide filters.
* Use [UnitMovementAlgorithms.canPassThrough] to check whether a specific unit can pass through
* a specific tile.
*/
fun canPassThroughTiles(otherCiv: CivilizationInfo): Boolean {
if (otherCiv == this) return true
if (otherCiv.isBarbarian()) return true
if (nation.isBarbarian() && gameInfo.turns >= gameInfo.difficultyObject.turnBarbariansCanEnterPlayerTiles)
return true
val diplomacyManager = diplomacy[otherCiv.civName]
if (diplomacyManager != null && (diplomacyManager.hasOpenBorders || diplomacyManager.diplomaticStatus == DiplomaticStatus.War))
return true
// Players can always pass through city-state tiles
if (isHuman() && otherCiv.isCityState()) return true
return false
}
fun addNotification(text: String, location: Vector2, category:NotificationCategory, vararg notificationIcons: String) { fun addNotification(text: String, location: Vector2, category:NotificationCategory, vararg notificationIcons: String) {
addNotification(text, LocationAction(location), category, *notificationIcons) addNotification(text, LocationAction(location), category, *notificationIcons)
@ -819,13 +777,6 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
} }
} }
fun getResearchAgreementCost(): Int {
// https://forums.civfanatics.com/resources/research-agreements-bnw.25568/
return (
getEra().researchAgreementCost * gameInfo.speed.goldCostModifier
).toInt()
}
fun updateProximity(otherCiv: CivilizationInfo, preCalculated: Proximity? = null): Proximity = cache.updateProximity(otherCiv, preCalculated) fun updateProximity(otherCiv: CivilizationInfo, preCalculated: Proximity? = null): Proximity = cache.updateProximity(otherCiv, preCalculated)
/** /**

View File

@ -6,6 +6,8 @@ import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.NotificationCategory import com.unciv.logic.civilization.NotificationCategory
import com.unciv.logic.civilization.NotificationIcon import com.unciv.logic.civilization.NotificationIcon
import com.unciv.logic.civilization.PopupAlert import com.unciv.logic.civilization.PopupAlert
import com.unciv.logic.map.TileInfo
import com.unciv.logic.map.UnitMovementAlgorithms
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.Stat import com.unciv.models.stats.Stat
import com.unciv.models.stats.Stats import com.unciv.models.stats.Stats
@ -107,7 +109,7 @@ class DiplomacyFunctions(val civInfo:CivilizationInfo){
fun canSignResearchAgreementsWith(otherCiv: CivilizationInfo): Boolean { fun canSignResearchAgreementsWith(otherCiv: CivilizationInfo): Boolean {
val diplomacyManager = civInfo.getDiplomacyManager(otherCiv) val diplomacyManager = civInfo.getDiplomacyManager(otherCiv)
val cost = civInfo.getResearchAgreementCost() val cost = getResearchAgreementCost()
return canSignResearchAgreement() && otherCiv.diplomacyFunctions.canSignResearchAgreement() return canSignResearchAgreement() && otherCiv.diplomacyFunctions.canSignResearchAgreement()
&& diplomacyManager.hasFlag(DiplomacyFlags.DeclarationOfFriendship) && diplomacyManager.hasFlag(DiplomacyFlags.DeclarationOfFriendship)
&& !diplomacyManager.hasFlag(DiplomacyFlags.ResearchAgreement) && !diplomacyManager.hasFlag(DiplomacyFlags.ResearchAgreement)
@ -115,5 +117,35 @@ class DiplomacyFunctions(val civInfo:CivilizationInfo){
&& civInfo.gold >= cost && otherCiv.gold >= cost && civInfo.gold >= cost && otherCiv.gold >= cost
} }
fun getResearchAgreementCost(): Int {
// https://forums.civfanatics.com/resources/research-agreements-bnw.25568/
return (
civInfo.getEra().researchAgreementCost * civInfo.gameInfo.speed.goldCostModifier
).toInt()
}
/**
* @returns whether units of this civilization can pass through the tiles owned by [otherCiv],
* considering only civ-wide filters.
* Use [TileInfo.canCivPassThrough] to check whether units of a civilization can pass through
* a specific tile, considering only civ-wide filters.
* Use [UnitMovementAlgorithms.canPassThrough] to check whether a specific unit can pass through
* a specific tile.
*/
fun canPassThroughTiles(otherCiv: CivilizationInfo): Boolean {
if (otherCiv == civInfo) return true
if (otherCiv.isBarbarian()) return true
if (civInfo.isBarbarian() && civInfo.gameInfo.turns >= civInfo.gameInfo.difficultyObject.turnBarbariansCanEnterPlayerTiles)
return true
val diplomacyManager = civInfo.diplomacy[otherCiv.civName]
if (diplomacyManager != null && (diplomacyManager.hasOpenBorders || diplomacyManager.diplomaticStatus == DiplomaticStatus.War))
return true
// Players can always pass through city-state tiles
if (civInfo.isHuman() && otherCiv.isCityState()) return true
return false
}
} }

View File

@ -10,12 +10,35 @@ import com.unciv.logic.civilization.Proximity
import com.unciv.logic.map.MapShape import com.unciv.logic.map.MapShape
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
import com.unciv.models.ruleset.tile.ResourceSupplyList import com.unciv.models.ruleset.tile.ResourceSupplyList
import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.ruleset.unique.UniqueTarget import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
/** CivInfo class was getting too crowded */ /** CivInfo class was getting too crowded */
class CivInfoTransientCache(val civInfo: CivilizationInfo) { class CivInfoTransientCache(val civInfo: CivilizationInfo) {
@Transient
var lastEraResourceUsedForBuilding = java.util.HashMap<String, Int>()
@Transient
val lastEraResourceUsedForUnit = java.util.HashMap<String, Int>()
fun setTransients(){
val ruleset = civInfo.gameInfo.ruleSet
for (resource in ruleset.tileResources.values.asSequence().filter { it.resourceType == ResourceType.Strategic }.map { it.name }) {
val applicableBuildings = ruleset.buildings.values.filter { it.requiresResource(resource) && civInfo.getEquivalentBuilding(it) == it }
val applicableUnits = ruleset.units.values.filter { it.requiresResource(resource) && civInfo.getEquivalentUnit(it) == it }
val lastEraForBuilding = applicableBuildings.maxOfOrNull { ruleset.eras[ruleset.technologies[it.requiredTech]?.era()]?.eraNumber ?: 0 }
val lastEraForUnit = applicableUnits.maxOfOrNull { ruleset.eras[ruleset.technologies[it.requiredTech]?.era()]?.eraNumber ?: 0 }
if (lastEraForBuilding != null)
lastEraResourceUsedForBuilding[resource] = lastEraForBuilding
if (lastEraForUnit != null)
lastEraResourceUsedForUnit[resource] = lastEraForUnit
}
}
fun updateSightAndResources() { fun updateSightAndResources() {
updateViewableTiles() updateViewableTiles()
updateHasActiveEnemyMovementPenalty() updateHasActiveEnemyMovementPenalty()

View File

@ -846,7 +846,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
if (hasUnique(UniqueType.ReligiousUnit) if (hasUnique(UniqueType.ReligiousUnit)
&& getTile().getOwner() != null && getTile().getOwner() != null
&& !getTile().getOwner()!!.isCityState() && !getTile().getOwner()!!.isCityState()
&& !civInfo.canPassThroughTiles(getTile().getOwner()!!) && !civInfo.diplomacyFunctions.canPassThroughTiles(getTile().getOwner()!!)
) { ) {
val lostReligiousStrength = val lostReligiousStrength =
getMatchingUniques(UniqueType.CanEnterForeignTilesButLosesReligiousStrength) getMatchingUniques(UniqueType.CanEnterForeignTilesButLosesReligiousStrength)
@ -874,8 +874,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
due = true due = true
// Hakkapeliitta movement boost // Hakkapeliitta movement boost
if (getTile().getUnits().count() > 1) if (getTile().getUnits().count() > 1) {
{
// For every double-stacked tile, check if our cohabitant can boost our speed // For every double-stacked tile, check if our cohabitant can boost our speed
for (unit in getTile().getUnits()) for (unit in getTile().getUnits())
{ {
@ -893,11 +892,13 @@ class MapUnit : IsPartOfGameInfoSerialization {
this.currentTile.getTilesInDistance(3).any { this.currentTile.getTilesInDistance(3).any {
it.militaryUnit != null && it in civInfo.viewableTiles && it.militaryUnit!!.civInfo.isAtWarWith(civInfo) it.militaryUnit != null && it in civInfo.viewableTiles && it.militaryUnit!!.civInfo.isAtWarWith(civInfo)
} }
) ) action = null
action = null
val tileOwner = getTile().getOwner() val tileOwner = getTile().getOwner()
if (tileOwner != null && !canEnterForeignTerrain && !civInfo.canPassThroughTiles(tileOwner) && !tileOwner.isCityState()) // if an enemy city expanded onto this tile while I was in it if (tileOwner != null
&& !canEnterForeignTerrain
&& !civInfo.diplomacyFunctions.canPassThroughTiles(tileOwner)
&& !tileOwner.isCityState()) // if an enemy city expanded onto this tile while I was in it
movement.teleportToClosestMoveableTile() movement.teleportToClosestMoveableTile()
addMovementMemory() addMovementMemory()

View File

@ -1066,7 +1066,7 @@ open class TileInfo : IsPartOfGameInfoSerialization {
if (tileOwner == null || tileOwner == civInfo) return true if (tileOwner == null || tileOwner == civInfo) return true
if (isCityCenter() && civInfo.isAtWarWith(tileOwner) if (isCityCenter() && civInfo.isAtWarWith(tileOwner)
&& !getCity()!!.hasJustBeenConquered) return false && !getCity()!!.hasJustBeenConquered) return false
if (!civInfo.canPassThroughTiles(tileOwner)) return false if (!civInfo.diplomacyFunctions.canPassThroughTiles(tileOwner)) return false
return true return true
} }

View File

@ -98,7 +98,7 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci
city.getCenterTile().getUnits().toList().forEach { it.movement.teleportToClosestMoveableTile() } city.getCenterTile().getUnits().toList().forEach { it.movement.teleportToClosestMoveableTile() }
for (tile in city.getTiles()) { for (tile in city.getTiles()) {
for (unit in tile.getUnits().toList()) { for (unit in tile.getUnits().toList()) {
if (!unit.civInfo.canPassThroughTiles(to) && !unit.canEnterForeignTerrain) if (!unit.civInfo.diplomacyFunctions.canPassThroughTiles(to) && !unit.canEnterForeignTerrain)
unit.movement.teleportToClosestMoveableTile() unit.movement.teleportToClosestMoveableTile()
} }
} }

View File

@ -24,9 +24,7 @@ import com.unciv.logic.trade.TradeType
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
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.fillPlaceholders
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.audio.MusicMood import com.unciv.ui.audio.MusicMood
import com.unciv.ui.audio.MusicTrackChooserFlags import com.unciv.ui.audio.MusicTrackChooserFlags
@ -289,10 +287,6 @@ class DiplomacyScreen(
return diplomacyTable return diplomacyTable
} }
fun fillUniquePlaceholders(unique:Unique, vararg strings: String):String {
return unique.placeholderText.fillPlaceholders(*strings) + unique.conditionals.map { " <${it.text}>" }
.joinToString("")
}
private fun getCityStateDiplomacyTable(otherCiv: CivilizationInfo): Table { private fun getCityStateDiplomacyTable(otherCiv: CivilizationInfo): Table {
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv) val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
@ -453,7 +447,7 @@ class DiplomacyScreen(
} }
if (isNotPlayersTurn() || otherCivDiplomacyManager.getInfluence() < 60 || !needsImprovements) if (isNotPlayersTurn() || otherCivDiplomacyManager.getInfluence() < 60)
improveTileButton.disable() improveTileButton.disable()
return improveTileButton return improveTileButton
} }
@ -749,7 +743,7 @@ class DiplomacyScreen(
private fun getResearchAgreementButton(otherCiv: CivilizationInfo): TextButton { private fun getResearchAgreementButton(otherCiv: CivilizationInfo): TextButton {
val researchAgreementButton = "Research Agreement".toTextButton() val researchAgreementButton = "Research Agreement".toTextButton()
val requiredGold = viewingCiv.getResearchAgreementCost() val requiredGold = viewingCiv.diplomacyFunctions.getResearchAgreementCost()
researchAgreementButton.onClick { researchAgreementButton.onClick {
val tradeTable = setTrade(otherCiv) val tradeTable = setTrade(otherCiv)
val researchAgreement = val researchAgreement =