Declare & Revoke protection for city-state. (#3994)

* Declare protection for city-state.

* Text templates.

* Better protector text for city-states.
This commit is contained in:
Duan Tao 2021-06-01 20:02:23 +08:00 committed by GitHub
parent 55f943f428
commit 205f479ffe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 4 deletions

View File

@ -135,6 +135,10 @@ Provides 3 happiness at 30 Influence =
Provides land units every 20 turns at 30 Influence =
Gift [giftAmount] gold (+[influenceAmount] influence) =
Relationship changes in another [turnsToRelationshipChange] turns =
Protected by =
Revoke Protection =
Pledge to protect =
Declare Protection of [cityStateName]? =
Cultured =
Maritime =

View File

@ -45,6 +45,7 @@ object NextTurnAutomation {
chooseTechToResearch(civInfo)
automateCityBombardment(civInfo)
useGold(civInfo)
protectCityStates(civInfo)
automateUnits(civInfo)
reassignWorkedTiles(civInfo)
trainSettler(civInfo)
@ -140,6 +141,20 @@ object NextTurnAutomation {
}
}
private fun protectCityStates(civInfo: CivilizationInfo) {
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.addProtectorCiv(civInfo)
} else if (diplomacyManager.relationshipLevel() < RelationshipLevel.Friend
&& diplomacyManager.diplomaticStatus == DiplomaticStatus.Protector) {
state.removeProtectorCiv(civInfo)
}
}
}
private fun getFreeTechForCityStates(civInfo: CivilizationInfo) {
// City-States automatically get all techs that at least half of the major civs know
val researchableTechs = civInfo.gameInfo.ruleSet.technologies.keys
@ -346,9 +361,14 @@ object NextTurnAutomation {
private fun motivationToAttack(civInfo: CivilizationInfo, otherCiv: CivilizationInfo): Int {
val ourCombatStrength = Automation.evaluteCombatStrength(civInfo).toFloat()
val theirCombatStrength = Automation.evaluteCombatStrength(otherCiv)
if (theirCombatStrength > ourCombatStrength) return 0
var theirCombatStrength = Automation.evaluteCombatStrength(otherCiv)
//for city-states, also consider there protectors
if(otherCiv.isCityState() and otherCiv.getProtectorCivs().isNotEmpty()) {
theirCombatStrength += otherCiv.getProtectorCivs().sumOf{Automation.evaluteCombatStrength(it)}
}
if (theirCombatStrength > ourCombatStrength) return 0
fun isTileCanMoveThrough(tileInfo: TileInfo): Boolean {
val owner = tileInfo.getOwner()
@ -410,7 +430,8 @@ object NextTurnAutomation {
if (theirCity.getTiles().none { it.neighbors.any { it.getOwner() == theirCity.civInfo && it.getCity() != theirCity } })
modifierMap["Isolated city"] = 15
if (otherCiv.isCityState()) modifierMap["City-state"] = -20
//Maybe not needed if city-state has potential protectors?
if (otherCiv.isCityState()) modifierMap["City-state"] = -10
return modifierMap.values.sum()
}

View File

@ -653,6 +653,30 @@ class CivilizationInfo {
fun getAllyCiv() = allyCivName
fun getProtectorCivs() : List<CivilizationInfo> {
if(this.isMajorCiv()) return emptyList()
return diplomacy.values
.filter{!it.otherCiv().isDefeated() && it.diplomaticStatus == DiplomaticStatus.Protector}
.map{it->it.otherCiv()}
}
fun addProtectorCiv(otherCiv: CivilizationInfo) {
if(!this.isCityState() or !otherCiv.isMajorCiv() or otherCiv.isDefeated()) return
if(!knows(otherCiv) or isAtWarWith(otherCiv)) return //Exception
val diplomacy = getDiplomacyManager(otherCiv.civName)
diplomacy.diplomaticStatus = DiplomaticStatus.Protector
}
fun removeProtectorCiv(otherCiv: CivilizationInfo) {
if(!this.isCityState() or !otherCiv.isMajorCiv() or otherCiv.isDefeated()) return
if(!knows(otherCiv) or isAtWarWith(otherCiv)) return //Exception
val diplomacy = getDiplomacyManager(otherCiv.civName)
diplomacy.diplomaticStatus = DiplomaticStatus.Peace
diplomacy.influence -= 20
}
fun updateAllyCivForCityState() {
var newAllyName = ""
if (!isCityState()) return

View File

@ -182,6 +182,7 @@ class DiplomacyManager() {
var restingPoint = 0f
for (unique in otherCiv().getMatchingUniques("Resting point for Influence with City-States is increased by []"))
restingPoint += unique.params[0].toInt()
if(diplomaticStatus == DiplomaticStatus.Protector) restingPoint += 5
return restingPoint
}
@ -546,6 +547,16 @@ class DiplomacyManager() {
}
}
}
if (otherCiv.isCityState())
{
for (thirdCiv in otherCiv.getProtectorCivs()) {
if (thirdCiv.knows(civInfo)
&& thirdCiv.getDiplomacyManager(civInfo).canDeclareWar()) {
thirdCiv.getDiplomacyManager(civInfo).declareWar()
}
}
}
}
/** Should only be called from makePeace */

View File

@ -2,5 +2,6 @@ package com.unciv.logic.civilization.diplomacy
enum class DiplomaticStatus{
Peace,
Protector, //city state's diplomacy for major civ can be marked as Protector, not vice versa.
War
}

View File

@ -11,6 +11,7 @@ import com.unciv.logic.civilization.*
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers.*
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
import com.unciv.logic.trade.TradeLogic
import com.unciv.logic.trade.TradeOffer
@ -114,6 +115,12 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
diplomacyTable.add(allyString.toLabel()).row()
}
val protectors = otherCiv.getProtectorCivs()
if (protectors.size > 0) {
val protectorString = "{Protected by}: " + protectors.map{it.civName}.joinToString(", ")
diplomacyTable.add(protectorString.toLabel()).row()
}
val nextLevelString = when {
otherCivDiplomacyManager.influence.toInt() < 30 -> "Reach 30 for friendship."
ally == viewingCiv.civName -> ""
@ -156,8 +163,32 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
diplomacyTable.add(giftButton).row()
if (viewingCiv.gold < giftAmount || isNotPlayersTurn()) giftButton.disable()
val diplomacyManager = viewingCiv.getDiplomacyManager(otherCiv)
if (otherCivDiplomacyManager.diplomaticStatus == DiplomaticStatus.Protector){
val RevokeProtectionButton = "Revoke Protection".toTextButton()
RevokeProtectionButton.onClick{
YesNoPopup("Revoke protection for [${otherCiv.civName}]?".tr(), {
otherCiv.removeProtectorCiv(viewingCiv)
updateLeftSideTable()
updateRightSide(otherCiv)
}, this).open()
}
diplomacyTable.add(RevokeProtectionButton).row()
} else {
val ProtectionButton = "Pledge to protect".toTextButton()
ProtectionButton.onClick{
YesNoPopup("Declare Protection of [${otherCiv.civName}]?".tr(), {
otherCiv.addProtectorCiv(viewingCiv)
updateLeftSideTable()
updateRightSide(otherCiv)
}, this).open()
}
if(viewingCiv.isAtWarWith(otherCiv)) {
ProtectionButton.disable()
}
diplomacyTable.add(ProtectionButton).row()
}
val diplomacyManager = viewingCiv.getDiplomacyManager(otherCiv)
if (!viewingCiv.gameInfo.ruleSet.modOptions.uniques.contains(ModOptionsConstants.diplomaticRelationshipsCannotChange)) {
if (viewingCiv.isAtWarWith(otherCiv)) {
val peaceButton = "Negotiate Peace".toTextButton()