mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-12 08:49:22 +07:00
chore: Split 'city state civ diplomacy table' from DiplomacyScreen
This commit is contained in:
@ -0,0 +1,496 @@
|
|||||||
|
package com.unciv.ui.screens.diplomacyscreen
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||||
|
import com.badlogic.gdx.utils.Align
|
||||||
|
import com.unciv.Constants
|
||||||
|
import com.unciv.UncivGame
|
||||||
|
import com.unciv.logic.civilization.AlertType
|
||||||
|
import com.unciv.logic.civilization.Civilization
|
||||||
|
import com.unciv.logic.civilization.PopupAlert
|
||||||
|
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
|
||||||
|
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
|
||||||
|
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||||
|
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
||||||
|
import com.unciv.logic.civilization.managers.AssignedQuest
|
||||||
|
import com.unciv.logic.trade.TradeLogic
|
||||||
|
import com.unciv.logic.trade.TradeOffer
|
||||||
|
import com.unciv.logic.trade.TradeType
|
||||||
|
import com.unciv.models.ruleset.ModOptionsConstants
|
||||||
|
import com.unciv.models.ruleset.Quest
|
||||||
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
|
import com.unciv.models.translations.tr
|
||||||
|
import com.unciv.ui.components.Fonts
|
||||||
|
import com.unciv.ui.components.UncivTooltip.Companion.addTooltip
|
||||||
|
import com.unciv.ui.components.extensions.addSeparator
|
||||||
|
import com.unciv.ui.components.extensions.disable
|
||||||
|
import com.unciv.ui.components.extensions.toLabel
|
||||||
|
import com.unciv.ui.components.extensions.toTextButton
|
||||||
|
import com.unciv.ui.components.input.onClick
|
||||||
|
import com.unciv.ui.components.widgets.ColorMarkupLabel
|
||||||
|
import com.unciv.ui.images.ImageGetter
|
||||||
|
import com.unciv.ui.popups.ConfirmPopup
|
||||||
|
import com.unciv.ui.screens.civilopediascreen.CivilopediaScreen
|
||||||
|
|
||||||
|
class CityStateDiplomacyTable(private val diplomacyScreen: DiplomacyScreen) {
|
||||||
|
val viewingCiv = diplomacyScreen.viewingCiv
|
||||||
|
|
||||||
|
fun getCityStateDiplomacyTable(otherCiv: Civilization): Table {
|
||||||
|
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
||||||
|
|
||||||
|
val diplomacyTable = getCityStateDiplomacyTableHeader(otherCiv)
|
||||||
|
|
||||||
|
diplomacyTable.addSeparator()
|
||||||
|
|
||||||
|
val giveGiftButton = "Give a Gift".toTextButton()
|
||||||
|
giveGiftButton.onClick {
|
||||||
|
diplomacyScreen.rightSideTable.clear()
|
||||||
|
diplomacyScreen.rightSideTable.add(ScrollPane(getGoldGiftTable(otherCiv)))
|
||||||
|
}
|
||||||
|
diplomacyTable.add(giveGiftButton).row()
|
||||||
|
if (diplomacyScreen.isNotPlayersTurn() || viewingCiv.isAtWarWith(otherCiv)) giveGiftButton.disable()
|
||||||
|
|
||||||
|
val improveTileButton = getImproveTilesButton(otherCiv, otherCivDiplomacyManager)
|
||||||
|
if (improveTileButton != null) diplomacyTable.add(improveTileButton).row()
|
||||||
|
|
||||||
|
if (otherCivDiplomacyManager.diplomaticStatus != DiplomaticStatus.Protector)
|
||||||
|
diplomacyTable.add(getPledgeToProtectButton(otherCiv)).row()
|
||||||
|
else
|
||||||
|
diplomacyTable.add(getRevokeProtectionButton(otherCiv)).row()
|
||||||
|
|
||||||
|
val demandTributeButton = "Demand Tribute".toTextButton()
|
||||||
|
demandTributeButton.onClick {
|
||||||
|
diplomacyScreen.rightSideTable.clear()
|
||||||
|
diplomacyScreen.rightSideTable.add(ScrollPane(getDemandTributeTable(otherCiv)))
|
||||||
|
}
|
||||||
|
diplomacyTable.add(demandTributeButton).row()
|
||||||
|
if (diplomacyScreen.isNotPlayersTurn() || viewingCiv.isAtWarWith(otherCiv)) demandTributeButton.disable()
|
||||||
|
|
||||||
|
val diplomacyManager = viewingCiv.getDiplomacyManager(otherCiv)
|
||||||
|
if (!viewingCiv.gameInfo.ruleset.modOptions.uniques.contains(ModOptionsConstants.diplomaticRelationshipsCannotChange)) {
|
||||||
|
if (viewingCiv.isAtWarWith(otherCiv))
|
||||||
|
diplomacyTable.add(getNegotiatePeaceCityStateButton(otherCiv, diplomacyManager)).row()
|
||||||
|
else diplomacyTable.add(diplomacyScreen.getDeclareWarButton(diplomacyManager, otherCiv)).row()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (otherCiv.cities.isNotEmpty() && otherCiv.getCapital() != null && viewingCiv.hasExplored(otherCiv.getCapital()!!.getCenterTile()))
|
||||||
|
diplomacyTable.add(diplomacyScreen.getGoToOnMapButton(otherCiv)).row()
|
||||||
|
|
||||||
|
val diplomaticMarriageButton = getDiplomaticMarriageButton(otherCiv)
|
||||||
|
if (diplomaticMarriageButton != null) diplomacyTable.add(diplomaticMarriageButton).row()
|
||||||
|
|
||||||
|
for (assignedQuest in otherCiv.questManager.assignedQuests.filter { it.assignee == viewingCiv.civName }) {
|
||||||
|
diplomacyTable.addSeparator()
|
||||||
|
diplomacyTable.add(getQuestTable(assignedQuest)).row()
|
||||||
|
}
|
||||||
|
|
||||||
|
for (target in otherCiv.getKnownCivs().filter { otherCiv.questManager.warWithMajorActive(it) && viewingCiv != it }) {
|
||||||
|
diplomacyTable.addSeparator()
|
||||||
|
diplomacyTable.add(getWarWithMajorTable(target, otherCiv)).row()
|
||||||
|
}
|
||||||
|
|
||||||
|
return diplomacyTable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun getCityStateDiplomacyTableHeader(otherCiv: Civilization): Table {
|
||||||
|
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
||||||
|
|
||||||
|
val diplomacyTable = Table()
|
||||||
|
diplomacyTable.defaults().pad(2.5f)
|
||||||
|
|
||||||
|
diplomacyTable.add(LeaderIntroTable(otherCiv)).padBottom(15f).row()
|
||||||
|
|
||||||
|
diplomacyTable.add("{Type}: {${otherCiv.cityStateType.name}}".toLabel()).row()
|
||||||
|
diplomacyTable.add("{Personality}: {${otherCiv.cityStatePersonality}}".toLabel()).row()
|
||||||
|
|
||||||
|
if (otherCiv.detailedCivResources.any { it.resource.resourceType != ResourceType.Bonus }) {
|
||||||
|
val resourcesTable = Table()
|
||||||
|
resourcesTable.add("{Resources}: ".toLabel()).padRight(10f)
|
||||||
|
val cityStateResources = otherCiv.cityStateFunctions.getCityStateResourcesForAlly()
|
||||||
|
for (supplyList in cityStateResources) {
|
||||||
|
if (supplyList.resource.resourceType == ResourceType.Bonus)
|
||||||
|
continue
|
||||||
|
val name = supplyList.resource.name
|
||||||
|
val wrapper = Table()
|
||||||
|
val image = ImageGetter.getResourcePortrait(name, 30f)
|
||||||
|
wrapper.add(image).padRight(5f)
|
||||||
|
wrapper.add(supplyList.amount.toLabel())
|
||||||
|
resourcesTable.add(wrapper).padRight(20f)
|
||||||
|
wrapper.addTooltip(name, 18f)
|
||||||
|
wrapper.onClick {
|
||||||
|
UncivGame.Current.pushScreen(CivilopediaScreen(UncivGame.Current.gameInfo!!.ruleset, link = "Resource/$name"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diplomacyTable.add(resourcesTable).row()
|
||||||
|
}
|
||||||
|
diplomacyTable.row().padTop(15f)
|
||||||
|
|
||||||
|
otherCiv.cityStateFunctions.updateAllyCivForCityState()
|
||||||
|
var ally = otherCiv.getAllyCiv()
|
||||||
|
if (ally != null) {
|
||||||
|
val allyInfluence = otherCiv.getDiplomacyManager(ally).getInfluence().toInt()
|
||||||
|
if (!viewingCiv.knows(ally) && ally != viewingCiv.civName)
|
||||||
|
ally = "Unknown civilization"
|
||||||
|
diplomacyTable
|
||||||
|
.add("Ally: [$ally] with [$allyInfluence] Influence".toLabel())
|
||||||
|
.row()
|
||||||
|
}
|
||||||
|
|
||||||
|
val protectors = otherCiv.cityStateFunctions.getProtectorCivs()
|
||||||
|
if (protectors.isNotEmpty()) {
|
||||||
|
val newProtectors = arrayListOf<String>()
|
||||||
|
for (protector in protectors) {
|
||||||
|
if (!viewingCiv.knows(protector) && protector.civName != viewingCiv.civName)
|
||||||
|
newProtectors.add("Unknown civilization".tr())
|
||||||
|
else
|
||||||
|
newProtectors.add(protector.civName.tr())
|
||||||
|
}
|
||||||
|
val protectorString = "{Protected by}: " + newProtectors.joinToString(", ")
|
||||||
|
diplomacyTable.add(protectorString.toLabel()).row()
|
||||||
|
}
|
||||||
|
|
||||||
|
val atWar = otherCiv.isAtWarWith(viewingCiv)
|
||||||
|
|
||||||
|
val nextLevelString = when {
|
||||||
|
atWar -> ""
|
||||||
|
otherCivDiplomacyManager.getInfluence().toInt() < 30 -> "Reach 30 for friendship."
|
||||||
|
ally == viewingCiv.civName -> ""
|
||||||
|
else -> "Reach highest influence above 60 for alliance."
|
||||||
|
}
|
||||||
|
diplomacyTable.add(diplomacyScreen.getRelationshipTable(otherCivDiplomacyManager)).row()
|
||||||
|
if (nextLevelString.isNotEmpty()) {
|
||||||
|
diplomacyTable.add(nextLevelString.toLabel()).row()
|
||||||
|
}
|
||||||
|
diplomacyTable.row().padTop(15f)
|
||||||
|
|
||||||
|
var friendBonusText = "When Friends:".tr()+"\n"
|
||||||
|
val friendBonusObjects = viewingCiv.cityStateFunctions.getCityStateBonuses(otherCiv.cityStateType, RelationshipLevel.Friend)
|
||||||
|
friendBonusText += friendBonusObjects.joinToString(separator = "\n") { it.text.tr() }
|
||||||
|
|
||||||
|
var allyBonusText = "When Allies:".tr()+"\n"
|
||||||
|
val allyBonusObjects = viewingCiv.cityStateFunctions.getCityStateBonuses(otherCiv.cityStateType, RelationshipLevel.Ally)
|
||||||
|
allyBonusText += allyBonusObjects.joinToString(separator = "\n") { it.text.tr() }
|
||||||
|
|
||||||
|
val relationLevel = otherCivDiplomacyManager.relationshipIgnoreAfraid()
|
||||||
|
if (relationLevel >= RelationshipLevel.Friend) {
|
||||||
|
// RelationshipChange = Ally -> Friend or Friend -> Favorable
|
||||||
|
val turnsToRelationshipChange = otherCivDiplomacyManager.getTurnsToRelationshipChange()
|
||||||
|
if (turnsToRelationshipChange != 0)
|
||||||
|
diplomacyTable.add("Relationship changes in another [$turnsToRelationshipChange] turns".toLabel())
|
||||||
|
.row()
|
||||||
|
}
|
||||||
|
|
||||||
|
val friendBonusLabelColor = if (relationLevel == RelationshipLevel.Friend) Color.GREEN else Color.GRAY
|
||||||
|
val friendBonusLabel = ColorMarkupLabel(friendBonusText, friendBonusLabelColor)
|
||||||
|
.apply { setAlignment(Align.center) }
|
||||||
|
diplomacyTable.add(friendBonusLabel).row()
|
||||||
|
|
||||||
|
val allyBonusLabelColor = if (relationLevel == RelationshipLevel.Ally) Color.GREEN else Color.GRAY
|
||||||
|
val allyBonusLabel = ColorMarkupLabel(allyBonusText, allyBonusLabelColor)
|
||||||
|
.apply { setAlignment(Align.center) }
|
||||||
|
diplomacyTable.add(allyBonusLabel).row()
|
||||||
|
|
||||||
|
if (otherCiv.cityStateUniqueUnit != null) {
|
||||||
|
val unitName = otherCiv.cityStateUniqueUnit
|
||||||
|
val techName = viewingCiv.gameInfo.ruleset.units[otherCiv.cityStateUniqueUnit]!!.requiredTech
|
||||||
|
diplomacyTable.add("[${otherCiv.civName}] is able to provide [${unitName}] once [${techName}] is researched.".toLabel(fontSize = Constants.defaultFontSize)).row()
|
||||||
|
}
|
||||||
|
|
||||||
|
return diplomacyTable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun getRevokeProtectionButton(otherCiv: Civilization): TextButton {
|
||||||
|
val revokeProtectionButton = "Revoke Protection".toTextButton()
|
||||||
|
revokeProtectionButton.onClick {
|
||||||
|
ConfirmPopup(diplomacyScreen, "Revoke protection for [${otherCiv.civName}]?", "Revoke Protection") {
|
||||||
|
otherCiv.cityStateFunctions.removeProtectorCiv(viewingCiv)
|
||||||
|
diplomacyScreen.updateLeftSideTable(otherCiv)
|
||||||
|
diplomacyScreen.updateRightSide(otherCiv)
|
||||||
|
}.open()
|
||||||
|
}
|
||||||
|
if (diplomacyScreen.isNotPlayersTurn() || !otherCiv.cityStateFunctions.otherCivCanWithdrawProtection(viewingCiv))
|
||||||
|
revokeProtectionButton.disable()
|
||||||
|
return revokeProtectionButton
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getPledgeToProtectButton(otherCiv: Civilization): TextButton {
|
||||||
|
val protectionButton = "Pledge to protect".toTextButton()
|
||||||
|
protectionButton.onClick {
|
||||||
|
ConfirmPopup(
|
||||||
|
diplomacyScreen,
|
||||||
|
"Declare Protection of [${otherCiv.civName}]?",
|
||||||
|
"Pledge to protect",
|
||||||
|
true
|
||||||
|
) {
|
||||||
|
otherCiv.cityStateFunctions.addProtectorCiv(viewingCiv)
|
||||||
|
diplomacyScreen.updateLeftSideTable(otherCiv)
|
||||||
|
diplomacyScreen.updateRightSide(otherCiv)
|
||||||
|
}.open()
|
||||||
|
}
|
||||||
|
if (diplomacyScreen.isNotPlayersTurn() || !otherCiv.cityStateFunctions.otherCivCanPledgeProtection(viewingCiv))
|
||||||
|
protectionButton.disable()
|
||||||
|
return protectionButton
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getNegotiatePeaceCityStateButton(
|
||||||
|
otherCiv: Civilization,
|
||||||
|
otherCivDiplomacyManager: DiplomacyManager
|
||||||
|
): TextButton {
|
||||||
|
val peaceButton = "Negotiate Peace".toTextButton()
|
||||||
|
peaceButton.onClick {
|
||||||
|
ConfirmPopup(
|
||||||
|
diplomacyScreen,
|
||||||
|
"Peace with [${otherCiv.civName}]?",
|
||||||
|
"Negotiate Peace",
|
||||||
|
true
|
||||||
|
) {
|
||||||
|
val tradeLogic = TradeLogic(viewingCiv, otherCiv)
|
||||||
|
tradeLogic.currentTrade.ourOffers.add(
|
||||||
|
TradeOffer(
|
||||||
|
Constants.peaceTreaty,
|
||||||
|
TradeType.Treaty
|
||||||
|
)
|
||||||
|
)
|
||||||
|
tradeLogic.currentTrade.theirOffers.add(
|
||||||
|
TradeOffer(
|
||||||
|
Constants.peaceTreaty,
|
||||||
|
TradeType.Treaty
|
||||||
|
)
|
||||||
|
)
|
||||||
|
tradeLogic.acceptTrade()
|
||||||
|
diplomacyScreen.updateLeftSideTable(otherCiv)
|
||||||
|
diplomacyScreen.updateRightSide(otherCiv)
|
||||||
|
}.open()
|
||||||
|
}
|
||||||
|
val cityStatesAlly = otherCiv.getAllyCiv()
|
||||||
|
val atWarWithItsAlly = viewingCiv.getKnownCivs()
|
||||||
|
.any { it.civName == cityStatesAlly && it.isAtWarWith(viewingCiv) }
|
||||||
|
if (diplomacyScreen.isNotPlayersTurn() || atWarWithItsAlly) peaceButton.disable()
|
||||||
|
|
||||||
|
if (otherCivDiplomacyManager.hasFlag(DiplomacyFlags.DeclaredWar)) {
|
||||||
|
peaceButton.disable() // Can't trade for 10 turns after war was declared
|
||||||
|
val turnsLeft = otherCivDiplomacyManager.getFlag(DiplomacyFlags.DeclaredWar)
|
||||||
|
peaceButton.setText(peaceButton.text.toString() + "\n$turnsLeft" + Fonts.turn)
|
||||||
|
}
|
||||||
|
|
||||||
|
return peaceButton
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getImproveTilesButton(
|
||||||
|
otherCiv: Civilization,
|
||||||
|
otherCivDiplomacyManager: DiplomacyManager
|
||||||
|
): TextButton? {
|
||||||
|
if (otherCiv.cities.isEmpty()) return null
|
||||||
|
val improvableResourceTiles = getImprovableResourceTiles(otherCiv)
|
||||||
|
val improvements =
|
||||||
|
otherCiv.gameInfo.ruleset.tileImprovements.filter { it.value.turnsToBuild != -1 }
|
||||||
|
var needsImprovements = false
|
||||||
|
|
||||||
|
for (improvableTile in improvableResourceTiles)
|
||||||
|
for (tileImprovement in improvements.values)
|
||||||
|
if (improvableTile.tileResource.isImprovedBy(tileImprovement.name)
|
||||||
|
&& improvableTile.improvementFunctions.canBuildImprovement(tileImprovement, otherCiv)
|
||||||
|
)
|
||||||
|
needsImprovements = true
|
||||||
|
|
||||||
|
if (!needsImprovements) return null
|
||||||
|
|
||||||
|
|
||||||
|
val improveTileButton = "Gift Improvement".toTextButton()
|
||||||
|
improveTileButton.onClick {
|
||||||
|
diplomacyScreen.rightSideTable.clear()
|
||||||
|
diplomacyScreen.rightSideTable.add(ScrollPane(getImprovementGiftTable(otherCiv)))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (diplomacyScreen.isNotPlayersTurn() || otherCivDiplomacyManager.getInfluence() < 60)
|
||||||
|
improveTileButton.disable()
|
||||||
|
return improveTileButton
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDiplomaticMarriageButton(otherCiv: Civilization): TextButton? {
|
||||||
|
if (!viewingCiv.hasUnique(UniqueType.CityStateCanBeBoughtForGold))
|
||||||
|
return null
|
||||||
|
|
||||||
|
val diplomaticMarriageButton =
|
||||||
|
"Diplomatic Marriage ([${otherCiv.cityStateFunctions.getDiplomaticMarriageCost()}] Gold)".toTextButton()
|
||||||
|
diplomaticMarriageButton.onClick {
|
||||||
|
val newCities = otherCiv.cities
|
||||||
|
otherCiv.cityStateFunctions.diplomaticMarriage(viewingCiv)
|
||||||
|
UncivGame.Current.popScreen() // The other civ will no longer exist
|
||||||
|
for (city in newCities)
|
||||||
|
viewingCiv.popupAlerts.add(PopupAlert(AlertType.DiplomaticMarriage, city.id)) // Player gets to choose between annex and puppet
|
||||||
|
}
|
||||||
|
if (diplomacyScreen.isNotPlayersTurn() || !otherCiv.cityStateFunctions.canBeMarriedBy(viewingCiv))
|
||||||
|
diplomaticMarriageButton.disable()
|
||||||
|
return diplomaticMarriageButton
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getGoldGiftTable(otherCiv: Civilization): Table {
|
||||||
|
val diplomacyTable = getCityStateDiplomacyTableHeader(otherCiv)
|
||||||
|
diplomacyTable.addSeparator()
|
||||||
|
|
||||||
|
for (giftAmount in listOf(250, 500, 1000)) {
|
||||||
|
val influenceAmount = otherCiv.cityStateFunctions.influenceGainedByGift(viewingCiv, giftAmount)
|
||||||
|
val giftButton =
|
||||||
|
"Gift [$giftAmount] gold (+[$influenceAmount] influence)".toTextButton()
|
||||||
|
giftButton.onClick {
|
||||||
|
otherCiv.cityStateFunctions.receiveGoldGift(viewingCiv, giftAmount)
|
||||||
|
diplomacyScreen.updateLeftSideTable(otherCiv)
|
||||||
|
diplomacyScreen.updateRightSide(otherCiv)
|
||||||
|
}
|
||||||
|
diplomacyTable.add(giftButton).row()
|
||||||
|
if (viewingCiv.gold < giftAmount || diplomacyScreen.isNotPlayersTurn()) giftButton.disable()
|
||||||
|
}
|
||||||
|
|
||||||
|
val backButton = "Back".toTextButton()
|
||||||
|
backButton.onClick {
|
||||||
|
diplomacyScreen.rightSideTable.clear()
|
||||||
|
diplomacyScreen.rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
||||||
|
}
|
||||||
|
diplomacyTable.add(backButton)
|
||||||
|
return diplomacyTable
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getImprovableResourceTiles(otherCiv:Civilization) = otherCiv.getCapital()!!.getTiles().filter {
|
||||||
|
it.hasViewableResource(otherCiv)
|
||||||
|
&& it.tileResource.resourceType != ResourceType.Bonus
|
||||||
|
&& (it.improvement == null || !it.tileResource.isImprovedBy(it.improvement!!))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getImprovementGiftTable(otherCiv: Civilization): Table {
|
||||||
|
val improvementGiftTable = getCityStateDiplomacyTableHeader(otherCiv)
|
||||||
|
improvementGiftTable.addSeparator()
|
||||||
|
|
||||||
|
val improvableResourceTiles = getImprovableResourceTiles(otherCiv)
|
||||||
|
val tileImprovements =
|
||||||
|
otherCiv.gameInfo.ruleset.tileImprovements
|
||||||
|
|
||||||
|
for (improvableTile in improvableResourceTiles) {
|
||||||
|
for (tileImprovement in tileImprovements.values) {
|
||||||
|
if (improvableTile.tileResource.isImprovedBy(tileImprovement.name)
|
||||||
|
&& improvableTile.improvementFunctions.canBuildImprovement(tileImprovement, otherCiv)
|
||||||
|
) {
|
||||||
|
val improveTileButton =
|
||||||
|
"Build [${tileImprovement}] on [${improvableTile.tileResource}] (200 Gold)".toTextButton()
|
||||||
|
improveTileButton.onClick {
|
||||||
|
viewingCiv.addGold(-200)
|
||||||
|
improvableTile.stopWorkingOnImprovement()
|
||||||
|
improvableTile.changeImprovement(tileImprovement.name)
|
||||||
|
otherCiv.cache.updateCivResources()
|
||||||
|
diplomacyScreen.rightSideTable.clear()
|
||||||
|
diplomacyScreen.rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
||||||
|
}
|
||||||
|
if (viewingCiv.gold < 200)
|
||||||
|
improveTileButton.disable()
|
||||||
|
improvementGiftTable.add(improveTileButton).row()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val backButton = "Back".toTextButton()
|
||||||
|
backButton.onClick {
|
||||||
|
diplomacyScreen.rightSideTable.clear()
|
||||||
|
diplomacyScreen.rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
||||||
|
}
|
||||||
|
improvementGiftTable.add(backButton)
|
||||||
|
return improvementGiftTable
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDemandTributeTable(otherCiv: Civilization): Table {
|
||||||
|
val diplomacyTable = getCityStateDiplomacyTableHeader(otherCiv)
|
||||||
|
diplomacyTable.addSeparator()
|
||||||
|
diplomacyTable.add("Tribute Willingness".toLabel()).row()
|
||||||
|
val modifierTable = Table()
|
||||||
|
val tributeModifiers = otherCiv.cityStateFunctions.getTributeModifiers(viewingCiv, requireWholeList = true)
|
||||||
|
for (item in tributeModifiers) {
|
||||||
|
val color = if (item.value >= 0) Color.GREEN else Color.RED
|
||||||
|
modifierTable.add(item.key.toLabel(color))
|
||||||
|
modifierTable.add(item.value.toString().toLabel(color)).row()
|
||||||
|
}
|
||||||
|
modifierTable.add("Sum:".toLabel())
|
||||||
|
modifierTable.add(tributeModifiers.values.sum().toLabel()).row()
|
||||||
|
diplomacyTable.add(modifierTable).row()
|
||||||
|
diplomacyTable.add("At least 0 to take gold, at least 30 and size 4 city for worker".toLabel()).row()
|
||||||
|
diplomacyTable.addSeparator()
|
||||||
|
|
||||||
|
val demandGoldButton = "Take [${otherCiv.cityStateFunctions.goldGainedByTribute()}] gold (-15 Influence)".toTextButton()
|
||||||
|
demandGoldButton.onClick {
|
||||||
|
otherCiv.cityStateFunctions.tributeGold(viewingCiv)
|
||||||
|
diplomacyScreen.rightSideTable.clear()
|
||||||
|
diplomacyScreen.rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
||||||
|
}
|
||||||
|
diplomacyTable.add(demandGoldButton).row()
|
||||||
|
if (otherCiv.cityStateFunctions.getTributeWillingness(viewingCiv, demandingWorker = false) < 0) demandGoldButton.disable()
|
||||||
|
|
||||||
|
val demandWorkerButton = "Take worker (-50 Influence)".toTextButton()
|
||||||
|
demandWorkerButton.onClick {
|
||||||
|
otherCiv.cityStateFunctions.tributeWorker(viewingCiv)
|
||||||
|
diplomacyScreen.rightSideTable.clear()
|
||||||
|
diplomacyScreen.rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
||||||
|
}
|
||||||
|
diplomacyTable.add(demandWorkerButton).row()
|
||||||
|
if (otherCiv.cityStateFunctions.getTributeWillingness(viewingCiv, demandingWorker = true) < 0) demandWorkerButton.disable()
|
||||||
|
|
||||||
|
val backButton = "Back".toTextButton()
|
||||||
|
backButton.onClick {
|
||||||
|
diplomacyScreen.rightSideTable.clear()
|
||||||
|
diplomacyScreen.rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
||||||
|
}
|
||||||
|
diplomacyTable.add(backButton)
|
||||||
|
return diplomacyTable
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getQuestTable(assignedQuest: AssignedQuest): Table {
|
||||||
|
val questTable = Table()
|
||||||
|
questTable.defaults().pad(10f)
|
||||||
|
|
||||||
|
val quest: Quest = viewingCiv.gameInfo.ruleset.quests[assignedQuest.questName]!!
|
||||||
|
val remainingTurns: Int = assignedQuest.getRemainingTurns()
|
||||||
|
val title = if (quest.influence > 0)
|
||||||
|
"[${quest.name}] (+[${quest.influence.toInt()}] influence)"
|
||||||
|
else
|
||||||
|
quest.name
|
||||||
|
val description = assignedQuest.getDescription()
|
||||||
|
|
||||||
|
questTable.add(title.toLabel(fontSize = Constants.headingFontSize)).row()
|
||||||
|
questTable.add(description.toLabel().apply { wrap = true; setAlignment(Align.center) })
|
||||||
|
.width(diplomacyScreen.stage.width / 2).row()
|
||||||
|
if (quest.duration > 0)
|
||||||
|
questTable.add("[${remainingTurns}] turns remaining".toLabel()).row()
|
||||||
|
if (quest.isGlobal()) {
|
||||||
|
val leaderString = viewingCiv.gameInfo.getCivilization(assignedQuest.assigner).questManager.getLeaderStringForQuest(assignedQuest.questName)
|
||||||
|
if (leaderString != "")
|
||||||
|
questTable.add(leaderString.toLabel()).row()
|
||||||
|
}
|
||||||
|
|
||||||
|
questTable.onClick {
|
||||||
|
assignedQuest.onClickAction()
|
||||||
|
}
|
||||||
|
return questTable
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getWarWithMajorTable(target: Civilization, otherCiv: Civilization): Table {
|
||||||
|
val warTable = Table()
|
||||||
|
warTable.defaults().pad(10f)
|
||||||
|
|
||||||
|
val title = "War against [${target.civName}]"
|
||||||
|
val description = "We need you to help us defend against [${target.civName}]. Killing [${otherCiv.questManager.unitsToKill(target)}] of their military units would slow their offensive."
|
||||||
|
val progress = if (viewingCiv.knows(target)) "Currently you have killed [${otherCiv.questManager.unitsKilledSoFar(target, viewingCiv)}] of their military units."
|
||||||
|
else "You need to find them first!"
|
||||||
|
|
||||||
|
warTable.add(title.toLabel(fontSize = Constants.headingFontSize)).row()
|
||||||
|
warTable.add(description.toLabel().apply { wrap = true; setAlignment(Align.center) })
|
||||||
|
.width(diplomacyScreen.stage.width / 2).row()
|
||||||
|
warTable.add(progress.toLabel().apply { wrap = true; setAlignment(Align.center) })
|
||||||
|
.width(diplomacyScreen.stage.width / 2).row()
|
||||||
|
|
||||||
|
return warTable
|
||||||
|
}
|
||||||
|
}
|
@ -8,27 +8,15 @@ import com.badlogic.gdx.utils.Align
|
|||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.GUI
|
import com.unciv.GUI
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.civilization.AlertType
|
|
||||||
import com.unciv.logic.civilization.Civilization
|
import com.unciv.logic.civilization.Civilization
|
||||||
import com.unciv.logic.civilization.PopupAlert
|
|
||||||
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
|
|
||||||
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
|
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
|
||||||
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.civilization.managers.AssignedQuest
|
|
||||||
import com.unciv.logic.trade.Trade
|
import com.unciv.logic.trade.Trade
|
||||||
import com.unciv.logic.trade.TradeLogic
|
|
||||||
import com.unciv.logic.trade.TradeOffer
|
|
||||||
import com.unciv.logic.trade.TradeType
|
|
||||||
import com.unciv.models.ruleset.ModOptionsConstants
|
|
||||||
import com.unciv.models.ruleset.Quest
|
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.audio.MusicMood
|
import com.unciv.ui.audio.MusicMood
|
||||||
import com.unciv.ui.audio.MusicTrackChooserFlags
|
import com.unciv.ui.audio.MusicTrackChooserFlags
|
||||||
import com.unciv.ui.components.Fonts
|
import com.unciv.ui.components.Fonts
|
||||||
import com.unciv.ui.components.UncivTooltip.Companion.addTooltip
|
|
||||||
import com.unciv.ui.components.extensions.addSeparator
|
import com.unciv.ui.components.extensions.addSeparator
|
||||||
import com.unciv.ui.components.extensions.disable
|
import com.unciv.ui.components.extensions.disable
|
||||||
import com.unciv.ui.components.extensions.setFontSize
|
import com.unciv.ui.components.extensions.setFontSize
|
||||||
@ -40,12 +28,10 @@ import com.unciv.ui.components.input.keyShortcuts
|
|||||||
import com.unciv.ui.components.input.onActivation
|
import com.unciv.ui.components.input.onActivation
|
||||||
import com.unciv.ui.components.input.onClick
|
import com.unciv.ui.components.input.onClick
|
||||||
import com.unciv.ui.components.tilegroups.InfluenceTable
|
import com.unciv.ui.components.tilegroups.InfluenceTable
|
||||||
import com.unciv.ui.components.widgets.ColorMarkupLabel
|
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
import com.unciv.ui.popups.ConfirmPopup
|
import com.unciv.ui.popups.ConfirmPopup
|
||||||
import com.unciv.ui.screens.basescreen.BaseScreen
|
import com.unciv.ui.screens.basescreen.BaseScreen
|
||||||
import com.unciv.ui.screens.basescreen.RecreateOnResize
|
import com.unciv.ui.screens.basescreen.RecreateOnResize
|
||||||
import com.unciv.ui.screens.civilopediascreen.CivilopediaScreen
|
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
import com.unciv.ui.components.widgets.AutoScrollPane as ScrollPane
|
import com.unciv.ui.components.widgets.AutoScrollPane as ScrollPane
|
||||||
|
|
||||||
@ -168,465 +154,12 @@ class DiplomacyScreen(
|
|||||||
UncivGame.Current.musicController.chooseTrack(otherCiv.civName,
|
UncivGame.Current.musicController.chooseTrack(otherCiv.civName,
|
||||||
MusicMood.peaceOrWar(viewingCiv.isAtWarWith(otherCiv)),MusicTrackChooserFlags.setSelectNation)
|
MusicMood.peaceOrWar(viewingCiv.isAtWarWith(otherCiv)),MusicTrackChooserFlags.setSelectNation)
|
||||||
rightSideTable.add(ScrollPane(
|
rightSideTable.add(ScrollPane(
|
||||||
if (otherCiv.isCityState()) getCityStateDiplomacyTable(otherCiv)
|
if (otherCiv.isCityState()) CityStateDiplomacyTable(this).getCityStateDiplomacyTable(otherCiv)
|
||||||
else MajorCivDiplomacyTable(this).getMajorCivDiplomacyTable(otherCiv)
|
else MajorCivDiplomacyTable(this).getMajorCivDiplomacyTable(otherCiv)
|
||||||
)).height(stage.height)
|
)).height(stage.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
//region City State Diplomacy
|
//region City State Diplomacy
|
||||||
private fun getCityStateDiplomacyTableHeader(otherCiv: Civilization): Table {
|
|
||||||
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
|
||||||
|
|
||||||
val diplomacyTable = Table()
|
|
||||||
diplomacyTable.defaults().pad(2.5f)
|
|
||||||
|
|
||||||
diplomacyTable.add(LeaderIntroTable(otherCiv)).padBottom(15f).row()
|
|
||||||
|
|
||||||
diplomacyTable.add("{Type}: {${otherCiv.cityStateType.name}}".toLabel()).row()
|
|
||||||
diplomacyTable.add("{Personality}: {${otherCiv.cityStatePersonality}}".toLabel()).row()
|
|
||||||
|
|
||||||
if (otherCiv.detailedCivResources.any { it.resource.resourceType != ResourceType.Bonus }) {
|
|
||||||
val resourcesTable = Table()
|
|
||||||
resourcesTable.add("{Resources}: ".toLabel()).padRight(10f)
|
|
||||||
val cityStateResources = otherCiv.cityStateFunctions.getCityStateResourcesForAlly()
|
|
||||||
for (supplyList in cityStateResources) {
|
|
||||||
if (supplyList.resource.resourceType == ResourceType.Bonus)
|
|
||||||
continue
|
|
||||||
val name = supplyList.resource.name
|
|
||||||
val wrapper = Table()
|
|
||||||
val image = ImageGetter.getResourcePortrait(name, 30f)
|
|
||||||
wrapper.add(image).padRight(5f)
|
|
||||||
wrapper.add(supplyList.amount.toLabel())
|
|
||||||
resourcesTable.add(wrapper).padRight(20f)
|
|
||||||
wrapper.addTooltip(name, 18f)
|
|
||||||
wrapper.onClick {
|
|
||||||
UncivGame.Current.pushScreen(CivilopediaScreen(UncivGame.Current.gameInfo!!.ruleset, link = "Resource/$name"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diplomacyTable.add(resourcesTable).row()
|
|
||||||
}
|
|
||||||
diplomacyTable.row().padTop(15f)
|
|
||||||
|
|
||||||
otherCiv.cityStateFunctions.updateAllyCivForCityState()
|
|
||||||
var ally = otherCiv.getAllyCiv()
|
|
||||||
if (ally != null) {
|
|
||||||
val allyInfluence = otherCiv.getDiplomacyManager(ally).getInfluence().toInt()
|
|
||||||
if (!viewingCiv.knows(ally) && ally != viewingCiv.civName)
|
|
||||||
ally = "Unknown civilization"
|
|
||||||
diplomacyTable
|
|
||||||
.add("Ally: [$ally] with [$allyInfluence] Influence".toLabel())
|
|
||||||
.row()
|
|
||||||
}
|
|
||||||
|
|
||||||
val protectors = otherCiv.cityStateFunctions.getProtectorCivs()
|
|
||||||
if (protectors.isNotEmpty()) {
|
|
||||||
val newProtectors = arrayListOf<String>()
|
|
||||||
for (protector in protectors) {
|
|
||||||
if (!viewingCiv.knows(protector) && protector.civName != viewingCiv.civName)
|
|
||||||
newProtectors.add("Unknown civilization".tr())
|
|
||||||
else
|
|
||||||
newProtectors.add(protector.civName.tr())
|
|
||||||
}
|
|
||||||
val protectorString = "{Protected by}: " + newProtectors.joinToString(", ")
|
|
||||||
diplomacyTable.add(protectorString.toLabel()).row()
|
|
||||||
}
|
|
||||||
|
|
||||||
val atWar = otherCiv.isAtWarWith(viewingCiv)
|
|
||||||
|
|
||||||
val nextLevelString = when {
|
|
||||||
atWar -> ""
|
|
||||||
otherCivDiplomacyManager.getInfluence().toInt() < 30 -> "Reach 30 for friendship."
|
|
||||||
ally == viewingCiv.civName -> ""
|
|
||||||
else -> "Reach highest influence above 60 for alliance."
|
|
||||||
}
|
|
||||||
diplomacyTable.add(getRelationshipTable(otherCivDiplomacyManager)).row()
|
|
||||||
if (nextLevelString.isNotEmpty()) {
|
|
||||||
diplomacyTable.add(nextLevelString.toLabel()).row()
|
|
||||||
}
|
|
||||||
diplomacyTable.row().padTop(15f)
|
|
||||||
|
|
||||||
var friendBonusText = "When Friends:".tr()+"\n"
|
|
||||||
val friendBonusObjects = viewingCiv.cityStateFunctions.getCityStateBonuses(otherCiv.cityStateType, RelationshipLevel.Friend)
|
|
||||||
friendBonusText += friendBonusObjects.joinToString(separator = "\n") { it.text.tr() }
|
|
||||||
|
|
||||||
var allyBonusText = "When Allies:".tr()+"\n"
|
|
||||||
val allyBonusObjects = viewingCiv.cityStateFunctions.getCityStateBonuses(otherCiv.cityStateType, RelationshipLevel.Ally)
|
|
||||||
allyBonusText += allyBonusObjects.joinToString(separator = "\n") { it.text.tr() }
|
|
||||||
|
|
||||||
val relationLevel = otherCivDiplomacyManager.relationshipIgnoreAfraid()
|
|
||||||
if (relationLevel >= RelationshipLevel.Friend) {
|
|
||||||
// RelationshipChange = Ally -> Friend or Friend -> Favorable
|
|
||||||
val turnsToRelationshipChange = otherCivDiplomacyManager.getTurnsToRelationshipChange()
|
|
||||||
if (turnsToRelationshipChange != 0)
|
|
||||||
diplomacyTable.add("Relationship changes in another [$turnsToRelationshipChange] turns".toLabel())
|
|
||||||
.row()
|
|
||||||
}
|
|
||||||
|
|
||||||
val friendBonusLabelColor = if (relationLevel == RelationshipLevel.Friend) Color.GREEN else Color.GRAY
|
|
||||||
val friendBonusLabel = ColorMarkupLabel(friendBonusText, friendBonusLabelColor)
|
|
||||||
.apply { setAlignment(Align.center) }
|
|
||||||
diplomacyTable.add(friendBonusLabel).row()
|
|
||||||
|
|
||||||
val allyBonusLabelColor = if (relationLevel == RelationshipLevel.Ally) Color.GREEN else Color.GRAY
|
|
||||||
val allyBonusLabel = ColorMarkupLabel(allyBonusText, allyBonusLabelColor)
|
|
||||||
.apply { setAlignment(Align.center) }
|
|
||||||
diplomacyTable.add(allyBonusLabel).row()
|
|
||||||
|
|
||||||
if (otherCiv.cityStateUniqueUnit != null) {
|
|
||||||
val unitName = otherCiv.cityStateUniqueUnit
|
|
||||||
val techName = viewingCiv.gameInfo.ruleset.units[otherCiv.cityStateUniqueUnit]!!.requiredTech
|
|
||||||
diplomacyTable.add("[${otherCiv.civName}] is able to provide [${unitName}] once [${techName}] is researched.".toLabel(fontSize = Constants.defaultFontSize)).row()
|
|
||||||
}
|
|
||||||
|
|
||||||
return diplomacyTable
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCityStateDiplomacyTable(otherCiv: Civilization): Table {
|
|
||||||
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
|
||||||
|
|
||||||
val diplomacyTable = getCityStateDiplomacyTableHeader(otherCiv)
|
|
||||||
|
|
||||||
diplomacyTable.addSeparator()
|
|
||||||
|
|
||||||
val giveGiftButton = "Give a Gift".toTextButton()
|
|
||||||
giveGiftButton.onClick {
|
|
||||||
rightSideTable.clear()
|
|
||||||
rightSideTable.add(ScrollPane(getGoldGiftTable(otherCiv)))
|
|
||||||
}
|
|
||||||
diplomacyTable.add(giveGiftButton).row()
|
|
||||||
if (isNotPlayersTurn() || viewingCiv.isAtWarWith(otherCiv)) giveGiftButton.disable()
|
|
||||||
|
|
||||||
val improveTileButton = getImproveTilesButton(otherCiv, otherCivDiplomacyManager)
|
|
||||||
if (improveTileButton != null) diplomacyTable.add(improveTileButton).row()
|
|
||||||
|
|
||||||
if (otherCivDiplomacyManager.diplomaticStatus != DiplomaticStatus.Protector)
|
|
||||||
diplomacyTable.add(getPledgeToProtectButton(otherCiv)).row()
|
|
||||||
else
|
|
||||||
diplomacyTable.add(getRevokeProtectionButton(otherCiv)).row()
|
|
||||||
|
|
||||||
val demandTributeButton = "Demand Tribute".toTextButton()
|
|
||||||
demandTributeButton.onClick {
|
|
||||||
rightSideTable.clear()
|
|
||||||
rightSideTable.add(ScrollPane(getDemandTributeTable(otherCiv)))
|
|
||||||
}
|
|
||||||
diplomacyTable.add(demandTributeButton).row()
|
|
||||||
if (isNotPlayersTurn() || viewingCiv.isAtWarWith(otherCiv)) demandTributeButton.disable()
|
|
||||||
|
|
||||||
val diplomacyManager = viewingCiv.getDiplomacyManager(otherCiv)
|
|
||||||
if (!viewingCiv.gameInfo.ruleset.modOptions.uniques.contains(ModOptionsConstants.diplomaticRelationshipsCannotChange)) {
|
|
||||||
if (viewingCiv.isAtWarWith(otherCiv))
|
|
||||||
diplomacyTable.add(getNegotiatePeaceCityStateButton(otherCiv, diplomacyManager)).row()
|
|
||||||
else diplomacyTable.add(getDeclareWarButton(diplomacyManager, otherCiv)).row()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (otherCiv.cities.isNotEmpty() && otherCiv.getCapital() != null && viewingCiv.hasExplored(otherCiv.getCapital()!!.getCenterTile()))
|
|
||||||
diplomacyTable.add(getGoToOnMapButton(otherCiv)).row()
|
|
||||||
|
|
||||||
val diplomaticMarriageButton = getDiplomaticMarriageButton(otherCiv)
|
|
||||||
if (diplomaticMarriageButton != null) diplomacyTable.add(diplomaticMarriageButton).row()
|
|
||||||
|
|
||||||
for (assignedQuest in otherCiv.questManager.assignedQuests.filter { it.assignee == viewingCiv.civName }) {
|
|
||||||
diplomacyTable.addSeparator()
|
|
||||||
diplomacyTable.add(getQuestTable(assignedQuest)).row()
|
|
||||||
}
|
|
||||||
|
|
||||||
for (target in otherCiv.getKnownCivs().filter { otherCiv.questManager.warWithMajorActive(it) && viewingCiv != it }) {
|
|
||||||
diplomacyTable.addSeparator()
|
|
||||||
diplomacyTable.add(getWarWithMajorTable(target, otherCiv)).row()
|
|
||||||
}
|
|
||||||
|
|
||||||
return diplomacyTable
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getRevokeProtectionButton(otherCiv: Civilization): TextButton {
|
|
||||||
val revokeProtectionButton = "Revoke Protection".toTextButton()
|
|
||||||
revokeProtectionButton.onClick {
|
|
||||||
ConfirmPopup(this, "Revoke protection for [${otherCiv.civName}]?", "Revoke Protection") {
|
|
||||||
otherCiv.cityStateFunctions.removeProtectorCiv(viewingCiv)
|
|
||||||
updateLeftSideTable(otherCiv)
|
|
||||||
updateRightSide(otherCiv)
|
|
||||||
}.open()
|
|
||||||
}
|
|
||||||
if (isNotPlayersTurn() || !otherCiv.cityStateFunctions.otherCivCanWithdrawProtection(viewingCiv))
|
|
||||||
revokeProtectionButton.disable()
|
|
||||||
return revokeProtectionButton
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPledgeToProtectButton(otherCiv: Civilization): TextButton {
|
|
||||||
val protectionButton = "Pledge to protect".toTextButton()
|
|
||||||
protectionButton.onClick {
|
|
||||||
ConfirmPopup(
|
|
||||||
this,
|
|
||||||
"Declare Protection of [${otherCiv.civName}]?",
|
|
||||||
"Pledge to protect",
|
|
||||||
true
|
|
||||||
) {
|
|
||||||
otherCiv.cityStateFunctions.addProtectorCiv(viewingCiv)
|
|
||||||
updateLeftSideTable(otherCiv)
|
|
||||||
updateRightSide(otherCiv)
|
|
||||||
}.open()
|
|
||||||
}
|
|
||||||
if (isNotPlayersTurn() || !otherCiv.cityStateFunctions.otherCivCanPledgeProtection(viewingCiv))
|
|
||||||
protectionButton.disable()
|
|
||||||
return protectionButton
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getNegotiatePeaceCityStateButton(
|
|
||||||
otherCiv: Civilization,
|
|
||||||
otherCivDiplomacyManager: DiplomacyManager
|
|
||||||
): TextButton {
|
|
||||||
val peaceButton = "Negotiate Peace".toTextButton()
|
|
||||||
peaceButton.onClick {
|
|
||||||
ConfirmPopup(
|
|
||||||
this,
|
|
||||||
"Peace with [${otherCiv.civName}]?",
|
|
||||||
"Negotiate Peace",
|
|
||||||
true
|
|
||||||
) {
|
|
||||||
val tradeLogic = TradeLogic(viewingCiv, otherCiv)
|
|
||||||
tradeLogic.currentTrade.ourOffers.add(
|
|
||||||
TradeOffer(
|
|
||||||
Constants.peaceTreaty,
|
|
||||||
TradeType.Treaty
|
|
||||||
)
|
|
||||||
)
|
|
||||||
tradeLogic.currentTrade.theirOffers.add(
|
|
||||||
TradeOffer(
|
|
||||||
Constants.peaceTreaty,
|
|
||||||
TradeType.Treaty
|
|
||||||
)
|
|
||||||
)
|
|
||||||
tradeLogic.acceptTrade()
|
|
||||||
updateLeftSideTable(otherCiv)
|
|
||||||
updateRightSide(otherCiv)
|
|
||||||
}.open()
|
|
||||||
}
|
|
||||||
val cityStatesAlly = otherCiv.getAllyCiv()
|
|
||||||
val atWarWithItsAlly = viewingCiv.getKnownCivs()
|
|
||||||
.any { it.civName == cityStatesAlly && it.isAtWarWith(viewingCiv) }
|
|
||||||
if (isNotPlayersTurn() || atWarWithItsAlly) peaceButton.disable()
|
|
||||||
|
|
||||||
if (otherCivDiplomacyManager.hasFlag(DiplomacyFlags.DeclaredWar)) {
|
|
||||||
peaceButton.disable() // Can't trade for 10 turns after war was declared
|
|
||||||
val turnsLeft = otherCivDiplomacyManager.getFlag(DiplomacyFlags.DeclaredWar)
|
|
||||||
peaceButton.setText(peaceButton.text.toString() + "\n$turnsLeft" + Fonts.turn)
|
|
||||||
}
|
|
||||||
|
|
||||||
return peaceButton
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getImproveTilesButton(
|
|
||||||
otherCiv: Civilization,
|
|
||||||
otherCivDiplomacyManager: DiplomacyManager
|
|
||||||
): TextButton? {
|
|
||||||
if (otherCiv.cities.isEmpty()) return null
|
|
||||||
val improvableResourceTiles = getImprovableResourceTiles(otherCiv)
|
|
||||||
val improvements =
|
|
||||||
otherCiv.gameInfo.ruleset.tileImprovements.filter { it.value.turnsToBuild != -1 }
|
|
||||||
var needsImprovements = false
|
|
||||||
|
|
||||||
for (improvableTile in improvableResourceTiles)
|
|
||||||
for (tileImprovement in improvements.values)
|
|
||||||
if (improvableTile.tileResource.isImprovedBy(tileImprovement.name)
|
|
||||||
&& improvableTile.improvementFunctions.canBuildImprovement(tileImprovement, otherCiv)
|
|
||||||
)
|
|
||||||
needsImprovements = true
|
|
||||||
|
|
||||||
if (!needsImprovements) return null
|
|
||||||
|
|
||||||
|
|
||||||
val improveTileButton = "Gift Improvement".toTextButton()
|
|
||||||
improveTileButton.onClick {
|
|
||||||
rightSideTable.clear()
|
|
||||||
rightSideTable.add(ScrollPane(getImprovementGiftTable(otherCiv)))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (isNotPlayersTurn() || otherCivDiplomacyManager.getInfluence() < 60)
|
|
||||||
improveTileButton.disable()
|
|
||||||
return improveTileButton
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getDiplomaticMarriageButton(otherCiv: Civilization): TextButton? {
|
|
||||||
if (!viewingCiv.hasUnique(UniqueType.CityStateCanBeBoughtForGold))
|
|
||||||
return null
|
|
||||||
|
|
||||||
val diplomaticMarriageButton =
|
|
||||||
"Diplomatic Marriage ([${otherCiv.cityStateFunctions.getDiplomaticMarriageCost()}] Gold)".toTextButton()
|
|
||||||
diplomaticMarriageButton.onClick {
|
|
||||||
val newCities = otherCiv.cities
|
|
||||||
otherCiv.cityStateFunctions.diplomaticMarriage(viewingCiv)
|
|
||||||
UncivGame.Current.popScreen() // The other civ will no longer exist
|
|
||||||
for (city in newCities)
|
|
||||||
viewingCiv.popupAlerts.add(PopupAlert(AlertType.DiplomaticMarriage, city.id)) // Player gets to choose between annex and puppet
|
|
||||||
}
|
|
||||||
if (isNotPlayersTurn() || !otherCiv.cityStateFunctions.canBeMarriedBy(viewingCiv))
|
|
||||||
diplomaticMarriageButton.disable()
|
|
||||||
return diplomaticMarriageButton
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getGoldGiftTable(otherCiv: Civilization): Table {
|
|
||||||
val diplomacyTable = getCityStateDiplomacyTableHeader(otherCiv)
|
|
||||||
diplomacyTable.addSeparator()
|
|
||||||
|
|
||||||
for (giftAmount in listOf(250, 500, 1000)) {
|
|
||||||
val influenceAmount = otherCiv.cityStateFunctions.influenceGainedByGift(viewingCiv, giftAmount)
|
|
||||||
val giftButton =
|
|
||||||
"Gift [$giftAmount] gold (+[$influenceAmount] influence)".toTextButton()
|
|
||||||
giftButton.onClick {
|
|
||||||
otherCiv.cityStateFunctions.receiveGoldGift(viewingCiv, giftAmount)
|
|
||||||
updateLeftSideTable(otherCiv)
|
|
||||||
updateRightSide(otherCiv)
|
|
||||||
}
|
|
||||||
diplomacyTable.add(giftButton).row()
|
|
||||||
if (viewingCiv.gold < giftAmount || isNotPlayersTurn()) giftButton.disable()
|
|
||||||
}
|
|
||||||
|
|
||||||
val backButton = "Back".toTextButton()
|
|
||||||
backButton.onClick {
|
|
||||||
rightSideTable.clear()
|
|
||||||
rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
|
||||||
}
|
|
||||||
diplomacyTable.add(backButton)
|
|
||||||
return diplomacyTable
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getImprovableResourceTiles(otherCiv:Civilization) = otherCiv.getCapital()!!.getTiles().filter {
|
|
||||||
it.hasViewableResource(otherCiv)
|
|
||||||
&& it.tileResource.resourceType != ResourceType.Bonus
|
|
||||||
&& (it.improvement == null || !it.tileResource.isImprovedBy(it.improvement!!))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getImprovementGiftTable(otherCiv: Civilization): Table {
|
|
||||||
val improvementGiftTable = getCityStateDiplomacyTableHeader(otherCiv)
|
|
||||||
improvementGiftTable.addSeparator()
|
|
||||||
|
|
||||||
val improvableResourceTiles = getImprovableResourceTiles(otherCiv)
|
|
||||||
val tileImprovements =
|
|
||||||
otherCiv.gameInfo.ruleset.tileImprovements
|
|
||||||
|
|
||||||
for (improvableTile in improvableResourceTiles) {
|
|
||||||
for (tileImprovement in tileImprovements.values) {
|
|
||||||
if (improvableTile.tileResource.isImprovedBy(tileImprovement.name)
|
|
||||||
&& improvableTile.improvementFunctions.canBuildImprovement(tileImprovement, otherCiv)
|
|
||||||
) {
|
|
||||||
val improveTileButton =
|
|
||||||
"Build [${tileImprovement}] on [${improvableTile.tileResource}] (200 Gold)".toTextButton()
|
|
||||||
improveTileButton.onClick {
|
|
||||||
viewingCiv.addGold(-200)
|
|
||||||
improvableTile.stopWorkingOnImprovement()
|
|
||||||
improvableTile.changeImprovement(tileImprovement.name)
|
|
||||||
otherCiv.cache.updateCivResources()
|
|
||||||
rightSideTable.clear()
|
|
||||||
rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
|
||||||
}
|
|
||||||
if (viewingCiv.gold < 200)
|
|
||||||
improveTileButton.disable()
|
|
||||||
improvementGiftTable.add(improveTileButton).row()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val backButton = "Back".toTextButton()
|
|
||||||
backButton.onClick {
|
|
||||||
rightSideTable.clear()
|
|
||||||
rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
|
||||||
}
|
|
||||||
improvementGiftTable.add(backButton)
|
|
||||||
return improvementGiftTable
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getDemandTributeTable(otherCiv: Civilization): Table {
|
|
||||||
val diplomacyTable = getCityStateDiplomacyTableHeader(otherCiv)
|
|
||||||
diplomacyTable.addSeparator()
|
|
||||||
diplomacyTable.add("Tribute Willingness".toLabel()).row()
|
|
||||||
val modifierTable = Table()
|
|
||||||
val tributeModifiers = otherCiv.cityStateFunctions.getTributeModifiers(viewingCiv, requireWholeList = true)
|
|
||||||
for (item in tributeModifiers) {
|
|
||||||
val color = if (item.value >= 0) Color.GREEN else Color.RED
|
|
||||||
modifierTable.add(item.key.toLabel(color))
|
|
||||||
modifierTable.add(item.value.toString().toLabel(color)).row()
|
|
||||||
}
|
|
||||||
modifierTable.add("Sum:".toLabel())
|
|
||||||
modifierTable.add(tributeModifiers.values.sum().toLabel()).row()
|
|
||||||
diplomacyTable.add(modifierTable).row()
|
|
||||||
diplomacyTable.add("At least 0 to take gold, at least 30 and size 4 city for worker".toLabel()).row()
|
|
||||||
diplomacyTable.addSeparator()
|
|
||||||
|
|
||||||
val demandGoldButton = "Take [${otherCiv.cityStateFunctions.goldGainedByTribute()}] gold (-15 Influence)".toTextButton()
|
|
||||||
demandGoldButton.onClick {
|
|
||||||
otherCiv.cityStateFunctions.tributeGold(viewingCiv)
|
|
||||||
rightSideTable.clear()
|
|
||||||
rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
|
||||||
}
|
|
||||||
diplomacyTable.add(demandGoldButton).row()
|
|
||||||
if (otherCiv.cityStateFunctions.getTributeWillingness(viewingCiv, demandingWorker = false) < 0) demandGoldButton.disable()
|
|
||||||
|
|
||||||
val demandWorkerButton = "Take worker (-50 Influence)".toTextButton()
|
|
||||||
demandWorkerButton.onClick {
|
|
||||||
otherCiv.cityStateFunctions.tributeWorker(viewingCiv)
|
|
||||||
rightSideTable.clear()
|
|
||||||
rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
|
||||||
}
|
|
||||||
diplomacyTable.add(demandWorkerButton).row()
|
|
||||||
if (otherCiv.cityStateFunctions.getTributeWillingness(viewingCiv, demandingWorker = true) < 0) demandWorkerButton.disable()
|
|
||||||
|
|
||||||
val backButton = "Back".toTextButton()
|
|
||||||
backButton.onClick {
|
|
||||||
rightSideTable.clear()
|
|
||||||
rightSideTable.add(ScrollPane(getCityStateDiplomacyTable(otherCiv)))
|
|
||||||
}
|
|
||||||
diplomacyTable.add(backButton)
|
|
||||||
return diplomacyTable
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getQuestTable(assignedQuest: AssignedQuest): Table {
|
|
||||||
val questTable = Table()
|
|
||||||
questTable.defaults().pad(10f)
|
|
||||||
|
|
||||||
val quest: Quest = viewingCiv.gameInfo.ruleset.quests[assignedQuest.questName]!!
|
|
||||||
val remainingTurns: Int = assignedQuest.getRemainingTurns()
|
|
||||||
val title = if (quest.influence > 0)
|
|
||||||
"[${quest.name}] (+[${quest.influence.toInt()}] influence)"
|
|
||||||
else
|
|
||||||
quest.name
|
|
||||||
val description = assignedQuest.getDescription()
|
|
||||||
|
|
||||||
questTable.add(title.toLabel(fontSize = Constants.headingFontSize)).row()
|
|
||||||
questTable.add(description.toLabel().apply { wrap = true; setAlignment(Align.center) })
|
|
||||||
.width(stage.width / 2).row()
|
|
||||||
if (quest.duration > 0)
|
|
||||||
questTable.add("[${remainingTurns}] turns remaining".toLabel()).row()
|
|
||||||
if (quest.isGlobal()) {
|
|
||||||
val leaderString = viewingCiv.gameInfo.getCivilization(assignedQuest.assigner).questManager.getLeaderStringForQuest(assignedQuest.questName)
|
|
||||||
if (leaderString != "")
|
|
||||||
questTable.add(leaderString.toLabel()).row()
|
|
||||||
}
|
|
||||||
|
|
||||||
questTable.onClick {
|
|
||||||
assignedQuest.onClickAction()
|
|
||||||
}
|
|
||||||
return questTable
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getWarWithMajorTable(target: Civilization, otherCiv: Civilization): Table {
|
|
||||||
val warTable = Table()
|
|
||||||
warTable.defaults().pad(10f)
|
|
||||||
|
|
||||||
val title = "War against [${target.civName}]"
|
|
||||||
val description = "We need you to help us defend against [${target.civName}]. Killing [${otherCiv.questManager.unitsToKill(target)}] of their military units would slow their offensive."
|
|
||||||
val progress = if (viewingCiv.knows(target)) "Currently you have killed [${otherCiv.questManager.unitsKilledSoFar(target, viewingCiv)}] of their military units."
|
|
||||||
else "You need to find them first!"
|
|
||||||
|
|
||||||
warTable.add(title.toLabel(fontSize = Constants.headingFontSize)).row()
|
|
||||||
warTable.add(description.toLabel().apply { wrap = true; setAlignment(Align.center) })
|
|
||||||
.width(stage.width / 2).row()
|
|
||||||
warTable.add(progress.toLabel().apply { wrap = true; setAlignment(Align.center) })
|
|
||||||
.width(stage.width / 2).row()
|
|
||||||
|
|
||||||
return warTable
|
|
||||||
}
|
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
//region Major Civ Diplomacy
|
//region Major Civ Diplomacy
|
||||||
|
Reference in New Issue
Block a user