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

@ -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")
}
}
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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