mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-14 17:59:11 +07:00
Resolved #3501 - Added city-state toggle to diplomacy overview, clicking on civ names in overview opens diplomacy screen
This commit is contained in:
@ -17,6 +17,7 @@ import com.unciv.logic.trade.TradeOffersList
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.pickerscreens.PromotionPickerScreen
|
||||
import com.unciv.ui.trade.DiplomacyScreen
|
||||
import com.unciv.ui.utils.*
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.abs
|
||||
@ -103,46 +104,67 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa
|
||||
stage.addActor(table)
|
||||
}
|
||||
|
||||
private fun setDiplomacyTable() {
|
||||
private fun setDiplomacyTable(includeCityStates:Boolean=false) {
|
||||
centerTable.clear()
|
||||
val relevantCivs = viewingPlayer.gameInfo.civilizations.filter { !it.isBarbarian() && !it.isCityState() }
|
||||
val playerKnowsAndUndefeatedCivs = relevantCivs.filter { playerKnows(it) && !it.isDefeated() }
|
||||
val playerKnowsAndDefeatedCivs = relevantCivs.filter { playerKnows(it) && it.isDefeated() }
|
||||
val relevantCivs = viewingPlayer.gameInfo.civilizations.filter { !it.isBarbarian() && (includeCityStates || !it.isCityState()) }
|
||||
val diplomacyGroup = DiplomacyGroup(viewingPlayer, stage.height - topTable.height, includeCityStates)
|
||||
val playerKnowsAndUndefeatedCivs = relevantCivs.filter { diplomacyGroup.playerKnows(it) && !it.isDefeated() }
|
||||
val playerKnowsAndDefeatedCivs = relevantCivs.filter { diplomacyGroup.playerKnows(it) && it.isDefeated() }
|
||||
if (playerKnowsAndUndefeatedCivs.size > 1)
|
||||
centerTable.add(getDiplomacyGroup())
|
||||
val civTable = Table()
|
||||
civTable.background = ImageGetter.getBackground(Color.BLACK)
|
||||
civTable.add("[${relevantCivs.size}] Civilizations in the game".toLabel()).pad(5f).colspan(4).row()
|
||||
centerTable.add(diplomacyGroup)
|
||||
fun getCivMinitable(civInfo: CivilizationInfo):Table{
|
||||
val table = Table()
|
||||
table.add(ImageGetter.getNationIndicator(civInfo.nation, 25f)).pad(5f)
|
||||
table.add(civInfo.civName.toLabel()).left()
|
||||
table.touchable = Touchable.enabled
|
||||
table.onClick {
|
||||
game.setScreen(DiplomacyScreen(viewingPlayer).apply { updateRightSide(civInfo) })
|
||||
}
|
||||
return table
|
||||
}
|
||||
|
||||
val titleTable = Table()
|
||||
titleTable.add("Our Civilization:".toLabel())
|
||||
titleTable.add(ImageGetter.getNationIndicator(viewingPlayer.nation, 25f)).pad(5f)
|
||||
titleTable.add(viewingPlayer.civName.toLabel()).left().row()
|
||||
civTable.add(titleTable).colspan(4).row()
|
||||
|
||||
|
||||
val civTable = Table()
|
||||
civTable.defaults().pad(5f)
|
||||
civTable.background = ImageGetter.getBackground(Color.BLACK)
|
||||
civTable.add("[${relevantCivs.size}] Civilizations in the game".toLabel()).pad(5f).colspan(2).row()
|
||||
civTable.add(titleTable).colspan(2).row()
|
||||
civTable.addSeparator()
|
||||
civTable.add("Known and alive ([${playerKnowsAndUndefeatedCivs.size - 1}])".toLabel()).pad(5f).colspan(4).row()
|
||||
civTable.add("Known and alive ([${playerKnowsAndUndefeatedCivs.size - 1}])".toLabel()).pad(5f).colspan(2).row()
|
||||
if (playerKnowsAndUndefeatedCivs.size > 1) {
|
||||
civTable.addSeparator()
|
||||
playerKnowsAndUndefeatedCivs.filter { it != viewingPlayer }.forEach {
|
||||
civTable.add(ImageGetter.getNationIndicator(it.nation, 25f)).pad(5f)
|
||||
if (playerKnowsAndUndefeatedCivs.indexOf(it) % 2 == 0)
|
||||
civTable.add(it.civName.toLabel()).left().row()
|
||||
else civTable.add(it.civName.toLabel()).left()
|
||||
civTable.add(getCivMinitable(it)).left()
|
||||
if (playerKnowsAndUndefeatedCivs.indexOf(it) % 2 == 0) civTable.row()
|
||||
}
|
||||
}
|
||||
civTable.addSeparator()
|
||||
civTable.add("Known and defeated ([${playerKnowsAndDefeatedCivs.size}])".toLabel()).pad(5f).colspan(4).row()
|
||||
civTable.add("Known and defeated ([${playerKnowsAndDefeatedCivs.size}])".toLabel()).pad(5f).colspan(2).row()
|
||||
if (playerKnowsAndDefeatedCivs.isNotEmpty()) {
|
||||
civTable.addSeparator()
|
||||
playerKnowsAndDefeatedCivs.forEach {
|
||||
civTable.add(ImageGetter.getNationIndicator(it.nation, 25f)).pad(5f)
|
||||
if (playerKnowsAndDefeatedCivs.indexOf(it) % 2 != 0)
|
||||
civTable.add(it.civName.toLabel()).left().row()
|
||||
else civTable.add(it.civName.toLabel()).left()
|
||||
civTable.add(getCivMinitable(it)).left()
|
||||
if (playerKnowsAndUndefeatedCivs.indexOf(it) % 2 == 0) civTable.row()
|
||||
}
|
||||
}
|
||||
val civTableScrollPane = ScrollPane(civTable)
|
||||
civTableScrollPane.setOverscroll(false, false)
|
||||
centerTable.add(civTableScrollPane.addBorder(2f, Color.WHITE)).pad(10f)
|
||||
|
||||
val toggleCityStatesButton = "City-States".toTextButton()
|
||||
toggleCityStatesButton.color = if(includeCityStates)Color.RED else Color.GREEN
|
||||
toggleCityStatesButton.onClick { setDiplomacyTable(!includeCityStates) }
|
||||
civTable.add(toggleCityStatesButton).row()
|
||||
|
||||
val floatingTable = Table()
|
||||
floatingTable.add(toggleCityStatesButton).row()
|
||||
floatingTable.add(civTableScrollPane.addBorder(2f, Color.WHITE)).pad(10f)
|
||||
|
||||
centerTable.add(floatingTable)
|
||||
centerTable.pack()
|
||||
}
|
||||
|
||||
@ -370,89 +392,6 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa
|
||||
}
|
||||
|
||||
|
||||
private fun playerKnows(civ:CivilizationInfo) = civ==viewingPlayer ||
|
||||
viewingPlayer.diplomacy.containsKey(civ.civName)
|
||||
|
||||
private fun getDiplomacyGroup(): Group {
|
||||
val relevantCivs = viewingPlayer.gameInfo.civilizations.filter { !it.isBarbarian() && !it.isCityState() }
|
||||
val playerKnowsAndUndefeatedCivs = relevantCivs.filter { playerKnows(it) && !it.isDefeated() }
|
||||
val freeHeight = stage.height - topTable.height
|
||||
val group = Group()
|
||||
group.setSize(freeHeight, freeHeight)
|
||||
val civGroups = HashMap<String, Actor>()
|
||||
val civLines = HashMap<String, MutableSet<Actor>>()
|
||||
for (i in 0..playerKnowsAndUndefeatedCivs.lastIndex) {
|
||||
val civ = playerKnowsAndUndefeatedCivs[i]
|
||||
|
||||
val civGroup = ImageGetter.getNationIndicator(civ.nation, 30f)
|
||||
|
||||
val vector = HexMath.getVectorForAngle(2 * Math.PI.toFloat() * i / playerKnowsAndUndefeatedCivs.size)
|
||||
civGroup.center(group)
|
||||
civGroup.moveBy(vector.x * freeHeight / 2.25f, vector.y * freeHeight / 2.25f)
|
||||
civGroup.touchable = Touchable.enabled
|
||||
civGroup.onClick {
|
||||
onCivClicked(civLines, civ.civName)
|
||||
}
|
||||
|
||||
civGroups[civ.civName] = civGroup
|
||||
group.addActor(civGroup)
|
||||
}
|
||||
|
||||
for (civ in relevantCivs.filter { playerKnows(it) && !it.isDefeated() })
|
||||
for (diplomacy in civ.diplomacy.values.filter {
|
||||
it.otherCiv().isMajorCiv() && playerKnows(it.otherCiv()) && !it.otherCiv().isDefeated()
|
||||
}) {
|
||||
val civGroup = civGroups[civ.civName]!!
|
||||
val otherCivGroup = civGroups[diplomacy.otherCivName]!!
|
||||
|
||||
if (!civLines.containsKey(civ.civName))
|
||||
civLines[civ.civName] = mutableSetOf()
|
||||
|
||||
val statusLine = ImageGetter.getLine(civGroup.x + civGroup.width / 2, civGroup.y + civGroup.height / 2,
|
||||
otherCivGroup.x + otherCivGroup.width / 2, otherCivGroup.y + otherCivGroup.height / 2, 2f)
|
||||
|
||||
statusLine.color = if (diplomacy.diplomaticStatus == DiplomaticStatus.Peace) Color.GREEN else Color.RED
|
||||
|
||||
civLines[civ.civName]!!.add(statusLine)
|
||||
|
||||
group.addActor(statusLine)
|
||||
statusLine.toBack()
|
||||
}
|
||||
|
||||
return group
|
||||
}
|
||||
|
||||
private fun onCivClicked(civLines: HashMap<String, MutableSet<Actor>>, name: String) {
|
||||
// ignore the clicks on "dead" civilizations, and remember the selected one
|
||||
val selectedLines = civLines[name] ?: return
|
||||
|
||||
// let's check whether lines of all civs are visible (except selected one)
|
||||
var atLeastOneLineVisible = false
|
||||
var allAreLinesInvisible = true
|
||||
for (lines in civLines.values) {
|
||||
// skip the civilization selected by user, and civilizations with no lines
|
||||
if (lines == selectedLines || lines.isEmpty()) continue
|
||||
|
||||
val visibility = lines.first().isVisible
|
||||
atLeastOneLineVisible = atLeastOneLineVisible || visibility
|
||||
allAreLinesInvisible = allAreLinesInvisible && visibility
|
||||
|
||||
// check whether both visible and invisible lines are present
|
||||
if (atLeastOneLineVisible && !allAreLinesInvisible) {
|
||||
// invert visibility of the selected civ's lines
|
||||
selectedLines.forEach { it.isVisible = !it.isVisible }
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedLines.first().isVisible)
|
||||
// invert visibility of all lines except selected one
|
||||
civLines.filter { it.key != name }.forEach { it.value.forEach { line -> line.isVisible = !line.isVisible } }
|
||||
else
|
||||
// it happens only when all are visible except selected one
|
||||
// invert visibility of the selected civ's lines
|
||||
selectedLines.forEach { it.isVisible = !it.isVisible }
|
||||
}
|
||||
|
||||
|
||||
private fun getResourcesTable(): Table {
|
||||
@ -560,3 +499,87 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class DiplomacyGroup(val viewingPlayer: CivilizationInfo, freeHeight: Float, includeCityStates: Boolean): Group() {
|
||||
private fun onCivClicked(civLines: HashMap<String, MutableSet<Actor>>, name: String) {
|
||||
// ignore the clicks on "dead" civilizations, and remember the selected one
|
||||
val selectedLines = civLines[name] ?: return
|
||||
|
||||
// let's check whether lines of all civs are visible (except selected one)
|
||||
var atLeastOneLineVisible = false
|
||||
var allAreLinesInvisible = true
|
||||
for (lines in civLines.values) {
|
||||
// skip the civilization selected by user, and civilizations with no lines
|
||||
if (lines == selectedLines || lines.isEmpty()) continue
|
||||
|
||||
val visibility = lines.first().isVisible
|
||||
atLeastOneLineVisible = atLeastOneLineVisible || visibility
|
||||
allAreLinesInvisible = allAreLinesInvisible && visibility
|
||||
|
||||
// check whether both visible and invisible lines are present
|
||||
if (atLeastOneLineVisible && !allAreLinesInvisible) {
|
||||
// invert visibility of the selected civ's lines
|
||||
selectedLines.forEach { it.isVisible = !it.isVisible }
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedLines.first().isVisible)
|
||||
// invert visibility of all lines except selected one
|
||||
civLines.filter { it.key != name }.forEach { it.value.forEach { line -> line.isVisible = !line.isVisible } }
|
||||
else
|
||||
// it happens only when all are visible except selected one
|
||||
// invert visibility of the selected civ's lines
|
||||
selectedLines.forEach { it.isVisible = !it.isVisible }
|
||||
}
|
||||
|
||||
|
||||
fun playerKnows(civ: CivilizationInfo) = civ == viewingPlayer ||
|
||||
viewingPlayer.diplomacy.containsKey(civ.civName)
|
||||
|
||||
init {
|
||||
val relevantCivs = viewingPlayer.gameInfo.civilizations.filter { !it.isBarbarian() && (includeCityStates || !it.isCityState()) }
|
||||
val playerKnowsAndUndefeatedCivs = relevantCivs.filter { playerKnows(it) && !it.isDefeated() }
|
||||
setSize(freeHeight, freeHeight)
|
||||
val civGroups = HashMap<String, Actor>()
|
||||
val civLines = HashMap<String, MutableSet<Actor>>()
|
||||
for (i in 0..playerKnowsAndUndefeatedCivs.lastIndex) {
|
||||
val civ = playerKnowsAndUndefeatedCivs[i]
|
||||
|
||||
val civGroup = ImageGetter.getNationIndicator(civ.nation, 30f)
|
||||
|
||||
val vector = HexMath.getVectorForAngle(2 * Math.PI.toFloat() * i / playerKnowsAndUndefeatedCivs.size)
|
||||
civGroup.center(this)
|
||||
civGroup.moveBy(vector.x * freeHeight / 2.25f, vector.y * freeHeight / 2.25f)
|
||||
civGroup.touchable = Touchable.enabled
|
||||
civGroup.onClick {
|
||||
onCivClicked(civLines, civ.civName)
|
||||
}
|
||||
|
||||
civGroups[civ.civName] = civGroup
|
||||
addActor(civGroup)
|
||||
}
|
||||
|
||||
for (civ in relevantCivs.filter { playerKnows(it) && !it.isDefeated() })
|
||||
for (diplomacy in civ.diplomacy.values.filter {
|
||||
(it.otherCiv().isMajorCiv() || includeCityStates) && playerKnows(it.otherCiv()) && !it.otherCiv().isDefeated()
|
||||
}) {
|
||||
val civGroup = civGroups[civ.civName]!!
|
||||
val otherCivGroup = civGroups[diplomacy.otherCivName]!!
|
||||
|
||||
if (!civLines.containsKey(civ.civName))
|
||||
civLines[civ.civName] = mutableSetOf()
|
||||
|
||||
val statusLine = ImageGetter.getLine(civGroup.x + civGroup.width / 2, civGroup.y + civGroup.height / 2,
|
||||
otherCivGroup.x + otherCivGroup.width / 2, otherCivGroup.y + otherCivGroup.height / 2, 2f)
|
||||
|
||||
statusLine.color = if (diplomacy.diplomaticStatus == DiplomaticStatus.Peace) Color.GREEN else Color.RED
|
||||
|
||||
civLines[civ.civName]!!.add(statusLine)
|
||||
|
||||
addActor(statusLine)
|
||||
statusLine.toBack()
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user