Implemented the enhancing of religions (#4965)

* Generalize the concept of founding religions in preparation of enhancing

* Implemented enhancing religions

* Added all enhancer beliefs (mostly correctly, mostly tested)

* You can now found a religion without a pantheon, requiring you to choose a pantheon as well

* Parameterized 'enhance religion' action, fixed tests

* Implemented requested changes & simplified beliefContainer a lot

* Fixed rename

* Updated code to include features added in the meantime

* Merge branch 'master' into enhanceReligions

Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
Xander Lenstra
2021-08-28 21:36:11 +02:00
committed by GitHub
parent 3e22a36bbf
commit 1cc90a3953
20 changed files with 390 additions and 157 deletions

View File

@ -229,19 +229,26 @@ object BattleDamage {
for (unique in unit.unit.getMatchingUniques("+[]% Strength in []")
+ unit.getCivInfo()
.getMatchingUniques("+[]% Strength for units fighting in []")) {
// Deprecated since 3.16.7
.getMatchingUniques("+[]% Strength for units fighting in []")) {
//
val filter = unique.params[1]
if (tile.matchesFilter(filter, unit.getCivInfo()))
modifiers.add(filter, unique.params[0].toInt())
}
for (unique in unit.getCivInfo()
.getMatchingUniques("+[]% Strength if within [] tiles of a []")) {
for (unique in unit.getCivInfo().getMatchingUniques("+[]% Strength if within [] tiles of a []")) {
if (tile.getTilesInDistance(unique.params[1].toInt())
.any { it.matchesFilter(unique.params[2]) }
)
modifiers[unique.params[2]] = unique.params[0].toInt()
}
for (unique in unit.getCivInfo().getMatchingUniques("[]% Strength for [] units in []")) {
if (unit.matchesCategory(unique.params[1]) && tile.matchesFilter(unique.params[2], unit.getCivInfo())) {
modifiers.add(unique.params[2], unique.params[0].toInt())
}
}
return modifiers
}

View File

@ -3,6 +3,7 @@ package com.unciv.logic.city
import com.badlogic.gdx.math.Vector2
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.GreatPersonManager
import com.unciv.logic.civilization.ReligionState
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
import com.unciv.logic.map.RoadStatus
import com.unciv.logic.map.TileInfo
@ -108,7 +109,7 @@ class CityInfo {
tile.improvement = null
tile.improvementInProgress = null
if (civInfo.religionManager.religion != null && civInfo.religionManager.religion!!.isPantheon()) {
if (civInfo.religionManager.religionState == ReligionState.Pantheon) {
religion.addPressure(civInfo.religionManager.religion!!.name, 100)
}
@ -601,6 +602,9 @@ class CityInfo {
"in all cities in which the majority religion is a major religion" ->
religion.getMajorityReligionName() != null
&& religion.getMajorityReligion()!!.isMajorReligion()
"in all cities in which the majority religion is an enhanced religion" ->
religion.getMajorityReligionName() != null
&& religion.getMajorityReligion()!!.isEnhancedReligion()
"in non-enemy foreign cities" ->
viewingCiv != civInfo
&& !civInfo.isAtWarWith(viewingCiv)
@ -610,6 +614,7 @@ class CityInfo {
// religion a unique is active. However, since religion uniques only come from the city itself,
// this will always be true when checked.
"in cities following this religion" -> true
"in City-State cities" -> civInfo.isCityState()
else -> false
}
}

View File

@ -236,21 +236,34 @@ class CityInfoReligionManager {
addPressure(religionThisIsTheHolyCityOf!!,5 * pressureFromAdjacentCities, false)
}
val allCitiesWithin10Tiles =
val allCitiesWithinSpreadRange =
cityInfo.civInfo.gameInfo.getCities()
.filter {
it != cityInfo
&& it.getCenterTile().aerialDistanceTo(cityInfo.getCenterTile()) <= 10
&& it.getCenterTile().aerialDistanceTo(cityInfo.getCenterTile()) <= it.religion.getSpreadRange()
}
for (city in allCitiesWithin10Tiles) {
for (city in allCitiesWithinSpreadRange) {
val majorityReligionOfCity = city.religion.getMajorityReligionName() ?: continue
if (!cityInfo.civInfo.gameInfo.religions[majorityReligionOfCity]!!.isMajorReligion()) continue
addPressure(majorityReligionOfCity, pressureFromAdjacentCities, false)
addPressure(majorityReligionOfCity, city.religion.pressureAmountToAdjacentCities(cityInfo), false)
}
updateNumberOfFollowers()
}
private fun getSpreadRange(): Int {
var spreadRange = 10
for (unique in cityInfo.getMatchingUniques("Religion naturally spreads to cities [] tiles away"))
spreadRange += unique.params[0].toInt()
if (getMajorityReligion() != null)
for (unique in getMajorityReligion()!!.getFounderUniques()
.filter { it.placeholderText == "Religion naturally spreads to cities [] tiles away"}
) spreadRange += unique.params[0].toInt()
return spreadRange
}
/** Doesn't update the pressures, only returns what they are if the update were to happen right now */
fun getPressuresFromSurroundingCities(): Counter<String> {
val addedPressure = Counter<String>()
@ -261,13 +274,32 @@ class CityInfoReligionManager {
cityInfo.civInfo.gameInfo.getCities()
.filter {
it != cityInfo
&& it.getCenterTile().aerialDistanceTo(cityInfo.getCenterTile()) <= 10
&& it.getCenterTile().aerialDistanceTo(cityInfo.getCenterTile()) <= it.religion.getSpreadRange()
}
for (city in allCitiesWithin10Tiles) {
val majorityReligionOfCity = city.religion.getMajorityReligion() ?: continue
if (!majorityReligionOfCity.isMajorReligion()) continue
addedPressure.add(majorityReligionOfCity.name, pressureFromAdjacentCities)
addedPressure.add(majorityReligionOfCity.name, city.religion.pressureAmountToAdjacentCities(cityInfo))
}
return addedPressure
}
private fun pressureAmountToAdjacentCities(pressuredCity: CityInfo): Int {
var pressure = pressureFromAdjacentCities.toFloat()
for (unique in cityInfo.getMatchingUniques("[]% Natural religion spread []")) {
if (pressuredCity.matchesFilter(unique.params[1]))
pressure *= 1f + unique.params[0].toFloat() / 100f
}
for (unique in cityInfo.getMatchingUniques("[]% Natural religion spread [] with []"))
if (pressuredCity.matchesFilter(unique.params[1])
&& (
cityInfo.civInfo.tech.isResearched(unique.params[2])
|| cityInfo.civInfo.policies.isAdopted(unique.params[2])
)
) pressure *= 1f + unique.params[0].toFloat() / 100f
return pressure.toInt()
}
}

View File

@ -2,6 +2,7 @@ package com.unciv.logic.civilization
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
import com.unciv.models.metadata.BASE_GAME_DURATION_TURNS
import com.unciv.models.ruleset.BeliefType
import com.unciv.models.ruleset.Policy
import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.stats.Stat
@ -135,7 +136,7 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
statMap["Unit upkeep"] = Stats(gold = -getUnitMaintenance().toFloat())
if (civInfo.religionManager.religion != null) {
for (unique in civInfo.religionManager.religion!!.getFounderBeliefs().flatMap { it.uniqueObjects }) {
for (unique in civInfo.religionManager.religion!!.getBeliefs(BeliefType.Founder).flatMap { it.uniqueObjects }) {
if (unique.placeholderText == "[] for each global city following this religion") {
statMap.add(
"Religion",
@ -233,7 +234,7 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
if (civInfo.religionManager.religion != null) {
statMap["Religion"] = 0f
for (unique in civInfo.religionManager.religion!!.getFounderBeliefs().flatMap { it.uniqueObjects }) {
for (unique in civInfo.religionManager.religion!!.getBeliefs(BeliefType.Founder).flatMap { it.uniqueObjects }) {
if (unique.placeholderText == "[] for each global city following this religion") {
statMap["Religion"] =
statMap["Religion"]!! +

View File

@ -5,6 +5,7 @@ import com.unciv.logic.map.MapUnit
import com.unciv.models.Religion
import com.unciv.models.ruleset.Belief
import com.unciv.models.ruleset.BeliefType
import com.unciv.ui.pickerscreens.BeliefContainer
import kotlin.random.Random
class ReligionManager {
@ -73,6 +74,8 @@ class ReligionManager {
if (!civInfo.isMajorCiv()) return false
if (civInfo.gameInfo.ruleSet.beliefs.values.none { isPickablePantheonBelief(it) })
return false
if (civInfo.gameInfo.civilizations.any { it.religionManager.religionState == ReligionState.EnhancedReligion })
return false
return storedFaith >= faithForPantheon()
}
@ -95,10 +98,16 @@ class ReligionManager {
// https://www.reddit.com/r/civ/comments/2m82wu/can_anyone_detail_the_finer_points_of_great/
// Game files (globaldefines.xml)
fun faithForNextGreatProphet() = (
(200 + 100 * greatProphetsEarned * (greatProphetsEarned + 1) / 2) *
civInfo.gameInfo.gameParameters.gameSpeed.modifier
).toInt()
fun faithForNextGreatProphet(): Int {
var faithCost =
(200 + 100 * greatProphetsEarned * (greatProphetsEarned + 1) / 2f) *
civInfo.gameInfo.gameParameters.gameSpeed.modifier
for (unique in civInfo.getMatchingUniques("[]% Faith cost of generating Great Prophet equivalents"))
faithCost *= 1f + unique.params[0].toFloat() / 100f
return faithCost.toInt()
}
private fun canGenerateProphet(): Boolean {
if (religion == null || religionState == ReligionState.None) return false // First get a pantheon, then we'll talk about a real religion
@ -122,15 +131,25 @@ class ReligionManager {
greatProphetsEarned += 1
}
}
fun useGreatProphet(prophet: MapUnit) {
if (religionState <= ReligionState.Pantheon) {
if (!mayFoundReligionNow(prophet)) return // How did you do this?
religionState = ReligionState.FoundingReligion
foundingCityId = prophet.getTile().getCity()!!.id
} else if (religionState == ReligionState.Religion) {
if (!mayEnhanceReligionNow(prophet)) return
religionState = ReligionState.EnhancingReligion
}
}
fun mayFoundReligionAtAll(prophet: MapUnit): Boolean {
if (religion == null) return false // First found a pantheon
if (religion!!.isMajorReligion()) return false // Already created a major religion
if (religionState >= ReligionState.Religion) return false // Already created a major religion
if (prophet.abilityUsedCount.any { it.value != 0 }) return false // Already used its power for other things
if (!civInfo.isMajorCiv()) return false // Only major civs may use religion
val foundedReligionsCount = civInfo.gameInfo.civilizations.count {
it.religionManager.religion != null && it.religionManager.religion!!.isMajorReligion()
it.religionManager.religion != null && it.religionManager.religionState >= ReligionState.Religion
}
if (foundedReligionsCount >= civInfo.gameInfo.civilizations.count { it.isMajorCiv() } / 2 + 1)
@ -138,10 +157,13 @@ class ReligionManager {
if (foundedReligionsCount >= civInfo.gameInfo.ruleSet.religions.count())
return false // Mod maker did not provide enough religions for the amount of civs present
if (civInfo.gameInfo.ruleSet.beliefs.values.none {
it.type == BeliefType.Follower
&& civInfo.gameInfo.religions.values.none { religion -> it in religion.getBeliefs(BeliefType.Follower) }
}) return false // Mod maker did not provide enough follower beliefs
if (foundedReligionsCount >= civInfo.gameInfo.ruleSet.beliefs.values.count { it.type == BeliefType.Follower })
return false // Mod maker did not provide enough follower beliefs
// Shortcut as each religion will always have exactly one founder belief
if (foundedReligionsCount >= civInfo.gameInfo.ruleSet.beliefs.values.count { it.type == BeliefType.Founder })
return false // Mod maker did not provide enough founder beliefs
@ -153,21 +175,42 @@ class ReligionManager {
if (!prophet.getTile().isCityCenter()) return false
return true
}
fun useGreatProphet(prophet: MapUnit) {
if (!mayFoundReligionNow(prophet)) return // How did you do this?
religionState = ReligionState.FoundingReligion
foundingCityId = prophet.getTile().getCity()!!.id
fun getBeliefsToChooseAtFounding(): BeliefContainer {
if (religionState == ReligionState.None)
return BeliefContainer(pantheonBeliefCount = 1, founderBeliefCount = 1, followerBeliefCount = 1)
return BeliefContainer(founderBeliefCount = 1, followerBeliefCount = 1)
}
fun chooseBeliefs(iconName: String?, religionName: String?, beliefs: List<Belief>) {
if (religionState == ReligionState.FoundingReligion) {
foundReligion(iconName!!, religionName!!, beliefs)
return
}
if (religionState == ReligionState.EnhancingReligion)
enhanceReligion(beliefs)
}
fun foundReligion(iconName: String, name: String, founderBelief: List<String>, followerBeliefs: List<String>) {
fun foundReligion(iconName: String, name: String, beliefs: List<Belief>) {
val newReligion = Religion(name, civInfo.gameInfo, civInfo.civName)
newReligion.iconName = iconName
if (religion != null) {
newReligion.followerBeliefs.addAll(religion!!.followerBeliefs)
newReligion.founderBeliefs.addAll(religion!!.founderBeliefs)
}
newReligion.followerBeliefs.addAll(followerBeliefs)
newReligion.founderBeliefs.addAll(founderBelief)
newReligion.followerBeliefs.addAll(
beliefs
.filter { it.type == BeliefType.Pantheon || it.type == BeliefType.Follower }
.map { it.name }
)
newReligion.founderBeliefs.addAll(
beliefs
.filter { it.type == BeliefType.Founder }
.map { it.name }
)
religion = newReligion
civInfo.gameInfo.religions[name] = newReligion
@ -180,6 +223,41 @@ class ReligionManager {
foundingCityId = null
}
fun mayEnhanceReligionAtAll(prophet: MapUnit): Boolean {
if (religion == null) return false // First found a pantheon
if (religionState != ReligionState.Religion) return false // First found an actual religion
if (prophet.abilityUsedCount.any { it.value > 0 }) return false // Already used its ability for other things
if (!civInfo.isMajorCiv()) return false // Only major civs
if (civInfo.gameInfo.ruleSet.beliefs.values.none {
it.type == BeliefType.Follower
&& civInfo.gameInfo.religions.values.none { religion -> religion.getBeliefs(BeliefType.Follower).contains(it) }
}) return false // Mod maker did not provide enough follower beliefs
if (civInfo.gameInfo.ruleSet.beliefs.values.none {
it.type == BeliefType.Enhancer
&& civInfo.gameInfo.religions.values.none { religion -> religion.getBeliefs(BeliefType.Enhancer).contains(it) }
}) return false // Mod maker did not provide enough enhancer beliefs
return true
}
fun mayEnhanceReligionNow(prophet: MapUnit): Boolean {
if (!mayEnhanceReligionAtAll(prophet)) return false
if (!prophet.getTile().isCityCenter()) return false
return true
}
fun getBeliefsToChooseAtEnhancing(): BeliefContainer {
return BeliefContainer(followerBeliefCount = 1, enhancerBeliefCount = 1)
}
fun enhanceReligion(beliefs: List<Belief>) {
religion!!.followerBeliefs.addAll(beliefs.filter { it.type == BeliefType.Follower}.map { it.name })
religion!!.founderBeliefs.addAll(beliefs.filter { it.type == BeliefType.Enhancer}.map { it.name })
religionState = ReligionState.EnhancedReligion
}
fun numberOfCitiesFollowingThisReligion(): Int {
if (religion == null) return 0
return civInfo.gameInfo.getCities()

View File

@ -14,6 +14,7 @@ import com.unciv.models.ruleset.Unique
import com.unciv.models.ruleset.tile.TileImprovement
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.ruleset.unit.UnitType
import com.unciv.ui.utils.toPercent
import java.text.DecimalFormat
/**
@ -933,7 +934,9 @@ class MapUnit {
return when (filter) {
"Wounded", "wounded units" -> health < 100
"Barbarians", "Barbarian" -> civInfo.isBarbarian()
"City-State" -> civInfo.isCityState()
"Embarked" -> isEmbarked()
"Non-City" -> true
else -> {
if (baseUnit.matchesFilter(filter)) return true
if (hasUnique(filter)) return true
@ -963,7 +966,12 @@ class MapUnit {
}
fun getPressureAddedFromSpread(): Int {
return baseUnit.religiousStrength
var pressureAdded = baseUnit.religiousStrength.toFloat()
for (unique in civInfo.getMatchingUniques("[]% Spread Religion Strength for [] units"))
if (matchesFilter(unique.params[0]))
pressureAdded *= unique.params[0].toPercent()
return pressureAdded.toInt()
}
fun getActionString(action: String): String {

View File

@ -188,6 +188,11 @@ open class TileInfo {
else -> tileOwner.getDiplomacyManager(civInfo).isConsideredFriendlyTerritory()
}
}
fun isEnemyTerritory(civInfo: CivilizationInfo): Boolean {
val tileOwner = getOwner() ?: return false
return civInfo.isAtWarWith(tileOwner)
}
fun getTerrainFeatures(): List<Terrain> = terrainFeatures.mapNotNull { ruleset.terrains[it] }
fun getAllTerrains(): Sequence<Terrain> = sequence {
@ -458,6 +463,7 @@ open class TileInfo {
"Rough terrain" -> isRoughTerrain()
"Foreign Land", "Foreign" -> observingCiv != null && !isFriendlyTerritory(observingCiv)
"Friendly Land", "Friendly" -> observingCiv != null && isFriendlyTerritory(observingCiv)
"Enemy Land", "Enemy" -> observingCiv != null && isEnemyTerritory(observingCiv)
resource -> observingCiv != null && hasViewableResource(observingCiv)
"Water resource" -> isWater && observingCiv != null && hasViewableResource(observingCiv)
"Natural Wonder" -> naturalWonder != null

View File

@ -44,54 +44,41 @@ class Religion() : INamed {
else rulesetBeliefs[it]!!
}
}
fun getPantheonBeliefs(): Sequence<Belief> {
return mapToExistingBeliefs(followerBeliefs)
.asSequence()
.filter { it.type == BeliefType.Pantheon }
}
fun getFollowerBeliefs(): Sequence<Belief> {
return mapToExistingBeliefs(followerBeliefs)
.asSequence()
.filter { it.type == BeliefType.Follower }
}
fun getFounderBeliefs(): Sequence<Belief> {
return mapToExistingBeliefs(founderBeliefs)
.asSequence()
.filter { it.type == BeliefType.Founder }
}
private fun getUniquesOfBeliefs(beliefs: HashSet<String>): Sequence<Unique> {
fun getBeliefs(beliefType: BeliefType): Sequence<Belief> {
val beliefs =
when (beliefType) {
BeliefType.Pantheon -> followerBeliefs
BeliefType.Follower -> followerBeliefs
BeliefType.Founder -> founderBeliefs
BeliefType.Enhancer -> founderBeliefs
else -> null!! // This is fine...
}
return mapToExistingBeliefs(beliefs)
.flatMap { it.uniqueObjects }
.asSequence()
}
fun getFollowerUniques(): Sequence<Unique> {
return getUniquesOfBeliefs(followerBeliefs)
}
fun getFounderUniques(): Sequence<Unique> {
return getUniquesOfBeliefs(founderBeliefs)
}
fun isPantheon(): Boolean { // Currently unused
return hasPantheon() && !isMajorReligion()
}
fun isMajorReligion(): Boolean {
return founderBeliefs.isNotEmpty() && followerBeliefs
.any { gameInfo.ruleSet.beliefs[it]!!.type == BeliefType.Follower}
}
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 == BeliefType.Pantheon }
.filter { it.type == beliefType }
}
fun hasBelief(belief: String): Boolean {
return followerBeliefs.contains(belief) || founderBeliefs.contains(belief)
fun getAllBeliefsOrdered(): Sequence<Belief> {
return mapToExistingBeliefs(followerBeliefs).asSequence().filter { it.type == BeliefType.Pantheon } +
mapToExistingBeliefs(founderBeliefs).asSequence().filter { it.type == BeliefType.Founder } +
mapToExistingBeliefs(followerBeliefs).asSequence().filter { it.type == BeliefType.Follower } +
mapToExistingBeliefs(founderBeliefs).asSequence().filter { it.type == BeliefType.Enhancer }
}
private fun getUniquesOfBeliefs(beliefs: HashSet<String>) =
mapToExistingBeliefs(beliefs).asSequence().flatMap { it.uniqueObjects }
fun getFollowerUniques() = getUniquesOfBeliefs(followerBeliefs)
fun getFounderUniques() = getUniquesOfBeliefs(founderBeliefs)
fun hasBelief(belief: String) = followerBeliefs.contains(belief) || founderBeliefs.contains(belief)
fun isPantheon() = getBeliefs(BeliefType.Pantheon).any() && !isMajorReligion()
fun isMajorReligion() = getBeliefs(BeliefType.Founder).any()
fun isEnhancedReligion() = getBeliefs(BeliefType.Enhancer).any()
}

View File

@ -130,6 +130,8 @@ enum class UnitActionType(
null, 'g', UncivSound.Choir),
RemoveHeresy("Remove Heresy",
{ ImageGetter.getImage("OtherIcons/Remove Heresy") }, 'h', UncivSound.Fire),
EnhanceReligion("Enhance a Religion",
{ ImageGetter.getUnitIcon("Great Prophet") }, 'g', UncivSound.Choir),
DisbandUnit("Disband unit",
{ ImageGetter.getImage("OtherIcons/DisbandUnit") }, KeyCharAndCode.DEL),
GiftUnit("Gift unit",

View File

@ -74,5 +74,6 @@ enum class BeliefType(val color: String) {
None(""),
Pantheon("#44c6cc"),
Follower("#ccaa44"),
Founder("#c00000")
Founder("#c00000"),
Enhancer("#72cc45")
}

View File

@ -67,11 +67,7 @@ class ReligionOverviewTable(
statsTable.clear()
beliefsTable.clear()
topButtonLabel.setText(religion.name.tr())
for (belief in
religion.getPantheonBeliefs()
+ religion.getFollowerBeliefs()
+ religion.getFounderBeliefs()
) {
for (belief in religion.getAllBeliefsOrdered()) {
beliefsTable.add(createBeliefDescription(belief)).pad(10f).row()
}

View File

@ -1,6 +1,5 @@
package com.unciv.ui.pickerscreens
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.*
import com.badlogic.gdx.utils.Align
import com.unciv.UncivGame
@ -13,11 +12,11 @@ import com.unciv.models.ruleset.BeliefType
import com.unciv.models.translations.tr
import com.unciv.ui.utils.*
class FoundReligionPickerScreen (
class ReligiousBeliefsPickerScreen (
private val choosingCiv: CivilizationInfo,
private val gameInfo: GameInfo,
followerBeliefsToChoose: Int = 1,
founderBeliefsToChoose: Int = 1,
private val beliefsContainer: BeliefContainer,
private val pickIcon: Boolean
): PickerScreen(disableScroll = true) {
// Roughly follows the layout of the original (although I am not very good at UI designing, so please improve this)
@ -30,14 +29,13 @@ class FoundReligionPickerScreen (
private var previouslySelectedIcon: Button? = null
private var iconName: String? = null
private var religionName: String? = null
private val chosenFollowerBeliefs: MutableList<Belief?> = MutableList(followerBeliefsToChoose) { null }
private val chosenFounderBeliefs: MutableList<Belief?> = MutableList(founderBeliefsToChoose) { null }
init {
closeButton.isVisible = true
setDefaultCloseAction()
setupReligionIcons()
if (pickIcon) setupChoosableReligionIcons()
else setupVisibleReligionIcons()
updateLeftTable()
@ -51,22 +49,18 @@ class FoundReligionPickerScreen (
rightSideButton.label = "Choose a religion".toLabel()
rightSideButton.onClick(UncivSound.Choir) {
choosingCiv.religionManager.foundReligion(
iconName!!, religionName!!, chosenFounderBeliefs.map {it!!.name}, chosenFollowerBeliefs.map { it!!.name}
)
choosingCiv.religionManager.chooseBeliefs(iconName, religionName, beliefsContainer.chosenBeliefs.map { it!! })
UncivGame.Current.setWorldScreen()
}
}
private fun checkAndEnableRightSideButton() {
if (religionName == null) return
if (chosenFollowerBeliefs.any { it == null }) return
if (chosenFounderBeliefs.any { it == null }) return
// check if founder belief chosen
if (pickIcon && (religionName == null || iconName == null)) return
if (beliefsContainer.chosenBeliefs.any { it == null }) return
rightSideButton.enable()
}
private fun setupReligionIcons() {
private fun setupChoosableReligionIcons() {
topReligionIcons.clear()
// This should later be replaced with a user-modifiable text field, but not in this PR
@ -101,36 +95,36 @@ class FoundReligionPickerScreen (
topReligionIcons.add(descriptionLabel).center().padBottom(5f)
}
private fun setupVisibleReligionIcons() {
topReligionIcons.clear()
val descriptionLabel = choosingCiv.religionManager.religion!!.name.toLabel()
val iconsTable = Table()
for (religionName in gameInfo.ruleSet.religions) {
val button = Button(
ImageGetter.getCircledReligionIcon(religionName, 60f),
skin
)
button.disable()
iconsTable.add(button).pad(5f)
}
topReligionIcons.add(iconsTable).padBottom(10f).row()
topReligionIcons.add(descriptionLabel).center().padBottom(5f)
}
private fun updateLeftTable() {
leftChosenBeliefs.clear()
val currentReligion = choosingCiv.religionManager.religion ?: Religion("Unknown", gameInfo, choosingCiv.civName)
val currentReligion = choosingCiv.religionManager.religion ?: Religion("None", gameInfo, choosingCiv.civName)
for (pantheon in currentReligion.getPantheonBeliefs() + currentReligion.getFollowerBeliefs()) {
val beliefButton = convertBeliefToButton(pantheon)
for (belief in currentReligion.getAllBeliefsOrdered()) {
val beliefButton = convertBeliefToButton(belief)
leftChosenBeliefs.add(beliefButton).pad(10f).row()
beliefButton.disable()
}
for (newFollowerBelief in chosenFollowerBeliefs.withIndex()) {
val newFollowerBeliefButton =
if (newFollowerBelief.value == null) emptyBeliefButton(BeliefType.Follower)
else convertBeliefToButton(newFollowerBelief.value!!)
leftChosenBeliefs.add(newFollowerBeliefButton).pad(10f).row()
newFollowerBeliefButton.onClick {
loadRightTable(BeliefType.Follower, newFollowerBelief.index)
}
}
for (newFounderBelief in chosenFounderBeliefs.withIndex()) {
val newFounderBeliefButton =
if (newFounderBelief.value == null) emptyBeliefButton(BeliefType.Founder)
else convertBeliefToButton(newFounderBelief.value!!)
leftChosenBeliefs.add(newFounderBeliefButton).pad(10f).row()
newFounderBeliefButton.onClick {
loadRightTable(BeliefType.Founder, newFounderBelief.index)
}
for (newBelief in beliefsContainer.chosenBeliefs.withIndex()) {
addChoosableBeliefButton(newBelief, beliefsContainer.getBeliefTypeFromIndex(newBelief.index))
}
}
@ -142,13 +136,12 @@ class FoundReligionPickerScreen (
&& gameInfo.religions.values.none {
religion -> religion.hasBelief(it.name)
}
&& (!chosenFollowerBeliefs.contains(it) || chosenFollowerBeliefs[leftButtonIndex] == it)
&& (it !in beliefsContainer.chosenBeliefs)
}
for (belief in availableBeliefs) {
val beliefButton = convertBeliefToButton(belief)
beliefButton.onClick {
if (beliefType == BeliefType.Follower) chosenFollowerBeliefs[leftButtonIndex] = belief
else if (beliefType == BeliefType.Founder) chosenFounderBeliefs[leftButtonIndex] = belief
beliefsContainer.chosenBeliefs[leftButtonIndex] = belief
updateLeftTable()
checkAndEnableRightSideButton()
}
@ -156,6 +149,17 @@ class FoundReligionPickerScreen (
}
}
private fun addChoosableBeliefButton(belief: IndexedValue<Belief?>, beliefType: BeliefType) {
val newBeliefButton =
if (belief.value == null) emptyBeliefButton(beliefType)
else convertBeliefToButton(belief.value!!)
leftChosenBeliefs.add(newBeliefButton).pad(10f).row()
newBeliefButton.onClick {
loadRightTable(beliefType, belief.index)
}
}
private fun convertBeliefToButton(belief: Belief): Button {
val contentsTable = Table()
contentsTable.add(belief.type.name.toLabel()).row()
@ -170,3 +174,18 @@ class FoundReligionPickerScreen (
return Button(contentsTable, skin)
}
}
data class BeliefContainer(val pantheonBeliefCount: Int = 0, val founderBeliefCount: Int = 0, val followerBeliefCount: Int = 0, val enhancerBeliefCount: Int = 0) {
val chosenBeliefs: MutableList<Belief?> = MutableList(pantheonBeliefCount + founderBeliefCount + followerBeliefCount + enhancerBeliefCount) { null }
fun getBeliefTypeFromIndex(index: Int): BeliefType {
return when {
index < pantheonBeliefCount -> BeliefType.Pantheon
index < pantheonBeliefCount + founderBeliefCount -> BeliefType.Founder
index < pantheonBeliefCount + founderBeliefCount + followerBeliefCount -> BeliefType.Follower
else -> BeliefType.Enhancer
}
}
}

View File

@ -13,7 +13,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Button
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.utils.Align
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.GameInfo
import com.unciv.logic.GameSaver
@ -718,8 +717,24 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Cam
viewingCiv.religionManager.religionState == ReligionState.FoundingReligion ->
NextTurnAction("Found Religion", Color.WHITE) {
game.setScreen(FoundReligionPickerScreen(viewingCiv, gameInfo))
game.setScreen(ReligiousBeliefsPickerScreen(
viewingCiv,
gameInfo,
viewingCiv.religionManager.getBeliefsToChooseAtFounding(),
pickIcon = true
))
}
viewingCiv.religionManager.religionState == ReligionState.EnhancingReligion ->
NextTurnAction("Enhance Religion", Color.ORANGE) {
game.setScreen(ReligiousBeliefsPickerScreen(
viewingCiv,
gameInfo,
viewingCiv.religionManager.getBeliefsToChooseAtEnhancing(),
pickIcon = false
))
}
viewingCiv.mayVoteForDiplomaticVictory() ->
NextTurnAction("Vote for World Leader", Color.RED) {
game.setScreen(DiplomaticVotePickerScreen(viewingCiv))

View File

@ -17,6 +17,7 @@ import com.unciv.models.UnitAction
import com.unciv.models.UnitActionType
import com.unciv.models.ruleset.Building
import com.unciv.models.stats.Stat
import com.unciv.models.stats.Stats
import com.unciv.models.translations.tr
import com.unciv.ui.pickerscreens.ImprovementPickerScreen
import com.unciv.ui.pickerscreens.PromotionPickerScreen
@ -55,7 +56,8 @@ object UnitActions {
addBuildingImprovementsAction(unit, actionList, tile, worldScreen, unitTable)
addCreateWaterImprovements(unit, actionList)
addGreatPersonActions(unit, actionList, tile)
addFoundReligionAction(unit, actionList, tile)
addFoundReligionAction(unit, actionList)
addEnhanceReligionAction(unit, actionList)
actionList += getImprovementConstructionActions(unit, tile)
addActionsWithLimitedUses(unit, actionList, tile)
@ -394,7 +396,7 @@ object UnitActions {
actionList += UnitAction(UnitActionType.HurryResearch,
action = {
unit.civInfo.tech.addScience(unit.civInfo.tech.getScienceFromGreatScientist())
addGoldPerGreatPersonUsage(unit.civInfo)
addStatsPerGreatPersonUsage(unit)
unit.destroy()
}.takeIf { unit.civInfo.tech.currentTechnologyName() != null }
)
@ -404,7 +406,7 @@ object UnitActions {
actionList += UnitAction(UnitActionType.StartGoldenAge,
action = {
unit.civInfo.goldenAges.enterGoldenAge(turnsToGoldenAge)
addGoldPerGreatPersonUsage(unit.civInfo)
addStatsPerGreatPersonUsage(unit)
unit.destroy()
}.takeIf { unit.currentTile.getOwner() != null && unit.currentTile.getOwner() == unit.civInfo }
)
@ -422,8 +424,8 @@ object UnitActions {
addProductionPoints(((300 + 30 * tile.getCity()!!.population.population) * unit.civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt())
constructIfEnough()
}
addGoldPerGreatPersonUsage(unit.civInfo)
addStatsPerGreatPersonUsage(unit)
unit.destroy()
}.takeIf { canHurryWonder }
)
@ -453,7 +455,7 @@ object UnitActions {
constructIfEnough()
}
addGoldPerGreatPersonUsage(unit.civInfo)
addStatsPerGreatPersonUsage(unit)
unit.destroy()
}.takeIf { canHurryConstruction }
)
@ -472,7 +474,7 @@ object UnitActions {
tile.owningCity!!.civInfo.getDiplomacyManager(unit.civInfo).influence += influenceEarned
unit.civInfo.addNotification("Your trade mission to [${tile.owningCity!!.civInfo}] has earned you [${goldEarned}] gold and [$influenceEarned] influence!",
tile.owningCity!!.civInfo.civName, NotificationIcon.Gold, NotificationIcon.Culture)
addGoldPerGreatPersonUsage(unit.civInfo)
addStatsPerGreatPersonUsage(unit)
unit.destroy()
}.takeIf { canConductTradeMission }
)
@ -480,18 +482,31 @@ object UnitActions {
}
}
private fun addFoundReligionAction(unit: MapUnit, actionList: ArrayList<UnitAction>, tile: TileInfo) {
if (!unit.hasUnique("May found a religion")) return // should later also include enhance religion
private fun addFoundReligionAction(unit: MapUnit, actionList: ArrayList<UnitAction>) {
if (!unit.hasUnique("May found a religion")) return
if (!unit.civInfo.religionManager.mayFoundReligionAtAll(unit)) return
actionList += UnitAction(UnitActionType.FoundReligion,
action = {
addGoldPerGreatPersonUsage(unit.civInfo)
addStatsPerGreatPersonUsage(unit)
unit.civInfo.religionManager.useGreatProphet(unit)
unit.destroy()
}.takeIf { unit.civInfo.religionManager.mayFoundReligionNow(unit) }
)
}
private fun addEnhanceReligionAction(unit: MapUnit, actionList: ArrayList<UnitAction>) {
if (!unit.hasUnique("May enhance a religion")) return
if (!unit.civInfo.religionManager.mayEnhanceReligionAtAll(unit)) return
actionList += UnitAction(UnitActionType.EnhanceReligion,
title = "Enhance [${unit.civInfo.religionManager.religion!!.name}]",
action = {
addStatsPerGreatPersonUsage(unit)
unit.civInfo.religionManager.useGreatProphet(unit)
unit.destroy()
}.takeIf { unit.civInfo.religionManager.mayEnhanceReligionNow(unit) }
)
}
private fun addActionsWithLimitedUses(unit: MapUnit, actionList: ArrayList<UnitAction>, tile: TileInfo) {
val actionsToAdd = unit.religiousActionsUnitCanDo()
if (actionsToAdd.none()) return
@ -512,7 +527,7 @@ object UnitActions {
unit.abilityUsedCount[action] = unit.abilityUsedCount[action]!! + 1
if (unit.abilityUsedCount[action] == maximumUses) {
if (unit.isGreatPerson())
addGoldPerGreatPersonUsage(unit.civInfo)
addStatsPerGreatPersonUsage(unit)
unit.destroy()
}
}
@ -581,8 +596,7 @@ object UnitActions {
city.cityStats.update()
city.civInfo.updateDetailedCivResources()
}
if (unit.hasUnique("Great Person - []"))
addGoldPerGreatPersonUsage(unit.civInfo)
addStatsPerGreatPersonUsage(unit)
unit.destroy()
}.takeIf {
unit.currentMovement > 0f && tile.canBuildImprovement(improvement, unit.civInfo)
@ -636,15 +650,24 @@ object UnitActions {
otherCiv.addNotification("[${unit.civInfo}] has stolen your territory!", unit.currentTile.position, unit.civInfo.civName, NotificationIcon.War)
}
private fun addGoldPerGreatPersonUsage(civInfo: CivilizationInfo) {
val uniqueText = "Provides a sum of gold each time you spend a Great Person"
val cityWithMausoleum = civInfo.cities.firstOrNull { it.containsBuildingUnique(uniqueText) }
?: return
val goldEarned = (100 * civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt()
civInfo.addGold(goldEarned)
val mausoleum = cityWithMausoleum.cityConstructions.getBuiltBuildings().first { it.uniques.contains(uniqueText) }
civInfo.addNotification("[${mausoleum.name}] has provided [$goldEarned] Gold!", cityWithMausoleum.location, NotificationIcon.Gold)
private fun addStatsPerGreatPersonUsage(unit: MapUnit) {
if (!unit.isGreatPerson()) return
val civInfo = unit.civInfo
val gainedStats = Stats()
for (unique in civInfo.getMatchingUniques("Provides a sum of gold each time you spend a Great Person")) {
gainedStats.gold += (100 * civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt()
}
for (unique in civInfo.getMatchingUniques("[] whenever a Great Person is expended")) {
gainedStats.add(unique.stats)
}
if (gainedStats.isEmpty()) return
for (stat in gainedStats)
civInfo.addStat(stat.key, stat.value.toInt())
civInfo.addNotification("By expending your [${unit.name}] you gained [${gainedStats}]!", unit.getTile().position, unit.name)
}
private fun addFortifyActions(actionList: ArrayList<UnitAction>, unit: MapUnit, showingAdditionalActions: Boolean) {