mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-24 03:53:12 -04:00
Diplomacy trade layout fix (#8808)
* Diplomacy and Trade - Linting * Diplomacy and Trade - Fix gradual layout deterioration
This commit is contained in:
parent
253c669ba9
commit
5e61b0d313
@ -56,10 +56,11 @@ import com.unciv.ui.components.AutoScrollPane as ScrollPane
|
|||||||
*
|
*
|
||||||
* When [selectCiv] is given and [selectTrade] is not, that Civilization is selected as if clicked on the left side.
|
* When [selectCiv] is given and [selectTrade] is not, that Civilization is selected as if clicked on the left side.
|
||||||
* When [selectCiv] and [selectTrade] are supplied, that Trade for that Civilization is selected, used for the counter-offer option from `TradePopup`.
|
* When [selectCiv] and [selectTrade] are supplied, that Trade for that Civilization is selected, used for the counter-offer option from `TradePopup`.
|
||||||
|
* Note calling this with [selectCiv] a City State and [selectTrade] supplied is **not allowed**.
|
||||||
*/
|
*/
|
||||||
@Suppress("KDocUnresolvedReference") // Mentioning non-field parameters is flagged, but they work anyway
|
@Suppress("KDocUnresolvedReference") // Mentioning non-field parameters is flagged, but they work anyway
|
||||||
class DiplomacyScreen(
|
class DiplomacyScreen(
|
||||||
val viewingCiv: Civilization,
|
private val viewingCiv: Civilization,
|
||||||
private val selectCiv: Civilization? = null,
|
private val selectCiv: Civilization? = null,
|
||||||
private val selectTrade: Trade? = null
|
private val selectTrade: Trade? = null
|
||||||
): BaseScreen(), RecreateOnResize {
|
): BaseScreen(), RecreateOnResize {
|
||||||
@ -69,7 +70,7 @@ class DiplomacyScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val leftSideTable = Table().apply { defaults().pad(nationIconPad) }
|
private val leftSideTable = Table().apply { defaults().pad(nationIconPad) }
|
||||||
val leftSideScroll = ScrollPane(leftSideTable)
|
private val leftSideScroll = ScrollPane(leftSideTable)
|
||||||
private val rightSideTable = Table()
|
private val rightSideTable = Table()
|
||||||
private val closeButton = Constants.close.toTextButton()
|
private val closeButton = Constants.close.toTextButton()
|
||||||
|
|
||||||
@ -169,20 +170,13 @@ class DiplomacyScreen(
|
|||||||
rightSideTable.clear()
|
rightSideTable.clear()
|
||||||
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)
|
||||||
if (otherCiv.isCityState()) rightSideTable.add(
|
rightSideTable.add(ScrollPane(
|
||||||
ScrollPane(getCityStateDiplomacyTable(otherCiv))
|
if (otherCiv.isCityState()) getCityStateDiplomacyTable(otherCiv)
|
||||||
)
|
else getMajorCivDiplomacyTable(otherCiv)
|
||||||
else rightSideTable.add(ScrollPane(getMajorCivDiplomacyTable(otherCiv)))
|
)).height(stage.height)
|
||||||
.height(stage.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setTrade(civ: Civilization): TradeTable {
|
|
||||||
rightSideTable.clear()
|
|
||||||
val tradeTable = TradeTable(civ, this)
|
|
||||||
rightSideTable.add(tradeTable)
|
|
||||||
return tradeTable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//region City State Diplomacy
|
||||||
private fun getCityStateDiplomacyTableHeader(otherCiv: Civilization): Table {
|
private fun getCityStateDiplomacyTableHeader(otherCiv: Civilization): Table {
|
||||||
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
||||||
|
|
||||||
@ -290,7 +284,6 @@ class DiplomacyScreen(
|
|||||||
return diplomacyTable
|
return diplomacyTable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getCityStateDiplomacyTable(otherCiv: Civilization): Table {
|
private fun getCityStateDiplomacyTable(otherCiv: Civilization): Table {
|
||||||
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
||||||
|
|
||||||
@ -635,6 +628,8 @@ class DiplomacyScreen(
|
|||||||
return warTable
|
return warTable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
//region Major Civ Diplomacy
|
||||||
|
|
||||||
private fun getMajorCivDiplomacyTable(otherCiv: Civilization): Table {
|
private fun getMajorCivDiplomacyTable(otherCiv: Civilization): Table {
|
||||||
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
val otherCivDiplomacyManager = otherCiv.getDiplomacyManager(viewingCiv)
|
||||||
@ -701,6 +696,13 @@ class DiplomacyScreen(
|
|||||||
return diplomacyTable
|
return diplomacyTable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setTrade(civ: Civilization): TradeTable {
|
||||||
|
rightSideTable.clear()
|
||||||
|
val tradeTable = TradeTable(civ, this)
|
||||||
|
rightSideTable.add(tradeTable)
|
||||||
|
return tradeTable
|
||||||
|
}
|
||||||
|
|
||||||
private fun getNegotiatePeaceMajorCivButton(
|
private fun getNegotiatePeaceMajorCivButton(
|
||||||
otherCiv: Civilization,
|
otherCiv: Civilization,
|
||||||
otherCivDiplomacyManager: DiplomacyManager
|
otherCivDiplomacyManager: DiplomacyManager
|
||||||
@ -909,6 +911,8 @@ class DiplomacyScreen(
|
|||||||
return declareWarButton
|
return declareWarButton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
// response currently always gets "Very Well.", but that may expand in the future.
|
// response currently always gets "Very Well.", but that may expand in the future.
|
||||||
@Suppress("SameParameterValue")
|
@Suppress("SameParameterValue")
|
||||||
private fun setRightSideFlavorText(
|
private fun setRightSideFlavorText(
|
||||||
@ -940,6 +944,13 @@ class DiplomacyScreen(
|
|||||||
return goToOnMapButton
|
return goToOnMapButton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Calculate a width for [TradeTable] two-column layout, called from [OfferColumnsTable]
|
||||||
|
*
|
||||||
|
* _Caller is responsible to not exceed this **including its own padding**_
|
||||||
|
*/
|
||||||
|
// Note breaking the rule above will squeeze the leftSideScroll to the left - cumulatively.
|
||||||
|
internal fun getTradeColumnsWidth() = (stage.width - leftSideScroll.width - 3f) / 2 // 3 for SplitPane handle
|
||||||
|
|
||||||
override fun resize(width: Int, height: Int) {
|
override fun resize(width: Int, height: Int) {
|
||||||
super.resize(width, height)
|
super.resize(width, height)
|
||||||
positionCloseButton()
|
positionCloseButton()
|
||||||
|
@ -2,6 +2,7 @@ package com.unciv.ui.screens.diplomacyscreen
|
|||||||
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
|
import com.unciv.logic.civilization.Civilization
|
||||||
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.TradeOffersList
|
import com.unciv.logic.trade.TradeOffersList
|
||||||
@ -14,8 +15,11 @@ import com.unciv.ui.popups.AskNumberPopup
|
|||||||
import com.unciv.ui.screens.basescreen.BaseScreen
|
import com.unciv.ui.screens.basescreen.BaseScreen
|
||||||
|
|
||||||
/** This is the class that holds the 4 columns of the offers (ours/theirs/ offered/available) in trade */
|
/** This is the class that holds the 4 columns of the offers (ours/theirs/ offered/available) in trade */
|
||||||
class OfferColumnsTable(private val tradeLogic: TradeLogic, val screen: DiplomacyScreen, val onChange: () -> Unit): Table(
|
class OfferColumnsTable(
|
||||||
BaseScreen.skin) {
|
private val tradeLogic: TradeLogic,
|
||||||
|
private val screen: DiplomacyScreen,
|
||||||
|
private val onChange: () -> Unit
|
||||||
|
): Table(BaseScreen.skin) {
|
||||||
|
|
||||||
private fun addOffer(offer: TradeOffer, offerList: TradeOffersList, correspondingOfferList: TradeOffersList) {
|
private fun addOffer(offer: TradeOffer, offerList: TradeOffersList, correspondingOfferList: TradeOffersList) {
|
||||||
offerList.add(offer.copy())
|
offerList.add(offer.copy())
|
||||||
@ -23,34 +27,31 @@ class OfferColumnsTable(private val tradeLogic: TradeLogic, val screen: Diplomac
|
|||||||
onChange()
|
onChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val ourAvailableOffersTable = OffersListScroll("OurAvail") {
|
private fun offerClickImplementation(
|
||||||
when (it.type) {
|
offer: TradeOffer,
|
||||||
TradeType.Gold -> openGoldSelectionPopup(it, tradeLogic.currentTrade.ourOffers, tradeLogic.ourCivilization.gold)
|
invert: Boolean,
|
||||||
TradeType.Gold_Per_Turn -> openGoldSelectionPopup(it, tradeLogic.currentTrade.ourOffers, tradeLogic.ourCivilization.stats.statsForNextTurn.gold.toInt())
|
list: TradeOffersList,
|
||||||
else -> addOffer(it, tradeLogic.currentTrade.ourOffers, tradeLogic.currentTrade.theirOffers)
|
counterList: TradeOffersList,
|
||||||
|
civ: Civilization
|
||||||
|
) {
|
||||||
|
when (offer.type) {
|
||||||
|
TradeType.Gold -> openGoldSelectionPopup(offer, list, civ.gold)
|
||||||
|
TradeType.Gold_Per_Turn -> openGoldSelectionPopup(offer, list, civ.stats.statsForNextTurn.gold.toInt())
|
||||||
|
else -> addOffer(if (invert) offer.copy(amount = -offer.amount) else offer, list, counterList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val ourAvailableOffersTable = OffersListScroll("OurAvail") {
|
||||||
|
tradeLogic.currentTrade.run { offerClickImplementation(it, false, ourOffers, theirOffers, tradeLogic.ourCivilization) }
|
||||||
|
}
|
||||||
private val ourOffersTable = OffersListScroll("OurTrade") {
|
private val ourOffersTable = OffersListScroll("OurTrade") {
|
||||||
when (it.type) {
|
tradeLogic.currentTrade.run { offerClickImplementation(it, true, ourOffers, theirOffers, tradeLogic.ourCivilization) }
|
||||||
TradeType.Gold -> openGoldSelectionPopup(it, tradeLogic.currentTrade.ourOffers, tradeLogic.ourCivilization.gold)
|
|
||||||
TradeType.Gold_Per_Turn -> openGoldSelectionPopup(it, tradeLogic.currentTrade.ourOffers, tradeLogic.ourCivilization.stats.statsForNextTurn.gold.toInt())
|
|
||||||
else -> addOffer(it.copy(amount = -it.amount), tradeLogic.currentTrade.ourOffers, tradeLogic.currentTrade.theirOffers)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private val theirOffersTable = OffersListScroll("TheirTrade") {
|
private val theirOffersTable = OffersListScroll("TheirTrade") {
|
||||||
when (it.type) {
|
tradeLogic.currentTrade.run { offerClickImplementation(it, true, theirOffers, ourOffers, tradeLogic.otherCivilization) }
|
||||||
TradeType.Gold -> openGoldSelectionPopup(it, tradeLogic.currentTrade.theirOffers, tradeLogic.otherCivilization.gold)
|
|
||||||
TradeType.Gold_Per_Turn -> openGoldSelectionPopup(it, tradeLogic.currentTrade.theirOffers, tradeLogic.otherCivilization.stats.statsForNextTurn.gold.toInt())
|
|
||||||
else -> addOffer(it.copy(amount = -it.amount), tradeLogic.currentTrade.theirOffers, tradeLogic.currentTrade.ourOffers)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private val theirAvailableOffersTable = OffersListScroll("TheirAvail") {
|
private val theirAvailableOffersTable = OffersListScroll("TheirAvail") {
|
||||||
when (it.type) {
|
tradeLogic.currentTrade.run { offerClickImplementation(it, false, theirOffers, ourOffers, tradeLogic.otherCivilization) }
|
||||||
TradeType.Gold -> openGoldSelectionPopup(it, tradeLogic.currentTrade.theirOffers, tradeLogic.otherCivilization.gold)
|
|
||||||
TradeType.Gold_Per_Turn -> openGoldSelectionPopup(it, tradeLogic.currentTrade.theirOffers, tradeLogic.otherCivilization.stats.statsForNextTurn.gold.toInt())
|
|
||||||
else -> addOffer(it, tradeLogic.currentTrade.theirOffers, tradeLogic.currentTrade.ourOffers)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -58,9 +59,10 @@ class OfferColumnsTable(private val tradeLogic: TradeLogic, val screen: Diplomac
|
|||||||
|
|
||||||
val isPortraitMode = screen.isNarrowerThan4to3()
|
val isPortraitMode = screen.isNarrowerThan4to3()
|
||||||
|
|
||||||
val columnWidth = (screen.stage.width - screen.leftSideScroll.width) / 2
|
val columnWidth = screen.getTradeColumnsWidth() - 20f // Subtract padding: ours and OffersListScroll's
|
||||||
|
|
||||||
if (!isPortraitMode) {
|
if (!isPortraitMode) {
|
||||||
|
// In landscape, arrange in 4 panels: ours left / theirs right ; items top / offers bottom.
|
||||||
add("Our items".tr())
|
add("Our items".tr())
|
||||||
add("[${tradeLogic.otherCivilization.civName}]'s items".tr()).row()
|
add("[${tradeLogic.otherCivilization.civName}]'s items".tr()).row()
|
||||||
|
|
||||||
@ -73,8 +75,9 @@ class OfferColumnsTable(private val tradeLogic: TradeLogic, val screen: Diplomac
|
|||||||
add("[${tradeLogic.otherCivilization.civName}]'s trade offer".tr()).row()
|
add("[${tradeLogic.otherCivilization.civName}]'s trade offer".tr()).row()
|
||||||
add(ourOffersTable).size(columnWidth, screen.stage.height / 3)
|
add(ourOffersTable).size(columnWidth, screen.stage.height / 3)
|
||||||
add(theirOffersTable).size(columnWidth, screen.stage.height / 3)
|
add(theirOffersTable).size(columnWidth, screen.stage.height / 3)
|
||||||
}
|
} else {
|
||||||
else {
|
// In portrait, this will arrange the items lists vertically
|
||||||
|
// and the offers still side-by-side below that
|
||||||
add("Our items".tr()).colspan(2).row()
|
add("Our items".tr()).colspan(2).row()
|
||||||
add(ourAvailableOffersTable).height(screen.stage.height / 4f).colspan(2).row()
|
add(ourAvailableOffersTable).height(screen.stage.height / 4f).colspan(2).row()
|
||||||
|
|
||||||
|
@ -10,31 +10,33 @@ import com.unciv.ui.components.extensions.isEnabled
|
|||||||
import com.unciv.ui.components.extensions.onClick
|
import com.unciv.ui.components.extensions.onClick
|
||||||
import com.unciv.ui.components.extensions.toTextButton
|
import com.unciv.ui.components.extensions.toTextButton
|
||||||
|
|
||||||
class TradeTable(private val otherCivilization: Civilization, stage: DiplomacyScreen): Table(
|
class TradeTable(
|
||||||
BaseScreen.skin) {
|
private val otherCivilization: Civilization,
|
||||||
val currentPlayerCiv = otherCivilization.gameInfo.getCurrentPlayerCivilization()
|
diplomacyScreen: DiplomacyScreen
|
||||||
var tradeLogic = TradeLogic(currentPlayerCiv,otherCivilization)
|
): Table(BaseScreen.skin) {
|
||||||
var offerColumnsTable = OfferColumnsTable(tradeLogic, stage) { onChange() }
|
private val currentPlayerCiv = otherCivilization.gameInfo.getCurrentPlayerCivilization()
|
||||||
|
internal val tradeLogic = TradeLogic(currentPlayerCiv, otherCivilization)
|
||||||
|
internal val offerColumnsTable = OfferColumnsTable(tradeLogic, diplomacyScreen) { onChange() }
|
||||||
// This is so that after a trade has been traded, we can switch out the offersToDisplay to start anew - this is the easiest way
|
// This is so that after a trade has been traded, we can switch out the offersToDisplay to start anew - this is the easiest way
|
||||||
private var offerColumnsTableWrapper = Table()
|
private val offerColumnsTableWrapper = Table()
|
||||||
private val offerButton = "Offer trade".toTextButton()
|
private val offerButton = "Offer trade".toTextButton()
|
||||||
|
|
||||||
private fun isTradeOffered() = otherCivilization.tradeRequests.any { it.requestingCiv == currentPlayerCiv.civName }
|
private fun isTradeOffered() = otherCivilization.tradeRequests.any { it.requestingCiv == currentPlayerCiv.civName }
|
||||||
|
|
||||||
private fun retractOffer(){
|
private fun retractOffer() {
|
||||||
otherCivilization.tradeRequests.removeAll { it.requestingCiv == currentPlayerCiv.civName }
|
otherCivilization.tradeRequests.removeAll { it.requestingCiv == currentPlayerCiv.civName }
|
||||||
currentPlayerCiv.cache.updateCivResources()
|
currentPlayerCiv.cache.updateCivResources()
|
||||||
offerButton.setText("Offer trade".tr())
|
offerButton.setText("Offer trade".tr())
|
||||||
}
|
}
|
||||||
|
|
||||||
init{
|
init {
|
||||||
offerColumnsTableWrapper.add(offerColumnsTable)
|
offerColumnsTableWrapper.add(offerColumnsTable)
|
||||||
add(offerColumnsTableWrapper).row()
|
add(offerColumnsTableWrapper).row()
|
||||||
|
|
||||||
val lowerTable = Table().apply { defaults().pad(10f) }
|
val lowerTable = Table().apply { defaults().pad(10f) }
|
||||||
|
|
||||||
val existingOffer = otherCivilization.tradeRequests.firstOrNull { it.requestingCiv == currentPlayerCiv.civName }
|
val existingOffer = otherCivilization.tradeRequests.firstOrNull { it.requestingCiv == currentPlayerCiv.civName }
|
||||||
if (existingOffer != null){
|
if (existingOffer != null) {
|
||||||
tradeLogic.currentTrade.set(existingOffer.trade.reverse())
|
tradeLogic.currentTrade.set(existingOffer.trade.reverse())
|
||||||
offerColumnsTable.update()
|
offerColumnsTable.update()
|
||||||
}
|
}
|
||||||
@ -43,12 +45,12 @@ class TradeTable(private val otherCivilization: Civilization, stage: DiplomacySc
|
|||||||
else offerButton.apply { isEnabled = false }.setText("Offer trade".tr())
|
else offerButton.apply { isEnabled = false }.setText("Offer trade".tr())
|
||||||
|
|
||||||
offerButton.onClick {
|
offerButton.onClick {
|
||||||
if(isTradeOffered()) {
|
if (isTradeOffered()) {
|
||||||
retractOffer()
|
retractOffer()
|
||||||
return@onClick
|
return@onClick
|
||||||
}
|
}
|
||||||
|
|
||||||
otherCivilization.tradeRequests.add(TradeRequest(currentPlayerCiv.civName,tradeLogic.currentTrade.reverse()))
|
otherCivilization.tradeRequests.add(TradeRequest(currentPlayerCiv.civName, tradeLogic.currentTrade.reverse()))
|
||||||
currentPlayerCiv.cache.updateCivResources()
|
currentPlayerCiv.cache.updateCivResources()
|
||||||
offerButton.setText("Retract offer".tr())
|
offerButton.setText("Retract offer".tr())
|
||||||
}
|
}
|
||||||
@ -61,7 +63,7 @@ class TradeTable(private val otherCivilization: Civilization, stage: DiplomacySc
|
|||||||
pack()
|
pack()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onChange(){
|
private fun onChange() {
|
||||||
offerColumnsTable.update()
|
offerColumnsTable.update()
|
||||||
retractOffer()
|
retractOffer()
|
||||||
offerButton.isEnabled = !(tradeLogic.currentTrade.theirOffers.size == 0 && tradeLogic.currentTrade.ourOffers.size == 0)
|
offerButton.isEnabled = !(tradeLogic.currentTrade.theirOffers.size == 0 && tradeLogic.currentTrade.ourOffers.size == 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user