From eec3732c96ce4a8cb3e7171e81d74969d90ed529 Mon Sep 17 00:00:00 2001 From: Oskar Niesen Date: Tue, 5 Sep 2023 11:01:45 -0500 Subject: [PATCH] Defensive pact notification fix (#10025) * Fixed Civ getting two notifications of canceling their defensive pact when attacking. * Added Defensive Pact related warnings to the Declare War popup * Improved the warning to not include Civs that are already at war with the aggressor * Improved the warning to not include Civs that are already at war with the aggressor * Added defensive pact related warning translations * Refactored removeDefensivePacts * DeclareWarButton text now uses arrayListOf and changed the for loop to a while loop * Extracted the DeclareWarButton text to a new method. --- .../jsons/translations/template.properties | 3 ++ .../diplomacy/DiplomacyManager.kt | 34 ++++++++-------- .../diplomacyscreen/DiplomacyScreen.kt | 39 ++++++++++++++++++- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index f59d7d5a35..e8640da7d8 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -119,6 +119,9 @@ Peace = Research Agreement = Declare war = Declare war on [civName]? = +[civName] will also join them in the war = +An unknown civilization will also join them in the war = +This will cancel your defensive pact with [civName] = Go to on map = Let's begin! = [civName] has declared war on us! = diff --git a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt index a0691c319c..015eb983ad 100644 --- a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt +++ b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt @@ -765,27 +765,29 @@ class DiplomacyManager() : IsPartOfGameInfoSerialization { */ private fun removeDefensivePacts() { val civAtWarWith = otherCiv() - civInfo.diplomacy.values.filter { it.diplomaticStatus == DiplomaticStatus.DefensivePact }.forEach { + for (diploManager in civInfo.diplomacy.values) { + if (diploManager.diplomaticStatus != DiplomaticStatus.DefensivePact) continue + // We already removed the trades and we don't want to remove the flags yet. - if (it.otherCiv() != civAtWarWith) { + if (diploManager.otherCiv() != civAtWarWith) { // Trades with defensive pact are now invalid - val defensivePactOffer = it.trades.firstOrNull { trade -> trade.ourOffers.any { offer -> offer.name == Constants.defensivePact } } - it.trades.remove(defensivePactOffer) - val theirDefensivePactOffer = it.otherCivDiplomacy().trades.firstOrNull { trade -> trade.ourOffers.any { offer -> offer.name == Constants.defensivePact } } - it.otherCivDiplomacy().trades.remove(theirDefensivePactOffer) - it.removeFlag(DiplomacyFlags.DefensivePact) - it.otherCivDiplomacy().removeFlag(DiplomacyFlags.DefensivePact) - it.diplomaticStatus = DiplomaticStatus.Peace - it.otherCivDiplomacy().diplomaticStatus = DiplomaticStatus.Peace + val defensivePactOffer = diploManager.trades + .firstOrNull { trade -> trade.ourOffers.any { offer -> offer.name == Constants.defensivePact } } + diploManager.trades.remove(defensivePactOffer) + val theirDefensivePactOffer = diploManager.otherCivDiplomacy().trades + .firstOrNull { trade -> trade.ourOffers.any { offer -> offer.name == Constants.defensivePact } } + diploManager.otherCivDiplomacy().trades.remove(theirDefensivePactOffer) + diploManager.removeFlag(DiplomacyFlags.DefensivePact) + diploManager.otherCivDiplomacy().removeFlag(DiplomacyFlags.DefensivePact) + diploManager.diplomaticStatus = DiplomaticStatus.Peace + diploManager.otherCivDiplomacy().diplomaticStatus = DiplomaticStatus.Peace } for (civ in getCommonKnownCivs().filter { civ -> civ.isMajorCiv() }) { - civ.addNotification("[${civInfo.civName}] canceled their Defensive Pact with [${it.otherCivName}]!", - NotificationCategory.Diplomacy, civInfo.civName, NotificationIcon.Diplomacy, it.otherCivName) + civ.addNotification("[${civInfo.civName}] canceled their Defensive Pact with [${diploManager.otherCivName}]!", + NotificationCategory.Diplomacy, civInfo.civName, NotificationIcon.Diplomacy, diploManager.otherCivName) } - civInfo.addNotification("We have canceled our Defensive Pact with [${it.otherCivName}]!", - NotificationCategory.Diplomacy, NotificationIcon.Diplomacy, it.otherCivName) - it.otherCiv().addNotification("[${civInfo.civName}] has canceled our Defensive Pact with us!", - NotificationCategory.Diplomacy, civInfo.civName, NotificationIcon.Diplomacy) + civInfo.addNotification("We have canceled our Defensive Pact with [${diploManager.otherCivName}]!", + NotificationCategory.Diplomacy, NotificationIcon.Diplomacy, diploManager.otherCivName) } } diff --git a/core/src/com/unciv/ui/screens/diplomacyscreen/DiplomacyScreen.kt b/core/src/com/unciv/ui/screens/diplomacyscreen/DiplomacyScreen.kt index 798ef5dd80..bfe44dc1a5 100644 --- a/core/src/com/unciv/ui/screens/diplomacyscreen/DiplomacyScreen.kt +++ b/core/src/com/unciv/ui/screens/diplomacyscreen/DiplomacyScreen.kt @@ -873,7 +873,7 @@ class DiplomacyScreen( declareWarButton.setText(declareWarButton.text.toString() + " ($turnsToPeaceTreaty${Fonts.turn})") } declareWarButton.onClick { - ConfirmPopup(this, "Declare war on [${otherCiv.civName}]?", "Declare war") { + ConfirmPopup(this, getDeclareWarButtonText(otherCiv), "Declare war") { diplomacyManager.declareWar() setRightSideFlavorText(otherCiv, otherCiv.nation.attacked, "Very well.") updateLeftSideTable(otherCiv) @@ -883,6 +883,43 @@ class DiplomacyScreen( if (isNotPlayersTurn()) declareWarButton.disable() return declareWarButton } + + private fun getDeclareWarButtonText(otherCiv: Civilization): String { + val messageLines = arrayListOf() + messageLines += "Declare war on [${otherCiv.civName}]?" + // Tell the player who all will join the other side from defensive pacts + val otherCivDefensivePactList = otherCiv.diplomacy.values.filter { + otherCivDiploManager -> otherCivDiploManager.otherCiv() != viewingCiv + && otherCivDiploManager.diplomaticStatus == DiplomaticStatus.DefensivePact + && !otherCivDiploManager.otherCiv().isAtWarWith(viewingCiv) } + .map { it.otherCiv() }.toMutableList() + // Go through and find all of the defensive pact chains and add them to the list + var listIndex = 0 + while (listIndex < otherCivDefensivePactList.size) { + messageLines += if (viewingCiv.knows(otherCivDefensivePactList[listIndex])) + "[${otherCivDefensivePactList[listIndex].civName}] will also join them in the war" + else "An unknown civilization will also join them in the war" + + // Add their defensive pact allies + otherCivDefensivePactList.addAll(otherCivDefensivePactList[listIndex].diplomacy.values + .filter { diploChain -> diploChain.diplomaticStatus == DiplomaticStatus.DefensivePact + && !otherCivDefensivePactList.contains(diploChain.otherCiv()) + && diploChain.otherCiv() != viewingCiv && diploChain.otherCiv() != otherCiv + && !diploChain.otherCiv().isAtWarWith(viewingCiv) } + .map { it.otherCiv() }) + listIndex++ + } + + // Tell the player that their defensive pacts will be canceled. + for (civDiploManager in viewingCiv.diplomacy.values) { + if (civDiploManager.otherCiv() != otherCiv + && civDiploManager.diplomaticStatus == DiplomaticStatus.DefensivePact + && !otherCivDefensivePactList.contains(civDiploManager.otherCiv())) { + messageLines += "This will cancel your defensive pact with [${civDiploManager.otherCivName}]" + } + } + return messageLines.joinToString("\n") { "{$it}" } + } //endregion