Implemented the enhancing of religions (#4965)

* Generalize the concept of founding religions in preparation of enhancing

* Implemented enhancing religions

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

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

* Parameterized 'enhance religion' action, fixed tests

* Implemented requested changes & simplified beliefContainer a lot

* Fixed rename

* Updated code to include features added in the meantime

* Merge branch 'master' into enhanceReligions

Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
Xander Lenstra 2021-08-28 21:36:11 +02:00 committed by GitHub
parent 3e22a36bbf
commit 1cc90a3953
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 390 additions and 157 deletions

View File

@ -76,7 +76,7 @@
"name": "Monument to the Gods", "name": "Monument to the Gods",
"type": "Pantheon", "type": "Pantheon",
"uniques": ["+[15]% Production when constructing [Wonders]"] "uniques": ["+[15]% Production when constructing [Wonders]"]
// Should only be ancient/classical era wonders, but implementing that is another can of worms // ToDo: Should only be ancient/classical era wonders, but implementing that is another can of worms
// For that we really should need an era.matchesFilter() AND support for multiple values in // For that we really should need an era.matchesFilter() AND support for multiple values in
// construction.matchesFilter(), so we could write something like: // construction.matchesFilter(), so we could write something like:
//"uniques": ["[+15]% Production when constructing [{Ancient Era} {Wonders}]", //"uniques": ["[+15]% Production when constructing [{Ancient Era} {Wonders}]",
@ -149,7 +149,7 @@
"type": "Follower", "type": "Follower",
"uniques": ["[+2 Production] if this city has at least [1] specialists"] "uniques": ["[+2 Production] if this city has at least [1] specialists"]
}, },
// Missing: Holy Warriors (I have to look up the faith costs for these sometime) // ToDo: Holy Warriors (I have to look up the faith costs for these sometime)
{ {
"name": "Liturgical Drama", "name": "Liturgical Drama",
"type": "Follower", "type": "Follower",
@ -241,6 +241,56 @@
"name": "World Church", "name": "World Church",
"type": "Founder", "type": "Founder",
"uniques": ["[+1 Culture] for every [5] global followers [in foreign cities]"] "uniques": ["[+1 Culture] for every [5] global followers [in foreign cities]"]
},
////////////////////////////////////// Enhancer beliefs ///////////////////////////////////////
{
"name": "Defender of the Faith",
"type": "Enhancer",
"uniques": ["[+20]% Strength for [All] units in [Friendly Land]"],
// ToDo: Should only be friendly territory of cities that follow this religion
},
{
"name": "Holy Order",
"type": "Enhancer",
"uniques": ["[Faith] cost of purchasing [Missionary] units [-30]% ", "[Faith] cost of purchasing [Inquisitor] units [-30]% "]
},
{
"name": "Itinerant Preachers",
"type": "Enhancer",
"uniques": ["Religion naturally spreads to cities [+3] tiles away"]
},
{
"name": "Just War",
"type": "Enhancer",
"uniques": ["[+20]% Strength for [Non-City] units in [Enemy Land]"],
// ToDo: Should only be enemy territory of cities that follow this religion
},
{
"name": "Messiah",
"type": "Enhancer",
"uniques": ["[+25]% Spread Religion Strength for [Great Prophet] units", "[-25]% Faith cost of generating Great Prophet equivalents"]
},
{
"name": "Missionary Zeal",
"type": "Enhancer",
"uniques": ["[+25]% Spread Religion Strength for [Missionary] units"]
},
{
"name": "Religious Texts",
"type": "Enhancer",
"uniques": ["[+34]% Natural religion spread [in all cities]", "[+34]% Natural religion spread [in all cities] with [Printing Press]"]
},
{
"name": "Religious Unity",
"type": "Enhancer",
"uniques": ["[+100]% Natural religion spread to [in City-State cities]"]
},
{
"name": "Reliquary",
"type": "Enhancer",
"uniques": ["[+50 Faith] whenever a Great Person is expended"]
} }
] ]

View File

@ -723,7 +723,7 @@
"culture": 3, "culture": 3,
"isWonder": true, "isWonder": true,
"greatPersonPoints": {"Great Engineer": 2}, "greatPersonPoints": {"Great Engineer": 2},
"uniques": ["+[15]% Strength for units fighting in [Friendly Land]", "uniques": ["+[15]% Strength for [Non-City] units fighting in [Friendly Land]",
"Provides a free [Castle] [in this city]"], "Provides a free [Castle] [in this city]"],
"requiredTech": "Gunpowder", "requiredTech": "Gunpowder",
"quote": "'Bushido is realized in the presence of death. This means choosing death whenever there is a choice between life and death. There is no other reasoning.' - Yamamoto Tsunetomo" "quote": "'Bushido is realized in the presence of death. This means choosing death whenever there is a choice between life and death. There is no other reasoning.' - Yamamoto Tsunetomo"

View File

@ -432,7 +432,7 @@
}, },
{ {
"name": "Nationalism", "name": "Nationalism",
"uniques": ["+[15]% Strength for units fighting in [Friendly Land]"], "uniques": ["+[15]% Strength for [Non-City] units fighting in [Friendly Land]"],
"row": 1, "row": 1,
"column": 5 "column": 5
}, },

View File

@ -1500,8 +1500,9 @@
"name": "Great Prophet", "name": "Great Prophet",
"unitType": "Civilian", "unitType": "Civilian",
"uniques": ["Can construct [Holy site] if it hasn't used other actions yet", "Can [Spread Religion] [4] times", "uniques": ["Can construct [Holy site] if it hasn't used other actions yet", "Can [Spread Religion] [4] times",
"May found a religion", "May enter foreign tiles without open borders", "[-1] Visibility Range", "May found a religion", "May enhance a religion", "May enter foreign tiles without open borders",
"Great Person - [Faith]", "Unbuildable", "Religious Unit", "Hidden when religion is disabled"], "[-1] Visibility Range", "Great Person - [Faith]", "Unbuildable", "Religious Unit",
"Hidden when religion is disabled"],
"movement": 2, "movement": 2,
"religiousStrength": 1000 "religiousStrength": 1000
}, },
@ -1537,9 +1538,8 @@
"name": "Inquisitor", "name": "Inquisitor",
"unitType": "Civilian", "unitType": "Civilian",
"uniques": ["Prevents spreading of religion to the city it is next to", "uniques": ["Prevents spreading of religion to the city it is next to",
// ToDo: change this to an _enhanced_ religion when that is implemented
"Can [Remove Foreign religions from your own cities] [1] times", "Can [Remove Foreign religions from your own cities] [1] times",
"Can be purchased with [Faith] [in all cities in which the majority religion is a major religion]", "Can be purchased with [Faith] [in all cities in which the majority religion is an enhanced religion]",
"[+1] Visibility Range", "Hidden when religion is disabled", "Unbuildable", "Religious Unit" "[+1] Visibility Range", "Hidden when religion is disabled", "Unbuildable", "Religious Unit"
], ],
"movement": 3, "movement": 3,

View File

@ -831,6 +831,7 @@ Spread Religion = Verkondig Religie
Spread [religionName] = Verkondig [religionName] Spread [religionName] = Verkondig [religionName]
Remove Heresy = Verwijder Heidense Denkbeelden Remove Heresy = Verwijder Heidense Denkbeelden
Found a Religion = Richt een religie op Found a Religion = Richt een religie op
Enhance a Religion = Hervorm je religie
Your citizens have been happy with your rule for so long that the empire enters a Golden Age! = Je inwoners zijn al zo lang blij met jouw leiderschap, dat jouw rijk een Gouden Eeuw binnengaat! Your citizens have been happy with your rule for so long that the empire enters a Golden Age! = Je inwoners zijn al zo lang blij met jouw leiderschap, dat jouw rijk een Gouden Eeuw binnengaat!
You have entered the [newEra]! = Jij bent in het/de [newEra] aangekomen! You have entered the [newEra]! = Jij bent in het/de [newEra] aangekomen!
[civName] has entered the [eraName]! = [civName] is aangekomen in de [eraName]! [civName] has entered the [eraName]! = [civName] is aangekomen in de [eraName]!

View File

@ -521,7 +521,7 @@ Received [goldAmount] Gold for capturing [cityName] =
Our proposed trade is no longer relevant! = Our proposed trade is no longer relevant! =
[defender] could not withdraw from a [attacker] - blocked. = [defender] could not withdraw from a [attacker] - blocked. =
[defender] withdrew from a [attacker] = [defender] withdrew from a [attacker] =
[building] has provided [amount] Gold! = By expending your [unit] you gained [Stats]! =
[civName] has stolen your territory! = [civName] has stolen your territory! =
Clearing a [forest] has created [amount] Production for [cityName] = Clearing a [forest] has created [amount] Production for [cityName] =
[civName] assigned you a new quest: [questName]. = [civName] assigned you a new quest: [questName]. =
@ -739,6 +739,8 @@ Spread Religion =
Spread [religionName] = Spread [religionName] =
Remove Heresy = Remove Heresy =
Found a Religion = Found a Religion =
Enhance a Religion =
Enhance [religionName] =
Your citizens have been happy with your rule for so long that the empire enters a Golden Age! = Your citizens have been happy with your rule for so long that the empire enters a Golden Age! =
You have entered the [newEra]! = You have entered the [newEra]! =
[civName] has entered the [eraName]! = [civName] has entered the [eraName]! =

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -45,53 +45,40 @@ class Religion() : INamed {
} }
} }
fun getPantheonBeliefs(): Sequence<Belief> { fun getBeliefs(beliefType: BeliefType): Sequence<Belief> {
return mapToExistingBeliefs(followerBeliefs) val beliefs =
.asSequence() when (beliefType) {
.filter { it.type == BeliefType.Pantheon } BeliefType.Pantheon -> followerBeliefs
BeliefType.Follower -> followerBeliefs
BeliefType.Founder -> founderBeliefs
BeliefType.Enhancer -> founderBeliefs
else -> null!! // This is fine...
} }
fun getFollowerBeliefs(): Sequence<Belief> {
return mapToExistingBeliefs(followerBeliefs)
.asSequence()
.filter { it.type == BeliefType.Follower }
}
fun getFounderBeliefs(): Sequence<Belief> {
return mapToExistingBeliefs(founderBeliefs)
.asSequence()
.filter { it.type == BeliefType.Founder }
}
private fun getUniquesOfBeliefs(beliefs: HashSet<String>): Sequence<Unique> {
return mapToExistingBeliefs(beliefs) return mapToExistingBeliefs(beliefs)
.flatMap { it.uniqueObjects }
.asSequence() .asSequence()
.filter { it.type == beliefType }
} }
fun getFollowerUniques(): Sequence<Unique> { fun getAllBeliefsOrdered(): Sequence<Belief> {
return getUniquesOfBeliefs(followerBeliefs) return mapToExistingBeliefs(followerBeliefs).asSequence().filter { it.type == BeliefType.Pantheon } +
mapToExistingBeliefs(founderBeliefs).asSequence().filter { it.type == BeliefType.Founder } +
mapToExistingBeliefs(followerBeliefs).asSequence().filter { it.type == BeliefType.Follower } +
mapToExistingBeliefs(founderBeliefs).asSequence().filter { it.type == BeliefType.Enhancer }
} }
fun getFounderUniques(): Sequence<Unique> { private fun getUniquesOfBeliefs(beliefs: HashSet<String>) =
return getUniquesOfBeliefs(founderBeliefs) mapToExistingBeliefs(beliefs).asSequence().flatMap { it.uniqueObjects }
}
fun isPantheon(): Boolean { // Currently unused fun getFollowerUniques() = getUniquesOfBeliefs(followerBeliefs)
return hasPantheon() && !isMajorReligion()
}
fun isMajorReligion(): Boolean { fun getFounderUniques() = getUniquesOfBeliefs(founderBeliefs)
return founderBeliefs.isNotEmpty() && followerBeliefs
.any { gameInfo.ruleSet.beliefs[it]!!.type == BeliefType.Follower}
}
fun hasPantheon(): Boolean { // Currently unused fun hasBelief(belief: String) = followerBeliefs.contains(belief) || founderBeliefs.contains(belief)
// Temporary as a result of follower beliefs not yet being implemented
return followerBeliefs.any { it != "" && gameInfo.ruleSet.beliefs[it]!!.type == BeliefType.Pantheon }
}
fun hasBelief(belief: String): Boolean { fun isPantheon() = getBeliefs(BeliefType.Pantheon).any() && !isMajorReligion()
return followerBeliefs.contains(belief) || founderBeliefs.contains(belief)
} fun isMajorReligion() = getBeliefs(BeliefType.Founder).any()
fun isEnhancedReligion() = getBeliefs(BeliefType.Enhancer).any()
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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