Cache 'library' helper classes of CivilizationInfo (#6363)

This commit is contained in:
SomeTroglodyte 2022-03-17 21:22:54 +01:00 committed by GitHub
parent c117860d6f
commit c80db524b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 27 deletions

View File

@ -13,7 +13,6 @@ import java.util.*
import kotlin.collections.HashMap
import kotlin.collections.HashSet
import kotlin.collections.LinkedHashMap
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
@ -487,12 +486,12 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
if (diplomacy.diplomaticStatus == DiplomaticStatus.War) return // No reward for enemies
diplomacy.addInfluence(12f)
if (diplomacy.hasFlag(DiplomacyFlags.AngerFreeIntrusion))
diplomacy.setFlag(DiplomacyFlags.AngerFreeIntrusion, diplomacy.getFlag(DiplomacyFlags.AngerFreeIntrusion) + 5)
else
diplomacy.setFlag(DiplomacyFlags.AngerFreeIntrusion, 5)
otherCiv.addNotification("[${civInfo.civName}] is grateful that you killed a Barbarian that was threatening them!",
DiplomacyAction(civInfo.civName), civInfo.civName)
}
@ -645,13 +644,13 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
) {
thirdCiv.addNotification(
"[${civInfo.civName}] is being attacked by [${attacker.civName}] and asks all major civilizations to help them out by gifting them military units.",
civInfo.getCapital().location,
civInfo.civName,
civInfo.getCapital().location,
civInfo.civName,
"OtherIcons/Present",
)
}
}
fun getCityStateResourcesForAlly(): ResourceSupplyList {
val newDetailedCivResources = ResourceSupplyList()
for (city in civInfo.cities) {

View File

@ -144,7 +144,6 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
civInfo.hasUnique(UniqueType.EnemyLandUnitsSpendExtraMovement)
}
fun updateCitiesConnectedToCapital(initialSetup: Boolean = false) {
if (civInfo.cities.isEmpty()) return // eg barbarians
@ -173,7 +172,7 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
for (unique in civInfo.getMatchingUniques(UniqueType.CityStateResources))
resourceBonusPercentage += unique.params[0].toFloat() / 100
for (cityStateAlly in civInfo.getKnownCivs().filter { it.getAllyCiv() == civInfo.civName }) {
for (resource in CityStateFunctions(cityStateAlly).getCityStateResourcesForAlly()) {
for (resource in cityStateAlly.cityStateFunctions.getCityStateResourcesForAlly()) {
newDetailedCivResources.add(
resource.apply { amount = (amount * resourceBonusPercentage).toInt() }
)

View File

@ -188,7 +188,7 @@ class CivilizationInfo {
*
* @property attackingUnit Name key of [BaseUnit] type that performed the attack, or null (E.G. for city bombardments).
* @property source Position of the tile from which the attack was made.
* @property target Position of the tile targetted by the attack.
* @property target Position of the tile targeted by the attack.
* @see [MapUnit.UnitMovementMemory], [attacksSinceTurnStart]
*/
class HistoricalAttackMemory() {
@ -280,6 +280,7 @@ class CivilizationInfo {
fun getDiplomacyManager(civName: String) = diplomacy[civName]!!
fun getProximity(civInfo: CivilizationInfo) = getProximity(civInfo.civName)
@Suppress("MemberVisibilityCanBePrivate") // same visibility for overloads
fun getProximity(civName: String) = proximity[civName] ?: Proximity.None
/** Returns only undefeated civs, aka the ones we care about */
@ -303,7 +304,10 @@ class CivilizationInfo {
var cityStateUniqueUnit: String? = null // Unique unit for militaristic city state. Might still be null if there are no appropriate units
fun isMajorCiv() = nation.isMajorCiv()
fun isAlive(): Boolean = !isDefeated()
@Suppress("unused") //TODO remove if future use unlikely, including DiplomacyFlags.EverBeenFriends and 2 DiplomacyManager methods - see #3183
fun hasEverBeenFriendWith(otherCiv: CivilizationInfo): Boolean = getDiplomacyManager(otherCiv).everBeenFriends()
fun hasMetCivTerritory(otherCiv: CivilizationInfo): Boolean = otherCiv.getCivTerritory().any { it in exploredTiles }
fun getCompletedPolicyBranchesCount(): Int = policies.adoptedPolicies.count { Policy.isBranchCompleteByName(it) }
private fun getCivTerritory() = cities.asSequence().flatMap { it.tiles.asSequence() }
@ -317,8 +321,13 @@ class CivilizationInfo {
else VictoryType.Neutral
}
fun stats() = CivInfoStats(this)
fun transients() = CivInfoTransientUpdater(this)
@Transient
private val civInfoStats = CivInfoStats(this)
fun stats() = civInfoStats
@Transient
private val civInfoTransientUpdater = CivInfoTransientUpdater(this)
fun transients() = civInfoTransientUpdater
fun updateStatsForNextTurn() {
happinessForNextTurn = stats().getHappinessBreakdown().values.sum().roundToInt()
@ -650,7 +659,7 @@ class CivilizationInfo {
fun isMinorCivAggressor() = numMinorCivsAttacked >= 2
fun isMinorCivWarmonger() = numMinorCivsAttacked >= 4
fun isLongCountActive(): Boolean {
private fun isLongCountActive(): Boolean {
val unique = getMatchingUniques(UniqueType.MayanGainGreatPerson).firstOrNull()
?: return false
return tech.isResearched(unique.params[1])
@ -1011,10 +1020,8 @@ class CivilizationInfo {
return score
}
private fun getTurnsBeforeRevolt(): Int {
val score = ((4 + Random().nextInt(3)) * max(gameInfo.gameParameters.gameSpeed.modifier, 1f)).toInt()
return score
}
private fun getTurnsBeforeRevolt() =
((4 + Random().nextInt(3)) * max(gameInfo.gameParameters.gameSpeed.modifier, 1f)).toInt()
/** Modify gold by a given amount making sure it does neither overflow nor underflow.
* @param delta the amount to add (can be negative)

View File

@ -82,7 +82,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo): BaseScreen() {
val relationLevel = civ.getDiplomacyManager(viewingCiv).relationshipLevel()
val relationshipIcon = if (civ.isCityState() && relationLevel == RelationshipLevel.Ally)
ImageGetter.getImage("OtherIcons/Star")
.surroundWithCircle(size = 30f, color = relationLevel.color).apply {
.surroundWithCircle(size = 30f, color = relationLevel.color).apply {
actor.color = Color.GOLD
}
else
@ -146,8 +146,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo): BaseScreen() {
if (otherCiv.detailedCivResources.any { it.resource.resourceType != ResourceType.Bonus }) {
val resourcesTable = Table()
resourcesTable.add("{Resources}: ".toLabel()).padRight(10f)
val cityStateResources = CityStateFunctions(otherCiv)
.getCityStateResourcesForAlly()
val cityStateResources = otherCiv.cityStateFunctions.getCityStateResourcesForAlly()
for (supplyList in cityStateResources) {
if (supplyList.resource.resourceType == ResourceType.Bonus)
continue
@ -374,7 +373,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo): BaseScreen() {
diplomacyTable.addSeparator()
diplomacyTable.add(getQuestTable(assignedQuest)).row()
}
for (target in otherCiv.getKnownCivs().filter { otherCiv.questManager.warWithMajorActive(it) }) {
diplomacyTable.addSeparator()
diplomacyTable.add(getWarWithMajorTable(target, otherCiv)).row()
@ -580,7 +579,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo): BaseScreen() {
private fun getWarWithMajorTable(target: CivilizationInfo, otherCiv: CivilizationInfo): Table {
val warTable = Table()
warTable.defaults().pad(10f)
val title = "War against [${target.civName}]"
val description = "We need you to help us defend against [${target.civName}]. Killing [${otherCiv.questManager.unitsToKill(target)}] of their military units would slow their offensive."
val progress = if (viewingCiv.knows(target)) "Currently you have killed [${otherCiv.questManager.unitsKilledSoFar(target, viewingCiv)}] of their military units."
@ -591,7 +590,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo): BaseScreen() {
.width(stage.width / 2).row()
warTable.add(progress.toLabel().apply { wrap = true; setAlignment(Align.center) })
.width(stage.width / 2).row()
return warTable
}

View File

@ -16,15 +16,20 @@ import com.unciv.Constants
* @param fontSize Text size for [String.toLabel].
* @param fontColor Text colour for [String.toLabel].
*/
class IconTextButton(text: String, val icon: Actor? = null, fontSize: Int = Constants.defaultFontSize, fontColor: Color = Color.WHITE): Button(BaseScreen.skin) {
val button = Button(BaseScreen.skin)
class IconTextButton(
text: String,
val icon: Actor? = null,
fontSize: Int = Constants.defaultFontSize,
fontColor: Color = Color.WHITE
): Button(BaseScreen.skin) {
/** [Label] instance produced by and with content and formatting as specified to [String.toLabel]. */
val label = text.toLabel(fontColor, fontSize)
/** Table cell containing the [icon] if any, or `null`. */
val iconCell: Cell<Actor>? = if (icon != null) {
val iconCell: Cell<Actor>? =
if (icon != null) {
val size = fontSize.toFloat()
icon.setSize(size,size)
icon.setOrigin(Align.center)
icon.setSize(size,size)
icon.setOrigin(Align.center)
add(icon).size(size).padRight(size / 3)
} else null
/** Table cell instance containing the [label]. */