mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 14:24:43 -04:00
Disabled CS buttons when at war; CS keep influence when at war with ally (#6813)
* Disabled CS buttons when at war; CS keep influence when at war with ally This PR does two things: - When you are at war with a city state, you can no longer give them money, demand stuff, etc. - When at war with the ally of a city state, your influence is frozen, and after the end of the conflict set back to its original value. To implement this last thing, I had to split the getter of `influence` off of the underlying field, as otherwise when copying over the old value in `.clone()`, we would copy over -60 when at war, instead of the original value. Most of the changes in that PR are a result of that. Also resets the `simulateUntilTurns` variable after completing simulations * Updated comment
This commit is contained in:
parent
07562f23ff
commit
66feebae8d
@ -247,6 +247,8 @@ class GameInfo {
|
||||
}
|
||||
switchTurn()
|
||||
}
|
||||
if (turns == UncivGame.Current.simulateUntilTurnForDebug)
|
||||
UncivGame.Current.simulateUntilTurnForDebug = 0
|
||||
|
||||
currentTurnStartTime = System.currentTimeMillis()
|
||||
currentPlayer = thisPlayer.civName
|
||||
|
@ -244,7 +244,7 @@ object NextTurnAutomation {
|
||||
|
||||
private fun tryGainInfluence(civInfo: CivilizationInfo, cityState: CivilizationInfo) {
|
||||
if (civInfo.gold < 250) return // save up
|
||||
if (cityState.getDiplomacyManager(civInfo).influence < 20) {
|
||||
if (cityState.getDiplomacyManager(civInfo).getInfluence() < 20) {
|
||||
cityState.receiveGoldGift(civInfo, 250)
|
||||
return
|
||||
}
|
||||
@ -267,7 +267,7 @@ object NextTurnAutomation {
|
||||
for (cityState in civInfo.getKnownCivs()
|
||||
.filter { it.isCityState() && it.cityStateType == CityStateType.Cultured }) {
|
||||
val diploManager = cityState.getDiplomacyManager(civInfo)
|
||||
if (diploManager.influence < 40) { // we want to gain influence with them
|
||||
if (diploManager.getInfluence() < 40) { // we want to gain influence with them
|
||||
tryGainInfluence(civInfo, cityState)
|
||||
return
|
||||
}
|
||||
@ -329,7 +329,7 @@ object NextTurnAutomation {
|
||||
}
|
||||
if (cityState.getAllyCiv() != null && cityState.getAllyCiv() != civInfo.civName) {
|
||||
// easier not to compete if a third civ has this locked down
|
||||
val thirdCivInfluence = cityState.getDiplomacyManager(cityState.getAllyCiv()!!).influence.toInt()
|
||||
val thirdCivInfluence = cityState.getDiplomacyManager(cityState.getAllyCiv()!!).getInfluence().toInt()
|
||||
value -= (thirdCivInfluence - 60) / 10
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
||||
}
|
||||
|
||||
fun removeProtectorCiv(otherCiv: CivilizationInfo, forced: Boolean = false) {
|
||||
if(!otherCivCanWithdrawProtection(otherCiv) && !forced)
|
||||
if(!forced && !otherCivCanWithdrawProtection(otherCiv))
|
||||
return
|
||||
|
||||
val diplomacy = civInfo.getDiplomacyManager(otherCiv)
|
||||
@ -195,7 +195,7 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
||||
if (diplomacy.hasFlag(DiplomacyFlags.RecentlyWithdrewProtection))
|
||||
return false
|
||||
// Must have at least 0 influence
|
||||
if (diplomacy.influence < 0)
|
||||
if (diplomacy.getInfluence() < 0)
|
||||
return false
|
||||
// can't be at war
|
||||
if (civInfo.isAtWarWith(otherCiv))
|
||||
@ -225,8 +225,8 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
||||
if (!civInfo.isCityState()) return
|
||||
val maxInfluence = civInfo.diplomacy
|
||||
.filter { !it.value.otherCiv().isCityState() && !it.value.otherCiv().isDefeated() }
|
||||
.maxByOrNull { it.value.influence }
|
||||
if (maxInfluence != null && maxInfluence.value.influence >= 60) {
|
||||
.maxByOrNull { it.value.getInfluence() }
|
||||
if (maxInfluence != null && maxInfluence.value.getInfluence() >= 60) {
|
||||
newAllyName = maxInfluence.key
|
||||
}
|
||||
|
||||
@ -350,7 +350,7 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
||||
modifiers["Very recently paid tribute"] = -300
|
||||
else if (recentBullying != null)
|
||||
modifiers["Recently paid tribute"] = -40
|
||||
if (civInfo.getDiplomacyManager(demandingCiv).influence < -30)
|
||||
if (civInfo.getDiplomacyManager(demandingCiv).getInfluence() < -30)
|
||||
modifiers["Influence below -30"] = -300
|
||||
|
||||
// Slight optimization, we don't do the expensive stuff if we have no chance of getting a >= 0 result
|
||||
|
@ -598,12 +598,16 @@ class CivilizationInfo {
|
||||
fun getEraNumber(): Int = getEra().eraNumber
|
||||
|
||||
fun isAtWarWith(otherCiv: CivilizationInfo): Boolean {
|
||||
if (otherCiv == this) return false // never at war with itself
|
||||
if (otherCiv.isBarbarian() || isBarbarian()) return true
|
||||
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 isAtWar() = diplomacy.values.any { it.diplomaticStatus == DiplomaticStatus.War && !it.otherCiv().isDefeated() }
|
||||
|
||||
|
@ -115,10 +115,10 @@ class DiplomacyManager() {
|
||||
var diplomaticModifiers = HashMap<String, Float>()
|
||||
|
||||
/** For city-states. Influence is saved in the CITY STATE -> major civ Diplomacy, NOT in the major civ -> city state diplomacy.
|
||||
* Won't go below [MINIMUM_INFLUENCE]. Note this declaration leads to Major Civs getting MINIMUM_INFLUENCE serialized, but that is ignored. */
|
||||
var influence = 0f
|
||||
private set
|
||||
get() = if (civInfo.isAtWarWith(otherCiv())) MINIMUM_INFLUENCE else field
|
||||
* Access via getInfluence() and setInfluence() unless you know what you're doing.
|
||||
* Note that not using the setter skips recalculating the ally and bounds checks,
|
||||
* and skipping the getter bypasses the modified value when at war */
|
||||
private var influence = 0f
|
||||
|
||||
/** Total of each turn Science during Research Agreement */
|
||||
private var totalOfScienceDuringRA = 0
|
||||
@ -168,11 +168,11 @@ class DiplomacyManager() {
|
||||
return otherCiv().getDiplomacyManager(civInfo).relationshipLevel()
|
||||
|
||||
if (civInfo.isCityState()) return when {
|
||||
influence >= 60 && civInfo.getAllyCiv() == otherCivName -> RelationshipLevel.Ally
|
||||
influence >= 30 -> RelationshipLevel.Friend
|
||||
influence <= -30 || civInfo.isAtWarWith(otherCiv()) -> RelationshipLevel.Unforgivable
|
||||
influence < 30 && civInfo.getTributeWillingness(otherCiv()) > 0 -> RelationshipLevel.Afraid
|
||||
influence < 0 -> RelationshipLevel.Enemy
|
||||
getInfluence() <= -30 || civInfo.isAtWarWith(otherCiv()) -> RelationshipLevel.Unforgivable
|
||||
getInfluence() < 0 -> RelationshipLevel.Enemy
|
||||
getInfluence() < 30 && civInfo.getTributeWillingness(otherCiv()) > 0 -> RelationshipLevel.Afraid
|
||||
getInfluence() >= 60 && civInfo.getAllyCiv() == otherCivName -> RelationshipLevel.Ally
|
||||
getInfluence() >= 30 -> RelationshipLevel.Friend
|
||||
else -> RelationshipLevel.Neutral
|
||||
}
|
||||
|
||||
@ -201,8 +201,8 @@ class DiplomacyManager() {
|
||||
val dropPerTurn = getCityStateInfluenceDegrade()
|
||||
return when {
|
||||
dropPerTurn == 0f -> 0
|
||||
relationshipLevel() >= RelationshipLevel.Ally -> ceil((influence - 60f) / dropPerTurn).toInt() + 1
|
||||
relationshipLevel() >= RelationshipLevel.Friend -> ceil((influence - 30f) / dropPerTurn).toInt() + 1
|
||||
relationshipLevel() >= RelationshipLevel.Ally -> ceil((getInfluence() - 60f) / dropPerTurn).toInt() + 1
|
||||
relationshipLevel() >= RelationshipLevel.Friend -> ceil((getInfluence() - 30f) / dropPerTurn).toInt() + 1
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
@ -231,6 +231,8 @@ class DiplomacyManager() {
|
||||
civInfo.updateAllyCivForCityState()
|
||||
}
|
||||
|
||||
fun getInfluence() = if (civInfo.isAtWarWith(otherCiv())) MINIMUM_INFLUENCE else influence
|
||||
|
||||
// To be run from City-State DiplomacyManager, which holds the influence. Resting point for every major civ can be different.
|
||||
private fun getCityStateInfluenceRestingPoint(): Float {
|
||||
var restingPoint = 0f
|
||||
@ -251,7 +253,7 @@ class DiplomacyManager() {
|
||||
}
|
||||
|
||||
private fun getCityStateInfluenceDegrade(): Float {
|
||||
if (influence < getCityStateInfluenceRestingPoint())
|
||||
if (getInfluence() < getCityStateInfluenceRestingPoint())
|
||||
return 0f
|
||||
|
||||
val decrement = when {
|
||||
@ -279,7 +281,7 @@ class DiplomacyManager() {
|
||||
}
|
||||
|
||||
private fun getCityStateInfluenceRecovery(): Float {
|
||||
if (influence > getCityStateInfluenceRestingPoint())
|
||||
if (getInfluence() > getCityStateInfluenceRestingPoint())
|
||||
return 0f
|
||||
|
||||
val increment = 1f // sic: personality does not matter here
|
||||
@ -424,7 +426,7 @@ class DiplomacyManager() {
|
||||
updateHasOpenBorders()
|
||||
nextTurnDiplomaticModifiers()
|
||||
nextTurnFlags()
|
||||
if (civInfo.isCityState() && !otherCiv().isCityState())
|
||||
if (civInfo.isCityState() && otherCiv().isMajorCiv())
|
||||
nextTurnCityStateInfluence()
|
||||
updateEverBeenFriends()
|
||||
}
|
||||
@ -442,14 +444,16 @@ class DiplomacyManager() {
|
||||
val initialRelationshipLevel = relationshipLevel()
|
||||
|
||||
val restingPoint = getCityStateInfluenceRestingPoint()
|
||||
// We don't use `getInfluence()` here, as then during war with the ally of this CS,
|
||||
// our influence would be set to -59, overwriting the old value, which we want to keep
|
||||
// as it should be restored once the war ends (though we keep influence degradation from time during the war)
|
||||
if (influence > restingPoint) {
|
||||
val decrement = getCityStateInfluenceDegrade()
|
||||
influence = max(restingPoint, influence - decrement)
|
||||
setInfluence(max(restingPoint, influence - decrement))
|
||||
} else if (influence < restingPoint) {
|
||||
val increment = getCityStateInfluenceRecovery()
|
||||
influence = min(restingPoint, influence + increment)
|
||||
setInfluence(min(restingPoint, influence + increment))
|
||||
}
|
||||
civInfo.updateAllyCivForCityState()
|
||||
|
||||
if (!civInfo.isDefeated()) { // don't display city state relationship notifications when the city state is currently defeated
|
||||
val civCapitalLocation = if (civInfo.cities.isNotEmpty()) civInfo.getCapital().location else null
|
||||
@ -466,7 +470,7 @@ class DiplomacyManager() {
|
||||
}
|
||||
|
||||
// Potentially notify about afraid status
|
||||
if (influence < 30 // We usually don't want to bully our friends
|
||||
if (getInfluence() < 30 // We usually don't want to bully our friends
|
||||
&& !hasFlag(DiplomacyFlags.NotifiedAfraid)
|
||||
&& civInfo.getTributeWillingness(otherCiv()) > 0
|
||||
&& otherCiv().isMajorCiv()
|
||||
@ -650,6 +654,10 @@ class DiplomacyManager() {
|
||||
trades.clear()
|
||||
updateHasOpenBorders()
|
||||
|
||||
if (civInfo.isCityState() && civInfo.getProtectorCivs().contains(otherCiv())) {
|
||||
civInfo.removeProtectorCiv(otherCiv(), forced = true)
|
||||
}
|
||||
|
||||
diplomaticStatus = DiplomaticStatus.War
|
||||
|
||||
removeModifier(DiplomaticModifiers.YearsOfPeace)
|
||||
@ -658,7 +666,15 @@ class DiplomacyManager() {
|
||||
removeFlag(DiplomacyFlags.BorderConflict)
|
||||
}
|
||||
|
||||
fun declareWar() {
|
||||
/** Declares war with the other civ in this diplomacy manager.
|
||||
* Handles all war effects and diplomatic changes with other civs and such.
|
||||
*
|
||||
* @param indirectCityStateAttack Influence with city states should only be set to -60
|
||||
* when they are attacked directly, not when their ally is attacked.
|
||||
* When @indirectCityStateAttack is set to true, we thus don't reset the influence with this city state.
|
||||
* Should only ever be set to true for calls originating from within this function.
|
||||
*/
|
||||
fun declareWar(indirectCityStateAttack: Boolean = false) {
|
||||
val otherCiv = otherCiv()
|
||||
val otherCivDiplomacy = otherCivDiplomacy()
|
||||
|
||||
@ -675,6 +691,7 @@ class DiplomacyManager() {
|
||||
otherCivDiplomacy.setModifier(DiplomaticModifiers.DeclaredWarOnUs, -20f)
|
||||
otherCivDiplomacy.removeModifier(DiplomaticModifiers.ReturnedCapturedUnits)
|
||||
if (otherCiv.isCityState()) {
|
||||
if (!indirectCityStateAttack)
|
||||
otherCivDiplomacy.setInfluence(-60f)
|
||||
civInfo.changeMinorCivsAttacked(1)
|
||||
otherCiv.cityStateFunctions.cityStateAttacked(civInfo)
|
||||
@ -682,7 +699,7 @@ class DiplomacyManager() {
|
||||
|
||||
for (thirdCiv in civInfo.getKnownCivs()) {
|
||||
if (thirdCiv.isAtWarWith(otherCiv)) {
|
||||
if (thirdCiv.isCityState()) thirdCiv.getDiplomacyManager(civInfo).influence += 10
|
||||
if (thirdCiv.isCityState()) thirdCiv.getDiplomacyManager(civInfo).addInfluence(10f)
|
||||
else thirdCiv.getDiplomacyManager(civInfo).addModifier(DiplomaticModifiers.SharedEnemy, 5f)
|
||||
} else thirdCiv.getDiplomacyManager(civInfo).addModifier(DiplomaticModifiers.WarMongerer, -5f)
|
||||
}
|
||||
@ -710,11 +727,11 @@ class DiplomacyManager() {
|
||||
for (thirdCiv in civInfo.getKnownCivs()) {
|
||||
if (thirdCiv.isCityState() && thirdCiv.getAllyCiv() == civInfo.civName) {
|
||||
if (thirdCiv.knows(otherCiv) && !thirdCiv.isAtWarWith(otherCiv))
|
||||
thirdCiv.getDiplomacyManager(otherCiv).declareWar()
|
||||
thirdCiv.getDiplomacyManager(otherCiv).declareWar(true)
|
||||
else if (!thirdCiv.knows(otherCiv)) {
|
||||
// Our city state ally has not met them yet, so they have to meet first
|
||||
thirdCiv.makeCivilizationsMeet(otherCiv, warOnContact = true)
|
||||
thirdCiv.getDiplomacyManager(otherCiv).declareWar()
|
||||
thirdCiv.getDiplomacyManager(otherCiv).declareWar(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -725,11 +742,11 @@ class DiplomacyManager() {
|
||||
for (thirdCiv in otherCiv.getKnownCivs()) {
|
||||
if (thirdCiv.isCityState() && thirdCiv.getAllyCiv() == otherCiv.civName) {
|
||||
if (thirdCiv.knows(civInfo) && !thirdCiv.isAtWarWith(civInfo))
|
||||
thirdCiv.getDiplomacyManager(civInfo).declareWar()
|
||||
thirdCiv.getDiplomacyManager(civInfo).declareWar(true)
|
||||
else if (!thirdCiv.knows(civInfo)) {
|
||||
// Their city state ally has not met us yet, so we have to meet first
|
||||
thirdCiv.makeCivilizationsMeet(civInfo, warOnContact = true)
|
||||
thirdCiv.getDiplomacyManager(civInfo).declareWar()
|
||||
thirdCiv.getDiplomacyManager(civInfo).declareWar(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab
|
||||
|
||||
if (city.civInfo.isCityState() && city.civInfo.knows(worldScreen.viewingCiv)) {
|
||||
val diplomacyManager = city.civInfo.getDiplomacyManager(worldScreen.viewingCiv)
|
||||
val influenceBar = getInfluenceBar(diplomacyManager.influence, diplomacyManager.relationshipLevel())
|
||||
val influenceBar = getInfluenceBar(diplomacyManager.getInfluence(), diplomacyManager.relationshipLevel())
|
||||
add(influenceBar).row()
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ class DiplomacyScreen(
|
||||
otherCiv.updateAllyCivForCityState()
|
||||
val ally = otherCiv.getAllyCiv()
|
||||
if (ally != null) {
|
||||
val allyInfluence = otherCiv.getDiplomacyManager(ally).influence.toInt()
|
||||
val allyInfluence = otherCiv.getDiplomacyManager(ally).getInfluence().toInt()
|
||||
diplomacyTable
|
||||
.add("Ally: [$ally] with [$allyInfluence] Influence".toLabel())
|
||||
.row()
|
||||
@ -214,8 +214,11 @@ class DiplomacyScreen(
|
||||
diplomacyTable.add(protectorString.toLabel()).row()
|
||||
}
|
||||
|
||||
val atWar = otherCiv.isAtWarWith(viewingCiv)
|
||||
|
||||
val nextLevelString = when {
|
||||
otherCivDiplomacyManager.influence.toInt() < 30 -> "Reach 30 for friendship."
|
||||
atWar -> ""
|
||||
otherCivDiplomacyManager.getInfluence().toInt() < 30 -> "Reach 30 for friendship."
|
||||
ally == viewingCiv.civName -> ""
|
||||
else -> "Reach highest influence above 60 for alliance."
|
||||
}
|
||||
@ -322,7 +325,7 @@ class DiplomacyScreen(
|
||||
rightSideTable.add(ScrollPane(getGoldGiftTable(otherCiv)))
|
||||
}
|
||||
diplomacyTable.add(giveGiftButton).row()
|
||||
if (isNotPlayersTurn()) giveGiftButton.disable()
|
||||
if (isNotPlayersTurn() || viewingCiv.isAtWarWith(otherCiv)) giveGiftButton.disable()
|
||||
|
||||
val improveTileButton = getImproveTilesButton(otherCiv, otherCivDiplomacyManager)
|
||||
if (improveTileButton != null) diplomacyTable.add(improveTileButton).row()
|
||||
@ -357,7 +360,7 @@ class DiplomacyScreen(
|
||||
rightSideTable.add(ScrollPane(getDemandTributeTable(otherCiv)))
|
||||
}
|
||||
diplomacyTable.add(demandTributeButton).row()
|
||||
if (isNotPlayersTurn()) demandTributeButton.disable()
|
||||
if (isNotPlayersTurn() || viewingCiv.isAtWarWith(otherCiv)) demandTributeButton.disable()
|
||||
|
||||
val diplomacyManager = viewingCiv.getDiplomacyManager(otherCiv)
|
||||
if (!viewingCiv.gameInfo.ruleSet.modOptions.uniques.contains(ModOptionsConstants.diplomaticRelationshipsCannotChange)) {
|
||||
@ -440,7 +443,7 @@ class DiplomacyScreen(
|
||||
}
|
||||
|
||||
|
||||
if (isNotPlayersTurn() || otherCivDiplomacyManager.influence < 60 || !needsImprovements)
|
||||
if (isNotPlayersTurn() || otherCivDiplomacyManager.getInfluence() < 60 || !needsImprovements)
|
||||
improveTileButton.disable()
|
||||
return improveTileButton
|
||||
}
|
||||
@ -857,7 +860,7 @@ class DiplomacyScreen(
|
||||
val relationshipTable = Table()
|
||||
|
||||
val opinionOfUs =
|
||||
if (otherCivDiplomacyManager.civInfo.isCityState()) otherCivDiplomacyManager.influence.toInt()
|
||||
if (otherCivDiplomacyManager.civInfo.isCityState()) otherCivDiplomacyManager.getInfluence().toInt()
|
||||
else otherCivDiplomacyManager.opinionOfOtherCiv().toInt()
|
||||
|
||||
relationshipTable.add("{Our relationship}: ".toLabel())
|
||||
@ -875,8 +878,8 @@ class DiplomacyScreen(
|
||||
if (otherCivDiplomacyManager.civInfo.isCityState())
|
||||
relationshipTable.add(
|
||||
CityButton.getInfluenceBar(
|
||||
otherCivDiplomacyManager.influence,
|
||||
otherCivDiplomacyManager.relationshipLevel(),
|
||||
otherCivDiplomacyManager.getInfluence(),
|
||||
relationshipLevel,
|
||||
200f, 10f
|
||||
)
|
||||
).colspan(2).pad(5f)
|
||||
|
Loading…
x
Reference in New Issue
Block a user