mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-25 12:54:06 -04:00
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
This commit is contained in:
parent
306aef4c67
commit
28f65a7599
@ -1416,6 +1416,8 @@ Choose a pantheon =
|
|||||||
Choose a Religion =
|
Choose a Religion =
|
||||||
Found Religion =
|
Found Religion =
|
||||||
Found Pantheon =
|
Found Pantheon =
|
||||||
|
Reform Religion =
|
||||||
|
Expand Pantheon =
|
||||||
Follow [belief] =
|
Follow [belief] =
|
||||||
Religions and Beliefs =
|
Religions and Beliefs =
|
||||||
Majority Religion: [name] =
|
Majority Religion: [name] =
|
||||||
|
@ -535,10 +535,11 @@ object NextTurnAutomation {
|
|||||||
choosePantheon(civInfo)
|
choosePantheon(civInfo)
|
||||||
foundReligion(civInfo)
|
foundReligion(civInfo)
|
||||||
enhanceReligion(civInfo)
|
enhanceReligion(civInfo)
|
||||||
|
chooseFreeBeliefs(civInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun choosePantheon(civInfo: CivilizationInfo) {
|
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,
|
// So looking through the source code of the base game available online,
|
||||||
// the functions for choosing beliefs total in at around 400 lines.
|
// the functions for choosing beliefs total in at around 400 lines.
|
||||||
// https://github.com/Gedemon/Civ5-DLL/blob/aa29e80751f541ae04858b6d2a2c7dcca454201e/CvGameCoreDLL_Expansion1/CvReligionClasses.cpp
|
// 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.
|
// Should probably be changed later, but it works for now.
|
||||||
val chosenPantheon = chooseBeliefOfType(civInfo, BeliefType.Pantheon)
|
val chosenPantheon = chooseBeliefOfType(civInfo, BeliefType.Pantheon)
|
||||||
?: return // panic!
|
?: return // panic!
|
||||||
civInfo.religionManager.choosePantheonBelief(chosenPantheon)
|
civInfo.religionManager.chooseBeliefs(
|
||||||
|
listOf(chosenPantheon),
|
||||||
|
useFreeBeliefs = civInfo.religionManager.usingFreeBeliefs()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun foundReligion(civInfo: CivilizationInfo) {
|
private fun foundReligion(civInfo: CivilizationInfo) {
|
||||||
@ -559,18 +563,24 @@ object NextTurnAutomation {
|
|||||||
else availableReligionIcons.randomOrNull()
|
else availableReligionIcons.randomOrNull()
|
||||||
?: return // Wait what? How did we pass the checking when using a great prophet but not this?
|
?: 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()
|
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) {
|
private fun enhanceReligion(civInfo: CivilizationInfo) {
|
||||||
if (civInfo.religionManager.religionState != ReligionState.EnhancingReligion) return
|
if (civInfo.religionManager.religionState != ReligionState.EnhancingReligion) return
|
||||||
civInfo.religionManager.chooseBeliefs(
|
civInfo.religionManager.chooseBeliefs(
|
||||||
null,
|
|
||||||
null,
|
|
||||||
chooseBeliefs(civInfo, civInfo.religionManager.getBeliefsToChooseAtEnhancing()).toList()
|
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<BeliefType>): HashSet<Belief> {
|
private fun chooseBeliefs(civInfo: CivilizationInfo, beliefsToChoose: Counter<BeliefType>): HashSet<Belief> {
|
||||||
val chosenBeliefs = hashSetOf<Belief>()
|
val chosenBeliefs = hashSetOf<Belief>()
|
||||||
// The `continue`s should never be reached, but just in case I'd rather have the AI have a
|
// 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 {
|
.filter {
|
||||||
(it.value.type == beliefType || beliefType == BeliefType.Any)
|
(it.value.type == beliefType || beliefType == BeliefType.Any)
|
||||||
&& !additionalBeliefsToExclude.contains(it.value)
|
&& !additionalBeliefsToExclude.contains(it.value)
|
||||||
&& !civInfo.gameInfo.religions.values
|
&& civInfo.religionManager.getReligionWithBelief(it.value) == null
|
||||||
.flatMap { religion -> religion.getBeliefs(beliefType) }.contains(it.value)
|
|
||||||
}
|
}
|
||||||
.map { it.value }
|
.map { it.value }
|
||||||
.maxByOrNull { ReligionAutomation.rateBelief(civInfo, it) }
|
.maxByOrNull { ReligionAutomation.rateBelief(civInfo, it) }
|
||||||
|
@ -163,7 +163,7 @@ object ReligionAutomation {
|
|||||||
it.getMapUnit(civInfo).canDoReligiousAction(Constants.removeHeresy)
|
it.getMapUnit(civInfo).canDoReligiousAction(Constants.removeHeresy)
|
||||||
|| it.hasUnique(UniqueType.PreventSpreadingReligion)
|
|| it.hasUnique(UniqueType.PreventSpreadingReligion)
|
||||||
}
|
}
|
||||||
|
|
||||||
inquisitors = inquisitors.map { civInfo.getEquivalentUnit(it) }
|
inquisitors = inquisitors.map { civInfo.getEquivalentUnit(it) }
|
||||||
|
|
||||||
val inquisitorConstruction = inquisitors
|
val inquisitorConstruction = inquisitors
|
||||||
@ -173,8 +173,8 @@ object ReligionAutomation {
|
|||||||
// And from that list determine the cheapest price
|
// And from that list determine the cheapest price
|
||||||
.minByOrNull { it.value.minOf { city -> it.key.getStatBuyCost(city, Stat.Faith)!! }}?.key
|
.minByOrNull { it.value.minOf { city -> it.key.getStatBuyCost(city, Stat.Faith)!! }}?.key
|
||||||
?: return
|
?: return
|
||||||
|
|
||||||
|
|
||||||
val hasUniqueToTakeCivReligion = civInfo.gameInfo.ruleSet.units[inquisitorConstruction.name]!!.hasUnique(UniqueType.TakeReligionOverBirthCity)
|
val hasUniqueToTakeCivReligion = civInfo.gameInfo.ruleSet.units[inquisitorConstruction.name]!!.hasUnique(UniqueType.TakeReligionOverBirthCity)
|
||||||
|
|
||||||
val validCitiesToBuy = civInfo.cities.filter {
|
val validCitiesToBuy = civInfo.cities.filter {
|
||||||
|
@ -10,6 +10,7 @@ import com.unciv.models.ruleset.Belief
|
|||||||
import com.unciv.models.ruleset.BeliefType
|
import com.unciv.models.ruleset.BeliefType
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.ui.utils.extensions.toPercent
|
import com.unciv.ui.utils.extensions.toPercent
|
||||||
|
import java.lang.Integer.max
|
||||||
import java.lang.Integer.min
|
import java.lang.Integer.min
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@ -35,6 +36,10 @@ class ReligionManager : IsPartOfGameInfoSerialization {
|
|||||||
var religionState = ReligionState.None
|
var religionState = ReligionState.None
|
||||||
private set
|
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<String> = Counter()
|
||||||
|
|
||||||
// These cannot be transient, as saving and loading after using a great prophet but before
|
// These cannot be transient, as saving and loading after using a great prophet but before
|
||||||
// founding a religion would break :(
|
// founding a religion would break :(
|
||||||
private var foundingCityId: String? = null
|
private var foundingCityId: String? = null
|
||||||
@ -49,6 +54,7 @@ class ReligionManager : IsPartOfGameInfoSerialization {
|
|||||||
clone.shouldChoosePantheonBelief = shouldChoosePantheonBelief
|
clone.shouldChoosePantheonBelief = shouldChoosePantheonBelief
|
||||||
clone.storedFaith = storedFaith
|
clone.storedFaith = storedFaith
|
||||||
clone.religionState = religionState
|
clone.religionState = religionState
|
||||||
|
clone.freeBeliefs.putAll(freeBeliefs)
|
||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,34 +83,52 @@ class ReligionManager : IsPartOfGameInfoSerialization {
|
|||||||
return civInfo.cities.count { it.religion.getMajorityReligion() == religion } > civInfo.cities.size / 2
|
return civInfo.cities.count { it.religion.getMajorityReligion() == religion } > civInfo.cities.size / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This helper function makes it easy to interface the Counter<String> [freeBeliefs] with functions
|
||||||
|
* that use Counter<BeliefType>
|
||||||
|
*/
|
||||||
|
fun freeBeliefsAsEnums(): Counter<BeliefType> {
|
||||||
|
val toReturn = Counter<BeliefType>()
|
||||||
|
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) =
|
fun faithForPantheon(additionalCivs: Int = 0) =
|
||||||
10 + (civInfo.gameInfo.civilizations.count { it.isMajorCiv() && it.religionManager.religion != null } + additionalCivs) * 5
|
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 (!civInfo.gameInfo.isReligionEnabled()) return false
|
||||||
if (religionState != ReligionState.None) return false
|
if (religionState > ReligionState.Pantheon) return false
|
||||||
if (!civInfo.isMajorCiv()) return false
|
if (!civInfo.isMajorCiv()) return false
|
||||||
if (civInfo.gameInfo.ruleSet.beliefs.values.none { isPickablePantheonBelief(it) })
|
if (numberOfBeliefsAvailable(BeliefType.Pantheon) == 0)
|
||||||
return false
|
return false // no more available pantheons
|
||||||
if (civInfo.gameInfo.civilizations.any { it.religionManager.religionState == ReligionState.EnhancedReligion })
|
if (civInfo.gameInfo.civilizations.any { it.religionManager.religionState == ReligionState.EnhancedReligion })
|
||||||
return false
|
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 {
|
private fun foundPantheon(beliefName: String, useFreeBelief: Boolean) {
|
||||||
if (belief.type != BeliefType.Pantheon) return false
|
if (!useFreeBelief) {
|
||||||
return (civInfo.gameInfo.civilizations.none { it.religionManager.religion?.followerBeliefs?.contains(belief.name) == true })
|
// paid for the initial pantheon using faith
|
||||||
}
|
storedFaith -= faithForPantheon()
|
||||||
|
}
|
||||||
fun choosePantheonBelief(belief: Belief) {
|
religion = Religion(beliefName, civInfo.gameInfo, civInfo.civName)
|
||||||
storedFaith -= faithForPantheon()
|
civInfo.gameInfo.religions[beliefName] = religion!!
|
||||||
religion = Religion(belief.name, civInfo.gameInfo, civInfo.civName)
|
|
||||||
religion!!.followerBeliefs.add(belief.name)
|
|
||||||
civInfo.gameInfo.religions[belief.name] = religion!!
|
|
||||||
for (city in civInfo.cities)
|
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
|
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/
|
// 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 */
|
/** Calculates the amount of religions that can still be founded */
|
||||||
fun remainingFoundableReligions(): Int {
|
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
|
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
|
// 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,
|
val maxNumberOfAdditionalReligions = min(gameInfo.ruleSet.religions.size,
|
||||||
civInfo.gameInfo.civilizations.count { it.isMajorCiv() } / 2 + 1) - foundedReligionsCount
|
gameInfo.civilizations.count { it.isMajorCiv() } / 2 + 1) - foundedReligionsCount
|
||||||
|
|
||||||
val availableBeliefsToFound = min(
|
val availableBeliefsToFound = min(
|
||||||
civInfo.gameInfo.ruleSet.beliefs.values.count {
|
numberOfBeliefsAvailable(BeliefType.Follower),
|
||||||
it.type == BeliefType.Follower
|
numberOfBeliefsAvailable(BeliefType.Founder)
|
||||||
&& 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) }
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return min(maxNumberOfAdditionalReligions, availableBeliefsToFound)
|
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 {
|
fun mayFoundReligionAtAll(prophet: MapUnit): Boolean {
|
||||||
if (!civInfo.gameInfo.isReligionEnabled()) return false // No religion
|
if (!civInfo.gameInfo.isReligionEnabled()) return false // No religion
|
||||||
|
|
||||||
@ -207,38 +238,99 @@ class ReligionManager : IsPartOfGameInfoSerialization {
|
|||||||
civInfo.religionManager.foundingCityId = prophet.getTile().getCity()!!.id
|
civInfo.religionManager.foundingCityId = prophet.getTile().getCity()!!.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBeliefsToChooseAtFounding(): Counter<BeliefType> {
|
/**
|
||||||
|
* 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<BeliefType> {
|
||||||
|
val action = if (enhancingReligion) "enhancing" else "founding"
|
||||||
val beliefsToChoose: Counter<BeliefType> = Counter()
|
val beliefsToChoose: Counter<BeliefType> = Counter()
|
||||||
beliefsToChoose.add(BeliefType.Founder, 1)
|
|
||||||
beliefsToChoose.add(BeliefType.Follower, 1)
|
// Counter of the number of available beliefs of each type
|
||||||
if (shouldChoosePantheonBelief)
|
val availableBeliefs = Counter<BeliefType>()
|
||||||
beliefsToChoose.add(BeliefType.Pantheon, 1)
|
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)) {
|
for (unique in civInfo.getMatchingUniques(UniqueType.FreeExtraBeliefs)) {
|
||||||
if (unique.params[2] != "founding") continue
|
if (unique.params[2] != action) continue
|
||||||
beliefsToChoose.add(BeliefType.valueOf(unique.params[1]), unique.params[0].toInt())
|
val type = BeliefType.valueOf(unique.params[1])
|
||||||
|
chooseBeliefToAdd(type, unique.params[0].toInt())
|
||||||
}
|
}
|
||||||
for (unique in civInfo.getMatchingUniques(UniqueType.FreeExtraAnyBeliefs)) {
|
for (unique in civInfo.getMatchingUniques(UniqueType.FreeExtraAnyBeliefs)) {
|
||||||
if (unique.params[1] != "founding") continue
|
if (unique.params[1] != action) continue
|
||||||
beliefsToChoose.add(BeliefType.Any, unique.params[0].toInt())
|
chooseBeliefToAdd(BeliefType.Any, unique.params[0].toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
return beliefsToChoose
|
return beliefsToChoose
|
||||||
}
|
}
|
||||||
|
|
||||||
fun chooseBeliefs(iconName: String?, religionName: String?, beliefs: List<Belief>) {
|
fun getBeliefsToChooseAtFounding(): Counter<BeliefType> = getBeliefsToChooseAtProphetUse(false)
|
||||||
when(religionState) {
|
fun getBeliefsToChooseAtEnhancing(): Counter<BeliefType> = getBeliefsToChooseAtProphetUse(true)
|
||||||
|
|
||||||
|
fun chooseBeliefs(beliefs: List<Belief>, iconName: String? = null, religionName: String? = null, useFreeBeliefs: Boolean = false) {
|
||||||
|
when (religionState) {
|
||||||
ReligionState.FoundingReligion ->
|
ReligionState.FoundingReligion ->
|
||||||
foundReligion(iconName!!, religionName!!, beliefs)
|
foundReligion(iconName!!, religionName!!)
|
||||||
ReligionState.EnhancingReligion ->
|
ReligionState.EnhancingReligion ->
|
||||||
enhanceReligion(beliefs)
|
religionState = ReligionState.EnhancedReligion
|
||||||
else -> return
|
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
|
civInfo.updateStatsForNextTurn() // a belief can have an immediate effect on stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun foundReligion(displayName: String, name: String, beliefs: List<Belief>) {
|
private fun foundReligion(displayName: String, name: String) {
|
||||||
val newReligion = Religion(name, civInfo.gameInfo, civInfo.civName)
|
val newReligion = Religion(name, civInfo.gameInfo, civInfo.civName)
|
||||||
newReligion.displayName = displayName
|
newReligion.displayName = displayName
|
||||||
if (religion != null) {
|
if (religion != null) {
|
||||||
@ -246,17 +338,6 @@ class ReligionManager : IsPartOfGameInfoSerialization {
|
|||||||
newReligion.founderBeliefs.addAll(religion!!.founderBeliefs)
|
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
|
religion = newReligion
|
||||||
civInfo.gameInfo.religions[name] = 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 (prophet.abilityUsesLeft.any { it.value != prophet.maxAbilityUses[it.key] }) return false
|
||||||
if (!civInfo.isMajorCiv()) return false // Only major civs
|
if (!civInfo.isMajorCiv()) return false // Only major civs
|
||||||
|
|
||||||
if (civInfo.gameInfo.ruleSet.beliefs.values.none {
|
if (numberOfBeliefsAvailable(BeliefType.Follower) == 0)
|
||||||
it.type == BeliefType.Follower
|
return false // Mod maker did not provide enough follower beliefs
|
||||||
&& 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 {
|
if (numberOfBeliefsAvailable(BeliefType.Enhancer) == 0)
|
||||||
it.type == BeliefType.Enhancer
|
return false // Mod maker did not provide enough enhancer beliefs
|
||||||
&& civInfo.gameInfo.religions.values.none { religion -> religion.getBeliefs(BeliefType.Enhancer).contains(it) }
|
|
||||||
}) return false // Mod maker did not provide enough enhancer beliefs
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -306,29 +383,6 @@ class ReligionManager : IsPartOfGameInfoSerialization {
|
|||||||
religionState = ReligionState.EnhancingReligion
|
religionState = ReligionState.EnhancingReligion
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBeliefsToChooseAtEnhancing(): Counter<BeliefType> {
|
|
||||||
val beliefsToChoose: Counter<BeliefType> = 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<Belief>) {
|
|
||||||
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 {
|
fun maySpreadReligionAtAll(missionary: MapUnit): Boolean {
|
||||||
if (!civInfo.gameInfo.isReligionEnabled()) return false // No religion, no spreading
|
if (!civInfo.gameInfo.isReligionEnabled()) return false // No religion, no spreading
|
||||||
if (religion == null) return false // Need a religion
|
if (religion == null) return false // Need a religion
|
||||||
|
@ -6,6 +6,7 @@ import com.unciv.logic.city.CityInfo
|
|||||||
import com.unciv.logic.civilization.*
|
import com.unciv.logic.civilization.*
|
||||||
import com.unciv.logic.map.MapUnit
|
import com.unciv.logic.map.MapUnit
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
|
import com.unciv.models.ruleset.BeliefType
|
||||||
import com.unciv.models.ruleset.Victory
|
import com.unciv.models.ruleset.Victory
|
||||||
import com.unciv.models.ruleset.unique.UniqueType.*
|
import com.unciv.models.ruleset.unique.UniqueType.*
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
@ -84,7 +85,7 @@ object UniqueTriggerActivation {
|
|||||||
.any { it.params[0] == "Land" }} ?: return false
|
.any { it.params[0] == "Land" }} ?: return false
|
||||||
unit = civInfo.getEquivalentUnit(replacementUnit.name)
|
unit = civInfo.getEquivalentUnit(replacementUnit.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
val placingTile =
|
val placingTile =
|
||||||
tile ?: civInfo.cities.random().getCenterTile()
|
tile ?: civInfo.cities.random().getCenterTile()
|
||||||
|
|
||||||
@ -389,6 +390,22 @@ object UniqueTriggerActivation {
|
|||||||
|
|
||||||
return true
|
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 -> {
|
OneTimeRevealSpecificMapTiles -> {
|
||||||
if (tile == null) return false
|
if (tile == null) return false
|
||||||
|
@ -678,6 +678,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
|||||||
OneTimeGainStat("Gain [amount] [stat]", UniqueTarget.Ruins),
|
OneTimeGainStat("Gain [amount] [stat]", UniqueTarget.Ruins),
|
||||||
OneTimeGainStatRange("Gain [amount]-[amount] [stat]", UniqueTarget.Ruins),
|
OneTimeGainStatRange("Gain [amount]-[amount] [stat]", UniqueTarget.Ruins),
|
||||||
OneTimeGainPantheon("Gain enough Faith for a Pantheon", 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),
|
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?
|
// 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"
|
// Or just reword it without the 'up to', so it reads "Reveal [amount/'all'] [tileFilter] tiles within [amount] tiles"
|
||||||
|
@ -17,7 +17,7 @@ class PantheonPickerScreen(
|
|||||||
for (belief in ruleset.beliefs.values) {
|
for (belief in ruleset.beliefs.values) {
|
||||||
if (belief.type != BeliefType.Pantheon) continue
|
if (belief.type != BeliefType.Pantheon) continue
|
||||||
val beliefButton = getBeliefButton(belief, withTypeLabel = false)
|
val beliefButton = getBeliefButton(belief, withTypeLabel = false)
|
||||||
if (choosingCiv.religionManager.isPickablePantheonBelief(belief)) {
|
if (choosingCiv.religionManager.getReligionWithBelief(belief) == null) {
|
||||||
beliefButton.onClickSelect(selection, belief) {
|
beliefButton.onClickSelect(selection, belief) {
|
||||||
selectedPantheon = belief
|
selectedPantheon = belief
|
||||||
pick("Follow [${belief.name}]".tr())
|
pick("Follow [${belief.name}]".tr())
|
||||||
@ -29,7 +29,7 @@ class PantheonPickerScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
setOKAction("Choose a pantheon") {
|
setOKAction("Choose a pantheon") {
|
||||||
choosePantheonBelief(selectedPantheon!!)
|
chooseBeliefs(listOf(selectedPantheon!!), useFreeBeliefs = usingFreeBeliefs())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ class ReligiousBeliefsPickerScreen (
|
|||||||
if (pickIconAndName) "Choose a Religion"
|
if (pickIconAndName) "Choose a Religion"
|
||||||
else "Enhance [${currentReligion.getReligionDisplayName()}]"
|
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()
|
rightSelection.clear()
|
||||||
val availableBeliefs = ruleset.beliefs.values
|
val availableBeliefs = ruleset.beliefs.values
|
||||||
.filter { (it.type == beliefType || beliefType == BeliefType.Any) }
|
.filter { (it.type == beliefType || beliefType == BeliefType.Any) }
|
||||||
|
val civReligionManager = currentReligion.getFounder().religionManager
|
||||||
for (belief in availableBeliefs) {
|
for (belief in availableBeliefs) {
|
||||||
val beliefButton = getBeliefButton(belief)
|
val beliefButton = getBeliefButton(belief)
|
||||||
when {
|
when {
|
||||||
@ -204,7 +205,8 @@ class ReligiousBeliefsPickerScreen (
|
|||||||
// The Belief button should be disabled because you already have it selected
|
// The Belief button should be disabled because you already have it selected
|
||||||
beliefButton.disable(greenDisableColor)
|
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
|
// The Belief is not available because someone already has it
|
||||||
beliefButton.disable(redDisableColor)
|
beliefButton.disable(redDisableColor)
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import com.unciv.logic.multiplayer.MultiplayerGameUpdated
|
|||||||
import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached
|
import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached
|
||||||
import com.unciv.logic.trade.TradeEvaluation
|
import com.unciv.logic.trade.TradeEvaluation
|
||||||
import com.unciv.models.TutorialTrigger
|
import com.unciv.models.TutorialTrigger
|
||||||
|
import com.unciv.models.ruleset.BeliefType
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.ui.cityscreen.CityScreen
|
import com.unciv.ui.cityscreen.CityScreen
|
||||||
@ -681,13 +682,17 @@ class WorldScreen(
|
|||||||
viewingCiv.policies.shouldOpenPolicyPicker = false
|
viewingCiv.policies.shouldOpenPolicyPicker = false
|
||||||
}
|
}
|
||||||
|
|
||||||
viewingCiv.religionManager.canFoundPantheon() ->
|
viewingCiv.religionManager.canFoundOrExpandPantheon() -> {
|
||||||
NextTurnAction("Found Pantheon", Color.WHITE) {
|
val displayString = if (viewingCiv.religionManager.religionState == ReligionState.Pantheon)
|
||||||
|
"Expand Pantheon"
|
||||||
|
else "Found Pantheon"
|
||||||
|
NextTurnAction(displayString, Color.valueOf(BeliefType.Pantheon.color)) {
|
||||||
game.pushScreen(PantheonPickerScreen(viewingCiv))
|
game.pushScreen(PantheonPickerScreen(viewingCiv))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
viewingCiv.religionManager.religionState == ReligionState.FoundingReligion ->
|
viewingCiv.religionManager.religionState == ReligionState.FoundingReligion ->
|
||||||
NextTurnAction("Found Religion", Color.WHITE) {
|
NextTurnAction("Found Religion", Color.valueOf(BeliefType.Founder.color)) {
|
||||||
game.pushScreen(
|
game.pushScreen(
|
||||||
ReligiousBeliefsPickerScreen(
|
ReligiousBeliefsPickerScreen(
|
||||||
viewingCiv,
|
viewingCiv,
|
||||||
@ -698,7 +703,7 @@ class WorldScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewingCiv.religionManager.religionState == ReligionState.EnhancingReligion ->
|
viewingCiv.religionManager.religionState == ReligionState.EnhancingReligion ->
|
||||||
NextTurnAction("Enhance a Religion", Color.ORANGE) {
|
NextTurnAction("Enhance a Religion", Color.valueOf(BeliefType.Enhancer.color)) {
|
||||||
game.pushScreen(
|
game.pushScreen(
|
||||||
ReligiousBeliefsPickerScreen(
|
ReligiousBeliefsPickerScreen(
|
||||||
viewingCiv,
|
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() ->
|
viewingCiv.mayVoteForDiplomaticVictory() ->
|
||||||
NextTurnAction("Vote for World Leader", Color.MAROON) {
|
NextTurnAction("Vote for World Leader", Color.MAROON) {
|
||||||
game.pushScreen(DiplomaticVotePickerScreen(viewingCiv))
|
game.pushScreen(DiplomaticVotePickerScreen(viewingCiv))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user