mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-20 20:59:18 +07:00
Implemented Follower beliefs for religions (#4530)
* Minor things * Added a few follower beliefs * Implemented follower beliefs when founding a religion * Added missing follower beliefs as much as possible * Religion screen now scrolls correctly * Buttons for chosen religions are now disabled instead of removed, idea couresty to someTroglodyte * Implemented requested changes
This commit is contained in:
@ -117,6 +117,47 @@
|
||||
"name": "Stone Circles",
|
||||
"type": "Pantheon",
|
||||
"uniques": ["[+2 Faith] from every [Quarry]"]
|
||||
},
|
||||
///////////////////////////////////////// Follower beliefs /////////////////////////////////////////
|
||||
|
||||
// Missing: asceticism (requires followers)
|
||||
// Missing: cathedrals (requires purchasing with faith)
|
||||
// Missing: choral music (requires followers)
|
||||
{
|
||||
"name": "Divine inspiration",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+2 Faith] from every Wonder"]
|
||||
},
|
||||
{
|
||||
"name": "Feed the World",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+1 Food] from every [Shrine]", "[+1 Food] from every [Temple]"]
|
||||
},
|
||||
{
|
||||
"name": "Guruship",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+2 Production] if this city has at least [1] specialists"]
|
||||
},
|
||||
// Missing: Holy Warriors (requires purchasing with faith)
|
||||
// Missing: Liturgical drama (requires followers)
|
||||
// Missing: Monasteries (requires purchasing with faith)
|
||||
// Missing: Mosques (requires purchasing with faith)
|
||||
// Missing: Pagodas (requires purchasing with faith)
|
||||
{
|
||||
"name": "Peace Gardens",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+2 Happiness] from every [Garden]"]
|
||||
},
|
||||
{
|
||||
"name": "Religious Art",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+8 Culture] from every [Hermitage]"]
|
||||
},
|
||||
// Missing: Religious center (requires followers)
|
||||
// Missing: Religious community (requires followers)
|
||||
{
|
||||
"name": "Swords into Ploughshares",
|
||||
"type": "Follower",
|
||||
"uniques": ["[+15]% growth [in this city] when not at war"]
|
||||
}
|
||||
|
||||
]
|
||||
|
@ -931,6 +931,7 @@ All policies adopted =
|
||||
# Religions
|
||||
|
||||
Choose an Icon and name for your Religion =
|
||||
Choose a [$beliefType] belief! =
|
||||
Found [religionName] =
|
||||
|
||||
# Terrains
|
||||
|
@ -159,9 +159,12 @@ class CityStats {
|
||||
fun getGrowthBonusFromPoliciesAndWonders(): Float {
|
||||
var bonus = 0f
|
||||
// "+[amount]% growth [cityFilter]"
|
||||
for (unique in cityInfo.civInfo.getMatchingUniques("+[]% growth []"))
|
||||
for (unique in cityInfo.getMatchingUniques("+[]% growth []"))
|
||||
if (cityInfo.matchesFilter(unique.params[1]))
|
||||
bonus += unique.params[0].toFloat()
|
||||
for (unique in cityInfo.getMatchingUniques("+[]% growth [] when not at war"))
|
||||
if (cityInfo.matchesFilter(unique.params[1]) && !cityInfo.civInfo.isAtWar())
|
||||
bonus += unique.params[0].toFloat()
|
||||
return bonus / 100
|
||||
}
|
||||
|
||||
@ -277,7 +280,11 @@ class CityStats {
|
||||
|
||||
// "[stats] in cities on [tileFilter] tiles"
|
||||
if (unique.placeholderText == "[] in cities on [] tiles" && cityInfo.getCenterTile().matchesTerrainFilter(unique.params[1]))
|
||||
{stats.add(unique.stats); println(unique.text)}
|
||||
stats.add(unique.stats)
|
||||
|
||||
// "[stats] if this city has at least [amount] specialists"
|
||||
if (unique.placeholderText == "[] if this city has at least [] specialists" && cityInfo.population.getNumberOfSpecialists() >= unique.params[1].toInt())
|
||||
stats.add(unique.stats)
|
||||
}
|
||||
|
||||
return stats
|
||||
|
@ -151,13 +151,13 @@ class ReligionManager {
|
||||
foundingCityId = prophet.getTile().getCity()!!.id
|
||||
}
|
||||
|
||||
fun foundReligion(iconName: String, name: String, founderBelief: String, followerBelief: String) {
|
||||
fun foundReligion(iconName: String, name: String, founderBelief: String, followerBeliefs: List<String>) {
|
||||
val newReligion = Religion(name, civInfo.gameInfo, civInfo.civName)
|
||||
newReligion.iconName = iconName
|
||||
if (religion != null) {
|
||||
newReligion.followerBeliefs.addAll(religion!!.followerBeliefs)
|
||||
}
|
||||
newReligion.followerBeliefs.add(followerBelief)
|
||||
newReligion.followerBeliefs.addAll(followerBeliefs)
|
||||
newReligion.founderBeliefs.add(founderBelief)
|
||||
newReligion.holyCityId = foundingCityId
|
||||
religion = newReligion
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.unciv.models
|
||||
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.ruleset.Belief
|
||||
import com.unciv.models.ruleset.Unique
|
||||
import com.unciv.models.stats.INamed
|
||||
|
||||
@ -13,7 +13,6 @@ class Religion() : INamed {
|
||||
lateinit var foundingCivName: String
|
||||
var holyCityId: String? = null
|
||||
|
||||
|
||||
var founderBeliefs: HashSet<String> = hashSetOf()
|
||||
var followerBeliefs: HashSet<String> = hashSetOf()
|
||||
|
||||
@ -39,13 +38,32 @@ class Religion() : INamed {
|
||||
fun setTransients(gameInfo: GameInfo) {
|
||||
this.gameInfo = gameInfo
|
||||
}
|
||||
|
||||
private fun getUniquesOfBeliefs(beliefs: HashSet<String>): Sequence<Unique> {
|
||||
|
||||
private fun mapToExistingBeliefs(beliefs: HashSet<String>): List<Belief> {
|
||||
val rulesetBeliefs = gameInfo.ruleSet.beliefs
|
||||
return beliefs.mapNotNull {
|
||||
if (it !in rulesetBeliefs) null
|
||||
else rulesetBeliefs[it]!!.uniqueObjects
|
||||
}.flatten().asSequence()
|
||||
else rulesetBeliefs[it]!!
|
||||
}
|
||||
}
|
||||
|
||||
fun getPantheonBeliefs(): Sequence<Belief> {
|
||||
return mapToExistingBeliefs(followerBeliefs)
|
||||
.filter { it.type == "Pantheon" }
|
||||
.asSequence()
|
||||
}
|
||||
|
||||
fun getFollowerBeliefs(): Sequence<Belief> {
|
||||
return mapToExistingBeliefs(followerBeliefs)
|
||||
.filter { it.type == "Follower" }
|
||||
.asSequence()
|
||||
}
|
||||
|
||||
private fun getUniquesOfBeliefs(beliefs: HashSet<String>): Sequence<Unique> {
|
||||
return mapToExistingBeliefs(beliefs)
|
||||
.map { it.uniqueObjects }
|
||||
.flatten()
|
||||
.asSequence()
|
||||
}
|
||||
|
||||
fun getFollowerUniques(): Sequence<Unique> {
|
||||
@ -56,7 +74,7 @@ class Religion() : INamed {
|
||||
return getUniquesOfBeliefs(founderBeliefs)
|
||||
}
|
||||
|
||||
fun isPantheon(): Boolean {
|
||||
fun isPantheon(): Boolean { // Currently unused
|
||||
return hasPantheon() && !isMajorReligion()
|
||||
}
|
||||
|
||||
@ -65,8 +83,12 @@ class Religion() : INamed {
|
||||
return founderBeliefs.isNotEmpty() && followerBeliefs.any { gameInfo.ruleSet.beliefs[it]!!.type == "Follower"}
|
||||
}
|
||||
|
||||
fun hasPantheon(): Boolean {
|
||||
fun hasPantheon(): Boolean { // Currently unused
|
||||
// Temporary as a result of follower beliefs not yet being implemented
|
||||
return followerBeliefs.any { it != "" && gameInfo.ruleSet.beliefs[it]!!.type == "Pantheon" }
|
||||
}
|
||||
|
||||
fun hasBelief(belief: String): Boolean {
|
||||
return followerBeliefs.contains(belief) || founderBeliefs.contains(belief)
|
||||
}
|
||||
}
|
@ -3,9 +3,9 @@ package com.unciv.models.ruleset
|
||||
import com.unciv.models.stats.INamed
|
||||
import java.util.ArrayList
|
||||
|
||||
class Belief:INamed {
|
||||
override var name:String=""
|
||||
var type:String=""
|
||||
class Belief: INamed {
|
||||
override var name: String = ""
|
||||
var type: String = ""
|
||||
var uniques = ArrayList<String>()
|
||||
val uniqueObjects: List<Unique> by lazy { uniques.map { Unique(it) } }
|
||||
}
|
||||
|
@ -6,59 +6,63 @@ import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.Religion
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.ruleset.Belief
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.*
|
||||
import kotlin.math.max
|
||||
|
||||
class FoundReligionPickerScreen (
|
||||
private val choosingCiv: CivilizationInfo,
|
||||
private val gameInfo: GameInfo
|
||||
): PickerScreen() {
|
||||
private val gameInfo: GameInfo,
|
||||
followerBeliefsToChoose: Int = 1,
|
||||
founderBeliefsToChoose: Int = 1,
|
||||
): PickerScreen(disableScroll = true) {
|
||||
|
||||
// Roughly follows the layout of the original (although I suck at UI designing, so please improve this)
|
||||
// Roughly follows the layout of the original (although I am not very good at UI designing, so please improve this)
|
||||
private val topReligionIcons = Table() // Top of the layout, contains icons for religions
|
||||
private val leftChosenBeliefs: ScrollPane // Left middle part, contains buttons to select the types of beliefs to choose
|
||||
private val rightBeliefsToChoose: ScrollPane // Right middle part, contains the beliefs to choose
|
||||
private val leftChosenBeliefs = Table() // Left middle part, contains buttons to select the types of beliefs to choose
|
||||
private val rightBeliefsToChoose = Table() // Right middle part, contains the beliefs to choose
|
||||
|
||||
private val middlePanes = Table()
|
||||
|
||||
private var previouslySelectedIcon: Button? = null
|
||||
private var iconName: String? = null
|
||||
private var religionName: String? = null
|
||||
private var chosenFounderBelief: Belief? = null
|
||||
private var chosenFollowerBelief: Belief? = null
|
||||
private val chosenFollowerBeliefs: MutableList<Belief?> = MutableList(followerBeliefsToChoose) { null }
|
||||
private val chosenFounderBeliefs: MutableList<Belief?> = MutableList(founderBeliefsToChoose) { null }
|
||||
|
||||
init {
|
||||
closeButton.isVisible = true
|
||||
setDefaultCloseAction()
|
||||
|
||||
setupReligionIcons()
|
||||
|
||||
leftChosenBeliefs = ScrollPane(Table())
|
||||
rightBeliefsToChoose = ScrollPane(Table())
|
||||
|
||||
middlePanes.add(leftChosenBeliefs)
|
||||
updateLeftTable()
|
||||
|
||||
middlePanes.add(ScrollPane(leftChosenBeliefs))
|
||||
middlePanes.addSeparatorVertical()
|
||||
middlePanes.add(rightBeliefsToChoose)
|
||||
middlePanes.add(ScrollPane(rightBeliefsToChoose))
|
||||
|
||||
topTable.add(topReligionIcons).row()
|
||||
// commented out, as the middle panes will always be empty for now, and this will create a random line otherwise
|
||||
// topTable.addSeparator()
|
||||
topTable.addSeparator()
|
||||
topTable.add(middlePanes)
|
||||
|
||||
rightSideButton.label = "Choose a religion".toLabel()
|
||||
rightSideButton.onClick(UncivSound.Choir) {
|
||||
choosingCiv.religionManager.foundReligion(iconName!!, religionName!!, "", "", /**chosenFollowerBelief!!.name, chosenFounderBelief!!.name*/)
|
||||
choosingCiv.religionManager.foundReligion(
|
||||
iconName!!, religionName!!, "" /**chosenFollowerBeliefs.map {it!!.name} */, chosenFollowerBeliefs.map { it!!.name}
|
||||
)
|
||||
UncivGame.Current.setWorldScreen()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun checkAndEnableRightSideButton() {
|
||||
if (religionName == null) return
|
||||
println(chosenFollowerBeliefs)
|
||||
if (chosenFollowerBeliefs.any { it == null }) return
|
||||
// check if founder belief chosen
|
||||
// check if follower belief chosen
|
||||
rightSideButton.enable()
|
||||
}
|
||||
|
||||
@ -71,7 +75,6 @@ class FoundReligionPickerScreen (
|
||||
val iconsTable = Table()
|
||||
iconsTable.align(Align.center)
|
||||
for (religionName in gameInfo.ruleSet.religions) {
|
||||
if (gameInfo.religions.keys.any { it == religionName }) continue
|
||||
val image = ImageGetter.getReligionIcon(religionName)
|
||||
image.color = Color.BLACK
|
||||
val icon = image.surroundWithCircle(60f)
|
||||
@ -89,11 +92,69 @@ class FoundReligionPickerScreen (
|
||||
rightSideButton.label = "Found [$translatedReligionName]".toLabel()
|
||||
checkAndEnableRightSideButton()
|
||||
}
|
||||
if (religionName == this.religionName) button.disable()
|
||||
if (religionName == this.religionName || gameInfo.religions.keys.any { it == religionName }) button.disable()
|
||||
iconsTable.add(button).pad(5f)
|
||||
}
|
||||
iconsTable.row()
|
||||
topReligionIcons.add(iconsTable).padBottom(10f).row()
|
||||
topReligionIcons.add(descriptionLabel).center()
|
||||
topReligionIcons.add(descriptionLabel).center().padBottom(5f)
|
||||
}
|
||||
|
||||
private fun updateLeftTable() {
|
||||
leftChosenBeliefs.clear()
|
||||
val currentReligion = choosingCiv.religionManager.religion ?: Religion("Unknown", gameInfo, choosingCiv.civName)
|
||||
|
||||
for (pantheon in currentReligion.getPantheonBeliefs() + currentReligion.getFollowerBeliefs()) {
|
||||
val beliefButton = convertBeliefToButton(pantheon)
|
||||
leftChosenBeliefs.add(beliefButton).pad(10f).row()
|
||||
beliefButton.disable()
|
||||
}
|
||||
|
||||
for (newFollowerBelief in chosenFollowerBeliefs.withIndex()) {
|
||||
val newFollowerBeliefButton =
|
||||
if (newFollowerBelief.value == null) emptyBeliefButton("Follower")
|
||||
else convertBeliefToButton(newFollowerBelief.value!!)
|
||||
|
||||
leftChosenBeliefs.add(newFollowerBeliefButton).pad(10f).row()
|
||||
newFollowerBeliefButton.onClick {
|
||||
loadRightTable("Follower", newFollowerBelief.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadRightTable(beliefType: String, leftButtonIndex: Int) {
|
||||
rightBeliefsToChoose.clear()
|
||||
val availableBeliefs = gameInfo.ruleSet.beliefs.values
|
||||
.filter {
|
||||
it.type == beliefType
|
||||
&& gameInfo.religions.values.none {
|
||||
religion -> religion.hasBelief(it.name)
|
||||
}
|
||||
&& (!chosenFollowerBeliefs.contains(it) || chosenFollowerBeliefs[leftButtonIndex] == it)
|
||||
}
|
||||
for (belief in availableBeliefs) {
|
||||
val beliefButton = convertBeliefToButton(belief)
|
||||
beliefButton.onClick {
|
||||
if (beliefType == "Follower") chosenFollowerBeliefs[leftButtonIndex] = belief
|
||||
else if (beliefType == "Founder") chosenFounderBeliefs[leftButtonIndex] = belief
|
||||
updateLeftTable()
|
||||
checkAndEnableRightSideButton()
|
||||
}
|
||||
rightBeliefsToChoose.add(beliefButton).pad(10f).row()
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertBeliefToButton(belief: Belief): Button {
|
||||
val contentsTable = Table()
|
||||
contentsTable.add(belief.type.toLabel()).row()
|
||||
contentsTable.add(belief.name.toLabel(fontSize = 24)).row()
|
||||
contentsTable.add(belief.uniques.joinToString().toLabel())
|
||||
return Button(contentsTable, skin)
|
||||
}
|
||||
|
||||
private fun emptyBeliefButton(beliefType: String): Button {
|
||||
val contentsTable = Table()
|
||||
contentsTable.add("Choose a [$beliefType] belief!".toLabel())
|
||||
return Button(contentsTable, skin)
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ class PantheonPickerScreen(choosingCiv: CivilizationInfo, gameInfo: GameInfo) :
|
||||
topTable.apply { defaults().pad(10f) }
|
||||
for (belief in gameInfo.ruleSet.beliefs.values) {
|
||||
if (!choosingCiv.religionManager.isPickablePantheonBelief(belief)) continue
|
||||
val beliefTable = Table().apply { touchable = Touchable.enabled;
|
||||
val beliefTable = Table(skin).apply { touchable = Touchable.enabled;
|
||||
background =
|
||||
// Ideally I want to this to be the darker blue we use for pressed buttons, but I suck at UI so I'll leave it like this.
|
||||
if (belief == chosenPantheon) ImageGetter.getBackground(ImageGetter.getBlue())
|
||||
|
Reference in New Issue
Block a user