Pedia from mainmenu (#6788)

* Make Civilopedia independent of worldScreen or gameInfo

* Make Civilopedia callable from Main Menu

* Era category for Civilopedia

* Era category for Civilopedia - atlas
This commit is contained in:
SomeTroglodyte
2022-05-13 11:36:06 +02:00
committed by GitHub
parent ab82328211
commit 345ca0ec25
16 changed files with 873 additions and 771 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 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

@ -1249,6 +1249,10 @@ Granted by: = Erteilt von:
[bonus] with [tech] = [bonus] mit [tech] [bonus] with [tech] = [bonus] mit [tech]
Difficulty levels = Schwierigkeitsgrade Difficulty levels = Schwierigkeitsgrade
The possible rewards are: = Mögliche Belohnungen: The possible rewards are: = Mögliche Belohnungen:
Eras = Äras
Embarked strength: [amount]† = Stärke eingeschiffter Einheiten: [amount]†
Base unit buy cost: [amount]¤ = Einheiten-Kauf Basispreis: [amount]¤
Research agreement cost: [amount]¤ = Forschungsabkommen kosten: [amount]¤
# Policies # Policies

View File

@ -1255,8 +1255,13 @@ Granted by: =
[bonus] with [tech] = [bonus] with [tech] =
Difficulty levels = Difficulty levels =
The possible rewards are: = The possible rewards are: =
Eras =
Embarked strength: [amount]† =
Base unit buy cost: [amount]¤ =
Research agreement cost: [amount]¤ =
# Policies
S# Policies
Adopt policy = Adopt policy =
Adopt free policy = Adopt free policy =

View File

@ -1,9 +1,11 @@
package com.unciv package com.unciv
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.Input
import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.actions.Actions import com.badlogic.gdx.scenes.scene2d.actions.Actions
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align
import com.unciv.logic.GameInfo import com.unciv.logic.GameInfo
import com.unciv.logic.GameSaver import com.unciv.logic.GameSaver
import com.unciv.logic.GameStarter import com.unciv.logic.GameStarter
@ -12,10 +14,12 @@ import com.unciv.logic.map.MapSize
import com.unciv.logic.map.MapSizeNew import com.unciv.logic.map.MapSizeNew
import com.unciv.logic.map.MapType import com.unciv.logic.map.MapType
import com.unciv.logic.map.mapgenerator.MapGenerator import com.unciv.logic.map.mapgenerator.MapGenerator
import com.unciv.models.metadata.BaseRuleset
import com.unciv.models.ruleset.RulesetCache import com.unciv.models.ruleset.RulesetCache
import com.unciv.ui.MultiplayerScreen import com.unciv.ui.MultiplayerScreen
import com.unciv.ui.mapeditor.* import com.unciv.ui.mapeditor.*
import com.unciv.models.metadata.GameSetupInfo import com.unciv.models.metadata.GameSetupInfo
import com.unciv.ui.civilopedia.CivilopediaScreen
import com.unciv.ui.crashhandling.crashHandlingThread import com.unciv.ui.crashhandling.crashHandlingThread
import com.unciv.ui.crashhandling.postCrashHandlingRunnable import com.unciv.ui.crashhandling.postCrashHandlingRunnable
import com.unciv.ui.images.ImageGetter import com.unciv.ui.images.ImageGetter
@ -144,6 +148,18 @@ class MainMenuScreen: BaseScreen() {
} }
ExitGamePopup(this) ExitGamePopup(this)
} }
val helpButton = "?".toLabel(fontSize = 32)
.apply { setAlignment(Align.center) }
.surroundWithCircle(40f, color = ImageGetter.getBlue())
.apply { actor.y -= 2.5f } // compensate font baseline (empirical)
.surroundWithCircle(42f, resizeActor = false)
helpButton.touchable = Touchable.enabled
helpButton.onClick { openCivilopedia() }
keyPressDispatcher[Input.Keys.F1] = { openCivilopedia() }
helpButton.addTooltip(KeyCharAndCode(Input.Keys.F1), 20f)
helpButton.setPosition(20f, 20f)
stage.addActor(helpButton)
} }
@ -222,6 +238,13 @@ class MainMenuScreen: BaseScreen() {
} }
} }
private fun openCivilopedia() {
val ruleset =RulesetCache[game.settings.lastGameSetup?.gameParameters?.baseRuleset]
?: RulesetCache[BaseRuleset.Civ_V_GnK.fullName]
?: return
game.setScreen(CivilopediaScreen(ruleset, this))
}
override fun resize(width: Int, height: Int) { override fun resize(width: Int, height: Int) {
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) { if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
game.setScreen(MainMenuScreen()) game.setScreen(MainMenuScreen())

View File

@ -64,6 +64,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
val alertBattle = false val alertBattle = false
lateinit var worldScreen: WorldScreen lateinit var worldScreen: WorldScreen
fun getWorldScreenOrNull() = if (this::worldScreen.isInitialized) worldScreen else null
var isInitialized = false var isInitialized = false

View File

@ -461,7 +461,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
for (unique in uniqueObjects) { for (unique in uniqueObjects) {
@Suppress("NON_EXHAUSTIVE_WHEN") @Suppress("NON_EXHAUSTIVE_WHEN")
when (unique.type) { // TODO: Lots of typification… when (unique.type) {
UniqueType.OnlyAvailableWhen-> UniqueType.OnlyAvailableWhen->
if (!unique.conditionalsApply(civInfo, cityConstructions.cityInfo)) if (!unique.conditionalsApply(civInfo, cityConstructions.cityInfo))
rejectionReasons.add(RejectionReason.ShouldNotBeDisplayed) rejectionReasons.add(RejectionReason.ShouldNotBeDisplayed)

View File

@ -3,9 +3,9 @@ package com.unciv.models.ruleset
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.unciv.logic.civilization.CityStateType import com.unciv.logic.civilization.CityStateType
import com.unciv.logic.civilization.diplomacy.RelationshipLevel import com.unciv.logic.civilization.diplomacy.RelationshipLevel
import com.unciv.models.ruleset.unique.IHasUniques import com.unciv.models.ruleset.unique.*
import com.unciv.models.ruleset.unique.Unique import com.unciv.ui.civilopedia.FormattedLine
import com.unciv.models.ruleset.unique.UniqueTarget import com.unciv.ui.utils.Fonts
import com.unciv.ui.utils.colorFromRGB import com.unciv.ui.utils.colorFromRGB
class Era : RulesetObject(), IHasUniques { class Era : RulesetObject(), IHasUniques {
@ -32,8 +32,52 @@ class Era : RulesetObject(), IHasUniques {
val allyBonusObjects: Map<CityStateType, List<Unique>> by lazy { initBonuses(allyBonus) } val allyBonusObjects: Map<CityStateType, List<Unique>> by lazy { initBonuses(allyBonus) }
var iconRGB: List<Int>? = null var iconRGB: List<Int>? = null
companion object {
private val eraConditionals = setOf(UniqueType.ConditionalBeforeEra, UniqueType.ConditionalDuringEra, UniqueType.ConditionalStartingFromEra)
}
override fun getUniqueTarget() = UniqueTarget.Era override fun getUniqueTarget() = UniqueTarget.Era
override fun makeLink() = "" // No own category on Civilopedia screen
override fun makeLink() = "Era/$name"
override fun getCivilopediaTextHeader() = FormattedLine(name, header = 2, color = getHexColor())
override fun getCivilopediaTextLines(ruleset: Ruleset) = sequence {
yield(FormattedLine("Embarked strength: [$embarkDefense]${Fonts.strength}"))
yield(FormattedLine("Base unit buy cost: [$baseUnitBuyCost]${Fonts.gold}"))
yield(FormattedLine("Research agreement cost: [$researchAgreementCost]${Fonts.gold}"))
yield(FormattedLine())
yieldAll(ruleset.technologies.values.asSequence()
.filter { it.era() == name }
.map { FormattedLine(it.name, it.makeLink()) })
if (uniques.isNotEmpty()) yield(FormattedLine())
yieldAll(uniqueObjects.asSequence().map { FormattedLine(it) })
val eraGatedObjects = getEraGatedObjects(ruleset).toList()
if (eraGatedObjects.isEmpty()) return@sequence
yield(FormattedLine())
yield(FormattedLine("{See also}:"))
yieldAll(eraGatedObjects.map { FormattedLine(it.name, it.makeLink()) })
}.toList()
private fun getEraGatedObjects(ruleset: Ruleset): Sequence<IRulesetObject> {
val policyBranches = ruleset.policyBranches.values.asSequence()
.filter { it.era == name }
return policyBranches +
// This second part is empty in our base rulesets, yes
ruleset.allRulesetObjects()
.flatMap { obj ->
obj.getMatchingUniques(
UniqueType.OnlyAvailableWhen,
StateForConditionals.IgnoreConditionals
)
.map { unique -> obj to unique }
}.filter { (_, unique) ->
unique.conditionals.any {
it.type in eraConditionals
}
}.map { it.first }.distinct()
}
private fun initBonuses(bonusMap: Map<String, List<String>>): Map<CityStateType, List<Unique>> { private fun initBonuses(bonusMap: Map<String, List<String>>): Map<CityStateType, List<Unique>> {
val objectMap = HashMap<CityStateType, List<Unique>>() val objectMap = HashMap<CityStateType, List<Unique>>()

View File

@ -54,8 +54,10 @@ open class Policy : RulesetObject() {
val lineList = ArrayList<FormattedLine>() val lineList = ArrayList<FormattedLine>()
lineList += if (this is PolicyBranch) { lineList += if (this is PolicyBranch) {
val eraColor = ruleset.eras[era]?.getHexColor() ?: "" val era = ruleset.eras[era]
FormattedLine("{Unlocked at} {${branch.era}}", header = 4, color = eraColor) val eraColor = era?.getHexColor() ?: ""
val eraLink = era?.makeLink() ?: ""
FormattedLine("{Unlocked at} {${branch.era}}", header = 4, color = eraColor, link = eraLink)
} else { } else {
FormattedLine("Policy branch: [${branch.name}]", link = branch.makeLink()) FormattedLine("Policy branch: [${branch.name}]", link = branch.makeLink())
} }

View File

@ -52,14 +52,14 @@ class Technology: RulesetObject() {
} }
val viewingCiv = UncivGame.Current.worldScreen.viewingCiv val viewingCiv = UncivGame.Current.worldScreen.viewingCiv
val enabledUnits = getEnabledUnits(viewingCiv) val enabledUnits = getEnabledUnits(ruleset, viewingCiv)
if (enabledUnits.any()) { if (enabledUnits.any()) {
lineList += "{Units enabled}: " lineList += "{Units enabled}: "
for (unit in enabledUnits) for (unit in enabledUnits)
lineList += " * " + unit.name.tr() + " (" + unit.getShortDescription() + ")" lineList += " * " + unit.name.tr() + " (" + unit.getShortDescription() + ")"
} }
val enabledBuildings = getEnabledBuildings(viewingCiv) val enabledBuildings = getEnabledBuildings(ruleset, viewingCiv)
val regularBuildings = enabledBuildings.filter { !it.isAnyWonder() } val regularBuildings = enabledBuildings.filter { !it.isAnyWonder() }
if (regularBuildings.any()) { if (regularBuildings.any()) {
@ -75,7 +75,7 @@ class Technology: RulesetObject() {
lineList += " * " + wonder.name.tr() + " (" + wonder.getShortDescription() + ")" lineList += " * " + wonder.name.tr() + " (" + wonder.getShortDescription() + ")"
} }
for (obj in getObsoletedObjects(viewingCiv)) for (obj in getObsoletedObjects(ruleset, viewingCiv))
lineList += "[${obj.name}] obsoleted" lineList += "[${obj.name}] obsoleted"
for (resource in ruleset.tileResources.values.asSequence().filter { it.revealedBy == name } for (resource in ruleset.tileResources.values.asSequence().filter { it.revealedBy == name }
@ -94,7 +94,7 @@ class Technology: RulesetObject() {
* nuclear weapons and religion settings, and without those expressly hidden from Civilopedia. * nuclear weapons and religion settings, and without those expressly hidden from Civilopedia.
*/ */
// Used for Civilopedia, Alert and Picker, so if any of these decide to ignore the "Will not be displayed in Civilopedia" unique this needs refactoring // Used for Civilopedia, Alert and Picker, so if any of these decide to ignore the "Will not be displayed in Civilopedia" unique this needs refactoring
fun getEnabledBuildings(civInfo: CivilizationInfo) = getFilteredBuildings(civInfo) fun getEnabledBuildings(ruleset: Ruleset, civInfo: CivilizationInfo?) = getFilteredBuildings(ruleset, civInfo)
{ it.requiredTech == name } { it.requiredTech == name }
/** /**
@ -103,41 +103,48 @@ class Technology: RulesetObject() {
*/ */
// Used for Civilopedia, Alert and Picker, so if any of these decide to ignore the "Will not be displayed in Civilopedia" unique this needs refactoring // Used for Civilopedia, Alert and Picker, so if any of these decide to ignore the "Will not be displayed in Civilopedia" unique this needs refactoring
fun getObsoletedObjects(civInfo: CivilizationInfo): Sequence<RulesetStatsObject> = fun getObsoletedObjects(ruleset: Ruleset, civInfo: CivilizationInfo?): Sequence<RulesetStatsObject> =
(getFilteredBuildings(civInfo){true} (getFilteredBuildings(ruleset, civInfo){true}
+ civInfo.gameInfo.ruleSet.tileResources.values.asSequence() + ruleset.tileResources.values.asSequence()
+ civInfo.gameInfo.ruleSet.tileImprovements.values.filter { + ruleset.tileImprovements.values.filter {
it.uniqueTo==null || it.uniqueTo == civInfo.civName it.uniqueTo == null || it.uniqueTo == civInfo?.civName
}).filter { it.getMatchingUniques(UniqueType.ObsoleteWith).any { it.params[0] == name } } }).filter { obj: RulesetStatsObject ->
obj.getMatchingUniques(UniqueType.ObsoleteWith).any { it.params[0] == name }
}
// Helper: common filtering for both getEnabledBuildings and getObsoletedBuildings, difference via predicate parameter // Helper: common filtering for both getEnabledBuildings and getObsoletedBuildings, difference via predicate parameter
private fun getFilteredBuildings(civInfo: CivilizationInfo, predicate: (Building)->Boolean): Sequence<Building> { private fun getFilteredBuildings(
val nuclearWeaponsEnabled = civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled ruleset: Ruleset,
val religionEnabled = civInfo.gameInfo.isReligionEnabled() civInfo: CivilizationInfo?,
predicate: (Building)->Boolean
return civInfo.gameInfo.ruleSet.buildings.values.asSequence() ): Sequence<Building> {
val (nuclearWeaponsEnabled, religionEnabled) = getNukeAndReligionSwitches(civInfo)
return ruleset.buildings.values.asSequence()
.filter { .filter {
predicate(it) // expected to be the most selective, thus tested first predicate(it) // expected to be the most selective, thus tested first
&& (it.uniqueTo == civInfo.civName || it.uniqueTo==null && civInfo.getEquivalentBuilding(it) == it) && (it.uniqueTo == civInfo?.civName || it.uniqueTo == null && civInfo?.getEquivalentBuilding(it) == it)
&& (nuclearWeaponsEnabled || !it.hasUnique(UniqueType.EnablesNuclearWeapons)) && (nuclearWeaponsEnabled || !it.hasUnique(UniqueType.EnablesNuclearWeapons))
&& (religionEnabled || !it.hasUnique(UniqueType.HiddenWithoutReligion)) && (religionEnabled || !it.hasUnique(UniqueType.HiddenWithoutReligion))
&& !it.hasUnique(UniqueType.HiddenFromCivilopedia) && !it.hasUnique(UniqueType.HiddenFromCivilopedia)
} }
} }
private fun getNukeAndReligionSwitches(civInfo: CivilizationInfo?): Pair<Boolean, Boolean> {
if (civInfo == null) return true to true
return civInfo.gameInfo.run { gameParameters.nuclearWeaponsEnabled to isReligionEnabled() }
}
/** /**
* Returns a Sequence of [BaseUnit]s enabled by this Technology, filtered for [civInfo]'s uniques, * Returns a Sequence of [BaseUnit]s enabled by this Technology, filtered for [civInfo]'s uniques,
* nuclear weapons and religion settings, and without those expressly hidden from Civilopedia. * nuclear weapons and religion settings, and without those expressly hidden from Civilopedia.
*/ */
// Used for Civilopedia, Alert and Picker, so if any of these decide to ignore the "Will not be displayed in Civilopedia"/HiddenFromCivilopedia unique this needs refactoring // Used for Civilopedia, Alert and Picker, so if any of these decide to ignore the "Will not be displayed in Civilopedia"/HiddenFromCivilopedia unique this needs refactoring
fun getEnabledUnits(civInfo: CivilizationInfo): Sequence<BaseUnit> { fun getEnabledUnits(ruleset: Ruleset, civInfo: CivilizationInfo?): Sequence<BaseUnit> {
val nuclearWeaponsEnabled = civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled val (nuclearWeaponsEnabled, religionEnabled) = getNukeAndReligionSwitches(civInfo)
val religionEnabled = civInfo.gameInfo.isReligionEnabled() return ruleset.units.values.asSequence()
return civInfo.gameInfo.ruleSet.units.values.asSequence()
.filter { .filter {
it.requiredTech == name it.requiredTech == name
&& (it.uniqueTo == civInfo.civName || it.uniqueTo==null && civInfo.getEquivalentUnit(it) == it) && (it.uniqueTo == civInfo?.civName || it.uniqueTo == null && civInfo?.getEquivalentUnit(it) == it)
&& (nuclearWeaponsEnabled || !it.isNuclearWeapon()) && (nuclearWeaponsEnabled || !it.isNuclearWeapon())
&& (religionEnabled || !it.hasUnique(UniqueType.HiddenWithoutReligion)) && (religionEnabled || !it.hasUnique(UniqueType.HiddenWithoutReligion))
&& !it.hasUnique(UniqueType.HiddenFromCivilopedia) && !it.hasUnique(UniqueType.HiddenFromCivilopedia)
@ -218,8 +225,8 @@ class Technology: RulesetObject() {
} }
} }
val viewingCiv = UncivGame.Current.worldScreen.viewingCiv val viewingCiv = UncivGame.Current.getWorldScreenOrNull()?.viewingCiv
val enabledUnits = getEnabledUnits(viewingCiv) val enabledUnits = getEnabledUnits(ruleset, viewingCiv)
if (enabledUnits.any()) { if (enabledUnits.any()) {
lineList += FormattedLine() lineList += FormattedLine()
lineList += FormattedLine("{Units enabled}:") lineList += FormattedLine("{Units enabled}:")
@ -227,7 +234,7 @@ class Technology: RulesetObject() {
lineList += FormattedLine(unit.name.tr() + " (" + unit.getShortDescription() + ")", link = unit.makeLink()) lineList += FormattedLine(unit.name.tr() + " (" + unit.getShortDescription() + ")", link = unit.makeLink())
} }
val enabledBuildings = getEnabledBuildings(viewingCiv) val enabledBuildings = getEnabledBuildings(ruleset, viewingCiv)
.partition { it.isAnyWonder() } .partition { it.isAnyWonder() }
if (enabledBuildings.first.isNotEmpty()) { if (enabledBuildings.first.isNotEmpty()) {
lineList += FormattedLine() lineList += FormattedLine()
@ -242,7 +249,7 @@ class Technology: RulesetObject() {
lineList += FormattedLine(building.name.tr() + " (" + building.getShortDescription() + ")", link = building.makeLink()) lineList += FormattedLine(building.name.tr() + " (" + building.getShortDescription() + ")", link = building.makeLink())
} }
val obsoletedObjects = getObsoletedObjects(viewingCiv) val obsoletedObjects = getObsoletedObjects(ruleset, viewingCiv)
if (obsoletedObjects.any()) { if (obsoletedObjects.any()) {
lineList += FormattedLine() lineList += FormattedLine()
obsoletedObjects.forEach { obsoletedObjects.forEach {

View File

@ -183,6 +183,11 @@ enum class CivilopediaCategories (
getImage = null, getImage = null,
KeyCharAndCode('D'), KeyCharAndCode('D'),
"OtherIcons/Quickstart" "OtherIcons/Quickstart"
),
Era ("Eras", false,
getImage = null,
KeyCharAndCode('D'),
"OtherIcons/Tyrannosaurus"
); );
fun getByOffset(offset: Int) = values()[(ordinal + count + offset) % count] fun getByOffset(offset: Int) = values()[(ordinal + count + offset) % count]

View File

@ -205,6 +205,7 @@ class CivilopediaScreen(
CivilopediaCategories.Difficulty -> ruleset.difficulties.values CivilopediaCategories.Difficulty -> ruleset.difficulties.values
CivilopediaCategories.Belief -> (ruleset.beliefs.values.asSequence() + CivilopediaCategories.Belief -> (ruleset.beliefs.values.asSequence() +
Belief.getCivilopediaReligionEntry(ruleset)).toList() Belief.getCivilopediaReligionEntry(ruleset)).toList()
CivilopediaCategories.Era -> ruleset.eras.values
} }
for (loopCategory in CivilopediaCategories.values()) { for (loopCategory in CivilopediaCategories.values()) {
@ -312,7 +313,7 @@ class CivilopediaScreen(
override fun resize(width: Int, height: Int) { override fun resize(width: Int, height: Int) {
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) { if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
game.setScreen(CivilopediaScreen(game.worldScreen.gameInfo.ruleSet, previousScreen, currentCategory, currentEntry)) game.setScreen(CivilopediaScreen(ruleset, previousScreen, currentCategory, currentEntry))
} }
} }
} }

View File

@ -430,7 +430,9 @@ interface ICivilopediaText {
/** Generate automatic lines from object metadata. /** Generate automatic lines from object metadata.
* *
* Please do not rely on a UncivGame.Current.gameInfo being initialized, this should be able to run from the main menu. * This function ***MUST not rely*** on [UncivGame.Current.gameInfo][UncivGame.gameInfo]
* **or** [UncivGame.Current.worldScreen][UncivGame.worldScreen] being initialized,
* this should be able to run from the main menu.
* (And the info displayed should be about the **ruleset**, not the player situation) * (And the info displayed should be about the **ruleset**, not the player situation)
* *
* Default implementation is empty - no need to call super in overrides. * Default implementation is empty - no need to call super in overrides.

View File

@ -57,18 +57,18 @@ class TechButton(techName:String, private val techManager: TechManager, isWorldS
val tech = ruleset.technologies[techName]!! val tech = ruleset.technologies[techName]!!
for (unit in tech.getEnabledUnits(techManager.civInfo)) for (unit in tech.getEnabledUnits(ruleset, techManager.civInfo))
techEnabledIcons.add(ImageGetter.getConstructionImage(unit.name).surroundWithCircle(techIconSize)) techEnabledIcons.add(ImageGetter.getConstructionImage(unit.name).surroundWithCircle(techIconSize))
for (building in tech.getEnabledBuildings(techManager.civInfo)) for (building in tech.getEnabledBuildings(ruleset, techManager.civInfo))
techEnabledIcons.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(techIconSize)) techEnabledIcons.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(techIconSize))
for (obj in tech.getObsoletedObjects(techManager.civInfo)) { for (obj in tech.getObsoletedObjects(ruleset, techManager.civInfo)) {
val obsoletedIcon = when { val obsoletedIcon = when (obj) {
obj is Building -> ImageGetter.getConstructionImage(obj.name) is Building -> ImageGetter.getConstructionImage(obj.name)
.surroundWithCircle(techIconSize) .surroundWithCircle(techIconSize)
obj is TileResource -> ImageGetter.getResourceImage(obj.name, techIconSize) is TileResource -> ImageGetter.getResourceImage(obj.name, techIconSize)
obj is TileImprovement -> ImageGetter.getImprovementIcon(obj.name, techIconSize) is TileImprovement -> ImageGetter.getImprovementIcon(obj.name, techIconSize)
else -> continue else -> continue
}.also { }.also {
val closeImage = ImageGetter.getRedCross(techIconSize / 2, 1f) val closeImage = ImageGetter.getRedCross(techIconSize / 2, 1f)

View File

@ -687,6 +687,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
- [Party](https://thenounproject.com/icon/party-1784941/) by Adrien Coquet for WLTK header on City Overview - [Party](https://thenounproject.com/icon/party-1784941/) by Adrien Coquet for WLTK header on City Overview
- [Party](https://thenounproject.com/icon/party-2955155/) by Lars Meiertoberens as additional WLKT decoration - [Party](https://thenounproject.com/icon/party-2955155/) by Lars Meiertoberens as additional WLKT decoration
- [turn right](https://thenounproject.com/icon/turn-right-1920867/) by Alice Design for Resource Overview - [turn right](https://thenounproject.com/icon/turn-right-1920867/) by Alice Design for Resource Overview
- [Tyrannosaurus Rex](https://thenounproject.com/icon/tyrannosaurus-rex-4130976/) by Amethyst Studio for Civilopedia Eras header
### Main menu ### Main menu