diff --git a/core/src/com/unciv/ui/cityscreen/CityReligionInfoTable.kt b/core/src/com/unciv/ui/cityscreen/CityReligionInfoTable.kt new file mode 100644 index 0000000000..ec596a3a27 --- /dev/null +++ b/core/src/com/unciv/ui/cityscreen/CityReligionInfoTable.kt @@ -0,0 +1,77 @@ +package com.unciv.ui.cityscreen + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.unciv.logic.city.CityInfoReligionManager +import com.unciv.models.Religion +import com.unciv.ui.utils.* + +class CityReligionInfoTable( + private val religionManager: CityInfoReligionManager, + showMajority: Boolean = false +) : Table(CameraStageBaseScreen.skin) { + private val gameInfo = religionManager.cityInfo.civInfo.gameInfo + + init { + val gridColor = Color.DARK_GRAY + val followers = religionManager.getNumberOfFollowers() + val futurePressures = religionManager.getPressuresFromSurroundingCities() + + if (showMajority) { + val (icon, label) = getIconAndLabel(religionManager.getMajorityReligion()) + add(ImageGetter.getCircledReligionIcon(icon, 30f)).pad(5f) + add() // skip vertical separator + add("Majority Religion: [$label]".toLabel()).colspan(3).center().row() + } + + val (icon, label) = getIconAndLabel(religionManager.religionThisIsTheHolyCityOf) + if (label != "None") { + add(ImageGetter.getCircledReligionIcon(icon, 30f)).pad(5f) + add() + add("Holy city of: [$label]".toLabel()).colspan(3).center().row() + } + + add().pad(5f) // column for icon + addSeparatorVertical(gridColor) + add("Followers".toLabel()).pad(5f) + addSeparatorVertical(gridColor) + add("Pressure".toLabel()).pad(5f).row() + addSeparator(gridColor) + + for ((religion, followerCount) in followers) { + val iconName = gameInfo.religions[religion]!!.getIconName() + add(ImageGetter.getCircledReligionIcon(iconName, 30f)).pad(5f) + addSeparatorVertical(gridColor) + add(followerCount.toLabel()).pad(5f) + addSeparatorVertical(gridColor) + if (futurePressures.containsKey(religion)) + add(("+ [${futurePressures[religion]!!}] pressure").toLabel()).pad(5f) + else + add() + row() + } + } + + private fun getIconAndLabel(religionName: String?) = + getIconAndLabel(gameInfo.religions[religionName]) + private fun getIconAndLabel(religion: Religion?): Pair { + return if (religion == null) "Religion" to "None" + else religion.getIconName() to religion.getReligionDisplayName() + } + + fun asExpander(onChange: (()->Unit)?): ExpanderTab { + val (icon, label) = getIconAndLabel(religionManager.getMajorityReligion()) + return ExpanderTab( + title = "Majority Religion: [$label]", + fontSize = 18, + icon = ImageGetter.getCircledReligionIcon(icon, 30f), + defaultPad = 0f, + persistenceID = "CityStatsTable.Religion", + startsOutOpened = false, + onChange = onChange + ) { + defaults().center().pad(5f) + it.add(this) + } + } +} diff --git a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt index 0de9b78c9a..a88f582176 100644 --- a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt @@ -83,67 +83,12 @@ class CityStatsTable(val cityScreen: CityScreen): Table() { } private fun addReligionInfo() { - val label = cityInfo.religion.getMajorityReligion()?.getReligionDisplayName() - ?: "None" - val icon = - if (label == "None") "Religion" - else cityInfo.religion.getMajorityReligion()!!.getIconName() - val expanderTab = - ExpanderTab( - title = "Majority Religion: [$label]", - fontSize = 18, - icon = ImageGetter.getCircledReligionIcon(icon, 30f), - defaultPad = 0f, - persistenceID = "CityStatsTable.Religion", - startsOutOpened = false, - onChange = { - pack() - // We have to re-anchor as our position in the city screen, otherwise it expands upwards. - // ToDo: This probably should be refactored so its placed somewhere else in due time - setPosition(stage.width - CityScreen.posFromEdge, stage.height - CityScreen.posFromEdge, Align.topRight) - } - ) { - if (cityInfo.religion.religionThisIsTheHolyCityOf != null) { - // I want this to be centered, but `.center()` doesn't seem to do anything, - // regardless of where I place it :( - it.add( - "Holy city of: [${cityInfo.civInfo.gameInfo.religions[cityInfo.religion.religionThisIsTheHolyCityOf!!]!!.getReligionDisplayName()}]".toLabel() - ).center().colspan(2).pad(5f).row() - } - it.add(getReligionsTable()).colspan(2).pad(5f) - } - + val expanderTab = CityReligionInfoTable(cityInfo.religion).asExpander { + pack() + // We have to re-anchor as our position in the city screen, otherwise it expands upwards. + // ToDo: This probably should be refactored so its placed somewhere else in due time + setPosition(stage.width - CityScreen.posFromEdge, stage.height - CityScreen.posFromEdge, Align.topRight) + } innerTable.add(expanderTab).growX().row() } - - private fun getReligionsTable(): Table { - val gridColor = Color.DARK_GRAY - val religionsTable = Table(CameraStageBaseScreen.skin) - val followers = cityInfo.religion.getNumberOfFollowers() - val futurePressures = cityInfo.religion.getPressuresFromSurroundingCities() - - religionsTable.add().pad(5f) - religionsTable.addSeparatorVertical(gridColor) - religionsTable.add("Followers".toLabel()).pad(5f) - religionsTable.addSeparatorVertical(gridColor) - religionsTable.add("Pressure".toLabel()).pad(5f) - religionsTable.row() - religionsTable.addSeparator(gridColor) - - for ((religion, followerCount) in followers) { - religionsTable.add( - ImageGetter.getCircledReligionIcon(cityInfo.civInfo.gameInfo.religions[religion]!!.getIconName(), 30f) - ).pad(5f) - religionsTable.addSeparatorVertical(gridColor) - religionsTable.add(followerCount.toLabel()).pad(5f) - religionsTable.addSeparatorVertical(gridColor) - if (futurePressures.containsKey(religion)) - religionsTable.add(("+ [${futurePressures[religion]!!}] pressure").toLabel()).pad(5f) - else - religionsTable.add() - religionsTable.row() - } - - return religionsTable - } -} \ No newline at end of file +} diff --git a/core/src/com/unciv/ui/tilegroups/CityButton.kt b/core/src/com/unciv/ui/tilegroups/CityButton.kt index 53cf3987e8..9eefb12f95 100644 --- a/core/src/com/unciv/ui/tilegroups/CityButton.kt +++ b/core/src/com/unciv/ui/tilegroups/CityButton.kt @@ -15,8 +15,8 @@ import com.unciv.logic.city.CityConstructions import com.unciv.logic.city.CityInfo import com.unciv.logic.city.INonPerpetualConstruction import com.unciv.logic.city.PerpetualConstruction -import com.unciv.logic.civilization.CityStateType import com.unciv.logic.civilization.diplomacy.RelationshipLevel +import com.unciv.ui.cityscreen.CityReligionInfoTable import com.unciv.ui.cityscreen.CityScreen import com.unciv.ui.trade.DiplomacyScreen import com.unciv.ui.utils.* @@ -129,13 +129,13 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab private fun addAirUnitTable() { if (!showAdditionalInfoTags || tileGroup.tileInfo.airUnits.isEmpty()) return - val secondarycolor = city.civInfo.nation.getInnerColor() + val secondaryColor = city.civInfo.nation.getInnerColor() val airUnitTable = Table() airUnitTable.background = ImageGetter.getRoundedEdgeRectangle(city.civInfo.nation.getOuterColor()).apply { setMinSize(0f,0f) } val aircraftImage = ImageGetter.getImage("OtherIcons/Aircraft") - aircraftImage.color = secondarycolor + aircraftImage.color = secondaryColor airUnitTable.add(aircraftImage).size(15f) - airUnitTable.add(tileGroup.tileInfo.airUnits.size.toString().toLabel(secondarycolor,14)) + airUnitTable.add(tileGroup.tileInfo.airUnits.size.toString().toLabel(secondaryColor,14)) add(airUnitTable).row() } @@ -158,10 +158,7 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab if (uncivGame.viewEntireMapForDebug || belongsToViewingCiv() || viewingCiv.isSpectator()) { uncivGame.setScreen(CityScreen(city)) } else if (viewingCiv.knows(city.civInfo)) { - // If city doesn't belong to you, go directly to its owner's diplomacy screen. - val screen = DiplomacyScreen(viewingCiv) - screen.updateRightSide(city.civInfo) - uncivGame.setScreen(screen) + foreignCityInfoPopup() } } else { moveButtonDown() @@ -180,13 +177,13 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab } } - private fun getIconTable(): Table { + private fun getIconTable(forPopup: Boolean = false): Table { val secondaryColor = city.civInfo.nation.getInnerColor() - class IconTable:Table(){ + class IconTable: Table() { override fun draw(batch: Batch?, parentAlpha: Float) { super.draw(batch, parentAlpha) } } val iconTable = IconTable() - iconTable.touchable=Touchable.enabled + iconTable.touchable = Touchable.enabled iconTable.background = ImageGetter.getRoundedEdgeRectangle(city.civInfo.nation.getOuterColor()) if (city.isInResistance()) { @@ -204,6 +201,7 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab val fireImage = ImageGetter.getImage("OtherIcons/Fire") iconTable.add(fireImage).size(20f).padLeft(5f) } + if (city.isCapital()) { if (city.civInfo.isCityState()) { val cityStateImage = ImageGetter.getNationIcon("CityState") @@ -233,11 +231,14 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab label.toBack() // this is so the label is rendered right before the population group, // so we save the font texture and avoid another texture switch - // City strength is added NOT inside the table, but rather - top-center to it val cityStrength = CityCombatant(city).getCityStrength() - val cityStrengthLabel = "${Fonts.strength}$cityStrength".toLabel(city.civInfo.nation.getInnerColor(), 10) - iconTable.addActor(cityStrengthLabel) // We create this here to we can .toBack() it as well. - cityStrengthLabel.toBack() + val cityStrengthLabel = + "${Fonts.strength}$cityStrength".toLabel(city.civInfo.nation.getInnerColor(), 10) + if (!forPopup) { + // City strength is added NOT inside the table, but rather - top-center to it + iconTable.addActor(cityStrengthLabel) // We create this here to we can .toBack() it as well. + cityStrengthLabel.toBack() + } if (city.civInfo.isCityState()) { val cityStateImage = ImageGetter.getImage(city.civInfo.cityStateType.icon).apply { color = secondaryColor } @@ -253,22 +254,25 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab // and the two labels in the the population group are rendered *first* (toBack()), // What we get is that ALL 4 LABELS are rendered one after the other, // and so the glyph texture only needs to be swapped in once rather than 4 times! :) - } - else if (city.civInfo.isMajorCiv()) { + } else if (city.civInfo.isMajorCiv()) { val nationIcon = ImageGetter.getNationIcon(city.civInfo.nation.name) nationIcon.color = secondaryColor iconTable.add(nationIcon).size(20f) } - - val cityReligion = city.religion.getMajorityReligion() - if (cityReligion != null) { - val religionImage = ImageGetter.getReligionImage(cityReligion.getIconName()) - iconTable.add(religionImage).size(20f).padLeft(5f).fillY() + + if (!forPopup) { + val cityReligion = city.religion.getMajorityReligion() + if (cityReligion != null) { + val religionImage = ImageGetter.getReligionImage(cityReligion.getIconName()) + iconTable.add(religionImage).size(20f).padLeft(5f).fillY() + } } iconTable.pack() - cityStrengthLabel.x = label.x // so it'll be aligned right above the city name - cityStrengthLabel.setY(iconTable.height, Align.top) + if (!forPopup) { + cityStrengthLabel.x = label.x // so it'll be aligned right above the city name + cityStrengthLabel.setY(iconTable.height, Align.top) + } return iconTable } @@ -280,7 +284,7 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab updateHiddenUnitMarkers() } ) - parent.addAction(moveButtonAction) // Move the whole cityButtonLayerGroup down, so the citybutton remains clickable + parent.addAction(moveButtonAction) // Move the whole cityButtonLayerGroup down, so the CityButton remains clickable } private fun moveButtonUp() { @@ -329,17 +333,16 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab group.addActor(growthBar) - val turnLabel : Label - when { + val turnLabel: Label = when { city.isGrowing() -> { val turnsToGrowth = city.getNumTurnsToNewPopulation() - turnLabel = if (turnsToGrowth != null && turnsToGrowth < 100) turnsToGrowth.toString().toLabel() else "∞".toLabel() + if (turnsToGrowth != null && turnsToGrowth < 100) turnsToGrowth.toString().toLabel() else "∞".toLabel() } city.isStarving() -> { val turnsToStarvation = city.getNumTurnsToStarvation() - turnLabel = if (turnsToStarvation != null && turnsToStarvation < 100) turnsToStarvation.toString().toLabel() else "∞".toLabel() + if (turnsToStarvation != null && turnsToStarvation < 100) turnsToStarvation.toString().toLabel() else "∞".toLabel() } - else -> turnLabel = "∞".toLabel() + else -> "∞".toLabel() } turnLabel.color = city.civInfo.nation.getInnerColor() turnLabel.setFontSize(14) @@ -409,6 +412,28 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab return group } + private fun foreignCityInfoPopup() { + fun openDiplomacy() { + // If city doesn't belong to you, go directly to its owner's diplomacy screen. + val screen = DiplomacyScreen(worldScreen.viewingCiv) + screen.updateRightSide(city.civInfo) + worldScreen.game.setScreen(screen) + } + + // If there's nothing to display cuz no Religion - skip popup + if (!city.civInfo.gameInfo.isReligionEnabled()) return openDiplomacy() + + val popup = Popup(worldScreen).apply { + name = "ForeignCityInfoPopup" + add(getIconTable(true)).fillX().padBottom(5f).colspan(3).row() + add(CityReligionInfoTable(city.religion, true)).colspan(3).row() + addOKButton("Diplomacy") { openDiplomacy() } + add().expandX() + addCloseButton() + } + popup.open() + } + companion object { fun getInfluenceBar(influence: Float, relationshipLevel: RelationshipLevel, width: Float = 100f, height: Float = 5f): Table { val normalizedInfluence = max(-60f, min(influence, 60f)) / 30f