From 92728e9007f637141c317324902690836532e228 Mon Sep 17 00:00:00 2001 From: Xander Lenstra <71121390+xlenstra@users.noreply.github.com> Date: Sun, 8 Aug 2021 22:46:39 +0200 Subject: [PATCH] Added an overview screen for religions (#4808) * Added an overview screen for religions * Missed a thing * Implemented requested changes --- .../jsons/translations/template.properties | 8 +- .../logic/civilization/ReligionManager.kt | 7 +- core/src/com/unciv/models/Religion.kt | 17 +-- .../ui/newgamescreen/PlayerPickerTable.kt | 9 +- .../ui/overviewscreen/EmpireOverviewScreen.kt | 12 +- .../overviewscreen/ReligionOverviewTable.kt | 106 ++++++++++++++++++ core/src/com/unciv/ui/utils/ImageGetter.kt | 8 ++ .../unciv/ui/worldscreen/WorldScreenTopBar.kt | 12 +- 8 files changed, 156 insertions(+), 23 deletions(-) create mode 100644 core/src/com/unciv/ui/overviewscreen/ReligionOverviewTable.kt diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index c4516a9828..11ff691497 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -827,7 +827,7 @@ Spaceship parts remaining = Branches completed = Undefeated civs = # The \n here means: put a newline (enter) here. If this is omitted, the sidebox in the diplomacy overview will become _really_ wide. - # Feel free to replace it with a space and put it somewhere else in your translation + # Feel free to replace it with a space and put it between other words in your translation Turns until the next\ndiplomacy victory vote: [amount] = Choose a civ to vote for = Choose who should become the world leader and win a diplomatic victory! = @@ -990,6 +990,12 @@ Found Pantheon = Follow [belief] = Religions and Beliefs = +# Religion overview screen +Religion Name: = +Founding Civ: = +Cities following this religion: = +Click an icon to see the stats of this religion = + # Terrains Impassable = diff --git a/core/src/com/unciv/logic/civilization/ReligionManager.kt b/core/src/com/unciv/logic/civilization/ReligionManager.kt index d1d0af6c49..a159329b8a 100644 --- a/core/src/com/unciv/logic/civilization/ReligionManager.kt +++ b/core/src/com/unciv/logic/civilization/ReligionManager.kt @@ -139,7 +139,6 @@ class ReligionManager { return false // Mod maker did not provide enough religions for the amount of civs present - return true } @@ -174,6 +173,12 @@ class ReligionManager { foundingCityId = null } + + fun numberOfCitiesFollowingThisReligion(): Int { + if (religion == null) return 0 + return civInfo.gameInfo.getCities() + .count { it.religion.getMajorityReligion() == religion!!.name } + } } enum class ReligionState { diff --git a/core/src/com/unciv/models/Religion.kt b/core/src/com/unciv/models/Religion.kt index 26c538e1f9..484402452c 100644 --- a/core/src/com/unciv/models/Religion.kt +++ b/core/src/com/unciv/models/Religion.kt @@ -16,8 +16,7 @@ class Religion() : INamed { var founderBeliefs: HashSet = hashSetOf() var followerBeliefs: HashSet = hashSetOf() - - + @Transient lateinit var gameInfo: GameInfo @@ -50,20 +49,25 @@ class Religion() : INamed { fun getPantheonBeliefs(): Sequence { return mapToExistingBeliefs(followerBeliefs) - .filter { it.type == BeliefType.Pantheon } .asSequence() + .filter { it.type == BeliefType.Pantheon } } fun getFollowerBeliefs(): Sequence { return mapToExistingBeliefs(followerBeliefs) - .filter { it.type == BeliefType.Follower } .asSequence() + .filter { it.type == BeliefType.Follower } + } + + fun getFounderBeliefs(): Sequence { + return mapToExistingBeliefs(founderBeliefs) + .asSequence() + .filter { it.type == BeliefType.Founder } } private fun getUniquesOfBeliefs(beliefs: HashSet): Sequence { return mapToExistingBeliefs(beliefs) - .map { it.uniqueObjects } - .flatten() + .flatMap { it.uniqueObjects } .asSequence() } @@ -80,7 +84,6 @@ class Religion() : INamed { } fun isMajorReligion(): Boolean { - if ("" in followerBeliefs) return true // Temporary as a result of follower beliefs not yet being implemented return founderBeliefs.isNotEmpty() && followerBeliefs .any { gameInfo.ruleSet.beliefs[it]!!.type == BeliefType.Follower} } diff --git a/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt b/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt index b40a6604d1..85b3e096da 100644 --- a/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt +++ b/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt @@ -199,11 +199,10 @@ class PlayerPickerTable( */ private fun getNationTable(player: Player): Table { val nationTable = Table() - val nationImage = if (player.chosenCiv == Constants.random) "?".toLabel(Color.WHITE, 25) - .apply { this.setAlignment(Align.center) } - .surroundWithCircle(36f).apply { circle.color = Color.BLACK } - .surroundWithCircle(40f, false).apply { circle.color = Color.WHITE } - else ImageGetter.getNationIndicator(previousScreen.ruleset.nations[player.chosenCiv]!!, 40f) + val nationImage = + if (player.chosenCiv == Constants.random) + ImageGetter.getRandomNationIndicator(40f) + else ImageGetter.getNationIndicator(previousScreen.ruleset.nations[player.chosenCiv]!!, 40f) nationTable.add(nationImage).pad(5f) nationTable.add(player.chosenCiv.toLabel()).pad(5f) nationTable.touchable = Touchable.enabled diff --git a/core/src/com/unciv/ui/overviewscreen/EmpireOverviewScreen.kt b/core/src/com/unciv/ui/overviewscreen/EmpireOverviewScreen.kt index 2af0b34664..68d4cff005 100644 --- a/core/src/com/unciv/ui/overviewscreen/EmpireOverviewScreen.kt +++ b/core/src/com/unciv/ui/overviewscreen/EmpireOverviewScreen.kt @@ -32,7 +32,8 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa Pair("Trades", IconAndKey("StatIcons/Acquire", 'T')), Pair("Units", IconAndKey("OtherIcons/Shield", 'U')), Pair("Diplomacy", IconAndKey("OtherIcons/DiplomacyW", 'D')), - Pair("Resources", IconAndKey("StatIcons/Happiness", 'R')) + Pair("Resources", IconAndKey("StatIcons/Happiness", 'R')), + Pair("Religion", IconAndKey("StatIcons/Faith", 'F')) ) } @@ -85,6 +86,8 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa addCategory("Units", UnitOverviewTable(viewingPlayer, this), viewingPlayer.getCivUnits().none()) addCategory("Diplomacy", DiplomacyOverviewTable(viewingPlayer, this), viewingPlayer.diplomacy.isEmpty()) addCategory("Resources", ResourcesOverviewTable(viewingPlayer, this), viewingPlayer.detailedCivResources.isEmpty()) + if (viewingPlayer.gameInfo.hasReligionEnabled()) + addCategory("Religion", ReligionOverviewTable(viewingPlayer, this), viewingPlayer.gameInfo.religions.isEmpty()) val closeButton = Constants.close.toTextButton().apply { setColor(0.75f, 0.1f, 0.1f, 1f) @@ -131,12 +134,7 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa backgroundColor = civ.nation.getOuterColor() labelColor = civ.nation.getInnerColor() } else { - civGroup.add( - "?".toLabel(Color.WHITE) - .apply { this.setAlignment(Align.center) } - .surroundWithCircle(27f).apply { circle.color = Color.BLACK } - .surroundWithCircle(30f, false).apply { circle.color = Color.WHITE } - ) + civGroup.add(ImageGetter.getRandomNationIndicator(30f)) backgroundColor = Color.DARK_GRAY labelText = "???" } diff --git a/core/src/com/unciv/ui/overviewscreen/ReligionOverviewTable.kt b/core/src/com/unciv/ui/overviewscreen/ReligionOverviewTable.kt new file mode 100644 index 0000000000..91346f1be0 --- /dev/null +++ b/core/src/com/unciv/ui/overviewscreen/ReligionOverviewTable.kt @@ -0,0 +1,106 @@ +package com.unciv.ui.overviewscreen + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.scenes.scene2d.ui.Button +import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.unciv.logic.civilization.CivilizationInfo +import com.unciv.models.Religion +import com.unciv.models.ruleset.Belief +import com.unciv.models.translations.tr +import com.unciv.ui.utils.* +import kotlin.math.min + +class ReligionOverviewTable( + private val viewingPlayer: CivilizationInfo, + private val overviewScreen: EmpireOverviewScreen +): Table() { + + val gameInfo = viewingPlayer.gameInfo + private val topButtons = Table(CameraStageBaseScreen.skin) + private val topButtonLabel = "Click an icon to see the stats of this religion".toLabel() + private val statsTable = Table(CameraStageBaseScreen.skin) + private val beliefsTable = Table(CameraStageBaseScreen.skin) + private var selectedReligion: String? = null + + init { + addReligionButtons() + + add(topButtons).pad(5f).row() + add(topButtonLabel).pad(5f) + addSeparator() + add(statsTable).pad(5f).row() + add(beliefsTable).pad(5f) + } + + private fun addReligionButtons() { + topButtons.clear() + val existingReligions: List = gameInfo.civilizations.mapNotNull { it.religionManager.religion } + for (religion in existingReligions) { + val button: Button + if (religion.isPantheon()) { + val image = if (viewingPlayer.knows(religion.foundingCivName) || viewingPlayer.civName == religion.foundingCivName) + ImageGetter.getNationIndicator(gameInfo.getCivilization(religion.foundingCivName).nation, 60f) + else + ImageGetter.getRandomNationIndicator(60f) + button = Button(image, CameraStageBaseScreen.skin) + } else { + val image = ImageGetter.getReligionIcon(religion.iconName) + image.color = Color.BLACK + val icon = image.surroundWithCircle(60f) + button = Button(icon, CameraStageBaseScreen.skin) + } + + button.onClick { + selectedReligion = religion.name + addReligionButtons() + loadReligion(religion) + } + + if (selectedReligion == religion.name) + button.disable() + + topButtons.add(button).pad(5f) + } + } + + private fun loadReligion(religion: Religion) { + statsTable.clear() + beliefsTable.clear() + topButtonLabel.setText(religion.name.tr()) + for (belief in + religion.getPantheonBeliefs() + + religion.getFollowerBeliefs() + + religion.getFounderBeliefs() + ) { + beliefsTable.add(createBeliefDescription(belief)).pad(10f).row() + } + + statsTable.add("Religion Name:".tr()) + statsTable.add(religion.name.tr()).pad(5f).row() + statsTable.add("Founding Civ:".tr()) + val foundingCivName = + if (viewingPlayer.knows(religion.foundingCivName) || viewingPlayer.civName == religion.foundingCivName) + religion.foundingCivName + else "???" + statsTable.add(foundingCivName.tr()).pad(5f).row() + statsTable.add("Cities following this religion:".tr()) + statsTable.add(gameInfo.getCivilization(religion.foundingCivName).religionManager.numberOfCitiesFollowingThisReligion().toString()).pad(5f).row() + + val minWidth = min(statsTable.minWidth, beliefsTable.minWidth) + 5f + + statsTable.width = minWidth + for (cell in beliefsTable.cells) { + cell.minWidth(minWidth) + } + } + + private fun createBeliefDescription(belief: Belief): Table { + val contentsTable = Table(CameraStageBaseScreen.skin) + contentsTable.add(belief.type.name.toLabel()).row() + contentsTable.add(belief.name.toLabel(fontSize = 24)).row() + contentsTable.add(belief.uniques.joinToString().toLabel()) + contentsTable.background = ImageGetter.getBackground(ImageGetter.getBlue()) + contentsTable.padTop(5f).padBottom(5f) + return contentsTable + } +} diff --git a/core/src/com/unciv/ui/utils/ImageGetter.kt b/core/src/com/unciv/ui/utils/ImageGetter.kt index ba578cf1a1..10299145ee 100644 --- a/core/src/com/unciv/ui/utils/ImageGetter.kt +++ b/core/src/com/unciv/ui/utils/ImageGetter.kt @@ -220,6 +220,14 @@ object ImageGetter { } else getCircle().apply { color = nation.getOuterColor() } .surroundWithCircle(size).apply { circle.color = nation.getInnerColor() } } + + fun getRandomNationIndicator(size: Float): IconCircleGroup { + return "?" + .toLabel(Color.WHITE, (size * 5f/8f).toInt()) + .apply { this.setAlignment(Align.center) } + .surroundWithCircle(size * 0.9f).apply { circle.color = Color.BLACK } + .surroundWithCircle(size, false).apply { circle.color = Color.WHITE } + } private fun nationIconExists(nation: String) = imageExists("NationIcons/$nation") fun getNationIcon(nation: String) = getImage("NationIcons/$nation") diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreenTopBar.kt b/core/src/com/unciv/ui/worldscreen/WorldScreenTopBar.kt index 725697b5b7..424d62e556 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreenTopBar.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreenTopBar.kt @@ -34,7 +34,7 @@ class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() { private val scienceLabel = "0".toLabel(colorFromRGB(78, 140, 151)) private val happinessLabel = "0".toLabel() private val cultureLabel = "0".toLabel(colorFromRGB(210, 94, 210)) - private val faithLabel = "0".toLabel(colorFromRGB(210, 94, 210)) + private val faithLabel = "0".toLabel(colorFromRGB(210, 94, 210)) // TODO: This colour should be changed at some point private val resourceLabels = HashMap() private val resourceImages = HashMap() private val happinessImage = Group() @@ -126,7 +126,15 @@ class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() { if(worldScreen.gameInfo.hasReligionEnabled()) { statsTable.add(faithLabel).padLeft(20f) - statsTable.add(ImageGetter.getStatIcon("Faith")).padBottom(6f).size(20f) + val faithImage = ImageGetter.getStatIcon("Faith") + statsTable.add(faithImage).padBottom(6f).size(20f) + + val invokeFaithOverview = { + worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.selectedCiv, "Religion")) + } + + faithLabel.onClick(invokeFaithOverview) + faithImage.onClick(invokeFaithOverview) } statsTable.pack()