Founding Religions (#4505)

* Fixed crashes on loading save games with religion

* Added missing credit

* Religious cities now show religion icons in the city button

* Add icons for religions

* You can now found beliefs, with snazzy icons!

* Fixed bug which made prophets impossible to generate

* Added missing translatable strings

* Fixed translation tests properly

* Implemented requested changes

* Implemented part of the requested changes

* Removed SplitPane in favor of Table

* Removed unused code

* Capped the amount of foundable religions to the amount of religions
This commit is contained in:
Xander Lenstra 2021-07-14 21:09:51 +02:00 committed by GitHub
parent 477051c616
commit 2752c713b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 975 additions and 675 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -0,0 +1,7 @@
[
"Buddhism",
"Christianity",
"Hinduism",
"Islam",
"Taoism"
]

View File

@ -1477,7 +1477,8 @@
{
"name": "Great Prophet",
"unitType": "Civilian",
"uniques": ["Can construct [Holy site] if it hasn't spread religion yet", "Can spread religion [4] times","Great Person - [Faith]", "Unbuildable"],
"uniques": ["Can construct [Holy site] if it hasn't spread religion yet", "Can spread religion [4] times",
"May found a religion", "Great Person - [Faith]", "Unbuildable"],
"movement": 2
},
{

View File

@ -723,6 +723,7 @@ Your trade mission to [civName] has earned you [goldAmount] gold and [influenceA
Hurry Wonder = Versnel Wonder
Spread Religion = Verkondig Religie
Spread [religionName] = Verkondig [religionName]
Found a Religion = Begin een religie
Your citizens have been happy with your rule for so long that the empire enters a Golden Age! = Jouw dorpelingen zijn voor zo een lange tijd blij met jouw leiderschap dat jouw rijk de Gulden Eeuw binnen gaat.
You have entered the [newEra]! = Jij bent in het/de [newEra] aangekomen!
[civName] has entered the [eraName]! = [civName] is aangekomen in de [eraName]!

View File

@ -679,6 +679,7 @@ Your trade mission to [civName] has earned you [goldAmount] gold and [influenceA
Hurry Wonder =
Spread Religion =
Spread [religionName] =
Found a Religion =
Your citizens have been happy with your rule for so long that the empire enters a Golden Age! =
You have entered the [newEra]! =
[civName] has entered the [eraName]! =
@ -904,6 +905,11 @@ Unlocked at =
Gain 2 free technologies =
All policies adopted =
# Religions
Choose an Icon and name for your Religion =
Found [religionName] =
# Terrains
Impassable =

View File

@ -395,7 +395,7 @@ object Battle {
UncivGame.Current.settings.addCompletedTutorialTask("Conquer a city")
} else {
city.puppetCity(attackerCiv)
if (city.population.population < 4 && !city.isOriginalCapital) {
if (city.population.population < 4 && city.canBeDestroyed()) {
city.annexCity()
city.isBeingRazed = true
}

View File

@ -433,7 +433,7 @@ class CityInfo {
}
} else population.nextTurn(foodForNextTurn())
if (civInfo.gameInfo.hasReligionEnabled()) religion.getAffectedBySurroundingCities()
// if (civInfo.gameInfo.hasReligionEnabled()) religion.getAffectedBySurroundingCities()
if (this in civInfo.cities) { // city was not destroyed
health = min(health + 20, getMaxHealth())
@ -442,10 +442,9 @@ class CityInfo {
}
fun destroyCity(overrideSafeties: Boolean = false) {
// Original capitals can't be destroyed.
// Unless they are captured by a one-city-challenger for some reason.
// This was tested in the original.
if (isOriginalCapital && !overrideSafeties) return
// Original capitals and holy cities cannot be destroyed,
// unless, of course, they are captured by a one-city-challenger.
if (!canBeDestroyed() && !overrideSafeties) return
for (airUnit in getCenterTile().airUnits.toList()) airUnit.destroy() //Destroy planes stationed in city
@ -594,6 +593,14 @@ class CityInfo {
.filter { it.params.none { param -> param == "in this city" } }
// Note that we don't query religion here, as those only have local effects (for now at least)
}
fun isHolyCity(): Boolean {
return civInfo.gameInfo.religions.values.any { it.holyCityId == id }
}
fun canBeDestroyed(): Boolean {
return !isCapital() && !isHolyCity()
}
//endregion
}

View File

@ -1,5 +1,6 @@
package com.unciv.logic.civilization
import com.unciv.logic.city.CityInfo
import com.unciv.logic.map.MapUnit
import com.unciv.models.Religion
import com.unciv.models.ruleset.Belief
@ -15,7 +16,7 @@ class ReligionManager {
var religion: Religion? = null
// You might ask why this is the transient variable, and not the one in GameInfo.
// After all, filling a hashmap is much easier than later distributing its contents over multiple classes.
// I would agree that that is better. However, there is, of course, a problem.
// There is, however, a problem.
// When founding a religion, the religion of your pantheon doesn't immediately disappear.
// It just stops growing. Your new religion will then have to spread out from your holy city
// and convert these cities. This means, that civilizations can have multiple active religions
@ -25,9 +26,18 @@ class ReligionManager {
private var greatProphetsEarned = 0
var religionState = ReligionState.None
private set
private var foundingCityId: String? = null
// Only used for keeping track of the city a prophet was used when founding a religion
fun clone(): ReligionManager {
val clone = ReligionManager()
clone.foundingCityId = foundingCityId
clone.storedFaith = storedFaith
clone.religionState = religionState
clone.greatProphetsEarned = greatProphetsEarned
return clone
}
@ -45,17 +55,7 @@ class ReligionManager {
}
fun startTurn() {
if (canGenerateProphet()) {
val prophetSpawnChange = (5f + storedFaith - faithForNextGreatProphet()) / 100f
if (Random(civInfo.gameInfo.turns).nextFloat() < prophetSpawnChange) {
val birthCity = civInfo.cities.filter { it.religion.getMajorityReligion() == religion!!.name }.random()
val prophet = civInfo.addUnit("Great Prophet", birthCity)
if (prophet == null) return
prophet.religion = religion!!.name
prophet.abilityUsedCount["Religion Spread"] = 0
storedFaith -= faithForNextGreatProphet()
}
}
if (canGenerateProphet()) generateProphet()
}
fun endTurn(faithFromNewTurn: Int) {
@ -65,8 +65,8 @@ class ReligionManager {
private fun faithForPantheon() = 10 + civInfo.gameInfo.civilizations.count { it.isMajorCiv() && it.religionManager.religion != null } * 5
fun canFoundPantheon(): Boolean {
if (religion != null) return false
if (!civInfo.gameInfo.hasReligionEnabled()) return false
if (religionState != ReligionState.None) return false
if (!civInfo.isMajorCiv()) return false
if (civInfo.gameInfo.ruleSet.beliefs.values.none { isPickablePantheonBelief(it) })
return false
@ -75,7 +75,7 @@ class ReligionManager {
fun isPickablePantheonBelief(belief: Belief): Boolean {
if (belief.type != "Pantheon") return false
if (civInfo.gameInfo.civilizations.any { it.religionManager.religion != null && it.religionManager.religion!!.pantheonBeliefs.contains(belief.name)})
if (civInfo.gameInfo.civilizations.any { it.religionManager.religion != null && it.religionManager.religion!!.followerBeliefs.contains(belief.name)})
return false
return true
}
@ -83,23 +83,101 @@ class ReligionManager {
fun choosePantheonBelief(belief: Belief) {
storedFaith -= faithForPantheon()
religion = Religion(belief.name, civInfo.gameInfo, civInfo.civName)
religion!!.pantheonBeliefs.add(belief.name)
religion!!.followerBeliefs.add(belief.name)
civInfo.gameInfo.religions[belief.name] = religion!!
// This should later be changed when religions can have multiple beliefs
civInfo.getCapital().religion[belief.name] = 100 // Capital is religious, other cities are not
religionState = ReligionState.Pantheon
}
// https://www.reddit.com/r/civ/comments/2m82wu/can_anyone_detail_the_finer_points_of_great/
// Game files (globaldefines.xml)
fun faithForNextGreatProphet() = ((200 + 100 * greatProphetsEarned * (greatProphetsEarned + 1)/2) * civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt()
private fun faithForNextGreatProphet() = (
(200 + 100 * greatProphetsEarned * (greatProphetsEarned + 1) / 2) *
civInfo.gameInfo.gameParameters.gameSpeed.modifier
).toInt()
fun canGenerateProphet(): Boolean {
if (religion == null || !religion!!.hasPantheon()) return false // First get a pantheon, then we'll talk about a real religion
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 (storedFaith < faithForNextGreatProphet()) return false
// In the base game, great prophets shouldn't generate anymore starting from the industrial era
// This is difficult to implement in the current codebase, probably requires an additional variable in eras.json
// Also only if you either [have founded a religion] or [the max amount of religions (players/2 + 1) has not been reached].
// As this is yet to be implemented, this function does almost nothing
return true
}
private fun generateProphet() {
val prophetSpawnChange = (5f + storedFaith - faithForNextGreatProphet()) / 100f
if (Random(civInfo.gameInfo.turns).nextFloat() < prophetSpawnChange) {
val birthCity =
if (religionState == ReligionState.Pantheon) civInfo.getCapital()
else civInfo.cities.firstOrNull { it.id == religion!!.holyCityId }
val prophet = civInfo.addUnit("Great Prophet", birthCity)
if (prophet == null) return
prophet.religion = religion!!.name
prophet.abilityUsedCount["Religion Spread"] = 0
storedFaith -= faithForNextGreatProphet()
}
}
fun mayUseGreatProphetAtAll(prophet: MapUnit): Boolean {
if (religion == null) return false // First found a pantheon
if (religion!!.isMajorReligion()) return false // Already created a major religion
if (prophet.abilityUsedCount["Religion Spread"] != 0) return false // Already used its power for other things
val foundedReligionsCount = civInfo.gameInfo.civilizations.count {
it.religionManager.religion != null && it.religionManager.religion!!.isMajorReligion()
}
if (foundedReligionsCount >= civInfo.gameInfo.civilizations.count { it.isMajorCiv() } / 2 + 1)
return false // Too bad, too many religions have already been founded.
if (foundedReligionsCount >= civInfo.gameInfo.ruleSet.religions.count())
return false
// Mod maker did not provide enough religions for the amount of civs present
return true
}
fun mayUseGreatProphetNow(prophet: MapUnit): Boolean {
if (!mayUseGreatProphetAtAll(prophet)) return false
if (!prophet.getTile().isCityCenter()) return false
return true
}
fun useGreatProphet(prophet: MapUnit) {
if (!mayUseGreatProphetNow(prophet)) return // How did you do this?
religionState = ReligionState.FoundingReligion
foundingCityId = prophet.getTile().getCity()!!.id
}
fun foundReligion(iconName: String, name: String, founderBelief: String, followerBelief: String) {
val newReligion = Religion(name, civInfo.gameInfo, civInfo.civName)
newReligion.iconName = iconName
if (religion != null) {
newReligion.followerBeliefs.addAll(religion!!.followerBeliefs)
}
newReligion.followerBeliefs.add(followerBelief)
newReligion.founderBeliefs.add(founderBelief)
newReligion.holyCityId = foundingCityId
religion = newReligion
civInfo.gameInfo.religions[name] = newReligion
religionState = ReligionState.Religion
val holyCity = civInfo.cities.firstOrNull { it.id == newReligion.holyCityId }!!
holyCity.religion.clear()
holyCity.religion[name] = 100
foundingCityId = null
}
}
enum class ReligionState {
None,
Pantheon,
FoundingReligion, // Great prophet used, but religion has not yet been founded
Religion,
EnhancingReligion, // Great prophet used, but religion has not yet been enhanced
EnhancedReligion
}

View File

@ -7,34 +7,39 @@ import com.unciv.models.stats.INamed
/** Data object for Religions */
class Religion() : INamed {
var pantheonBeliefs: HashSet<String> = hashSetOf()
override lateinit var name: String
var iconName: String = "Pantheon"
lateinit var foundingCivName: String
var holyCityId: String? = null
var founderBeliefs: HashSet<String> = hashSetOf()
var followerBeliefs: HashSet<String> = hashSetOf()
override lateinit var name: String
lateinit var foundingCivName: String
@Transient
lateinit var gameInfo: GameInfo
constructor(name: String, gameInfo: GameInfo, foundingCivName: String) : this() {
this.name = name
this.foundingCivName = foundingCivName
this.gameInfo = gameInfo
}
fun clone(): Religion {
val toReturn = Religion(name, gameInfo, foundingCivName)
toReturn.pantheonBeliefs.addAll(pantheonBeliefs)
toReturn.iconName = iconName
toReturn.holyCityId = holyCityId
toReturn.founderBeliefs.addAll(founderBeliefs)
toReturn.followerBeliefs.addAll(followerBeliefs)
return toReturn
}
fun setTransients(gameInfo: GameInfo) {
this.gameInfo = gameInfo
}
private fun getUniquesOfBeliefs(beliefs: HashSet<String>): Sequence<Unique> {
val rulesetBeliefs = gameInfo.ruleSet.beliefs
return beliefs.mapNotNull {
@ -42,24 +47,26 @@ class Religion() : INamed {
else rulesetBeliefs[it]!!.uniqueObjects
}.flatten().asSequence()
}
fun getFollowerUniques(): Sequence<Unique> {
return getUniquesOfBeliefs((followerBeliefs + pantheonBeliefs).toHashSet())
return getUniquesOfBeliefs(followerBeliefs)
}
fun getFounderUniques(): Sequence<Unique> {
return getUniquesOfBeliefs(founderBeliefs)
}
fun isPantheon(): Boolean {
return hasPantheon() && !isMajorReligion()
}
fun isMajorReligion(): Boolean {
return founderBeliefs.isNotEmpty() && followerBeliefs.isNotEmpty()
if ("" in followerBeliefs) return true // Temporary as a result of follower beliefs not yet being implemented
return founderBeliefs.isNotEmpty() && followerBeliefs.any { gameInfo.ruleSet.beliefs[it]!!.type == "Follower"}
}
fun hasPantheon(): Boolean {
return pantheonBeliefs.isNotEmpty()
// Temporary as a result of follower beliefs not yet being implemented
return followerBeliefs.any { it != "" && gameInfo.ruleSet.beliefs[it]!!.type == "Pantheon" }
}
}

View File

@ -35,5 +35,6 @@ enum class UnitActionType(val value: String) {
StartGoldenAge("Start Golden Age"),
HurryWonder("Hurry Wonder"),
ConductTradeMission("Conduct Trade Mission"),
FoundReligion("Found a Religion"),
DisbandUnit("Disband unit")
}

View File

@ -45,21 +45,23 @@ class Ruleset {
var modWithReligionLoaded = false
var name = ""
val beliefs = LinkedHashMap<String, Belief>()
val religions = ArrayList<String>()
val buildings = LinkedHashMap<String, Building>()
val terrains = LinkedHashMap<String, Terrain>()
val tileResources = LinkedHashMap<String, TileResource>()
val tileImprovements = LinkedHashMap<String, TileImprovement>()
val technologies = LinkedHashMap<String, Technology>()
val difficulties = LinkedHashMap<String, Difficulty>()
val eras = LinkedHashMap<String, Era>()
val units = LinkedHashMap<String, BaseUnit>()
val unitPromotions = LinkedHashMap<String, Promotion>()
val nations = LinkedHashMap<String, Nation>()
val policies = LinkedHashMap<String, Policy>()
val policyBranches = LinkedHashMap<String, PolicyBranch>()
val quests = LinkedHashMap<String, Quest>()
val specialists = LinkedHashMap<String, Specialist>()
val policyBranches = LinkedHashMap<String, PolicyBranch>()
val policies = LinkedHashMap<String, Policy>()
val beliefs = LinkedHashMap<String, Belief>()
val difficulties = LinkedHashMap<String, Difficulty>()
val technologies = LinkedHashMap<String, Technology>()
val terrains = LinkedHashMap<String, Terrain>()
val tileImprovements = LinkedHashMap<String, TileImprovement>()
val tileResources = LinkedHashMap<String, TileResource>()
val units = LinkedHashMap<String, BaseUnit>()
val unitPromotions = LinkedHashMap<String, Promotion>()
val mods = LinkedHashSet<String>()
var modOptions = ModOptions()
@ -82,10 +84,12 @@ class Ruleset {
difficulties.putAll(ruleset.difficulties)
eras.putAll(ruleset.eras)
nations.putAll(ruleset.nations)
for (nationToRemove in ruleset.modOptions.nationsToRemove) nations.remove(nationToRemove)
policyBranches.putAll(ruleset.policyBranches)
policies.putAll(ruleset.policies)
beliefs.putAll(ruleset.beliefs)
quests.putAll(ruleset.quests)
religions.addAll(ruleset.religions)
specialists.putAll(ruleset.specialists)
technologies.putAll(ruleset.technologies)
for (techToRemove in ruleset.modOptions.techsToRemove) technologies.remove(techToRemove)
@ -95,7 +99,6 @@ class Ruleset {
unitPromotions.putAll(ruleset.unitPromotions)
units.putAll(ruleset.units)
for (unitToRemove in ruleset.modOptions.unitsToRemove) units.remove(unitToRemove)
for (nationToRemove in ruleset.modOptions.nationsToRemove) nations.remove(nationToRemove)
mods += ruleset.mods
modWithReligionLoaded = modWithReligionLoaded || ruleset.modWithReligionLoaded
}
@ -110,6 +113,7 @@ class Ruleset {
mods.clear()
nations.clear()
policies.clear()
religions.clear()
quests.clear()
technologies.clear()
terrains.clear()
@ -157,6 +161,7 @@ class Ruleset {
val erasFile = folderHandle.child("Eras.json")
if (erasFile.exists()) eras += createHashmap(jsonParser.getFromJson(Array<Era>::class.java, erasFile))
val unitsFile = folderHandle.child("Units.json")
if (unitsFile.exists()) units += createHashmap(jsonParser.getFromJson(Array<BaseUnit>::class.java, unitsFile))
@ -189,6 +194,9 @@ class Ruleset {
if (beliefsFile.exists())
beliefs += createHashmap(jsonParser.getFromJson(Array<Belief>::class.java, beliefsFile))
val religionsFile = folderHandle.child("Religions.json")
if (religionsFile.exists())
religions += jsonParser.getFromJson(Array<String>::class.java, religionsFile).toList()
val nationsFile = folderHandle.child("Nations.json")
if (nationsFile.exists()) {

View File

@ -147,7 +147,7 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() {
val razeCityButton = "Raze city".toTextButton()
razeCityButton.labelCell.pad(10f)
razeCityButton.onClick { city.isBeingRazed = true; update() }
if (!canChangeState || city.isOriginalCapital)
if (!canChangeState || !city.canBeDestroyed())
razeCityButton.disable()
razeCityButtonHolder.add(razeCityButton).colspan(cityPickerTable.columns)

View File

@ -0,0 +1,99 @@
package com.unciv.ui.pickerscreens
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.*
import com.badlogic.gdx.utils.Align
import com.unciv.UncivGame
import com.unciv.logic.GameInfo
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.UncivSound
import com.unciv.models.ruleset.Belief
import com.unciv.models.translations.tr
import com.unciv.ui.utils.*
import kotlin.math.max
class FoundReligionPickerScreen (
private val choosingCiv: CivilizationInfo,
private val gameInfo: GameInfo
): PickerScreen() {
// Roughly follows the layout of the original (although I suck at UI designing, so please improve this)
private val topReligionIcons = Table() // Top of the layout, contains icons for religions
private val leftChosenBeliefs: ScrollPane // Left middle part, contains buttons to select the types of beliefs to choose
private val rightBeliefsToChoose: ScrollPane // Right middle part, contains the beliefs to choose
private val middlePanes = Table()
private var previouslySelectedIcon: Button? = null
private var iconName: String? = null
private var religionName: String? = null
private var chosenFounderBelief: Belief? = null
private var chosenFollowerBelief: Belief? = null
init {
closeButton.isVisible = true
setDefaultCloseAction()
setupReligionIcons()
leftChosenBeliefs = ScrollPane(Table())
rightBeliefsToChoose = ScrollPane(Table())
middlePanes.add(leftChosenBeliefs)
middlePanes.addSeparatorVertical()
middlePanes.add(rightBeliefsToChoose)
topTable.add(topReligionIcons).row()
// commented out, as the middle panes will always be empty for now, and this will create a random line otherwise
// topTable.addSeparator()
topTable.add(middlePanes)
rightSideButton.label = "Choose a religion".toLabel()
rightSideButton.onClick(UncivSound.Choir) {
choosingCiv.religionManager.foundReligion(iconName!!, religionName!!, "", "", /**chosenFollowerBelief!!.name, chosenFounderBelief!!.name*/)
UncivGame.Current.setWorldScreen()
}
}
private fun checkAndEnableRightSideButton() {
if (religionName == null) return
// check if founder belief chosen
// check if follower belief chosen
rightSideButton.enable()
}
private fun setupReligionIcons() {
topReligionIcons.clear()
// This should later be replaced with a user-modifiable text field, but not in this PR
val descriptionLabel = "Choose an Icon and name for your Religion".toLabel()
val iconsTable = Table()
iconsTable.align(Align.center)
for (religionName in gameInfo.ruleSet.religions) {
if (gameInfo.religions.keys.any { it == religionName }) continue
val image = ImageGetter.getReligionIcon(religionName)
image.color = Color.BLACK
val icon = image.surroundWithCircle(60f)
val button = Button(icon, skin)
val translatedReligionName = religionName.tr()
button.onClick {
if (previouslySelectedIcon != null) {
previouslySelectedIcon!!.enable()
}
iconName = religionName
this.religionName = religionName
previouslySelectedIcon = button
button.disable()
descriptionLabel.setText(translatedReligionName)
rightSideButton.label = "Found [$translatedReligionName]".toLabel()
checkAndEnableRightSideButton()
}
if (religionName == this.religionName) button.disable()
iconsTable.add(button).pad(5f)
}
iconsTable.row()
topReligionIcons.add(iconsTable).padBottom(10f).row()
topReligionIcons.add(descriptionLabel).center()
}
}

View File

@ -12,7 +12,7 @@ open class PickerScreen(val disableScroll: Boolean = false) : CameraStageBaseScr
protected var descriptionLabel: Label
protected var rightSideGroup = VerticalGroup()
protected var rightSideButton: TextButton
private var screenSplit = 0.85f
protected var screenSplit = 0.85f
/**
* The table displaying the choices from which to pick (usually).

View File

@ -251,6 +251,13 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab
nationIcon.color = secondaryColor
iconTable.add(nationIcon).size(20f)
}
val cityReligionName = city.religion.getMajorityReligion()
if (cityReligionName != null) {
val cityReligion = city.civInfo.gameInfo.religions[cityReligionName]!!
val religionImage = ImageGetter.getReligionIcon(cityReligion.iconName)
iconTable.add(religionImage).size(20f).padLeft(5f).fillY()
}
iconTable.pack()
cityStrengthLabel.x = label.x // so it'll be aligned right above the city name

View File

@ -56,8 +56,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
private fun updateLeftSideTable() {
leftSideTable.clear()
for (civ in viewingCiv.gameInfo.civilizations
.filterNot { it.isDefeated() || it == viewingCiv || it.isBarbarian() || it.isSpectator() }) {
if (!viewingCiv.knows(civ)) continue
.filterNot { it.isDefeated() || it == viewingCiv || it.isBarbarian() || it.isSpectator() || viewingCiv.knows(it) }) {
val civIndicator = ImageGetter.getNationIndicator(civ.nation, 100f)

View File

@ -287,6 +287,10 @@ object ImageGetter {
}
return circle
}
fun getReligionIcon(iconName: String): Image {
return getImage("ReligionIcons/$iconName")
}
fun getBlue() = Color(0x004085bf)

View File

@ -142,7 +142,7 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu
close()
}
add("Raze".toTextButton().apply {
if (city.isOriginalCapital) disable()
if (!city.canBeDestroyed()) disable()
else {
onClick(function = razeAction)
keyPressDispatcher['r'] = razeAction

View File

@ -19,6 +19,7 @@ import com.unciv.UncivGame
import com.unciv.logic.GameInfo
import com.unciv.logic.GameSaver
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.ReligionState
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.models.Tutorial
import com.unciv.models.UncivSound
@ -697,6 +698,11 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Cam
NextTurnAction("Found Pantheon", Color.WHITE) {
game.setScreen(PantheonPickerScreen(viewingCiv, gameInfo))
}
viewingCiv.religionManager.religionState == ReligionState.FoundingReligion ->
NextTurnAction("Found Religion", Color.WHITE) {
game.setScreen(FoundReligionPickerScreen(viewingCiv, gameInfo))
}
else ->
NextTurnAction("${Fonts.turn}{Next turn}", Color.WHITE) {

View File

@ -63,6 +63,7 @@ object UnitActions {
//
addCreateWaterImprovements(unit, actionList)
addGreatPersonActions(unit, actionList, tile)
addFoundReligionAction(unit, actionList, tile)
addSpreadReligionActions(unit, actionList, tile)
actionList += getImprovementConstructionActions(unit, tile)
addDisbandAction(actionList, unit, worldScreen)
@ -372,7 +373,8 @@ object UnitActions {
unit.civInfo.tech.addScience(unit.civInfo.tech.getScienceFromGreatScientist())
addGoldPerGreatPersonUsage(unit.civInfo)
unit.destroy()
}.takeIf { unit.civInfo.tech.currentTechnologyName() != null })
}.takeIf { unit.civInfo.tech.currentTechnologyName() != null }
)
}
"Can start an []-turn golden age" -> {
val turnsToGoldenAge = unique.params[0].toInt()
@ -382,7 +384,8 @@ object UnitActions {
unit.civInfo.goldenAges.enterGoldenAge(turnsToGoldenAge)
addGoldPerGreatPersonUsage(unit.civInfo)
unit.destroy()
}.takeIf { unit.currentTile.getOwner() != null && unit.currentTile.getOwner() == unit.civInfo })
}.takeIf { unit.currentTile.getOwner() != null && unit.currentTile.getOwner() == unit.civInfo }
)
}
"Can speed up construction of a wonder" -> {
val canHurryWonder = if (!tile.isCityCenter()) false
@ -400,7 +403,8 @@ object UnitActions {
}
addGoldPerGreatPersonUsage(unit.civInfo)
unit.destroy()
}.takeIf { canHurryWonder })
}.takeIf { canHurryWonder }
)
}
"Can undertake a trade mission with City-State, giving a large sum of gold and [] Influence" -> {
val canConductTradeMission = tile.owningCity?.civInfo?.isCityState() == true
@ -419,16 +423,30 @@ object UnitActions {
tile.owningCity!!.civInfo.civName, NotificationIcon.Gold, NotificationIcon.Culture)
addGoldPerGreatPersonUsage(unit.civInfo)
unit.destroy()
}.takeIf { canConductTradeMission })
}.takeIf { canConductTradeMission }
)
}
}
}
private fun addFoundReligionAction(unit: MapUnit, actionList: ArrayList<UnitAction>, tile: TileInfo) {
if (!unit.hasUnique("May found a religion")) return // should later also include enhance religion
if (!unit.civInfo.religionManager.mayUseGreatProphetAtAll(unit)) return
actionList += UnitAction(UnitActionType.FoundReligion,
uncivSound = UncivSound.Choir,
action = {
addGoldPerGreatPersonUsage(unit.civInfo)
unit.civInfo.religionManager.useGreatProphet(unit)
unit.destroy()
}.takeIf { unit.civInfo.religionManager.mayUseGreatProphetNow(unit) }
)
}
private fun addSpreadReligionActions(unit: MapUnit, actionList: ArrayList<UnitAction>, tile: TileInfo) {
if (!unit.hasUnique("Can spread religion [] times")) return
if (unit.religion == null) return
val maxReligionSpreads = unit.maxReligionSpreads()
if (!unit.abilityUsedCount.containsKey("Religion Spread")) return // This should be impossible anways, but just in case
if (!unit.abilityUsedCount.containsKey("Religion Spread")) return // This should be impossible anyways, but just in case
if (maxReligionSpreads <= unit.abilityUsedCount["Religion Spread"]!!) return
val city = tile.getCity()
actionList += UnitAction(UnitActionType.SpreadReligion,

View File

@ -178,6 +178,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
* [Fort](https://thenounproject.com/term/fort/1697645/) By Adrien Coquet
* [Citadel](https://thenounproject.com/term/fort/1697646/) By Adrien Coquet
* [Village](https://thenounproject.com/search/?q=city+center&i=476338) by Andrey Vasiliev
* [pumping station](https://thenounproject.com/search/?q=dike&i=555172) by Peter van Driel for Polder
## Buildings
@ -551,6 +552,14 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
* [Anchor](https://thenounproject.com/term/anchor/676586) by Gregor Cresnar for Amphibious
* [survival knife](https://thenounproject.com/search/?q=survival&i=2663392) by b faris for Survivalism
## Religions
* [Lightning Bolt](https://thenounproject.com/search/?q=lightning+bolt&i=154820) by sian huxtable for Pantheon
* [Christianity](https://thenounproject.com/search/?q=christianity&i=181) by Public Domain Nouns for Christianity
* [Islam](https://thenounproject.com/search/?q=Islam&i=2431350) by Muhammed Riza for Islam
* [taoism](https://thenounproject.com/search/?q=Taoism&i=740812) by parkjisun for Taosim
* [Buddhism](https://thenounproject.com/search/?q=buddhism&i=38764) by Julio Yanes for Buddhism
* [Hinduism](https://thenounproject.com/search/?q=hinduism&i=20383) by Mugda Damle for Hinduism
## Others
* [Circle](https://thenounproject.com/term/circle/1841891/) By Aybige