From 28f65a7599eb4a4cecf64e371e0a0fd40dc2268c Mon Sep 17 00:00:00 2001 From: OptimizedForDensity <105244635+OptimizedForDensity@users.noreply.github.com> Date: Fri, 12 Aug 2022 07:24:42 -0400 Subject: [PATCH] Add free belief unique + refactor a few religion functions (#7612) * Free belief unique * Fix edge case * Another edge case * Bug fixes * Fix some conditions * Refactor another function * Handle edge case where the civ has enough faith for a pantheon but also gets a free pantheon pick on the same turn (allow civ to have both picks) * Fix the edge case handling * Cleanup * Reviews + more refactoring and cleanup * Update comments * Unnecessary comment * Improvements * Typo --- .../jsons/translations/template.properties | 2 + .../civilization/NextTurnAutomation.kt | 23 +- .../civilization/ReligionAutomation.kt | 6 +- .../logic/civilization/ReligionManager.kt | 224 +++++++++++------- .../ruleset/unique/UniqueTriggerActivation.kt | 19 +- .../unciv/models/ruleset/unique/UniqueType.kt | 1 + .../ui/pickerscreens/PantheonPickerScreen.kt | 4 +- .../ReligiousBeliefsPickerScreen.kt | 6 +- .../com/unciv/ui/worldscreen/WorldScreen.kt | 24 +- 9 files changed, 205 insertions(+), 104 deletions(-) diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index c882205a32..c67ba68fa4 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -1416,6 +1416,8 @@ Choose a pantheon = Choose a Religion = Found Religion = Found Pantheon = +Reform Religion = +Expand Pantheon = Follow [belief] = Religions and Beliefs = Majority Religion: [name] = diff --git a/core/src/com/unciv/logic/automation/civilization/NextTurnAutomation.kt b/core/src/com/unciv/logic/automation/civilization/NextTurnAutomation.kt index 3b70893d7f..6b7f93d436 100644 --- a/core/src/com/unciv/logic/automation/civilization/NextTurnAutomation.kt +++ b/core/src/com/unciv/logic/automation/civilization/NextTurnAutomation.kt @@ -535,10 +535,11 @@ object NextTurnAutomation { choosePantheon(civInfo) foundReligion(civInfo) enhanceReligion(civInfo) + chooseFreeBeliefs(civInfo) } private fun choosePantheon(civInfo: CivilizationInfo) { - if (!civInfo.religionManager.canFoundPantheon()) return + if (!civInfo.religionManager.canFoundOrExpandPantheon()) return // So looking through the source code of the base game available online, // the functions for choosing beliefs total in at around 400 lines. // https://github.com/Gedemon/Civ5-DLL/blob/aa29e80751f541ae04858b6d2a2c7dcca454201e/CvGameCoreDLL_Expansion1/CvReligionClasses.cpp @@ -547,7 +548,10 @@ object NextTurnAutomation { // Should probably be changed later, but it works for now. val chosenPantheon = chooseBeliefOfType(civInfo, BeliefType.Pantheon) ?: return // panic! - civInfo.religionManager.choosePantheonBelief(chosenPantheon) + civInfo.religionManager.chooseBeliefs( + listOf(chosenPantheon), + useFreeBeliefs = civInfo.religionManager.usingFreeBeliefs() + ) } private fun foundReligion(civInfo: CivilizationInfo) { @@ -559,18 +563,24 @@ object NextTurnAutomation { else availableReligionIcons.randomOrNull() ?: return // Wait what? How did we pass the checking when using a great prophet but not this? val chosenBeliefs = chooseBeliefs(civInfo, civInfo.religionManager.getBeliefsToChooseAtFounding()).toList() - civInfo.religionManager.chooseBeliefs(religionIcon, religionIcon, chosenBeliefs) + civInfo.religionManager.chooseBeliefs(chosenBeliefs, religionIcon, religionIcon) } private fun enhanceReligion(civInfo: CivilizationInfo) { if (civInfo.religionManager.religionState != ReligionState.EnhancingReligion) return civInfo.religionManager.chooseBeliefs( - null, - null, chooseBeliefs(civInfo, civInfo.religionManager.getBeliefsToChooseAtEnhancing()).toList() ) } + private fun chooseFreeBeliefs(civInfo: CivilizationInfo) { + if (!civInfo.religionManager.hasFreeBeliefs()) return + civInfo.religionManager.chooseBeliefs( + chooseBeliefs(civInfo, civInfo.religionManager.freeBeliefsAsEnums()).toList(), + useFreeBeliefs = true + ) + } + private fun chooseBeliefs(civInfo: CivilizationInfo, beliefsToChoose: Counter): HashSet { val chosenBeliefs = hashSetOf() // The `continue`s should never be reached, but just in case I'd rather have the AI have a @@ -592,8 +602,7 @@ object NextTurnAutomation { .filter { (it.value.type == beliefType || beliefType == BeliefType.Any) && !additionalBeliefsToExclude.contains(it.value) - && !civInfo.gameInfo.religions.values - .flatMap { religion -> religion.getBeliefs(beliefType) }.contains(it.value) + && civInfo.religionManager.getReligionWithBelief(it.value) == null } .map { it.value } .maxByOrNull { ReligionAutomation.rateBelief(civInfo, it) } diff --git a/core/src/com/unciv/logic/automation/civilization/ReligionAutomation.kt b/core/src/com/unciv/logic/automation/civilization/ReligionAutomation.kt index c3f026358b..838bbd6669 100644 --- a/core/src/com/unciv/logic/automation/civilization/ReligionAutomation.kt +++ b/core/src/com/unciv/logic/automation/civilization/ReligionAutomation.kt @@ -163,7 +163,7 @@ object ReligionAutomation { it.getMapUnit(civInfo).canDoReligiousAction(Constants.removeHeresy) || it.hasUnique(UniqueType.PreventSpreadingReligion) } - + inquisitors = inquisitors.map { civInfo.getEquivalentUnit(it) } val inquisitorConstruction = inquisitors @@ -173,8 +173,8 @@ object ReligionAutomation { // And from that list determine the cheapest price .minByOrNull { it.value.minOf { city -> it.key.getStatBuyCost(city, Stat.Faith)!! }}?.key ?: return - - + + val hasUniqueToTakeCivReligion = civInfo.gameInfo.ruleSet.units[inquisitorConstruction.name]!!.hasUnique(UniqueType.TakeReligionOverBirthCity) val validCitiesToBuy = civInfo.cities.filter { diff --git a/core/src/com/unciv/logic/civilization/ReligionManager.kt b/core/src/com/unciv/logic/civilization/ReligionManager.kt index bf48f7f36e..5271bc94ef 100644 --- a/core/src/com/unciv/logic/civilization/ReligionManager.kt +++ b/core/src/com/unciv/logic/civilization/ReligionManager.kt @@ -10,6 +10,7 @@ import com.unciv.models.ruleset.Belief import com.unciv.models.ruleset.BeliefType import com.unciv.models.ruleset.unique.UniqueType import com.unciv.ui.utils.extensions.toPercent +import java.lang.Integer.max import java.lang.Integer.min import kotlin.random.Random @@ -35,6 +36,10 @@ class ReligionManager : IsPartOfGameInfoSerialization { var religionState = ReligionState.None private set + // Counter containing the number of free beliefs types that this civ can add to its religion this turn + // Uses String instead of BeliefType enum for serialization reasons + var freeBeliefs: Counter = Counter() + // These cannot be transient, as saving and loading after using a great prophet but before // founding a religion would break :( private var foundingCityId: String? = null @@ -49,6 +54,7 @@ class ReligionManager : IsPartOfGameInfoSerialization { clone.shouldChoosePantheonBelief = shouldChoosePantheonBelief clone.storedFaith = storedFaith clone.religionState = religionState + clone.freeBeliefs.putAll(freeBeliefs) return clone } @@ -77,34 +83,52 @@ class ReligionManager : IsPartOfGameInfoSerialization { return civInfo.cities.count { it.religion.getMajorityReligion() == religion } > civInfo.cities.size / 2 } + /** + * This helper function makes it easy to interface the Counter [freeBeliefs] with functions + * that use Counter + */ + fun freeBeliefsAsEnums(): Counter { + val toReturn = Counter() + for (entry in freeBeliefs.entries) { + toReturn.add(BeliefType.valueOf(entry.key), entry.value) + } + return toReturn + } + + fun hasFreeBeliefs(): Boolean = freeBeliefs.sumValues() > 0 + + fun usingFreeBeliefs(): Boolean + = (religionState == ReligionState.None && storedFaith < faithForPantheon()) // first pantheon is free + || religionState == ReligionState.Pantheon // any subsequent pantheons before founding a religion + || (religionState == ReligionState.Religion || religionState == ReligionState.EnhancedReligion) // any belief adding outside of great prophet use + fun faithForPantheon(additionalCivs: Int = 0) = 10 + (civInfo.gameInfo.civilizations.count { it.isMajorCiv() && it.religionManager.religion != null } + additionalCivs) * 5 - fun canFoundPantheon(): Boolean { + /** Used for founding the pantheon and for each time the player gets additional pantheon beliefs + * before forming a religion */ + fun canFoundOrExpandPantheon(): Boolean { if (!civInfo.gameInfo.isReligionEnabled()) return false - if (religionState != ReligionState.None) return false + if (religionState > ReligionState.Pantheon) return false if (!civInfo.isMajorCiv()) return false - if (civInfo.gameInfo.ruleSet.beliefs.values.none { isPickablePantheonBelief(it) }) - return false + if (numberOfBeliefsAvailable(BeliefType.Pantheon) == 0) + return false // no more available pantheons if (civInfo.gameInfo.civilizations.any { it.religionManager.religionState == ReligionState.EnhancedReligion }) return false - return storedFaith >= faithForPantheon() + return (religionState == ReligionState.None && storedFaith >= faithForPantheon()) // earned pantheon + || (freeBeliefs[BeliefType.Pantheon.name] != null && freeBeliefs[BeliefType.Pantheon.name]!! > 0) // free pantheon belief } - fun isPickablePantheonBelief(belief: Belief): Boolean { - if (belief.type != BeliefType.Pantheon) return false - return (civInfo.gameInfo.civilizations.none { it.religionManager.religion?.followerBeliefs?.contains(belief.name) == true }) - } - - fun choosePantheonBelief(belief: Belief) { - storedFaith -= faithForPantheon() - religion = Religion(belief.name, civInfo.gameInfo, civInfo.civName) - religion!!.followerBeliefs.add(belief.name) - civInfo.gameInfo.religions[belief.name] = religion!! + private fun foundPantheon(beliefName: String, useFreeBelief: Boolean) { + if (!useFreeBelief) { + // paid for the initial pantheon using faith + storedFaith -= faithForPantheon() + } + religion = Religion(beliefName, civInfo.gameInfo, civInfo.civName) + civInfo.gameInfo.religions[beliefName] = religion!! for (city in civInfo.cities) - city.religion.addPressure(belief.name, 200 * city.population.population) + city.religion.addPressure(beliefName, 200 * city.population.population) religionState = ReligionState.Pantheon - civInfo.updateStatsForNextTurn() // a belief can have an immediate effect on stats } // https://www.reddit.com/r/civ/comments/2m82wu/can_anyone_detail_the_finer_points_of_great/ @@ -154,28 +178,35 @@ class ReligionManager : IsPartOfGameInfoSerialization { /** Calculates the amount of religions that can still be founded */ fun remainingFoundableReligions(): Int { - val foundedReligionsCount = civInfo.gameInfo.civilizations.count { + val gameInfo = civInfo.gameInfo + val foundedReligionsCount = gameInfo.civilizations.count { it.religionManager.religion != null && it.religionManager.religionState >= ReligionState.Religion } // count the number of foundable religions left given defined ruleset religions and number of civs in game - val maxNumberOfAdditionalReligions = min(civInfo.gameInfo.ruleSet.religions.size, - civInfo.gameInfo.civilizations.count { it.isMajorCiv() } / 2 + 1) - foundedReligionsCount + val maxNumberOfAdditionalReligions = min(gameInfo.ruleSet.religions.size, + gameInfo.civilizations.count { it.isMajorCiv() } / 2 + 1) - foundedReligionsCount val availableBeliefsToFound = min( - civInfo.gameInfo.ruleSet.beliefs.values.count { - it.type == BeliefType.Follower - && civInfo.gameInfo.religions.values.none { religion -> it in religion.getBeliefs(BeliefType.Follower) } - }, - civInfo.gameInfo.ruleSet.beliefs.values.count { - it.type == BeliefType.Founder - && civInfo.gameInfo.religions.values.none { religion -> it in religion.getBeliefs(BeliefType.Founder) } - } + numberOfBeliefsAvailable(BeliefType.Follower), + numberOfBeliefsAvailable(BeliefType.Founder) ) return min(maxNumberOfAdditionalReligions, availableBeliefsToFound) } + fun numberOfBeliefsAvailable(type: BeliefType): Int { + val gameInfo = civInfo.gameInfo + val numberOfBeliefs = if (type == BeliefType.Any) gameInfo.ruleSet.beliefs.values.count() + else gameInfo.ruleSet.beliefs.values.count { it.type == type } + return numberOfBeliefs - gameInfo.religions.flatMap { it.value.getBeliefs(type) }.count() + } + + fun getReligionWithBelief(belief: Belief): Religion? { + return civInfo.gameInfo.religions.values.firstOrNull { it.hasBelief(belief.name) } + } + + fun mayFoundReligionAtAll(prophet: MapUnit): Boolean { if (!civInfo.gameInfo.isReligionEnabled()) return false // No religion @@ -207,38 +238,99 @@ class ReligionManager : IsPartOfGameInfoSerialization { civInfo.religionManager.foundingCityId = prophet.getTile().getCity()!!.id } - fun getBeliefsToChooseAtFounding(): Counter { + /** + * Unifies the selection of what beliefs are available for when a great prophet is expended. Also + * accounts for the number of remaining beliefs of each type so that the player is not given a + * larger number of beliefs to select than there are available for selection ([mayFoundReligionAtAll] + * and [mayEnhanceReligionAtAll] only check if there is 1 founder/enhancer and 1 follower belief + * available but the civ may be given more beliefs through uniques or a missing pantheon belief) + */ + private fun getBeliefsToChooseAtProphetUse(enhancingReligion: Boolean): Counter { + val action = if (enhancingReligion) "enhancing" else "founding" val beliefsToChoose: Counter = Counter() - beliefsToChoose.add(BeliefType.Founder, 1) - beliefsToChoose.add(BeliefType.Follower, 1) - if (shouldChoosePantheonBelief) - beliefsToChoose.add(BeliefType.Pantheon, 1) + + // Counter of the number of available beliefs of each type + val availableBeliefs = Counter() + for (type in BeliefType.values()) { + if (type == BeliefType.None) continue + availableBeliefs[type] = numberOfBeliefsAvailable(type) + } + + // function to help with bookkeeping + fun chooseBeliefToAdd(type: BeliefType, number: Int) { + val numberToAdd = min(number, availableBeliefs[type]!!) + beliefsToChoose.add(type, numberToAdd) + availableBeliefs[type] = availableBeliefs[type]!! - numberToAdd + if (type != BeliefType.Any) { + // deduct from BeliefType.Any as well + availableBeliefs[BeliefType.Any] = availableBeliefs[BeliefType.Any]!! - numberToAdd + } + } + + if (enhancingReligion) { + chooseBeliefToAdd(BeliefType.Enhancer, 1) + } else { + chooseBeliefToAdd(BeliefType.Founder, 1) + if (shouldChoosePantheonBelief) + chooseBeliefToAdd(BeliefType.Pantheon, 1) + } + chooseBeliefToAdd(BeliefType.Follower, 1) for (unique in civInfo.getMatchingUniques(UniqueType.FreeExtraBeliefs)) { - if (unique.params[2] != "founding") continue - beliefsToChoose.add(BeliefType.valueOf(unique.params[1]), unique.params[0].toInt()) + if (unique.params[2] != action) continue + val type = BeliefType.valueOf(unique.params[1]) + chooseBeliefToAdd(type, unique.params[0].toInt()) } for (unique in civInfo.getMatchingUniques(UniqueType.FreeExtraAnyBeliefs)) { - if (unique.params[1] != "founding") continue - beliefsToChoose.add(BeliefType.Any, unique.params[0].toInt()) + if (unique.params[1] != action) continue + chooseBeliefToAdd(BeliefType.Any, unique.params[0].toInt()) } return beliefsToChoose } - fun chooseBeliefs(iconName: String?, religionName: String?, beliefs: List) { - when(religionState) { + fun getBeliefsToChooseAtFounding(): Counter = getBeliefsToChooseAtProphetUse(false) + fun getBeliefsToChooseAtEnhancing(): Counter = getBeliefsToChooseAtProphetUse(true) + + fun chooseBeliefs(beliefs: List, iconName: String? = null, religionName: String? = null, useFreeBeliefs: Boolean = false) { + when (religionState) { ReligionState.FoundingReligion -> - foundReligion(iconName!!, religionName!!, beliefs) + foundReligion(iconName!!, religionName!!) ReligionState.EnhancingReligion -> - enhanceReligion(beliefs) - else -> return + religionState = ReligionState.EnhancedReligion + ReligionState.None -> { + foundPantheon(beliefs[0].name, useFreeBeliefs) + } + else -> {} + } + // add beliefs (religion exists at this point) + religion!!.followerBeliefs.addAll( + beliefs + .filter { it.type == BeliefType.Pantheon || it.type == BeliefType.Follower } + .map { it.name } + ) + religion!!.founderBeliefs.addAll( + beliefs + .filter { it.type == BeliefType.Founder || it.type == BeliefType.Enhancer } + .map { it.name } + ) + // decrement free beliefs if used + if (useFreeBeliefs && hasFreeBeliefs()) { + for (belief in beliefs) { + if (freeBeliefs[belief.type.name] == null) continue + freeBeliefs[belief.type.name] = max(freeBeliefs[belief.type.name]!! - 1, 0) + } + } + // limit the number of free beliefs available to number of remaining beliefs even if player + // didn't use free beliefs (e.g., used a prophet or pantheon) + for (type in freeBeliefs.keys) { + freeBeliefs[type] = min(freeBeliefs[type]!!, numberOfBeliefsAvailable(BeliefType.valueOf(type))) } civInfo.updateStatsForNextTurn() // a belief can have an immediate effect on stats } - fun foundReligion(displayName: String, name: String, beliefs: List) { + private fun foundReligion(displayName: String, name: String) { val newReligion = Religion(name, civInfo.gameInfo, civInfo.civName) newReligion.displayName = displayName if (religion != null) { @@ -246,17 +338,6 @@ class ReligionManager : IsPartOfGameInfoSerialization { newReligion.founderBeliefs.addAll(religion!!.founderBeliefs) } - 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 || it.type == BeliefType.Enhancer } - .map { it.name } - ) - religion = newReligion civInfo.gameInfo.religions[name] = newReligion @@ -282,15 +363,11 @@ class ReligionManager : IsPartOfGameInfoSerialization { if (prophet.abilityUsesLeft.any { it.value != prophet.maxAbilityUses[it.key] }) return false 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 (numberOfBeliefsAvailable(BeliefType.Follower) == 0) + 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 + if (numberOfBeliefsAvailable(BeliefType.Enhancer) == 0) + return false // Mod maker did not provide enough enhancer beliefs return true } @@ -306,29 +383,6 @@ class ReligionManager : IsPartOfGameInfoSerialization { religionState = ReligionState.EnhancingReligion } - fun getBeliefsToChooseAtEnhancing(): Counter { - val beliefsToChoose: Counter = Counter() - beliefsToChoose.add(BeliefType.Follower, 1) - beliefsToChoose.add(BeliefType.Enhancer, 1) - - for (unique in civInfo.getMatchingUniques(UniqueType.FreeExtraBeliefs)) { - if (unique.params[2] != "enhancing") continue - beliefsToChoose.add(BeliefType.valueOf(unique.params[1]), unique.params[0].toInt()) - } - for (unique in civInfo.getMatchingUniques(UniqueType.FreeExtraAnyBeliefs)) { - if (unique.params[1] != "enhancing") continue - beliefsToChoose.add(BeliefType.Any, unique.params[0].toInt()) - } - - return beliefsToChoose - } - - fun enhanceReligion(beliefs: List) { - religion!!.followerBeliefs.addAll(beliefs.filter { it.type == BeliefType.Follower || it.type == BeliefType.Pantheon }.map { it.name }) - religion!!.founderBeliefs.addAll(beliefs.filter { it.type == BeliefType.Enhancer || it.type == BeliefType.Founder }.map { it.name }) - religionState = ReligionState.EnhancedReligion - } - fun maySpreadReligionAtAll(missionary: MapUnit): Boolean { if (!civInfo.gameInfo.isReligionEnabled()) return false // No religion, no spreading if (religion == null) return false // Need a religion diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt b/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt index 63676b6277..f7df6327ca 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt @@ -6,6 +6,7 @@ import com.unciv.logic.city.CityInfo import com.unciv.logic.civilization.* import com.unciv.logic.map.MapUnit import com.unciv.logic.map.TileInfo +import com.unciv.models.ruleset.BeliefType import com.unciv.models.ruleset.Victory import com.unciv.models.ruleset.unique.UniqueType.* import com.unciv.models.stats.Stat @@ -84,7 +85,7 @@ object UniqueTriggerActivation { .any { it.params[0] == "Land" }} ?: return false unit = civInfo.getEquivalentUnit(replacementUnit.name) } - + val placingTile = tile ?: civInfo.cities.random().getCenterTile() @@ -389,6 +390,22 @@ object UniqueTriggerActivation { return true } + OneTimeFreeBelief -> { + if (!civInfo.isMajorCiv()) return false + val beliefType = BeliefType.valueOf(unique.params[0]) + val religionManager = civInfo.religionManager + if ((beliefType != BeliefType.Pantheon && beliefType != BeliefType.Any) + && religionManager.religionState <= ReligionState.Pantheon) + return false // situation where we're trying to add a formal religion belief to a civ that hasn't founded a religion + if (religionManager.numberOfBeliefsAvailable(beliefType) == 0) + return false // no more available beliefs of this type + + if (beliefType == BeliefType.Any && religionManager.religionState <= ReligionState.Pantheon) + religionManager.freeBeliefs.add(BeliefType.Pantheon.name, 1) // add pantheon instead of any type + else + religionManager.freeBeliefs.add(beliefType.name, 1) + return true + } OneTimeRevealSpecificMapTiles -> { if (tile == null) return false diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index c51882114e..52086f762c 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -678,6 +678,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: OneTimeGainStat("Gain [amount] [stat]", UniqueTarget.Ruins), OneTimeGainStatRange("Gain [amount]-[amount] [stat]", UniqueTarget.Ruins), OneTimeGainPantheon("Gain enough Faith for a Pantheon", UniqueTarget.Ruins), + OneTimeFreeBelief("Gain a free [beliefType] belief", UniqueTarget.Triggerable), OneTimeGainProphet("Gain enough Faith for [amount]% of a Great Prophet", UniqueTarget.Ruins), // todo: The "up to [All]" used in vanilla json is not nice to read. Split? // Or just reword it without the 'up to', so it reads "Reveal [amount/'all'] [tileFilter] tiles within [amount] tiles" diff --git a/core/src/com/unciv/ui/pickerscreens/PantheonPickerScreen.kt b/core/src/com/unciv/ui/pickerscreens/PantheonPickerScreen.kt index 2c76cf5e12..54bc395458 100644 --- a/core/src/com/unciv/ui/pickerscreens/PantheonPickerScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/PantheonPickerScreen.kt @@ -17,7 +17,7 @@ class PantheonPickerScreen( for (belief in ruleset.beliefs.values) { if (belief.type != BeliefType.Pantheon) continue val beliefButton = getBeliefButton(belief, withTypeLabel = false) - if (choosingCiv.religionManager.isPickablePantheonBelief(belief)) { + if (choosingCiv.religionManager.getReligionWithBelief(belief) == null) { beliefButton.onClickSelect(selection, belief) { selectedPantheon = belief pick("Follow [${belief.name}]".tr()) @@ -29,7 +29,7 @@ class PantheonPickerScreen( } setOKAction("Choose a pantheon") { - choosePantheonBelief(selectedPantheon!!) + chooseBeliefs(listOf(selectedPantheon!!), useFreeBeliefs = usingFreeBeliefs()) } } } diff --git a/core/src/com/unciv/ui/pickerscreens/ReligiousBeliefsPickerScreen.kt b/core/src/com/unciv/ui/pickerscreens/ReligiousBeliefsPickerScreen.kt index 59611145ae..4a57c049fc 100644 --- a/core/src/com/unciv/ui/pickerscreens/ReligiousBeliefsPickerScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/ReligiousBeliefsPickerScreen.kt @@ -74,7 +74,7 @@ class ReligiousBeliefsPickerScreen ( if (pickIconAndName) "Choose a Religion" else "Enhance [${currentReligion.getReligionDisplayName()}]" ) { - chooseBeliefs(displayName, religionName, beliefsToChoose.map { it.belief!! }) + chooseBeliefs(beliefsToChoose.map { it.belief!! }, displayName, religionName, usingFreeBeliefs()) } } @@ -191,6 +191,7 @@ class ReligiousBeliefsPickerScreen ( rightSelection.clear() val availableBeliefs = ruleset.beliefs.values .filter { (it.type == beliefType || beliefType == BeliefType.Any) } + val civReligionManager = currentReligion.getFounder().religionManager for (belief in availableBeliefs) { val beliefButton = getBeliefButton(belief) when { @@ -204,7 +205,8 @@ class ReligiousBeliefsPickerScreen ( // The Belief button should be disabled because you already have it selected beliefButton.disable(greenDisableColor) } - gameInfo.religions.values.any { it.hasBelief(belief.name) } -> { + civReligionManager.getReligionWithBelief(belief) != null + && civReligionManager.getReligionWithBelief(belief) != currentReligion -> { // The Belief is not available because someone already has it beliefButton.disable(redDisableColor) } diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index 3fdaac9d34..80d8fffdd2 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -24,6 +24,7 @@ import com.unciv.logic.multiplayer.MultiplayerGameUpdated import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached import com.unciv.logic.trade.TradeEvaluation import com.unciv.models.TutorialTrigger +import com.unciv.models.ruleset.BeliefType import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.unique.UniqueType import com.unciv.ui.cityscreen.CityScreen @@ -681,13 +682,17 @@ class WorldScreen( viewingCiv.policies.shouldOpenPolicyPicker = false } - viewingCiv.religionManager.canFoundPantheon() -> - NextTurnAction("Found Pantheon", Color.WHITE) { + viewingCiv.religionManager.canFoundOrExpandPantheon() -> { + val displayString = if (viewingCiv.religionManager.religionState == ReligionState.Pantheon) + "Expand Pantheon" + else "Found Pantheon" + NextTurnAction(displayString, Color.valueOf(BeliefType.Pantheon.color)) { game.pushScreen(PantheonPickerScreen(viewingCiv)) } + } viewingCiv.religionManager.religionState == ReligionState.FoundingReligion -> - NextTurnAction("Found Religion", Color.WHITE) { + NextTurnAction("Found Religion", Color.valueOf(BeliefType.Founder.color)) { game.pushScreen( ReligiousBeliefsPickerScreen( viewingCiv, @@ -698,7 +703,7 @@ class WorldScreen( } viewingCiv.religionManager.religionState == ReligionState.EnhancingReligion -> - NextTurnAction("Enhance a Religion", Color.ORANGE) { + NextTurnAction("Enhance a Religion", Color.valueOf(BeliefType.Enhancer.color)) { game.pushScreen( ReligiousBeliefsPickerScreen( viewingCiv, @@ -708,6 +713,17 @@ class WorldScreen( ) } + viewingCiv.religionManager.hasFreeBeliefs() -> + NextTurnAction("Reform Religion", Color.valueOf(BeliefType.Enhancer.color)) { + game.pushScreen( + ReligiousBeliefsPickerScreen( + viewingCiv, + viewingCiv.religionManager.freeBeliefsAsEnums(), + pickIconAndName = false + ) + ) + } + viewingCiv.mayVoteForDiplomaticVictory() -> NextTurnAction("Vote for World Leader", Color.MAROON) { game.pushScreen(DiplomaticVotePickerScreen(viewingCiv))