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 =)
This commit is contained in:
Yair Morgenstern 2019-05-08 17:24:56 +03:00
parent 3106127dc4
commit 75bdced3c6
6 changed files with 91 additions and 45 deletions

View File

@ -2793,6 +2793,10 @@
French:"Nos problèmes militaires communs nous ont rapprochés" 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 screen
"Overview":{ "Overview":{

View File

@ -1,12 +1,12 @@
package com.unciv.logic.automation 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.DiplomacyFlags
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.logic.civilization.diplomacy.RelationshipLevel import com.unciv.logic.civilization.diplomacy.RelationshipLevel
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
import com.unciv.logic.trade.* 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.GameBasics
import com.unciv.models.gamebasics.tech.Technology import com.unciv.models.gamebasics.tech.Technology
import com.unciv.models.gamebasics.tr 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 // 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) 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() val relationshipLevel = civInfo.getDiplomacyManager(otherCiv).relationshipLevel()
if(relationshipLevel==RelationshipLevel.Enemy || relationshipLevel == RelationshipLevel.Unforgivable) if(relationshipLevel==RelationshipLevel.Enemy || relationshipLevel == RelationshipLevel.Unforgivable)
@ -205,7 +205,7 @@ class NextTurnAutomation{
val enemiesCiv = civInfo.diplomacy.filter{ it.value.diplomaticStatus == DiplomaticStatus.War } val enemiesCiv = civInfo.diplomacy.filter{ it.value.diplomaticStatus == DiplomaticStatus.War }
.map{ it.value.otherCiv() } .map{ it.value.otherCiv() }
.filterNot{ it == civInfo || it.isBarbarianCivilization() || it.cities.isEmpty() } .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) { for (enemy in enemiesCiv) {
val enemiesStrength = Automation().evaluteCombatStrength(enemy) val enemiesStrength = Automation().evaluteCombatStrength(enemy)
@ -245,30 +245,17 @@ class NextTurnAutomation{
private fun updateDiplomaticRelationship(civInfo: CivilizationInfo) { private fun updateDiplomaticRelationship(civInfo: CivilizationInfo) {
// Check if city-state invaded by other civs // Check if city-state invaded by other civs
if (civInfo.isCityState()) { if (civInfo.isCityState()) {
for (civ in civInfo.gameInfo.civilizations) { for (otherCiv in civInfo.getKnownCivs().filter { it.isMajorCiv() }) {
var needClearCounter = false if(civInfo.isAtWarWith(otherCiv)) continue
if (civ == civInfo || civ.isBarbarianCivilization() || !civInfo.getKnownCivs().contains(civ)) continue val diplomacy = civInfo.getDiplomacyManager(otherCiv)
val diplomacy = civInfo.getDiplomacyManager(civ)!!
if (diplomacy.diplomaticStatus == DiplomaticStatus.War) {
needClearCounter = true
}
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) { if (unitsInBorder > 0 && diplomacy.influence < 30f) {
diplomacy.influence -= 10f diplomacy.influence -= 10f
if (!diplomacy.flagsCountdown.containsKey("BorderConflict") if (!diplomacy.hasFlag(DiplomacyFlags.BorderConflict)) {
|| diplomacy.flagsCountdown["BorderConflict"]!! <= 0) { otherCiv.popupAlerts.add(PopupAlert(AlertType.BorderConflict,civInfo.civName))
civ.popupAlerts.add(PopupAlert(AlertType.BorderConflict,civInfo.civName)) diplomacy.setFlag(DiplomacyFlags.BorderConflict,10)
diplomacy.flagsCountdown["BorderConflict"] = 10
} else {
diplomacy.flagsCountdown["BorderConflict"]!!.minus(1)
} }
} else {
needClearCounter = true
}
if (needClearCounter && diplomacy.flagsCountdown.containsKey("BorderConflict")) {
diplomacy.flagsCountdown.remove("BorderConflict")
} }
} }
} }

View File

@ -127,6 +127,8 @@ class CivilizationInfo {
fun getDiplomacyManager(civInfo: CivilizationInfo) = diplomacy[civInfo.civName]!! fun getDiplomacyManager(civInfo: CivilizationInfo) = diplomacy[civInfo.civName]!!
fun getKnownCivs() = diplomacy.values.map { it.otherCiv() } 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 getCapital()=cities.first { it.isCapital() }
fun isPlayerCivilization() = playerType==PlayerType.Human fun isPlayerCivilization() = playerType==PlayerType.Human

View File

@ -23,15 +23,21 @@ enum class RelationshipLevel{
enum class DiplomacyFlags{ enum class DiplomacyFlags{
DeclinedLuxExchange, DeclinedLuxExchange,
DeclinedPeace DeclinedPeace,
DeclarationOfFriendship,
BorderConflict
} }
enum class DiplomaticModifiers{ enum class DiplomaticModifiers{
DeclaredWarOnUs, DeclaredWarOnUs,
WarMongerer, WarMongerer,
CapturedOurCities, CapturedOurCities,
DeclaredFriendshipWithOurEnemies,
YearsOfPeace, YearsOfPeace,
SharedEnemy SharedEnemy,
DeclarationOfFriendship,
DeclaredFriendshipWithOurAllies
} }
class DiplomacyManager() { class DiplomacyManager() {
@ -75,6 +81,7 @@ class DiplomacyManager() {
//region pure functions //region pure functions
fun otherCiv() = civInfo.gameInfo.getCivilization(otherCivName) fun otherCiv() = civInfo.gameInfo.getCivilization(otherCivName)
fun otherCivDiplomacy() = otherCiv().getDiplomacyManager(civInfo)
fun turnsToPeaceTreaty(): Int { fun turnsToPeaceTreaty(): Int {
for(trade in trades) for(trade in trades)
@ -190,7 +197,14 @@ class DiplomacyManager() {
updateHasOpenBorders() updateHasOpenBorders()
if(diplomaticStatus==DiplomaticStatus.Peace) 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()) { for(flag in flagsCountdown.keys.toList()) {
flagsCountdown[flag] = flagsCountdown[flag]!! - 1 flagsCountdown[flag] = flagsCountdown[flag]!! - 1
@ -231,10 +245,13 @@ class DiplomacyManager() {
otherCiv.popupAlerts.add(PopupAlert(AlertType.WarDeclaration,civInfo.civName)) otherCiv.popupAlerts.add(PopupAlert(AlertType.WarDeclaration,civInfo.civName))
/// AI won't propose peace for 10 turns /// AI won't propose peace for 10 turns
flagsCountdown[DiplomacyFlags.DeclinedPeace.toString()]=10 setFlag(DiplomacyFlags.DeclinedPeace,10)
otherCiv.getDiplomacyManager(civInfo).flagsCountdown[DiplomacyFlags.DeclinedPeace.toString()]=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()){ for(thirdCiv in civInfo.getKnownCivs()){
if(thirdCiv.isAtWarWith(otherCiv)) if(thirdCiv.isAtWarWith(otherCiv))
thirdCiv.getDiplomacyManager(civInfo).addModifier(DiplomaticModifiers.WarMongerer,5f) thirdCiv.getDiplomacyManager(civInfo).addModifier(DiplomaticModifiers.WarMongerer,5f)
@ -254,10 +271,46 @@ class DiplomacyManager() {
unit.movementAlgs().teleportToClosestMoveableTile() 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){ fun addModifier(modifier: DiplomaticModifiers, amount:Float){
val modifierString = modifier.toString() val modifierString = modifier.toString()
if(!diplomaticModifiers.containsKey(modifierString)) diplomaticModifiers[modifierString]=0f if(!hasModifier(modifier)) setModifier(modifier,0f)
diplomaticModifiers[modifierString] = diplomaticModifiers[modifierString]!!+amount 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 //endregion
} }

View File

@ -8,17 +8,15 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.civilization.CityStateType import com.unciv.logic.civilization.CityStateType
import com.unciv.logic.civilization.CivilizationInfo 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.civilization.diplomacy.RelationshipLevel
import com.unciv.logic.trade.TradeLogic import com.unciv.logic.trade.TradeLogic
import com.unciv.logic.trade.TradeOffer import com.unciv.logic.trade.TradeOffer
import com.unciv.logic.trade.TradeType import com.unciv.logic.trade.TradeType
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.models.stats.Stat
import com.unciv.ui.utils.* import com.unciv.ui.utils.*
import com.unciv.ui.worldscreen.optionstable.PopupTable import com.unciv.ui.worldscreen.optionstable.PopupTable
import com.unciv.ui.worldscreen.optionstable.YesNoPopupTable import com.unciv.ui.worldscreen.optionstable.YesNoPopupTable
import javax.xml.soap.Text
class DiplomacyScreen:CameraStageBaseScreen() { class DiplomacyScreen:CameraStageBaseScreen() {
@ -179,15 +177,17 @@ class DiplomacyScreen:CameraStageBaseScreen() {
diplomacyModifiersTable.add(relationshipText.toLabel()).row() diplomacyModifiersTable.add(relationshipText.toLabel()).row()
for(modifier in otherCivDiplomacyManager.diplomaticModifiers){ for(modifier in otherCivDiplomacyManager.diplomaticModifiers){
var text = when(DiplomaticModifiers.valueOf(modifier.key)){ var text = when(valueOf(modifier.key)){
DiplomaticModifiers.DeclaredWarOnUs -> "You declared war on us!" DeclaredWarOnUs -> "You declared war on us!"
DiplomaticModifiers.WarMongerer -> "Your warmongering ways are unacceptable to us." WarMongerer -> "Your warmongering ways are unacceptable to us."
DiplomaticModifiers.CapturedOurCities -> "You have captured our cities!" CapturedOurCities -> "You have captured our cities!"
DiplomaticModifiers.YearsOfPeace -> "Years of peace have strengthened our relations." YearsOfPeace -> "Years of peace have strengthened our relations."
DiplomaticModifiers.SharedEnemy -> "Our mutual military struggle brings us closer together." 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.tr()+" "
text += " "
if(modifier.value>0) text += "+" if(modifier.value>0) text += "+"
text += modifier.value.toInt() text += modifier.value.toInt()
val color = if(modifier.value<0) Color.RED else Color.GREEN val color = if(modifier.value<0) Color.RED else Color.GREEN

View File

@ -58,12 +58,12 @@ class TradePopup(worldScreen: WorldScreen): PopupTable(worldScreen){
addButton("Not this time.".tr()){ addButton("Not this time.".tr()){
currentPlayerCiv.tradeRequests.remove(tradeRequest) 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 }) 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" }) 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() remove()
worldScreen.shouldUpdate=true worldScreen.shouldUpdate=true