From 75bdced3c6a71422e7238c14cfe3c784fb4d5b22 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Wed, 8 May 2019 17:24:56 +0300 Subject: [PATCH] Added Declaration of Friendship logic @ninjatao - I changed your BorderConflict into a DiplomacyFlag, and so all the logic of "removing every turn and deleting if 0" is built-in =) --- android/assets/jsons/Translations/Other.json | 4 ++ .../logic/automation/NextTurnAutomation.kt | 35 +++------- .../logic/civilization/CivilizationInfo.kt | 2 + .../diplomacy/DiplomacyManager.kt | 67 +++++++++++++++++-- .../src/com/unciv/ui/trade/DiplomacyScreen.kt | 22 +++--- .../com/unciv/ui/worldscreen/TradePopup.kt | 6 +- 6 files changed, 91 insertions(+), 45 deletions(-) diff --git a/android/assets/jsons/Translations/Other.json b/android/assets/jsons/Translations/Other.json index ede5825efb..b5eceb1d14 100644 --- a/android/assets/jsons/Translations/Other.json +++ b/android/assets/jsons/Translations/Other.json @@ -2793,6 +2793,10 @@ French:"Nos problèmes militaires communs nous ont rapprochés" } + "We have signed a public declaration of friendship":{} + "You have declared friendship with our enemies!":{} + "You have declared friendship with our allies":{} + ////// Overview screen "Overview":{ diff --git a/core/src/com/unciv/logic/automation/NextTurnAutomation.kt b/core/src/com/unciv/logic/automation/NextTurnAutomation.kt index 72d508da3f..d6342f5de8 100644 --- a/core/src/com/unciv/logic/automation/NextTurnAutomation.kt +++ b/core/src/com/unciv/logic/automation/NextTurnAutomation.kt @@ -1,12 +1,12 @@ package com.unciv.logic.automation +import com.unciv.Constants +import com.unciv.logic.civilization.* 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.MapUnit import com.unciv.logic.trade.* -import com.unciv.Constants -import com.unciv.logic.civilization.* import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.tech.Technology import com.unciv.models.gamebasics.tr @@ -166,7 +166,7 @@ class NextTurnAutomation{ // B. have a way for the AI to keep track of the "pending offers" - see DiplomacyManager.resourcesFromTrade for (otherCiv in knownCivs.filter { it.isPlayerCivilization() && !it.isAtWarWith(civInfo) - && !civInfo.getDiplomacyManager(it).flagsCountdown.containsKey(DiplomacyFlags.DeclinedLuxExchange.toString())}) { + && !civInfo.getDiplomacyManager(it).hasFlag(DiplomacyFlags.DeclinedLuxExchange)}) { val relationshipLevel = civInfo.getDiplomacyManager(otherCiv).relationshipLevel() if(relationshipLevel==RelationshipLevel.Enemy || relationshipLevel == RelationshipLevel.Unforgivable) @@ -205,7 +205,7 @@ class NextTurnAutomation{ val enemiesCiv = civInfo.diplomacy.filter{ it.value.diplomaticStatus == DiplomaticStatus.War } .map{ it.value.otherCiv() } .filterNot{ it == civInfo || it.isBarbarianCivilization() || it.cities.isEmpty() } - .filter { !civInfo.getDiplomacyManager(it).flagsCountdown.containsKey(DiplomacyFlags.DeclinedPeace.toString()) } + .filter { !civInfo.getDiplomacyManager(it).hasFlag(DiplomacyFlags.DeclinedPeace) } for (enemy in enemiesCiv) { val enemiesStrength = Automation().evaluteCombatStrength(enemy) @@ -245,30 +245,17 @@ class NextTurnAutomation{ private fun updateDiplomaticRelationship(civInfo: CivilizationInfo) { // Check if city-state invaded by other civs if (civInfo.isCityState()) { - for (civ in civInfo.gameInfo.civilizations) { - var needClearCounter = false - if (civ == civInfo || civ.isBarbarianCivilization() || !civInfo.getKnownCivs().contains(civ)) continue - val diplomacy = civInfo.getDiplomacyManager(civ)!! - if (diplomacy.diplomaticStatus == DiplomaticStatus.War) { - needClearCounter = true - } + for (otherCiv in civInfo.getKnownCivs().filter { it.isMajorCiv() }) { + if(civInfo.isAtWarWith(otherCiv)) continue + val diplomacy = civInfo.getDiplomacyManager(otherCiv) - val unitsInBorder = civ.getCivUnits().count { !it.type.isCivilian() && it.getTile().getOwner() == civInfo } + val unitsInBorder = otherCiv.getCivUnits().count { !it.type.isCivilian() && it.getTile().getOwner() == civInfo } if (unitsInBorder > 0 && diplomacy.influence < 30f) { diplomacy.influence -= 10f - if (!diplomacy.flagsCountdown.containsKey("BorderConflict") - || diplomacy.flagsCountdown["BorderConflict"]!! <= 0) { - civ.popupAlerts.add(PopupAlert(AlertType.BorderConflict,civInfo.civName)) - diplomacy.flagsCountdown["BorderConflict"] = 10 - } else { - diplomacy.flagsCountdown["BorderConflict"]!!.minus(1) + if (!diplomacy.hasFlag(DiplomacyFlags.BorderConflict)) { + otherCiv.popupAlerts.add(PopupAlert(AlertType.BorderConflict,civInfo.civName)) + diplomacy.setFlag(DiplomacyFlags.BorderConflict,10) } - } else { - needClearCounter = true - } - - if (needClearCounter && diplomacy.flagsCountdown.containsKey("BorderConflict")) { - diplomacy.flagsCountdown.remove("BorderConflict") } } } diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 48ee4c8ced..122a09e6f7 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -127,6 +127,8 @@ class CivilizationInfo { fun getDiplomacyManager(civInfo: CivilizationInfo) = diplomacy[civInfo.civName]!! fun getKnownCivs() = diplomacy.values.map { it.otherCiv() } + fun knows(otherCiv: CivilizationInfo) = knows(otherCiv.civName) + fun knows(otherCivName: String) = diplomacy.containsKey(otherCivName) fun getCapital()=cities.first { it.isCapital() } fun isPlayerCivilization() = playerType==PlayerType.Human diff --git a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt index e67efd68b2..b086665022 100644 --- a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt +++ b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt @@ -23,15 +23,21 @@ enum class RelationshipLevel{ enum class DiplomacyFlags{ DeclinedLuxExchange, - DeclinedPeace + DeclinedPeace, + DeclarationOfFriendship, + BorderConflict } enum class DiplomaticModifiers{ DeclaredWarOnUs, WarMongerer, CapturedOurCities, + DeclaredFriendshipWithOurEnemies, + YearsOfPeace, - SharedEnemy + SharedEnemy, + DeclarationOfFriendship, + DeclaredFriendshipWithOurAllies } class DiplomacyManager() { @@ -75,6 +81,7 @@ class DiplomacyManager() { //region pure functions fun otherCiv() = civInfo.gameInfo.getCivilization(otherCivName) + fun otherCivDiplomacy() = otherCiv().getDiplomacyManager(civInfo) fun turnsToPeaceTreaty(): Int { for(trade in trades) @@ -190,7 +197,14 @@ class DiplomacyManager() { updateHasOpenBorders() if(diplomaticStatus==DiplomaticStatus.Peace) - addModifier(DiplomaticModifiers.YearsOfPeace,1f) + addModifier(DiplomaticModifiers.YearsOfPeace,0.5f) + else revertToZero(DiplomaticModifiers.YearsOfPeace,-0.5f) // war makes you forget the good ol' days + + revertToZero(DiplomaticModifiers.DeclaredWarOnUs,1/8f) // this disappears real slow - it'll take 160 turns to really forget, this is war declaration we're talking about + revertToZero(DiplomaticModifiers.WarMongerer,0.5f) // warmongering gives a big negative boost when it happens but they're forgotten relatively quickly, like WWII amirite + revertToZero(DiplomaticModifiers.CapturedOurCities,1/4f) // if you captured our cities, though, that's harder to forget + if(!hasFlag(DiplomacyFlags.DeclarationOfFriendship)) + revertToZero(DiplomaticModifiers.DeclarationOfFriendship, 0.5f) //decreases slowly and will revert to full if it is declared later for(flag in flagsCountdown.keys.toList()) { flagsCountdown[flag] = flagsCountdown[flag]!! - 1 @@ -231,10 +245,13 @@ class DiplomacyManager() { otherCiv.popupAlerts.add(PopupAlert(AlertType.WarDeclaration,civInfo.civName)) /// AI won't propose peace for 10 turns - flagsCountdown[DiplomacyFlags.DeclinedPeace.toString()]=10 - otherCiv.getDiplomacyManager(civInfo).flagsCountdown[DiplomacyFlags.DeclinedPeace.toString()]=10 + setFlag(DiplomacyFlags.DeclinedPeace,10) + otherCiv.getDiplomacyManager(civInfo).setFlag(DiplomacyFlags.DeclinedPeace,10) + otherCivDiplomacy.setModifier(DiplomaticModifiers.DeclaredWarOnUs,-20f) + + removeFlag(DiplomacyFlags.BorderConflict) + otherCivDiplomacy.removeFlag(DiplomacyFlags.BorderConflict) - otherCivDiplomacy.diplomaticModifiers[DiplomaticModifiers.DeclaredWarOnUs.toString()] = -20f for(thirdCiv in civInfo.getKnownCivs()){ if(thirdCiv.isAtWarWith(otherCiv)) thirdCiv.getDiplomacyManager(civInfo).addModifier(DiplomaticModifiers.WarMongerer,5f) @@ -254,10 +271,46 @@ class DiplomacyManager() { unit.movementAlgs().teleportToClosestMoveableTile() } + fun hasFlag(flag:DiplomacyFlags) = flagsCountdown.containsKey(flag.toString()) + fun setFlag(flag: DiplomacyFlags, amount: Int){ flagsCountdown[flag.toString()]=amount} + fun removeFlag(flag: DiplomacyFlags){ flagsCountdown.remove(flag.toString())} + fun addModifier(modifier: DiplomaticModifiers, amount:Float){ val modifierString = modifier.toString() - if(!diplomaticModifiers.containsKey(modifierString)) diplomaticModifiers[modifierString]=0f + if(!hasModifier(modifier)) setModifier(modifier,0f) diplomaticModifiers[modifierString] = diplomaticModifiers[modifierString]!!+amount + if(diplomaticModifiers[modifierString]==0f) diplomaticModifiers.remove(modifierString) + } + + fun setModifier(modifier: DiplomaticModifiers, amount: Float){ + val modifierString = modifier.toString() + diplomaticModifiers[modifierString] = amount + } + + fun hasModifier(modifier: DiplomaticModifiers) = diplomaticModifiers.containsKey(modifier.toString()) + + /** @param amount always positive, so you don't need to think about it */ + fun revertToZero(modifier: DiplomaticModifiers, amount: Float){ + if(!hasModifier(modifier)) return + val currentAmount = diplomaticModifiers[modifier.toString()]!! + if(currentAmount > 0) addModifier(modifier,-amount) + else addModifier(modifier,amount) + } + + fun signDeclarationOfFriendship(){ + setModifier(DiplomaticModifiers.DeclarationOfFriendship,35f) + otherCivDiplomacy().setModifier(DiplomaticModifiers.DeclarationOfFriendship,35f) + + for(thirdCiv in civInfo.getKnownCivs().filter { it.isMajorCiv() }){ + if(thirdCiv==otherCiv() || !thirdCiv.knows(otherCivName)) continue + val thirdCivRelationshipWithOtherCiv = thirdCiv.getDiplomacyManager(otherCiv()).relationshipLevel() + when(thirdCivRelationshipWithOtherCiv){ + RelationshipLevel.Unforgivable -> addModifier(DiplomaticModifiers.DeclaredFriendshipWithOurEnemies,15f) + RelationshipLevel.Enemy -> addModifier(DiplomaticModifiers.DeclaredFriendshipWithOurEnemies,5f) + RelationshipLevel.Friend -> addModifier(DiplomaticModifiers.DeclaredFriendshipWithOurAllies,5f) + RelationshipLevel.Ally -> addModifier(DiplomaticModifiers.DeclaredFriendshipWithOurAllies,15f) + } + } } //endregion } diff --git a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt index 43e4a2865d..fbfcfd4d30 100644 --- a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt +++ b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt @@ -8,17 +8,15 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.unciv.UnCivGame import com.unciv.logic.civilization.CityStateType import com.unciv.logic.civilization.CivilizationInfo -import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers +import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers.* import com.unciv.logic.civilization.diplomacy.RelationshipLevel import com.unciv.logic.trade.TradeLogic import com.unciv.logic.trade.TradeOffer import com.unciv.logic.trade.TradeType import com.unciv.models.gamebasics.tr -import com.unciv.models.stats.Stat import com.unciv.ui.utils.* import com.unciv.ui.worldscreen.optionstable.PopupTable import com.unciv.ui.worldscreen.optionstable.YesNoPopupTable -import javax.xml.soap.Text class DiplomacyScreen:CameraStageBaseScreen() { @@ -179,15 +177,17 @@ class DiplomacyScreen:CameraStageBaseScreen() { diplomacyModifiersTable.add(relationshipText.toLabel()).row() for(modifier in otherCivDiplomacyManager.diplomaticModifiers){ - var text = when(DiplomaticModifiers.valueOf(modifier.key)){ - DiplomaticModifiers.DeclaredWarOnUs -> "You declared war on us!" - DiplomaticModifiers.WarMongerer -> "Your warmongering ways are unacceptable to us." - DiplomaticModifiers.CapturedOurCities -> "You have captured our cities!" - DiplomaticModifiers.YearsOfPeace -> "Years of peace have strengthened our relations." - DiplomaticModifiers.SharedEnemy -> "Our mutual military struggle brings us closer together." + var text = when(valueOf(modifier.key)){ + DeclaredWarOnUs -> "You declared war on us!" + WarMongerer -> "Your warmongering ways are unacceptable to us." + CapturedOurCities -> "You have captured our cities!" + YearsOfPeace -> "Years of peace have strengthened our relations." + SharedEnemy -> "Our mutual military struggle brings us closer together." + DeclarationOfFriendship -> "We have signed a public declaration of friendship" + DeclaredFriendshipWithOurEnemies -> "You have declared friendship with our enemies!" + DeclaredFriendshipWithOurAllies -> "You have declared friendship with our allies" } - text = text.tr() - text += " " + text = text.tr()+" " if(modifier.value>0) text += "+" text += modifier.value.toInt() val color = if(modifier.value<0) Color.RED else Color.GREEN diff --git a/core/src/com/unciv/ui/worldscreen/TradePopup.kt b/core/src/com/unciv/ui/worldscreen/TradePopup.kt index 48246dbf6c..8059df44e8 100644 --- a/core/src/com/unciv/ui/worldscreen/TradePopup.kt +++ b/core/src/com/unciv/ui/worldscreen/TradePopup.kt @@ -58,12 +58,12 @@ class TradePopup(worldScreen: WorldScreen): PopupTable(worldScreen){ addButton("Not this time.".tr()){ currentPlayerCiv.tradeRequests.remove(tradeRequest) - val flagsCountdown = requestingCiv.getDiplomacyManager(currentPlayerCiv).flagsCountdown + val diplomacyManager = requestingCiv.getDiplomacyManager(currentPlayerCiv) if(trade.ourOffers.all { it.type==TradeType.Luxury_Resource } && trade.theirOffers.all { it.type==TradeType.Luxury_Resource }) - flagsCountdown[DiplomacyFlags.DeclinedLuxExchange.toString()]=20 // offer again in 20 turns + diplomacyManager.setFlag(DiplomacyFlags.DeclinedLuxExchange,20) // offer again in 20 turns if(trade.ourOffers.any{ it.type==TradeType.Treaty && it.name=="Peace Treaty" }) - flagsCountdown[DiplomacyFlags.DeclinedPeace.toString()]=5 // offer again in 20 turns + diplomacyManager.setFlag(DiplomacyFlags.DeclinedPeace,5) remove() worldScreen.shouldUpdate=true