diff --git a/core/src/com/unciv/logic/automation/NextTurnAutomation.kt b/core/src/com/unciv/logic/automation/NextTurnAutomation.kt index 8e191614bd..6354aa1510 100644 --- a/core/src/com/unciv/logic/automation/NextTurnAutomation.kt +++ b/core/src/com/unciv/logic/automation/NextTurnAutomation.kt @@ -217,11 +217,11 @@ object NextTurnAutomation { for (state in civInfo.getKnownCivs().filter{!it.isDefeated() && it.isCityState()}) { val diplomacyManager = state.getDiplomacyManager(civInfo.civName) if(diplomacyManager.relationshipLevel() >= RelationshipLevel.Friend - && diplomacyManager.diplomaticStatus == DiplomaticStatus.Peace) + && state.otherCivCanPledgeProtection(civInfo)) { state.addProtectorCiv(civInfo) } else if (diplomacyManager.relationshipLevel() < RelationshipLevel.Friend - && diplomacyManager.diplomaticStatus == DiplomaticStatus.Protector) { + && state.otherCivCanWithdrawProtection(civInfo)) { state.removeProtectorCiv(civInfo) } } diff --git a/core/src/com/unciv/logic/civilization/CityStateFunctions.kt b/core/src/com/unciv/logic/civilization/CityStateFunctions.kt index aa7f42110c..9029c0f4ea 100644 --- a/core/src/com/unciv/logic/civilization/CityStateFunctions.kt +++ b/core/src/com/unciv/logic/civilization/CityStateFunctions.kt @@ -94,22 +94,58 @@ class CityStateFunctions(val civInfo: CivilizationInfo) { } fun addProtectorCiv(otherCiv: CivilizationInfo) { - if(!civInfo.isCityState() or !otherCiv.isMajorCiv() or otherCiv.isDefeated()) return - if(!civInfo.knows(otherCiv) or civInfo.isAtWarWith(otherCiv)) return //Exception + if(!otherCivCanPledgeProtection(otherCiv)) + return val diplomacy = civInfo.getDiplomacyManager(otherCiv.civName) diplomacy.diplomaticStatus = DiplomaticStatus.Protector + diplomacy.setFlag(DiplomacyFlags.RecentlyPledgedProtection, 10) // Can't break for 10 turns } fun removeProtectorCiv(otherCiv: CivilizationInfo) { - if(!civInfo.isCityState() or !otherCiv.isMajorCiv() or otherCiv.isDefeated()) return - if(!civInfo.knows(otherCiv) or civInfo.isAtWarWith(otherCiv)) return //Exception + if(!otherCivCanWithdrawProtection(otherCiv)) + return - val diplomacy = civInfo.getDiplomacyManager(otherCiv.civName) + val diplomacy = civInfo.getDiplomacyManager(otherCiv) diplomacy.diplomaticStatus = DiplomaticStatus.Peace + diplomacy.setFlag(DiplomacyFlags.RecentlyWithdrewProtection, 20) // Can't re-pledge for 20 turns diplomacy.addInfluence(-20f) } + fun otherCivCanPledgeProtection(otherCiv: CivilizationInfo): Boolean { + // Must be a known city state + if(!civInfo.isCityState() || !otherCiv.isMajorCiv() || otherCiv.isDefeated() || !civInfo.knows(otherCiv)) + return false + val diplomacy = civInfo.getDiplomacyManager(otherCiv) + // Can't pledge too soon after withdrawing + if (diplomacy.hasFlag(DiplomacyFlags.RecentlyWithdrewProtection)) + return false + // Must have at least 0 influence + if (diplomacy.influence < 0) + return false + // can't be at war + if (civInfo.isAtWarWith(otherCiv)) + return false + // Must not be protected already + if (diplomacy.diplomaticStatus == DiplomaticStatus.Protector) + return false + return true + } + + fun otherCivCanWithdrawProtection(otherCiv: CivilizationInfo): Boolean { + // Must be a known city state + if(!civInfo.isCityState() || !otherCiv.isMajorCiv() || otherCiv.isDefeated() || !civInfo.knows(otherCiv)) + return false + val diplomacy = civInfo.getDiplomacyManager(otherCiv) + // Can't withdraw too soon after pledging + if (diplomacy.hasFlag(DiplomacyFlags.RecentlyPledgedProtection)) + return false + // Must be protected + if (diplomacy.diplomaticStatus != DiplomaticStatus.Protector) + return false + return true + } + fun updateAllyCivForCityState() { var newAllyName: String? = null if (!civInfo.isCityState()) return diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index fa49ac0eef..15ddbe7b96 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -911,6 +911,8 @@ class CivilizationInfo { fun removeProtectorCiv(otherCiv: CivilizationInfo) { cityStateFunctions.removeProtectorCiv(otherCiv) } + fun otherCivCanPledgeProtection(otherCiv: CivilizationInfo) = cityStateFunctions.otherCivCanPledgeProtection(otherCiv) + fun otherCivCanWithdrawProtection(otherCiv: CivilizationInfo) = cityStateFunctions.otherCivCanWithdrawProtection(otherCiv) fun updateAllyCivForCityState() { cityStateFunctions.updateAllyCivForCityState() } diff --git a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt index 0f0bf00559..aa4a31a3c9 100644 --- a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt +++ b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt @@ -41,6 +41,8 @@ enum class DiplomacyFlags{ EverBeenFriends, MarriageCooldown, NotifiedAfraid, + RecentlyPledgedProtection, + RecentlyWithdrewProtection, AngerFreeIntrusion } diff --git a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt index 8013eba0b3..a05d41325b 100644 --- a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt +++ b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt @@ -236,7 +236,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() { }, this).open() } diplomacyTable.add(revokeProtectionButton).row() - if (isNotPlayersTurn()) revokeProtectionButton.disable() + if (isNotPlayersTurn() || !otherCiv.otherCivCanWithdrawProtection(viewingCiv)) revokeProtectionButton.disable() } else { val protectionButton = "Pledge to protect".toTextButton() protectionButton.onClick { @@ -246,11 +246,8 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() { updateRightSide(otherCiv) }, this).open() } - if (viewingCiv.isAtWarWith(otherCiv)) { - protectionButton.disable() - } diplomacyTable.add(protectionButton).row() - if (isNotPlayersTurn()) protectionButton.disable() + if (isNotPlayersTurn() || !otherCiv.otherCivCanPledgeProtection(viewingCiv)) protectionButton.disable() } val demandTributeButton = "Demand Tribute".toTextButton()