Fix effect of new Beliefs not immediately visible in top bar (#6888)

* Fix effect of new Beliefs not immediately visible in top bar

* Fix effect of new Beliefs not immediately visible - reviews
This commit is contained in:
SomeTroglodyte 2022-05-21 20:37:06 +02:00 committed by GitHub
parent 8b9946e65e
commit 3e95e3f152
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 85 deletions

View File

@ -68,7 +68,7 @@ class ReligionManager {
fun endTurn(faithFromNewTurn: Int) {
storedFaith += faithFromNewTurn
}
fun isMajorityReligionForCiv(religion: Religion): Boolean {
return civInfo.cities.count { it.religion.getMajorityReligion() == religion } >= civInfo.cities.size / 2
}
@ -82,7 +82,7 @@ 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 })
if (civInfo.gameInfo.civilizations.any { it.religionManager.religionState == ReligionState.EnhancedReligion })
return false
return storedFaith >= faithForPantheon()
}
@ -98,17 +98,18 @@ class ReligionManager {
religion!!.followerBeliefs.add(belief.name)
civInfo.gameInfo.religions[belief.name] = religion!!
for (city in civInfo.cities)
city.religion.addPressure(belief.name, 200 * city.population.population)
city.religion.addPressure(belief.name, 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/
// Game files (globaldefines.xml)
fun faithForNextGreatProphet(): Int {
val greatProphetsEarned = civInfo.civConstructions.boughtItemsWithIncreasingPrice[getGreatProphetEquivalent()!!] ?: 0
var faithCost =
(200 + 100 * greatProphetsEarned * (greatProphetsEarned + 1) / 2f) *
var faithCost =
(200 + 100 * greatProphetsEarned * (greatProphetsEarned + 1) / 2f) *
civInfo.gameInfo.gameParameters.gameSpeed.modifier
for (unique in civInfo.getMatchingUniques(UniqueType.FaithCostOfGreatProphetChange))
@ -126,14 +127,14 @@ class ReligionManager {
if (civInfo.hasUnique(UniqueType.MayNotGenerateGreatProphet)) return false
return true
}
fun getGreatProphetEquivalent(): String? {
return civInfo.gameInfo.ruleSet.units.values.firstOrNull { it.hasUnique(UniqueType.MayFoundReligion) }?.name
}
private fun generateProphet() {
val prophetUnitName = getGreatProphetEquivalent() ?: return // No prophet units in this mod
val prophetSpawnChange = (5f + storedFaith - faithForNextGreatProphet()) / 100f
if (Random(civInfo.gameInfo.turns).nextFloat() < prophetSpawnChange) {
@ -146,12 +147,12 @@ class ReligionManager {
civInfo.civConstructions.boughtItemsWithIncreasingPrice.add(prophetUnitName, 1)
}
}
fun amountOfFoundableReligions() = civInfo.gameInfo.civilizations.count { it.isMajorCiv() } / 2 + 1
fun mayFoundReligionAtAll(prophet: MapUnit): Boolean {
if (!civInfo.gameInfo.isReligionEnabled()) return false // No religion
if (religionState >= ReligionState.Religion) return false // Already created a major religion
// Already used its power for other things
@ -165,7 +166,7 @@ class ReligionManager {
if (foundedReligionsCount >= amountOfFoundableReligions())
return false // Too bad, too many religions have already been founded
if (foundedReligionsCount >= civInfo.gameInfo.ruleSet.religions.size)
return false // Mod maker did not provide enough religions for the amount of civs present
@ -184,8 +185,8 @@ class ReligionManager {
fun mayFoundReligionNow(prophet: MapUnit): Boolean {
if (!mayFoundReligionAtAll(prophet)) return false
if (!prophet.getTile().isCityCenter()) return false
if (prophet.getTile().getCity()!!.isHolyCity()) return false
// No double holy cities. Not sure if these were allowed in the base game
if (prophet.getTile().getCity()!!.isHolyCity()) return false
// No double holy cities. Not sure if these were allowed in the base game
return true
}
@ -202,7 +203,7 @@ class ReligionManager {
beliefsToChoose.add(BeliefType.Follower, 1)
if (shouldChoosePantheonBelief)
beliefsToChoose.add(BeliefType.Pantheon, 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())
@ -211,17 +212,19 @@ class ReligionManager {
if (unique.params[1] != "founding") continue
beliefsToChoose.add(BeliefType.Any, unique.params[0].toInt())
}
return beliefsToChoose
}
fun chooseBeliefs(iconName: String?, religionName: String?, beliefs: List<Belief>) {
if (religionState == ReligionState.FoundingReligion) {
foundReligion(iconName!!, religionName!!, beliefs)
return
when(religionState) {
ReligionState.FoundingReligion ->
foundReligion(iconName!!, religionName!!, beliefs)
ReligionState.EnhancingReligion ->
enhanceReligion(beliefs)
else -> return
}
if (religionState == ReligionState.EnhancingReligion)
enhanceReligion(beliefs)
civInfo.updateStatsForNextTurn() // a belief can have an immediate effect on stats
}
@ -256,7 +259,7 @@ class ReligionManager {
foundingCityId = null
shouldChoosePantheonBelief = false
for (unit in civInfo.getCivUnits())
for (unit in civInfo.getCivUnits())
if (unit.hasUnique(UniqueType.ReligiousUnit) && unit.hasUnique(UniqueType.TakeReligionOverBirthCity))
unit.religion = newReligion.name
}
@ -269,13 +272,13 @@ class ReligionManager {
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
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
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
@ -306,7 +309,7 @@ class ReligionManager {
if (unique.params[1] != "enhancing") continue
beliefsToChoose.add(BeliefType.Any, unique.params[0].toInt())
}
return beliefsToChoose
}

View File

@ -21,7 +21,7 @@ class GlobalUniquesTests {
fun initTheWorld() {
game = TestGame()
}
// region stat uniques
@Test
@ -30,12 +30,12 @@ class GlobalUniquesTests {
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val buildingName = game.createBuildingWithUnique("[+1 Food]").name
cityInfo.cityConstructions.addBuilding(buildingName)
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Buildings"]!!.equals(Stats(food=1f)))
}
@Test
fun statsPerCity() {
val civInfo = game.addCiv()
@ -47,53 +47,50 @@ class GlobalUniquesTests {
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Buildings"]!!.equals(Stats(production=1f)))
}
@Test
fun statsPerSpecialist() {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 2)
val building = game.createBuildingWithUnique("[+3 Gold] from every specialist [in this city]")
val specialistName = game.addEmptySpecialist()
building.specialistSlots.add(specialistName,2)
cityInfo.population.addPopulation(2)
building.specialistSlots.add(specialistName, 2)
cityInfo.population.specialistAllocations[specialistName] = 2
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Specialists"]!!.equals(Stats(gold=6f)))
}
@Test
fun statsPerPopulation() {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 4)
val building = game.createBuildingWithUnique("[+3 Gold] per [2] population [in this city]")
cityInfo.population.addPopulation(4)
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Buildings"]!!.gold == 6f)
}
@Test
fun statsPerXPopulation() {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 2)
val building = game.createBuildingWithUnique("[+3 Gold] in cities with [3] or more population")
cityInfo.population.addPopulation(2)
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Buildings"]!!.gold == 0f)
cityInfo.population.setPopulation(5)
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Buildings"]!!.gold == 3f)
}
@Test
fun statsFromCitiesOnSpecificTiles() {
val civInfo = game.addCiv()
@ -101,14 +98,14 @@ class GlobalUniquesTests {
val cityInfo = game.addCity(civInfo, tile, true)
val building = game.createBuildingWithUnique("[+3 Gold] in cities on [${Constants.desert}] tiles")
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Buildings"]!!.gold == 3f)
tile.baseTerrain = Constants.grassland
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Buildings"]!!.gold == 0f)
}
@Test
fun statsSpendingGreatPeople() {
val civInfo = game.addCiv()
@ -123,7 +120,7 @@ class GlobalUniquesTests {
unit.consume()
Assert.assertTrue(civInfo.gold == 250)
}
@Test
fun statsFromTiles() {
game.makeHexagonalMap(2)
@ -136,7 +133,7 @@ class GlobalUniquesTests {
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
Assert.assertTrue(tile2.getTileStats(cityInfo, civInfo).gold == 4f)
}
@Test
fun statsFromTilesWithout() {
game.makeHexagonalMap(3)
@ -149,25 +146,24 @@ class GlobalUniquesTests {
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
game.addTileToCity(cityInfo, tile2)
Assert.assertTrue(tile2.getTileStats(cityInfo, civInfo).gold == 4f)
val tile3 = game.setTileFeatures(Vector2(0f, 2f), Constants.grassland, listOf(Constants.forest))
game.addTileToCity(cityInfo, tile3)
Assert.assertFalse(tile3.getTileStats(cityInfo, civInfo).gold == 4f)
}
@Test
fun statsFromObject() {
game.makeHexagonalMap(1)
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 2)
val specialist = game.addEmptySpecialist()
val building = game.createBuildingWithUnique("[+3 Faith] from every [${specialist}]")
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.population.addPopulation(2)
cityInfo.population.specialistAllocations[specialist] = 2
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Specialists"]!!.faith == 6f)
@ -177,18 +173,18 @@ class GlobalUniquesTests {
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
Assert.assertTrue(tile2.getTileStats(cityInfo, civInfo).faith == 3f)
cityInfo.cityConstructions.removeBuilding(building2.name)
val emptyBuilding = game.createBuildingWithUniques()
val building3 = game.createBuildingWithUnique("[+3 Faith] from every [${emptyBuilding.name}]")
cityInfo.cityConstructions.addBuilding(emptyBuilding.name)
cityInfo.cityConstructions.addBuilding(building3.name)
cityInfo.cityStats.update()
Assert.assertTrue(cityInfo.cityStats.finalStatList["Buildings"]!!.faith == 3f)
}
@Test
fun statsFromTradeRoute() {
game.makeHexagonalMap(3)
@ -206,10 +202,10 @@ class GlobalUniquesTests {
city2.cityStats.update()
println(city2.isConnectedToCapital())
println(city2.cityStats.finalStatList)
Assert.assertTrue(city2.cityStats.finalStatList["Trade routes"]!!.science == 30f)
}
@Test
fun statsFromGlobalCitiesFollowingReligion() {
val civ1 = game.addCiv()
@ -218,17 +214,34 @@ class GlobalUniquesTests {
religion.founderBeliefs.add(belief.name)
val civ2 = game.addCiv()
val tile = game.getTile(Vector2(0f,0f))
val cityOfCiv2 = game.addCity(civ2, tile)
cityOfCiv2.population.setPopulation(1) // Need someone to be converted
val cityOfCiv2 = game.addCity(civ2, tile, initialPopulation = 1) // Need someone to be converted
cityOfCiv2.religion.addPressure(religion.name, 1000)
Assert.assertTrue(cityOfCiv2.religion.getMajorityReligionName() == religion.name)
civ1.updateStatsForNextTurn()
Assert.assertTrue(civ1.statsForNextTurn.science == 30f)
}
@Test
fun happinessFromGlobalCitiesFollowingReligion() {
val civ1 = game.addCiv()
val religion = game.addReligion(civ1)
val belief = game.addBelief(BeliefType.Founder, "[+42 Happiness] for each global city following this religion")
religion.founderBeliefs.add(belief.name)
val civ2 = game.addCiv()
val tile = game.getTile(Vector2(0f,0f))
val cityOfCiv2 = game.addCity(civ2, tile, initialPopulation = 1) // Need someone to be converted
cityOfCiv2.religion.addPressure(religion.name, 1000)
civ1.updateStatsForNextTurn()
val baseHappiness = civ1.getDifficulty().baseHappiness
// Since civ1 has no cities, there are no other happiness sources
Assert.assertTrue(civ1.happinessForNextTurn == baseHappiness + 42)
}
@Test
fun statsFromGlobalFollowers() {
val civ1 = game.addCiv()
@ -237,21 +250,20 @@ class GlobalUniquesTests {
religion.founderBeliefs.add(belief.name)
val civ2 = game.addCiv()
val tile = game.getTile(Vector2(0f,0f))
val cityOfCiv2 = game.addCity(civ2, tile)
cityOfCiv2.population.setPopulation(9) // Need people to be converted
val cityOfCiv2 = game.addCity(civ2, tile, initialPopulation = 9) // Need people to be converted
cityOfCiv2.religion.addPressure(religion.name, 1000000000) // To completely overwhelm the default atheism in a city
civ1.updateStatsForNextTurn()
println(civ1.statsForNextTurn.science)
Assert.assertTrue(civ1.statsForNextTurn.science == 90f)
}
// endregion
// region stat percentage bonus providing uniques
@Test
fun statPercentBonus() {
val civ = game.addCiv()
@ -260,12 +272,12 @@ class GlobalUniquesTests {
val building = game.createBuildingWithUniques(arrayListOf("[+10 Science]", "[+200]% [Science]"))
city.cityConstructions.addBuilding(building.name)
city.cityStats.update()
println(city.cityStats.finalStatList)
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.science == 30f)
}
// endregion
}

View File

@ -57,7 +57,7 @@ class TestGame {
for (tile in row)
if (tile != null)
tile.baseTerrain = baseTerrain
gameInfo.tileMap = newTileMap
}
@ -65,7 +65,7 @@ class TestGame {
fun makeHexagonalMap(newRadius: Int, baseTerrain: String = Constants.desert) {
val newTileMap = TileMap(newRadius, ruleset, tileMap.mapParameters.worldWrap)
newTileMap.mapParameters.mapSize = MapSizeNew(newRadius)
for (row in tileMap.tileMatrix)
for (tile in row)
if (tile != null)
@ -73,9 +73,9 @@ class TestGame {
gameInfo.tileMap = newTileMap
}
fun getTile(position: Vector2) = tileMap[position]
/** Sets the [terrain] and [features] of the tile at [position], and then returns it */
fun setTileFeatures(position: Vector2, terrain: String = Constants.desert, features: List<String> = listOf()): TileInfo {
val tile = tileMap[position]
@ -86,8 +86,8 @@ class TestGame {
}
tile.setTerrainTransients()
return tile
}
}
fun addCiv(uniques: List<String> = emptyList(), isPlayer: Boolean = false, cityState: CityStateType? = null): CivilizationInfo {
val nationName = "Nation-${objectsCreated++}"
ruleset.nations[nationName] = Nation().apply {
@ -111,9 +111,15 @@ class TestGame {
return civInfo
}
fun addCity(civInfo: CivilizationInfo, tile: TileInfo, replacePalace: Boolean = false): CityInfo {
fun addCity(
civInfo: CivilizationInfo,
tile: TileInfo,
replacePalace: Boolean = false,
initialPopulation: Int = 0
): CityInfo {
val cityInfo = CityInfo(civInfo, tile.position)
cityInfo.population.addPopulation(-1) // Remove population
if (initialPopulation != 1)
cityInfo.population.addPopulation(initialPopulation - 1) // With defaults this will remove population
if (replacePalace && civInfo.cities.size == 1) {
// Add a capital indicator without any other stats
@ -123,7 +129,7 @@ class TestGame {
}
return cityInfo
}
fun addTileToCity(city: CityInfo, tile: TileInfo) {
city.tiles.add(tile.position)
}
@ -161,7 +167,7 @@ class TestGame {
gameInfo.religions[religion.name] = religion
return religion
}
fun addBelief(type: BeliefType = BeliefType.Any, vararg uniques: String): Belief {
val belief = Belief()
belief.name = "Belief-${objectsCreated++}"
@ -170,4 +176,4 @@ class TestGame {
ruleset.beliefs[belief.name] = belief
return belief
}
}
}