Better Religion info and some moddability (#8807)

* Make maximum number of religions moddable

* Explain remaining religion count in Empire Overview
This commit is contained in:
SomeTroglodyte 2023-03-04 18:20:23 +01:00 committed by GitHub
parent 5e61b0d313
commit c40b6159df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 44 deletions

View File

@ -1520,7 +1520,12 @@ Followers of this religion: = Anhänger dieser Religion:
Click an icon to see the stats of this religion = Klicke auf ein Icon, um die Statistiken dieser Religion anzuzeigen
Religion: Off = Religion: Aus
Minimal Faith required for\nthe next [Great Prophet]: = Mindest-Glaubenspunkte für\nden nächsten [Great Prophet]:
Religions to be founded: = Noch zu gründende Religionen:
Religions to be founded: [amount] = Noch zu gründende Religionen: [amount]
Available religion symbols = Verfügbare Religions-Symbole
Number of civilizations * [amount] + [amount2] = Maximum nach ([amount]*Zivilisationen)+[amount2]
Religions already founded = Bereits gegründete Religionen
Available founder beliefs = Verfügbare Gründer-Glaubenssätze
Available follower beliefs = Verfügbare Anhänger-Glaubenssätze
Religious status: = Religions-Status:
None = Keine

View File

@ -1521,7 +1521,12 @@ Followers of this religion: =
Click an icon to see the stats of this religion =
Religion: Off =
Minimal Faith required for\nthe next [Great Prophet]: =
Religions to be founded: =
Religions to be founded: [amount] =
Available religion symbols =
Number of civilizations * [amount] + [amount2] =
Religions already founded =
Available founder beliefs =
Available follower beliefs =
Religious status: =
None =

View File

@ -186,20 +186,24 @@ class ReligionManager : IsPartOfGameInfoSerialization {
}
}
private fun maxNumberOfReligions() = min(
civInfo.gameInfo.ruleset.religions.size,
civInfo.gameInfo.civilizations.count { it.isMajorCiv() } / 2 + 1
)
private fun maxNumberOfReligions(): Int {
val gameInfo = civInfo.gameInfo
val ruleset = gameInfo.ruleset
val multiplier = ruleset.modOptions.constants.religionLimitMultiplier
val base = ruleset.modOptions.constants.religionLimitBase
val civCount = gameInfo.civilizations.count { it.isMajorCiv() }
return min(ruleset.religions.size, base + (civCount * multiplier).toInt())
}
/** Calculates the number of religions that are already founded */
private fun foundedReligionsCount() = civInfo.gameInfo.civilizations.count {
it.religionManager.religion != null && it.religionManager.religionState >= ReligionState.Religion
}
/** Calculates the amount of religions that can still be founded */
fun remainingFoundableReligions(): Int {
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 = maxNumberOfReligions() - foundedReligionsCount
val maxNumberOfAdditionalReligions = maxNumberOfReligions() - foundedReligionsCount()
val availableBeliefsToFound = min(
numberOfBeliefsAvailable(BeliefType.Follower),
@ -209,6 +213,20 @@ class ReligionManager : IsPartOfGameInfoSerialization {
return min(maxNumberOfAdditionalReligions, availableBeliefsToFound)
}
/** Get info breaking down the reasons behind the result of [remainingFoundableReligions] */
fun remainingFoundableReligionsBreakdown() = sequence {
val gameInfo = civInfo.gameInfo
val ruleset = gameInfo.ruleset
val multiplier = ruleset.modOptions.constants.religionLimitMultiplier
val base = ruleset.modOptions.constants.religionLimitBase
val civCount = gameInfo.civilizations.count { it.isMajorCiv() }
yield("Available religion symbols" to ruleset.religions.size)
yield("Number of civilizations * [$multiplier] + [$base]" to base + (civCount * multiplier).toInt())
yield("Religions already founded" to foundedReligionsCount())
yield("Available founder beliefs" to numberOfBeliefsAvailable(BeliefType.Founder))
yield("Available follower beliefs" to numberOfBeliefsAvailable(BeliefType.Follower))
}
fun numberOfBeliefsAvailable(type: BeliefType): Int {
val gameInfo = civInfo.gameInfo
val numberOfBeliefs = if (type == BeliefType.Any) gameInfo.ruleset.beliefs.values.count()

View File

@ -62,6 +62,10 @@ class ModConstants {
var minRiverLength = 5
var maxRiverLength = 666 // Do not set to less than the maximal map radius
// Factors in formula for Maximum Number of foundable Religions
var religionLimitBase = 1
var religionLimitMultiplier = 0.5f
fun merge(other: ModConstants) {
if (other.maxXPfromBarbarians != defaults.maxXPfromBarbarians) maxXPfromBarbarians = other.maxXPfromBarbarians
if (other.cityStrengthBase != defaults.cityStrengthBase) cityStrengthBase = other.cityStrengthBase
@ -82,6 +86,8 @@ class ModConstants {
if (other.riverCountMultiplier != defaults.riverCountMultiplier) riverCountMultiplier = other.riverCountMultiplier
if (other.minRiverLength != defaults.minRiverLength) minRiverLength = other.minRiverLength
if (other.maxRiverLength != defaults.maxRiverLength) maxRiverLength = other.maxRiverLength
if (other.religionLimitBase != defaults.religionLimitBase) religionLimitBase = other.religionLimitBase
if (other.religionLimitMultiplier != defaults.religionLimitMultiplier) religionLimitMultiplier = other.religionLimitMultiplier
}
companion object {

View File

@ -12,6 +12,7 @@ import com.unciv.models.Religion
import com.unciv.models.ruleset.Belief
import com.unciv.models.translations.fillPlaceholders
import com.unciv.models.translations.tr
import com.unciv.ui.components.ExpanderTab
import com.unciv.ui.screens.civilopediascreen.CivilopediaScreen
import com.unciv.ui.screens.civilopediascreen.MarkupRenderer
import com.unciv.ui.images.ImageGetter
@ -66,6 +67,22 @@ class ReligionOverviewTab(
}
private fun Table.addCivSpecificStats() {
// This is not Civ-specific, but -oh well- still fits
val remaining = viewingPlayer.religionManager.remainingFoundableReligions()
val minWidth = max(religionButtonLabel.prefWidth, overviewScreen.stage.width / 3)
val headerText = "Religions to be founded: [$remaining]"
val religionCountExpander = ExpanderTab(
headerText, fontSize = 18, headerPad = 5f,
startsOutOpened = false, defaultPad = 0f, expanderWidth = minWidth
) {
it.defaults().padTop(10f)
for ((text, num) in viewingPlayer.religionManager.remainingFoundableReligionsBreakdown()) {
it.add(text.toLabel())
it.add(num.toString().toLabel(alignment = Align.right)).right().row()
}
}
add(religionCountExpander).colspan(2).growX().row()
if (viewingPlayer.religionManager.canGenerateProphet()) {
add("Minimal Faith required for\nthe next [great prophet equivalent]:"
.fillPlaceholders(viewingPlayer.religionManager.getGreatProphetEquivalent()!!)
@ -77,9 +94,6 @@ class ReligionOverviewTab(
).right().row()
}
add("Religions to be founded:".toLabel())
add((viewingPlayer.religionManager.remainingFoundableReligions()).toLabel()).right().row()
add("Religious status:".toLabel()).left()
add(viewingPlayer.religionManager.religionState.toString().toLabel()).right().row()
}

View File

@ -129,52 +129,56 @@ Stored in ModOptions.constants, this is a collection of constants used internall
This is the only structure that is _merged_ field by field from mods, not overwritten, so you can change XP from Barbarians in one mod
and city distance in another. In case of conflicts, there is no guarantee which mod wins, only that _default_ values are ignored.
| Attribute | Type | Default | Notes |
| --------- | ---- | -------- | ----- |
| maxXPfromBarbarians | Int | 30 | [^A] |
| cityStrengthBase| Float | 8.0 | [^B] |
| cityStrengthPerPop| Float | 0.4 | [^B] |
| cityStrengthFromTechsMultiplier| Float | 5.5 | [^B] |
| cityStrengthFromTechsExponent| Float | 2.8 | [^B] |
| cityStrengthFromTechsFullMultiplier| Float | 1.0 | [^B] |
| cityStrengthFromGarrison| Float | 0.2 | [^B] |
| unitSupplyPerPopulation| Float | 0.5 | [^C] |
| minimalCityDistance| Int | 3 | [^D] |
| minimalCityDistanceOnDifferentContinents| Int | 2 | [^D] |
| unitUpgradeCost | Object | see below | [^J] |
| naturalWonderCountMultiplier| Float | 0.124 | [^E] |
| naturalWonderCountAddedConstant| Float | 0.1 | [^E] |
| ancientRuinCountMultiplier| Float | 0.02 | [^F] |
| maxLakeSize| Int | 10 | [^H] |
| riverCountMultiplier| Float | 0.01 | [^I] |
| minRiverLength| Int | 5 | [^I] |
| maxRiverLength| Int | 666 | [^I] |
| Attribute | Type | Default | Notes |
|------------------------------------------|--------|-----------|-------|
| maxXPfromBarbarians | Int | 30 | [^A] |
| cityStrengthBase | Float | 8.0 | [^B] |
| cityStrengthPerPop | Float | 0.4 | [^B] |
| cityStrengthFromTechsMultiplier | Float | 5.5 | [^B] |
| cityStrengthFromTechsExponent | Float | 2.8 | [^B] |
| cityStrengthFromTechsFullMultiplier | Float | 1.0 | [^B] |
| cityStrengthFromGarrison | Float | 0.2 | [^B] |
| unitSupplyPerPopulation | Float | 0.5 | [^C] |
| minimalCityDistance | Int | 3 | [^D] |
| minimalCityDistanceOnDifferentContinents | Int | 2 | [^D] |
| unitUpgradeCost | Object | see below | [^J] |
| naturalWonderCountMultiplier | Float | 0.124 | [^E] |
| naturalWonderCountAddedConstant | Float | 0.1 | [^E] |
| ancientRuinCountMultiplier | Float | 0.02 | [^F] |
| maxLakeSize | Int | 10 | [^H] |
| riverCountMultiplier | Float | 0.01 | [^I] |
| minRiverLength | Int | 5 | [^I] |
| maxRiverLength | Int | 666 | [^I] |
| religionLimitBase | Int | 1 | [^K] |
| religionLimitMultiplier | Float | 0.5 | [^K] |
Legend:
- [^A]: Max amount of experience that can be gained from combat with barbarians
- [^B]: Formula for city Strength:
- [^A]: Max amount of experience that can be gained from combat with barbarians
- [^B]: Formula for city Strength:
Strength = baseStrength + strengthPerPop + strengthFromTiles +
((%techs * multiplier) ^ exponent) * fullMultiplier +
(garrisonBonus * garrisonUnitStrength * garrisonUnitHealth/100) +
defensiveBuildingStrength
where %techs is the percentage of techs in the tech tree that are complete
If no techs exist in this ruleset, %techs = 0.5 (=50%)
- [^C]: Formula for Unit Supply:
- [^C]: Formula for Unit Supply:
Supply = unitSupplyBase (difficulties.json)
unitSupplyPerCity * amountOfCities + (difficulties.json)
unitSupplyPerPopulation * amountOfPopulationInAllCities
unitSupplyBase and unitSupplyPerCity can be found in difficulties.json
unitSupplyBase, unitSupplyPerCity and unitSupplyPerPopulation can also be increased through uniques
- [^D]: The minimal distance that must be between any two cities, not counting the tiles cities are on
- [^D]: The minimal distance that must be between any two cities, not counting the tiles cities are on
The number is the amount of tiles between two cities, not counting the tiles the cities are on.
e.g. "C__C", where "C" is a tile with a city and "_" is a tile without a city, has a distance of 2.
First constant is for cities on the same landmass, the second is for cities on different continents.
- [^E]: NaturalWonderGenerator uses these to determine the number of Natural Wonders to spawn for a given map size. The number scales linearly with map radius: #wonders = radius * naturalWonderCountMultiplier + naturalWonderCountAddedConstant. The defaults effectively mean Tiny - 1, Small - 2, Medium - 3, Large - 4, Huge - 5, Custom radius >=109 - all G&K wonders.
- [^F]: MapGenerator.spreadAncientRuins: number of ruins = suitable tile count * this
- [^H]: MapGenerator.spawnLakesAndCoasts: Water bodies up to this tile count become Lakes
- [^I]: RiverGenerator: river frequency and length bounds
- [^J]: A [UnitUpgradeCost](#UnitUpgradeCost) sub-structure.
- [^E]: NaturalWonderGenerator uses these to determine the number of Natural Wonders to spawn for a given map size. The number scales linearly with map radius: #wonders = radius * naturalWonderCountMultiplier + naturalWonderCountAddedConstant. The defaults effectively mean Tiny - 1, Small - 2, Medium - 3, Large - 4, Huge - 5, Custom radius >=109 - all G&K wonders.
- [^F]: MapGenerator.spreadAncientRuins: number of ruins = suitable tile count * this
- [^H]: MapGenerator.spawnLakesAndCoasts: Water bodies up to this tile count become Lakes
- [^I]: RiverGenerator: river frequency and length bounds
- [^J]: A [UnitUpgradeCost](#UnitUpgradeCost) sub-structure.
- [^K]: Maximum foundable Religions = religionLimitBase + floor(MajorCivCount * religionLimitMultiplier)
#### UnitUpgradeCost