chore: Moved diplomacy functions to DiplomacyFunctions

This commit is contained in:
Yair Morgenstern
2023-01-18 18:11:18 +02:00
parent 4488a6fe51
commit e56d53dcd9
22 changed files with 184 additions and 163 deletions

View File

@ -167,7 +167,7 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
}
val multiplayerTable = getMenuButton("Multiplayer", "OtherIcons/Multiplayer", 'm')
{ game.pushScreen(MultiplayerScreen(this)) }
{ game.pushScreen(MultiplayerScreen()) }
column2.add(multiplayerTable).row()
val mapEditorScreenTable = getMenuButton("Map editor", "OtherIcons/MapEditor", 'e')

View File

@ -683,12 +683,12 @@ object NextTurnAutomation {
}
private fun offerResearchAgreement(civInfo: CivilizationInfo) {
if (!civInfo.canSignResearchAgreement()) return // don't waste your time
if (!civInfo.diplomacyFunctions.canSignResearchAgreement()) return // don't waste your time
val canSignResearchAgreementCiv = civInfo.getKnownCivs()
.asSequence()
.filter {
civInfo.canSignResearchAgreementsWith(it)
civInfo.diplomacyFunctions.canSignResearchAgreementsWith(it)
&& !civInfo.getDiplomacyManager(it).hasFlag(DiplomacyFlags.DeclinedResearchAgreement)
}
.sortedByDescending { it.stats.statsForNextTurn.science }
@ -752,12 +752,12 @@ object NextTurnAutomation {
val theirCity = closestCities.city2
if (civInfo.units.getCivUnits().filter { it.isMilitary() }.none {
val damageRecievedWhenAttacking =
val damageReceivedWhenAttacking =
BattleDamage.calculateDamageToAttacker(
MapUnitCombatant(it),
CityCombatant(theirCity)
)
damageRecievedWhenAttacking < 100
damageReceivedWhenAttacking < 100
})
return 0 // You don't have any units that can attack this city without dying, don't declare war.

View File

@ -174,7 +174,7 @@ class CityInfoConquestFunctions(val city: CityInfo){
// How can you conquer a city but not know the civ you conquered it from?!
// I don't know either, but some of our players have managed this, and crashed their game!
if (!conqueringCiv.knows(oldCiv))
conqueringCiv.makeCivilizationsMeet(oldCiv)
conqueringCiv.diplomacyFunctions.makeCivilizationsMeet(oldCiv)
oldCiv.getDiplomacyManager(conqueringCiv)
.addModifier(DiplomaticModifiers.CapturedOurCities, -aggroGenerated)
@ -246,7 +246,7 @@ class CityInfoConquestFunctions(val city: CityInfo){
// In order to get "plus points" in Diplomacy, you have to establish diplomatic relations if you haven't yet
if (!conqueringCiv.knows(foundingCiv))
conqueringCiv.makeCivilizationsMeet(foundingCiv)
conqueringCiv.diplomacyFunctions.makeCivilizationsMeet(foundingCiv)
if (foundingCiv.isMajorCiv()) {
foundingCiv.getDiplomacyManager(conqueringCiv)
@ -299,7 +299,7 @@ class CityInfoConquestFunctions(val city: CityInfo){
removeBuildingsOnMoveToCiv(oldCiv)
// Place palace for newCiv if this is the only city they have
// This needs to happen _before_ free buildings are added, as somtimes these should
// This needs to happen _before_ free buildings are added, as sometimes these should
// only be placed in the capital, and then there needs to be a capital.
if (newCivInfo.cities.size == 1) {
newCivInfo.moveCapitalTo(this)

View File

@ -12,8 +12,8 @@ import com.unciv.logic.automation.unit.WorkerAutomation
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.diplomacy.CityStateFunctions
import com.unciv.logic.civilization.diplomacy.CityStatePersonality
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
import com.unciv.logic.civilization.diplomacy.DiplomacyFunctions
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.logic.civilization.managers.EspionageManager
import com.unciv.logic.civilization.managers.GoldenAgeManager
@ -48,10 +48,8 @@ import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unique.getMatchingUniques
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.stats.Stat
import com.unciv.models.stats.Stats
import com.unciv.models.translations.tr
import com.unciv.ui.utils.extensions.toPercent
import com.unciv.ui.utils.extensions.withItem
import com.unciv.ui.victoryscreen.RankingType
import java.util.*
import kotlin.math.max
@ -91,6 +89,9 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
@Transient
val units = UnitManager(this)
@Transient
var diplomacyFunctions = DiplomacyFunctions(this)
@Transient
var viewableTiles = setOf<TileInfo>()
@ -328,39 +329,25 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
fun knows(otherCivName: String) = diplomacy.containsKey(otherCivName)
fun knows(otherCiv: CivilizationInfo) = knows(otherCiv.civName)
/** A sorted Sequence of all other civs we know (excluding barbarians and spectators) */
fun getKnownCivsSorted(includeCityStates: Boolean = true, includeDefeated: Boolean = false) =
gameInfo.civilizations.asSequence()
.filterNot {
it == this ||
it.isBarbarian() || it.isSpectator() ||
!this.knows(it) ||
(!includeDefeated && it.isDefeated()) ||
(!includeCityStates && it.isCityState())
}
.sortedWith(
compareByDescending<CivilizationInfo> { it.isMajorCiv() }
.thenBy (UncivGame.Current.settings.getCollatorFromLocale()) { it.civName.tr() }
)
fun getCapital() = cities.firstOrNull { it.isCapital() }
fun isHuman() = playerType == PlayerType.Human
fun isAI() = playerType == PlayerType.AI
fun isOneCityChallenger() = (
playerType == PlayerType.Human &&
gameInfo.gameParameters.oneCityChallenge)
fun isOneCityChallenger() = playerType == PlayerType.Human && gameInfo.gameParameters.oneCityChallenge
fun isCurrentPlayer() = gameInfo.currentPlayerCiv == this
fun isMajorCiv() = nation.isMajorCiv()
fun isMinorCiv() = nation.isCityState() || nation.isBarbarian()
fun isCityState(): Boolean = nation.isCityState()
fun isBarbarian() = nation.isBarbarian()
fun isSpectator() = nation.isSpectator()
fun isCityState(): Boolean = nation.isCityState()
fun isAlive(): Boolean = !isDefeated()
@delegate:Transient
val cityStateType: CityStateType by lazy { gameInfo.ruleSet.cityStateTypes[nation.cityStateType!!]!! }
var cityStatePersonality: CityStatePersonality = CityStatePersonality.Neutral
var cityStateResource: String? = null
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 isMinorCiv() = nation.isCityState() || nation.isBarbarian()
fun isAlive(): Boolean = !isDefeated()
fun hasMetCivTerritory(otherCiv: CivilizationInfo): Boolean = otherCiv.getCivTerritory().any { hasExplored(it) }
fun getCompletedPolicyBranchesCount(): Int = policies.adoptedPolicies.count { Policy.isBranchCompleteByName(it) }
@ -400,7 +387,6 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
fun getHappiness() = stats.happiness
fun getCivResources(): ResourceSupplyList = summarizedCivResources
// Preserves some origins for resources so we can separate them for trades
@ -509,6 +495,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
?: throw UncivShowableException("Unit $baseUnitName doesn't seem to exist!")
return getEquivalentUnit(baseUnit)
}
fun getEquivalentUnit(baseUnit: BaseUnit): BaseUnit {
if (baseUnit.replaces != null)
return getEquivalentUnit(baseUnit.replaces!!) // Equivalent of unique unit is the equivalent of the replaced unit
@ -519,56 +506,6 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
return baseUnit
}
fun makeCivilizationsMeet(otherCiv: CivilizationInfo, warOnContact: Boolean = false) {
meetCiv(otherCiv, warOnContact)
otherCiv.meetCiv(this, warOnContact)
}
private fun meetCiv(otherCiv: CivilizationInfo, warOnContact: Boolean = false) {
diplomacy[otherCiv.civName] = DiplomacyManager(this, otherCiv.civName)
.apply { diplomaticStatus = DiplomaticStatus.Peace }
if (!otherCiv.isSpectator())
otherCiv.popupAlerts.add(PopupAlert(AlertType.FirstContact, civName))
if (isCurrentPlayer())
UncivGame.Current.settings.addCompletedTutorialTask("Meet another civilization")
if (!(isCityState() && otherCiv.isMajorCiv())) return
if (warOnContact || otherCiv.isMinorCivAggressor()) return // No gift if they are bad people, or we are just about to be at war
val cityStateLocation = if (cities.isEmpty()) null else getCapital()!!.location
val giftAmount = Stats(gold = 15f)
val faithAmount = Stats(faith = 4f)
// Later, religious city-states will also gift gold, making this the better implementation
// For now, it might be overkill though.
var meetString = "[${civName}] has given us [${giftAmount}] as a token of goodwill for meeting us"
val religionMeetString = "[${civName}] has also given us [${faithAmount}]"
if (diplomacy.filter { it.value.otherCiv().isMajorCiv() }.size == 1) {
giftAmount.timesInPlace(2f)
meetString = "[${civName}] has given us [${giftAmount}] as we are the first major civ to meet them"
}
if (cityStateLocation != null)
otherCiv.addNotification(meetString, cityStateLocation, NotificationCategory.Diplomacy, NotificationIcon.Gold)
else
otherCiv.addNotification(meetString, NotificationCategory.Diplomacy, NotificationIcon.Gold)
if (otherCiv.isCityState() && otherCiv.cityStateFunctions.canProvideStat(Stat.Faith)){
otherCiv.addNotification(religionMeetString, NotificationCategory.Diplomacy, NotificationIcon.Faith)
for ((key, value) in faithAmount)
otherCiv.addStat(key, value.toInt())
}
for ((key, value) in giftAmount)
otherCiv.addStat(key, value.toInt())
if (cities.isNotEmpty())
otherCiv.exploredTiles = otherCiv.exploredTiles.withItem(getCapital()!!.location)
questManager.justMet(otherCiv) // Include them in war with major pseudo-quest
}
override fun toString(): String = civName // for debug
/**
@ -587,31 +524,10 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
fun getEraNumber(): Int = getEra().eraNumber
fun isAtWarWith(otherCiv: CivilizationInfo): Boolean {
return when {
otherCiv == this -> false
otherCiv.isBarbarian() || isBarbarian() -> true
else -> {
val diplomacyManager = diplomacy[otherCiv.civName]
?: return false // not encountered yet
return diplomacyManager.diplomaticStatus == DiplomaticStatus.War
}
}
}
fun isAtWarWith(otherCiv: CivilizationInfo) = diplomacyFunctions.isAtWarWith(otherCiv)
fun isAtWar() = diplomacy.values.any { it.diplomaticStatus == DiplomaticStatus.War && !it.otherCiv().isDefeated() }
fun getEnemyMovementPenalty(enemyUnit: MapUnit): Float {
if (enemyMovementPenaltyUniques != null && enemyMovementPenaltyUniques!!.any()) {
return enemyMovementPenaltyUniques!!.sumOf {
if (it.type!! == UniqueType.EnemyLandUnitsSpendExtraMovement
&& enemyUnit.matchesFilter(it.params[0]))
it.params[1].toInt()
else 0
}.toFloat()
}
return 0f // should not reach this point
}
/**
* Returns a civilization caption suitable for greetings including player type info:
@ -623,34 +539,13 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
val online = gameInfo.gameParameters.isOnlineMultiplayer
return nation.getLeaderDisplayName().tr() +
when {
!online && !severalHumans ->
"" // offline single player will know everybody else is AI
playerType == PlayerType.AI ->
" (" + "AI".tr() + ")"
online ->
" (" + "Human".tr() + " - " + "Multiplayer".tr() + ")"
else ->
" (" + "Human".tr() + " - " + "Hotseat".tr() + ")"
!online && !severalHumans -> "" // offline single player will know everybody else is AI
playerType == PlayerType.AI -> " (${"AI".tr()})"
online -> " (${"Human".tr()} - ${"Multiplayer".tr()})"
else -> " (${"Human".tr()} - ${"Hotseat".tr()})"
}
}
fun canSignResearchAgreement(): Boolean {
if (!isMajorCiv()) return false
if (!hasUnique(UniqueType.EnablesResearchAgreements)) return false
if (gameInfo.ruleSet.technologies.values
.none { tech.canBeResearched(it.name) && !tech.isResearched(it.name) }) return false
return true
}
fun canSignResearchAgreementsWith(otherCiv: CivilizationInfo): Boolean {
val diplomacyManager = getDiplomacyManager(otherCiv)
val cost = getResearchAgreementCost()
return canSignResearchAgreement() && otherCiv.canSignResearchAgreement()
&& diplomacyManager.hasFlag(DiplomacyFlags.DeclarationOfFriendship)
&& !diplomacyManager.hasFlag(DiplomacyFlags.ResearchAgreement)
&& !diplomacyManager.otherCivDiplomacy().hasFlag(DiplomacyFlags.ResearchAgreement)
&& gold >= cost && otherCiv.gold >= cost
}
fun getStatForRanking(category: RankingType): Int {
return if (isDefeated()) 0
@ -687,9 +582,6 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
return sum
}
fun hasTechOrPolicy(techOrPolicyName: String) =
tech.isResearched(techOrPolicyName) || policies.isAdopted(techOrPolicyName)
fun isMinorCivAggressor() = numMinorCivsAttacked >= 2
fun isMinorCivWarmonger() = numMinorCivsAttacked >= 4

View File

@ -257,7 +257,7 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
civInfo.getDiplomacyManager(newEnemy).declareWar()
else if (!civInfo.knows(newEnemy)) {
// We have to meet first
civInfo.makeCivilizationsMeet(newEnemy, warOnContact = true)
civInfo.diplomacyFunctions.makeCivilizationsMeet(newEnemy, warOnContact = true)
civInfo.getDiplomacyManager(newEnemy).declareWar()
}
}

View File

@ -0,0 +1,119 @@
package com.unciv.logic.civilization.diplomacy
import com.unciv.UncivGame
import com.unciv.logic.civilization.AlertType
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.NotificationCategory
import com.unciv.logic.civilization.NotificationIcon
import com.unciv.logic.civilization.PopupAlert
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.Stat
import com.unciv.models.stats.Stats
import com.unciv.models.translations.tr
import com.unciv.ui.utils.extensions.withItem
class DiplomacyFunctions(val civInfo:CivilizationInfo){
/** A sorted Sequence of all other civs we know (excluding barbarians and spectators) */
fun getKnownCivsSorted(includeCityStates: Boolean = true, includeDefeated: Boolean = false) =
civInfo.gameInfo.civilizations.asSequence()
.filterNot {
it == civInfo ||
it.isBarbarian() ||
it.isSpectator() ||
!civInfo.knows(it) ||
!includeDefeated && it.isDefeated() ||
!includeCityStates && it.isCityState()
}
.sortedWith(
compareByDescending<CivilizationInfo> { it.isMajorCiv() }
.thenBy (UncivGame.Current.settings.getCollatorFromLocale()) { it.civName.tr() }
)
fun makeCivilizationsMeet(otherCiv: CivilizationInfo, warOnContact: Boolean = false) {
meetCiv(otherCiv, warOnContact)
otherCiv.diplomacyFunctions.meetCiv(civInfo, warOnContact)
}
fun meetCiv(otherCiv: CivilizationInfo, warOnContact: Boolean = false) {
civInfo.diplomacy[otherCiv.civName] = DiplomacyManager(civInfo, otherCiv.civName)
.apply { diplomaticStatus = DiplomaticStatus.Peace }
if (!otherCiv.isSpectator())
otherCiv.popupAlerts.add(PopupAlert(AlertType.FirstContact, civInfo.civName))
if (civInfo.isCurrentPlayer())
UncivGame.Current.settings.addCompletedTutorialTask("Meet another civilization")
if (civInfo.isCityState() && otherCiv.isMajorCiv()) {
if (warOnContact || otherCiv.isMinorCivAggressor()) return // No gift if they are bad people, or we are just about to be at war
val cityStateLocation = if (civInfo.cities.isEmpty()) null else civInfo.getCapital()!!.location
val giftAmount = Stats(gold = 15f)
val faithAmount = Stats(faith = 4f)
// Later, religious city-states will also gift gold, making this the better implementation
// For now, it might be overkill though.
var meetString = "[${civInfo.civName}] has given us [${giftAmount}] as a token of goodwill for meeting us"
val religionMeetString = "[${civInfo.civName}] has also given us [${faithAmount}]"
if (civInfo.diplomacy.filter { it.value.otherCiv().isMajorCiv() }.size == 1) {
giftAmount.timesInPlace(2f)
meetString = "[${civInfo.civName}] has given us [${giftAmount}] as we are the first major civ to meet them"
}
if (cityStateLocation != null)
otherCiv.addNotification(meetString, cityStateLocation, NotificationCategory.Diplomacy, NotificationIcon.Gold)
else
otherCiv.addNotification(meetString, NotificationCategory.Diplomacy, NotificationIcon.Gold)
if (otherCiv.isCityState() && otherCiv.cityStateFunctions.canProvideStat(Stat.Faith)){
otherCiv.addNotification(religionMeetString, NotificationCategory.Diplomacy, NotificationIcon.Faith)
for ((key, value) in faithAmount)
otherCiv.addStat(key, value.toInt())
}
for ((key, value) in giftAmount)
otherCiv.addStat(key, value.toInt())
if (civInfo.cities.isNotEmpty())
otherCiv.exploredTiles = otherCiv.exploredTiles.withItem(civInfo.getCapital()!!.location)
civInfo.questManager.justMet(otherCiv) // Include them in war with major pseudo-quest
}
}
fun isAtWarWith(otherCiv: CivilizationInfo): Boolean {
return when {
otherCiv == civInfo -> false
otherCiv.isBarbarian() || civInfo.isBarbarian() -> true
else -> {
val diplomacyManager = civInfo.diplomacy[otherCiv.civName]
?: return false // not encountered yet
return diplomacyManager.diplomaticStatus == DiplomaticStatus.War
}
}
}
fun canSignResearchAgreement(): Boolean {
if (!civInfo.isMajorCiv()) return false
if (!civInfo.hasUnique(UniqueType.EnablesResearchAgreements)) return false
if (civInfo.gameInfo.ruleSet.technologies.values
.none { civInfo.tech.canBeResearched(it.name) && !civInfo.tech.isResearched(it.name) }) return false
return true
}
fun canSignResearchAgreementsWith(otherCiv: CivilizationInfo): Boolean {
val diplomacyManager = civInfo.getDiplomacyManager(otherCiv)
val cost = civInfo.getResearchAgreementCost()
return canSignResearchAgreement() && otherCiv.diplomacyFunctions.canSignResearchAgreement()
&& diplomacyManager.hasFlag(DiplomacyFlags.DeclarationOfFriendship)
&& !diplomacyManager.hasFlag(DiplomacyFlags.ResearchAgreement)
&& !diplomacyManager.otherCivDiplomacy().hasFlag(DiplomacyFlags.ResearchAgreement)
&& civInfo.gold >= cost && otherCiv.gold >= cost
}
}

View File

@ -665,7 +665,7 @@ class DiplomacyManager() : IsPartOfGameInfoSerialization {
thirdCiv.getDiplomacyManager(civAtWarWith).declareWar(true)
else if (!thirdCiv.knows(civAtWarWith)) {
// Our city state ally has not met them yet, so they have to meet first
thirdCiv.makeCivilizationsMeet(civAtWarWith, warOnContact = true)
thirdCiv.diplomacyFunctions.makeCivilizationsMeet(civAtWarWith, warOnContact = true)
thirdCiv.getDiplomacyManager(civAtWarWith).declareWar(true)
}
}

View File

@ -50,7 +50,7 @@ class CivInfoTransientCache(val civInfo: CivilizationInfo) {
for (entry in viewedCivs) {
val metCiv = entry.key
if (metCiv == civInfo || metCiv.isBarbarian() || civInfo.diplomacy.containsKey(metCiv.civName)) continue
civInfo.makeCivilizationsMeet(metCiv)
civInfo.diplomacyFunctions.makeCivilizationsMeet(metCiv)
civInfo.addNotification("We have encountered [${metCiv.civName}]!",
entry.value.position,
NotificationCategory.Diplomacy, metCiv.civName,

View File

@ -2,8 +2,8 @@ package com.unciv.logic.map
import com.badlogic.gdx.math.Vector2
import com.unciv.Constants
import com.unciv.logic.map.HexMath.getDistance
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.HexMath.getDistance
import com.unciv.models.helpers.UnitMovementMemoryType
import com.unciv.models.ruleset.unique.UniqueType
@ -11,6 +11,18 @@ class UnitMovementAlgorithms(val unit: MapUnit) {
private val pathfindingCache = PathfindingCache(unit)
fun getEnemyMovementPenalty(civInfo:CivilizationInfo, enemyUnit: MapUnit): Float {
if (civInfo.enemyMovementPenaltyUniques != null && civInfo.enemyMovementPenaltyUniques!!.any()) {
return civInfo.enemyMovementPenaltyUniques!!.sumOf {
if (it.type!! == UniqueType.EnemyLandUnitsSpendExtraMovement
&& enemyUnit.matchesFilter(it.params[0]))
it.params[1].toInt()
else 0
}.toFloat()
}
return 0f // should not reach this point
}
// This function is called ALL THE TIME and should be as time-optimal as possible!
private fun getMovementCostBetweenAdjacentTiles(
from: TileInfo,
@ -36,7 +48,7 @@ class UnitMovementAlgorithms(val unit: MapUnit) {
toOwner != null &&
toOwner.hasActiveEnemyMovementPenalty &&
civInfo.isAtWarWith(toOwner)
) toOwner.getEnemyMovementPenalty(unit) else 0f
) getEnemyMovementPenalty(toOwner, unit) else 0f
if (from.getUnpillagedRoad() == RoadStatus.Railroad && to.getUnpillagedRoad() == RoadStatus.Railroad)
return RoadStatus.Railroad.movement + extraCost

View File

@ -120,7 +120,7 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci
}
}
if (offer.type == TradeType.Introduction)
to.makeCivilizationsMeet(to.gameInfo.getCivilization(offer.name))
to.diplomacyFunctions.makeCivilizationsMeet(to.gameInfo.getCivilization(offer.name))
if (offer.type == TradeType.WarDeclaration) {
val nameOfCivToDeclareWarOn = offer.name
from.getDiplomacyManager(nameOfCivToDeclareWarOn).declareWar()

View File

@ -232,8 +232,6 @@ class Ruleset {
allRulesetObjects() + sequenceOf(modOptions)
fun load(folderHandle: FileHandle) {
val gameBasicsStartTime = System.currentTimeMillis()
val modOptionsFile = folderHandle.child("ModOptions.json")
if (modOptionsFile.exists()) {
try {

View File

@ -271,7 +271,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
UniqueType.ConditionalFirstCivToResearch -> sourceObjectType == UniqueTarget.Tech
&& state.civInfo != null
&& state.civInfo.gameInfo.civilizations.none {
it != state.civInfo && it.isMajorCiv() && it.hasTechOrPolicy(sourceObjectName!!)
it != state.civInfo && it.isMajorCiv() && (it.tech.isResearched(sourceObjectName!!) || it.policies.isAdopted(sourceObjectName))
}
else -> false

View File

@ -10,14 +10,13 @@ import com.unciv.models.translations.tr
import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.popup.Popup
import com.unciv.ui.popup.ToastPopup
import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.extensions.disable
import com.unciv.ui.utils.extensions.enable
import com.unciv.ui.utils.extensions.onClick
import com.unciv.ui.utils.extensions.toTextButton
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
class MultiplayerScreen(previousScreen: BaseScreen) : PickerScreen() {
class MultiplayerScreen : PickerScreen() {
private var selectedGame: OnlineMultiplayerGame? = null
private val editButtonText = "Game settings"

View File

@ -7,7 +7,6 @@ import com.unciv.models.metadata.GameSettings
import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.UncivSlider
import com.unciv.ui.utils.extensions.toLabel
import com.unciv.ui.worldscreen.WorldScreen
fun gameplayTab(
optionsPopup: OptionsPopup
@ -45,10 +44,14 @@ fun gameplayTab(
optionsPopup.addCheckbox(this, "Order trade offers by amount", settings.orderTradeOffersByAmount) { settings.orderTradeOffersByAmount = it }
optionsPopup.addCheckbox(this, "Ask for confirmation when pressing next turn", settings.confirmNextTurn) { settings.confirmNextTurn = it }
addNotificationLogMaxTurnsSlider(this, settings, UncivGame.Current.worldScreen, optionsPopup.selectBoxMinWidth)
addNotificationLogMaxTurnsSlider(this, settings, optionsPopup.selectBoxMinWidth)
}
private fun addNotificationLogMaxTurnsSlider(table: Table, settings: GameSettings, screen: BaseScreen?, selectBoxMinWidth: Float) {
private fun addNotificationLogMaxTurnsSlider(
table: Table,
settings: GameSettings,
selectBoxMinWidth: Float
) {
table.add("Notifications log max turns".toLabel()).left().fillX()
val minimapSlider = UncivSlider(

View File

@ -9,11 +9,11 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.utils.Align
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.map.HexMath
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
import com.unciv.logic.map.HexMath
import com.unciv.models.ruleset.Policy.PolicyBranchType
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.trade.DiplomacyScreen
@ -262,8 +262,8 @@ class GlobalPoliticsOverviewTable (
!it.isSpectator() && !it.isBarbarian() && (persistableData.includeCityStates || !it.isCityState())
}
undefeatedCivs = sequenceOf(viewingPlayer) +
viewingPlayer.getKnownCivsSorted(persistableData.includeCityStates)
defeatedCivs = viewingPlayer.getKnownCivsSorted(persistableData.includeCityStates, true)
viewingPlayer.diplomacyFunctions.getKnownCivsSorted(persistableData.includeCityStates)
defeatedCivs = viewingPlayer.diplomacyFunctions.getKnownCivsSorted(persistableData.includeCityStates, true)
.filter { it.isDefeated() }
clear()

View File

@ -83,7 +83,7 @@ class PickerPane(
/** Return a button for picker screens that display a list of big buttons with icons and labels. */
fun getPickerOptionButton(icon: Actor, label: String): Button {
return IconTextButton(label, icon).apply {
iconCell!!.size(pickerOptionIconSize).pad(10f)
iconCell.size(pickerOptionIconSize).pad(10f)
labelCell.pad(10f)
}
}

View File

@ -211,7 +211,7 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
topTable.row()
val branches = viewingCiv.gameInfo.ruleSet.policyBranches
var rowChangeCount = Int.MAX_VALUE
val rowChangeCount: Int
// estimate how many branch boxes fit using average size (including pad)
// TODO If we'd want to use scene2d correctly, this is supposed to happen inside an overridden layout() method
@ -220,9 +220,7 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
if (numBranchesY > 1.5f) {
val numRows = if (numBranchesY < 2.9f) 2 else (numBranchesY + 0.1f).toInt()
rowChangeCount = (branches.size + numRows - 1) / numRows
} else {
rowChangeCount = branches.size
}
} else rowChangeCount = branches.size
// Actually create and distribute the policy branches

View File

@ -8,7 +8,6 @@ import com.badlogic.gdx.utils.Align
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.civilization.AlertType
import com.unciv.logic.civilization.managers.AssignedQuest
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.PopupAlert
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
@ -17,6 +16,7 @@ import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers
import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers.*
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
import com.unciv.logic.civilization.managers.AssignedQuest
import com.unciv.logic.trade.Trade
import com.unciv.logic.trade.TradeLogic
import com.unciv.logic.trade.TradeOffer
@ -113,7 +113,7 @@ class DiplomacyScreen(
var selectCivY = 0f
for (civ in viewingCiv.getKnownCivsSorted()) {
for (civ in viewingCiv.diplomacyFunctions.getKnownCivsSorted()) {
if (civ == selectCiv) {
selectCivY = leftSideTable.prefHeight
}
@ -665,7 +665,7 @@ class DiplomacyScreen(
diplomacyTable.add(getDeclareFriendshipButton(otherCiv)).row()
if (viewingCiv.canSignResearchAgreementsWith(otherCiv))
if (viewingCiv.diplomacyFunctions.canSignResearchAgreementsWith(otherCiv))
diplomacyTable.add(getResearchAgreementButton(otherCiv)).row()
if (!diplomacyManager.hasFlag(DiplomacyFlags.Denunciation)

View File

@ -884,7 +884,7 @@ object UnitActions {
val otherCiv = tile.getOwner()
if (otherCiv != null) {
// decrease relations for -10 pt/tile
if (!otherCiv.knows(unit.civInfo)) otherCiv.makeCivilizationsMeet(unit.civInfo)
if (!otherCiv.knows(unit.civInfo)) otherCiv.diplomacyFunctions.makeCivilizationsMeet(unit.civInfo)
otherCiv.getDiplomacyManager(unit.civInfo).addModifier(DiplomaticModifiers.StealingTerritory, -10f)
civsToNotify.add(otherCiv)
}
@ -989,7 +989,7 @@ object UnitActions {
.addModifier(DiplomaticModifiers.GaveUsUnits, 5f)
if (recipient.isCityState() && unit.isGreatPerson())
unit.destroy() // City states dont get GPs
unit.destroy() // City states don't get GPs
else
unit.gift(recipient)
UncivGame.Current.worldScreen!!.shouldUpdate = true

View File

@ -25,7 +25,7 @@ class DiplomacyManagerTests {
private fun meetByName(civilization: String, civilizationToMeet: String) {
civilizations.getValue(civilization)
.makeCivilizationsMeet(civilizations.getValue(civilizationToMeet))
.diplomacyFunctions.makeCivilizationsMeet(civilizations.getValue(civilizationToMeet))
}
@Before

View File

@ -80,7 +80,7 @@ class SerializationTests {
// Ensure some diplomacy objects are instantiated
val otherCiv = game.getCivilization("Greece")
civ.makeCivilizationsMeet(otherCiv)
civ.diplomacyFunctions.makeCivilizationsMeet(otherCiv)
}
@Test

View File

@ -383,7 +383,7 @@ class GlobalUniquesTests {
val cityStateTile = game.getTile(Vector2(0f, 1f))
@Suppress("UNUSED_VARIABLE")
val cityStateCity = game.addCity(cityState, cityStateTile, true)
civInfo.makeCivilizationsMeet(cityState)
civInfo.diplomacyFunctions.makeCivilizationsMeet(cityState)
cityState.getDiplomacyManager(civInfo).addInfluence(100f)
city.cityStats.update()