mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-13 12:27:40 +07:00
Civilopedia phase 8 - Nations and Promotions (#4657)
* Civilopedia phase 8 - Nations and Promotions * Civilopedia phase 8 - Nations and Promotions - AS insubordination * Civilopedia phase 8 - Nations and Promotions - OR template * Civilopedia phase 8 - Nations and Promotions - proofread * Civilopedia phase 8 - Nations and Promotions - revert OR
This commit is contained in:
parent
4bcf821879
commit
130c318ae0
@ -152,8 +152,7 @@
|
||||
{
|
||||
"name": "Medic II",
|
||||
"prerequisites": ["Medic"],
|
||||
"uniques": ["[+5] HP when healing", "All adjacent units heal [5] HP when healing",
|
||||
"[+5] HP when healing in [Foreign Land] tiles"],
|
||||
"uniques": ["[+5] HP when healing", "[+5] HP when healing in [Foreign Land] tiles", "All adjacent units heal [5] HP when healing"],
|
||||
"unitTypes": ["Melee","Mounted","Scout"]
|
||||
},
|
||||
|
||||
|
@ -48,6 +48,7 @@ Required tech: [requiredTech] = Benötigt Technologie: [requiredTech]
|
||||
Requires [PolicyOrNationalWonder] = Benötigt [PolicyOrNationalWonder]
|
||||
Cannot be purchased = Kann nicht gekauft werden
|
||||
See also = Siehe auch
|
||||
Requires at least one of the following: = Benötigt eine der folgenden Vorraussetzungen:
|
||||
|
||||
Current construction = Aktuelle Produktion
|
||||
Construction queue = Produktionswarteschlange
|
||||
@ -852,6 +853,7 @@ Buildings that consume this resource = Gebäude welche diese Ressource verbrauch
|
||||
Buildings that require this resource worked near the city = Gebäude welche diese Ressource bewirtschaftet in der Nähe der Stadt benötigen
|
||||
Units that consume this resource = Einheiten welche diese Ressource verbrauchen
|
||||
Can be built on = Kann gebaut werden auf
|
||||
or [terrainType] = oder [terrainType]
|
||||
Can be constructed by = Kann erbaut werden von
|
||||
Defence bonus = Verteidigungsbonus
|
||||
Movement cost = Bewegungskosten
|
||||
@ -922,9 +924,13 @@ Gold reward for clearing barbarian camps = Gold-Belohnung für das Räumen von B
|
||||
# Other civilopedia things
|
||||
Nations = Nationen
|
||||
Available for [unitTypes] = Verfügbar für [unitTypes]
|
||||
Available for: = Verfügbar für:
|
||||
Free promotion: = Freie Beförderung:
|
||||
Free promotions: = Freie Beförderungen:
|
||||
Free for [units] = Frei für [units]
|
||||
Free for: = Frei für:
|
||||
Granted by [param] = Von [param] erteilt
|
||||
Granted by: = Erteilt von:
|
||||
[bonus] with [tech] = [bonus] mit [tech]
|
||||
Difficulty levels = Schwierigkeitsgrade
|
||||
|
||||
@ -978,7 +984,7 @@ Siege = Belagerung
|
||||
WaterCivilian = Wasser-Zivilist
|
||||
WaterMelee = Wassernahkampf
|
||||
WaterRanged = Wasserfernkampf
|
||||
WaterSubmarine = Wasser-U-Boot
|
||||
WaterSubmarine = U-Boote
|
||||
WaterAircraftCarrier = Flugzeugträger
|
||||
|
||||
Fighter = Jagdflugzeug
|
||||
@ -1196,7 +1202,8 @@ Paper Maker = Papiermacher
|
||||
|
||||
'Libraries are as the shrine where all the relics of the ancient saints, full of true virtue, and all that without delusion or imposture are preserved and reposed.' - Sir Francis Bacon = 'Bibliotheken sind wie der Schrein, wo alle Reliquien der Heiligen vergangener Tage, voll der wahren Tugend, ruhen und bewahrt werden, und zwar ganz ohne Irreführung und Betrug.' - Sir Francis Bacon
|
||||
Free Technology = Kostenlose Technologie
|
||||
Provides a free [building] [cityFilter] = Stellt das Gebäude [building] [cityFilter] bereit
|
||||
# Requires translation!
|
||||
Provides a free [building] [cityFilter] = Stellt das Gebäude [building] [cityFilter] kostenlos bereit
|
||||
The Great Library = Die Große Bibliothek
|
||||
|
||||
Circus = Zirkus
|
||||
@ -2346,7 +2353,7 @@ You have defeated us... but our spirits will never be vanquished! We shall retur
|
||||
Greetings, stranger. I am Hiawatha, speaker for the Iroquois. We seek peace with all, but we do not shrink from war. = Seid gegrüßt, Fremder. Ich bin Hiawatha, Sprecher der Irokesen. Wir streben nach Frieden, doch wenn es sein muss, scheuen wir nicht den Krieg.
|
||||
Does this trade work for you, my friend? = Ist dieser Tausch für dich ok, mein Freund?
|
||||
The Great Warpath = Auf dem Großen Kriegspfad
|
||||
All units move through Forest and Jungle Tiles in friendly territory as if they have roads. These tiles can be used to establish City Connections upon researching the Wheel. = Alle Einheiten bewegen sich durch verbündete Wald- und Dschungelfelder als hätten sie Straßen. Diese Felder können genutzt werden, um bei der Erforschung des Rades Stadtverbindungen herzustellen.
|
||||
All units move through Forest and Jungle Tiles in friendly territory as if they have roads. These tiles can be used to establish City Connections upon researching the Wheel. = Alle Einheiten bewegen sich durch verbündete Wald- und Dschungelfelder als hätten sie Straßen. Diese Felder können genutzt werden, um nach Erforschung des Rades Stadtverbindungen herzustellen.
|
||||
Greetings, noble Hiawatha, leader of the mighty Iroquois nations! Long have your people lived near the great and holy lake Ontario in the land that has come to be known as the New York state in North America. In the mists of antiquity, the five peoples of Seneca, Onondaga, Mohawks, Cayugas and Oneida united into one nation, the Haudenosaunee, the Iroquois. With no written language, the wise men of your nation created the great law of peace, the model for many constitutions including that of the United States. For many years, your people battled great enemies, such as the Huron, and the French and English invaders. Tough outnumbered and facing weapons far more advanced than the ones your warriors wielded, the Iroquois survived and prospered, until they were finally overwhelmed by the mighty armies of the new United States. = Seid gegrüßt, edler Hiawatha, Häuptling der mächtigen Irokesenvölker! Seit langem lebt euer Volk in der Nähe des großen und heiligen Sees Ontario in dem Land, das als der Staat New York in Nordamerika bekannt geworden ist. In den Nebeln des Altertums vereinigten sich die fünf Völker der Seneca, Onondaga, Mohawks, Cayugas und Oneida zu einer Nation, den Haudenosaunee, den Irokesen. Ohne Schriftsprache schufen die Weisen eures Volkes das große Friedensgesetz, das Vorbild für viele Verfassungen, darunter auch die der Vereinigten Staaten. Viele Jahre lang kämpfte euer Volk gegen große Feinde, wie die Huronen und die französischen und englischen Invasoren. Obwohl sie zahlenmäßig unterlegen und mit Waffen konfrontiert waren, die weitaus fortschrittlicher waren als die, die eure Krieger trugen, überlebten die Irokesen und gediehen, bis sie schließlich von den mächtigen Armeen der neuen Vereinigten Staaten überwältigt wurden.
|
||||
Oh noble Hiawatha, listen to the cries of your people! They call out to you to lead them in peace and war, to rebuild the great longhouse and unite the tribes once again. Will you accept this challenge, great leader? Will you build a civilization that will stand the test of time? = Oh edler Hiawatha, höre auf die Schreie deines Volkes! Sie rufen nach Euch, um sie in Frieden und Krieg zu führen, um das große Langhaus wieder aufzubauen und die Stämme wieder zu vereinen. Werdet Ihr diese Herausforderung annehmen, großer Anführer? Könnt Ihr eine Zivilisation aufbauen, die dem Test der Zeit standhält?
|
||||
Onondaga = Onondaga
|
||||
@ -2523,7 +2530,7 @@ I, Pho Kun Ramkhamhaeng, King of Siam, consider it a great honor that you have w
|
||||
Greetings. I believe this is a fair proposal for both parties. What do you think? = Ich grüße Euch. Ich glaube, dies ist ein fairer Vorschlag für beide Seiten. Was meint Ihr dazu?
|
||||
Welcome. = Willkommen.
|
||||
Father Governs Children = Vater und Kinder
|
||||
Food and Culture from Friendly City-States are increased by 50% = Nahrung und Kultur aus freundlichen Stadtstaaten werden um 50% erhöht.
|
||||
Food and Culture from Friendly City-States are increased by 50% = Nahrung und Kultur aus befreundeten Stadtstaaten werden um 50% erhöht.
|
||||
Greetings to you, Great King Ramkhamhaeng, leader of the glorious Siamese people! O mighty King, your people bow down before you in awe and fear! You are the ruler of Siam, an ancient country in the heart of Southeast Asia, a beautiful and mysterious land. Surrounded by foes, beset by bloody war and grinding poverty, the clever and loyal Siamese people have endured and triumphed. King Ramkhamhaeng, your empire was once part of the Khmer Empire, until the 13th century AD, when your ancestors revolted, forming the small Sukhothai kingdom. Through successful battle and cunning diplomacy, the tiny kingdom grew into a mighty empire, an empire which would dominate South East Asia for more than a century! = Sei gegrüßt, Großkönig Ramkhamhaeng, Führer des glorreichen siamesischen Volkes! O mächtiger König, euer Volk verneigt sich in Ehrfurcht und Furcht vor Euch! Ihr seid der Herrscher von Siam, einem alten Land im Herzen Südostasiens, einem schönen und geheimnisvollen Land. Umgeben von Feinden, bedrängt von blutigen Kriegen und drückender Armut, hat das kluge und treue siamesische Volk ausgehalten und triumphiert. König Ramkhamhaeng, euer Reich war einst Teil des Khmer-Reiches, bis zum 13. Jahrhundert n. Chr., als sich eure Vorfahren auflehnten und das kleine Königreich Sukhothai gründeten. Durch erfolgreiche Kämpfe und schlaue Diplomatie wuchs das winzige Königreich zu einem mächtigen Reich heran, ein Reich, das Südostasien für mehr als ein Jahrhundert beherrschen sollte!
|
||||
Oh, wise and puissant King Ramkhamhaeng, your people need you to once again lead them to greatness! Can you use your wits and strength of arms to protect your people and defeat your foes? Can you build a civilization that will stand the test of time? = Oh, weiser und mächtiger König Ramkhamhaeng, euer Volk braucht Euch, um es noch einmal zu Größe zu führen! Könnt Ihr Euren Verstand und Eure Waffenstärke nutzen, um euer Volk zu schützen und Eure Feinde zu besiegen? Könnt Ihr eine Zivilisation aufbauen, die dem Test der Zeit standhält?
|
||||
Sukhothai = Sukhothai
|
||||
@ -3427,7 +3434,7 @@ Telecommunications = Telekommunikation
|
||||
'The more we elaborate our means of communication, the less we communicate.' - J.B. Priestly = 'Je mehr wir unsere Kommunikationsmittel ausbauen, desto weniger kommunizieren wir.' – J.B. Priestly
|
||||
Mobile Tactics = Mobile Taktiken
|
||||
'All men can see these tactics whereby I conquer, but what none can see is the strategy out of which victory is evolved.' - Sun Tzu = 'Alle Menschen können diese Taten sehen, mit denen ich siege, aber was niemand sehen kann, ist die Strategie, aus der sich der Sieg entwickelt.' - Sun Tzu
|
||||
Advanced Ballistics = Erweiterte Ballistik
|
||||
Advanced Ballistics = Fortgeschrittene Ballistik
|
||||
'Our scientific power has outrun our spiritual power, we have guided missiles and misguided men.' – Martin Luther King Jr. = 'Unsere wissenschaftliche Macht hat unsere geistige Macht überholt, wir haben Raketen gelenkt und Menschen fehlgeleitet.' – Martin Luther King Jr.
|
||||
Satellites = Satelliten
|
||||
Reveals the entire map = Enthüllt die gesamte Weltkarte
|
||||
@ -3687,7 +3694,7 @@ Barrage III = Sperrfeuer III
|
||||
|
||||
Volley = Salve
|
||||
|
||||
Extended Range = erweiterte Reichweite
|
||||
Extended Range = Erhöhte Reichweite
|
||||
[amount] Range = [amount] Reichweite
|
||||
|
||||
Indirect Fire = Indirektes Feuer
|
||||
@ -3728,7 +3735,7 @@ Medic = Sanitäter I
|
||||
All adjacent units heal [amount] HP when healing = Beim Heilen werden alle benachbarten Einheiten um [amount] LP geheilt
|
||||
|
||||
Medic II = Sanitäter II
|
||||
[amount] HP when healing in [tileFilter] tiles = [amount] LP beim Heilen auf [tileFilter] Feldern
|
||||
[amount] HP when healing in [tileFilter] tiles = [amount] LP bei Heilung in [tileFilter] Feldern
|
||||
|
||||
Scouting I = Spähen I
|
||||
[amount] Visibility Range = [amount] Sichtweite
|
||||
@ -3753,12 +3760,12 @@ Boarding Party II = Enterkommando II
|
||||
|
||||
Boarding Party III = Enterkommando III
|
||||
|
||||
Coastal Raider I = KüstenräuberIn I
|
||||
Coastal Raider I = Küstenräuberei I
|
||||
Earn [amount]% of the damage done to [unitType] units as [stat] = Erhalte [amount]% des verursachten Schadens an [unitType] Einheiten als [stat]
|
||||
|
||||
Coastal Raider II = KüstenräuberIn II
|
||||
Coastal Raider II = Küstenräuberei II
|
||||
|
||||
Coastal Raider III = KüstenräuberIn III
|
||||
Coastal Raider III = Küstenräuberei III
|
||||
|
||||
Targeting I = Gezielter Schlag I
|
||||
|
||||
@ -3787,7 +3794,7 @@ Flight Deck II = Flugdeck II
|
||||
Flight Deck III = Flugdeck III
|
||||
|
||||
Supply = Versorgung
|
||||
May heal outside of friendly territory = Kann außerhalb des eigenen Territoriums heilen
|
||||
May heal outside of friendly territory = Darf auch außerhalb von befreundetem Territorium heilen
|
||||
|
||||
Siege I = Belagerung I
|
||||
|
||||
@ -3810,7 +3817,7 @@ Air Targeting I = Luftangriff I
|
||||
Air Targeting II = Luftangriff II
|
||||
|
||||
Sortie = Lufteinsatz
|
||||
[amount] extra interceptions may be made per turn = [amount] zusätzliche Abfangungen können pro Runde durchgeführt werden
|
||||
[amount] extra interceptions may be made per turn = Kann pro Runde [amount] mal zusätzlich Abfangen
|
||||
|
||||
Operational Range = Einsatzreichweite
|
||||
|
||||
@ -3938,7 +3945,7 @@ Knight = Ritter
|
||||
|
||||
Camel Archer = Kamel-Bogenschütze
|
||||
|
||||
Conquistador = Eroberer
|
||||
Conquistador = Konquistador
|
||||
Defense bonus when embarked = Verteidigungsbonus wenn Eingeschifft
|
||||
|
||||
Naresuan's Elephant = Naresuans Elefant
|
||||
@ -4052,7 +4059,7 @@ Zero = Zero
|
||||
B17 = B-17
|
||||
|
||||
Paratrooper = Fallschirmjäger
|
||||
May Paradrop up to [amount] tiles from inside friendly territory = Kann einen Fallschirmabsprung bis zu [amount] Felder von innerhalb des befreundeten Territoriums aus durchführen
|
||||
May Paradrop up to [amount] tiles from inside friendly territory = Kann aus befreundetem Territorium heraus einen Fallschirmabsprung bis zu [amount] Felder weit durchführen
|
||||
|
||||
Tank = Panzer
|
||||
|
||||
|
@ -48,6 +48,7 @@ Required tech: [requiredTech] =
|
||||
Requires [PolicyOrNationalWonder] =
|
||||
Cannot be purchased =
|
||||
See also =
|
||||
Requires at least one of the following: =
|
||||
|
||||
Current construction =
|
||||
Construction queue =
|
||||
@ -856,6 +857,7 @@ Buildings that consume this resource =
|
||||
Buildings that require this resource worked near the city =
|
||||
Units that consume this resource =
|
||||
Can be built on =
|
||||
or [terrainType] =
|
||||
Can be constructed by =
|
||||
Defence bonus =
|
||||
Movement cost =
|
||||
@ -927,9 +929,13 @@ Gold reward for clearing barbarian camps =
|
||||
# Other civilopedia things
|
||||
Nations =
|
||||
Available for [unitTypes] =
|
||||
Available for: =
|
||||
Free promotion: =
|
||||
Free promotions: =
|
||||
Free for [units] =
|
||||
Free for: =
|
||||
Granted by [param] =
|
||||
Granted by: =
|
||||
[bonus] with [tech] =
|
||||
Difficulty levels =
|
||||
|
||||
|
@ -575,7 +575,7 @@ open class TileInfo {
|
||||
}
|
||||
|
||||
fun toMarkup(viewingCiv: CivilizationInfo?): ArrayList<FormattedLine> {
|
||||
val lineList = ArrayList<FormattedLine>() // more readable than StringBuilder, with same performance for our use-case
|
||||
val lineList = ArrayList<FormattedLine>()
|
||||
val isViewableToPlayer = viewingCiv == null || UncivGame.Current.viewEntireMapForDebug
|
||||
|| viewingCiv.viewableTiles.contains(this)
|
||||
|
||||
|
@ -3,8 +3,14 @@
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.civilization.CityStateType
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.models.translations.Translations
|
||||
import com.unciv.models.translations.squareBraceRegex
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.CivilopediaText
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.civilopedia.ICivilopediaText
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.colorFromRGB
|
||||
|
||||
@ -15,7 +21,7 @@ enum class VictoryType {
|
||||
Scientific
|
||||
}
|
||||
|
||||
class Nation : INamed {
|
||||
class Nation : INamed, ICivilopediaText {
|
||||
override lateinit var name: String
|
||||
|
||||
var leaderName = ""
|
||||
@ -49,6 +55,8 @@ class Nation : INamed {
|
||||
var adjective = ArrayList<String>()
|
||||
*/
|
||||
|
||||
override var civilopediaText = listOf<FormattedLine>()
|
||||
|
||||
@Transient
|
||||
private lateinit var outerColorObject: Color
|
||||
fun getOuterColor(): Color = outerColorObject
|
||||
@ -88,14 +96,10 @@ class Nation : INamed {
|
||||
lateinit var cities: ArrayList<String>
|
||||
|
||||
|
||||
fun getUniqueString(ruleset: Ruleset, forPickerScreen: Boolean = true): String {
|
||||
/** Used only by NewGame Nation picker */
|
||||
fun getUniqueString(ruleset: Ruleset): String {
|
||||
val textList = ArrayList<String>()
|
||||
|
||||
if (leaderName.isNotEmpty() && !forPickerScreen) {
|
||||
textList += getLeaderDisplayName().tr()
|
||||
textList += ""
|
||||
}
|
||||
|
||||
if (uniqueName != "") textList += uniqueName.tr() + ":"
|
||||
if (uniqueText != "") {
|
||||
textList += " " + uniqueText.tr()
|
||||
@ -190,4 +194,152 @@ class Nation : INamed {
|
||||
textList += " " + unique.tr()
|
||||
}
|
||||
}
|
||||
|
||||
override fun makeLink() = "Nation/$name"
|
||||
override fun replacesCivilopediaDescription() = true
|
||||
override fun hasCivilopediaTextLines() = true
|
||||
|
||||
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
||||
val textList = ArrayList<FormattedLine>()
|
||||
|
||||
if (leaderName.isNotEmpty()) {
|
||||
textList += FormattedLine(extraImage = "LeaderIcons/$leaderName", imageSize = 200f)
|
||||
textList += FormattedLine(getLeaderDisplayName(), centered = true, header = 3)
|
||||
textList += FormattedLine()
|
||||
}
|
||||
|
||||
if (uniqueName != "")
|
||||
textList += FormattedLine("{$uniqueName}:", header = 4)
|
||||
if (uniqueText != "") {
|
||||
textList += FormattedLine(uniqueText, indent = 1)
|
||||
} else {
|
||||
uniqueObjects.forEach {
|
||||
textList += FormattedLine(it)
|
||||
}
|
||||
textList += FormattedLine()
|
||||
}
|
||||
|
||||
if (startBias.isNotEmpty()) {
|
||||
startBias.withIndex().forEach {
|
||||
// can be "Avoid []"
|
||||
val link = if ('[' !in it.value) it.value
|
||||
else squareBraceRegex.find(it.value)!!.groups[1]!!.value
|
||||
textList += FormattedLine(
|
||||
(if (it.index == 0) "[Start bias:] " else "") + it.value.tr(), // extra tr because tr cannot nest {[]}
|
||||
link = "Terrain/$link",
|
||||
indent = if (it.index == 0) 0 else 1)
|
||||
}
|
||||
textList += FormattedLine()
|
||||
}
|
||||
addUniqueBuildingsText(textList, ruleset)
|
||||
addUniqueUnitsText(textList, ruleset)
|
||||
addUniqueImprovementsText(textList, ruleset)
|
||||
|
||||
return textList
|
||||
}
|
||||
|
||||
@JvmName("addUniqueBuildingsText1") // These overloads are too similar - but I hope to remove the other one soon
|
||||
private fun addUniqueBuildingsText(textList: ArrayList<FormattedLine>, ruleset: Ruleset) {
|
||||
for (building in ruleset.buildings.values) {
|
||||
if (building.uniqueTo != name || "Will not be displayed in Civilopedia" in building.uniques) continue
|
||||
textList += FormattedLine("{${building.name}} -", link=building.makeLink())
|
||||
if (building.replaces != null && ruleset.buildings.containsKey(building.replaces!!)) {
|
||||
val originalBuilding = ruleset.buildings[building.replaces!!]!!
|
||||
textList += FormattedLine("Replaces [${originalBuilding.name}]", link=originalBuilding.makeLink(), indent=1)
|
||||
|
||||
val originalBuildingStatMap = originalBuilding.toHashMap()
|
||||
for (stat in building.toHashMap())
|
||||
if (stat.value != originalBuildingStatMap[stat.key])
|
||||
textList += FormattedLine(
|
||||
stat.key.toString().tr() + " " +
|
||||
"[${stat.value.toInt()}] vs [${originalBuildingStatMap[stat.key]!!.toInt()}]".tr(),
|
||||
indent=1)
|
||||
|
||||
for (unique in building.uniques.filter { it !in originalBuilding.uniques })
|
||||
textList += FormattedLine(unique, indent=1)
|
||||
if (building.maintenance != originalBuilding.maintenance)
|
||||
textList += FormattedLine("{Maintenance} ".tr() + "[${building.maintenance}] vs [${originalBuilding.maintenance}]".tr(), indent=1)
|
||||
if (building.cost != originalBuilding.cost)
|
||||
textList += FormattedLine("{Cost} ".tr() + "[${building.cost}] vs [${originalBuilding.cost}]".tr(), indent=1)
|
||||
if (building.cityStrength != originalBuilding.cityStrength)
|
||||
textList += FormattedLine("{City strength} ".tr() + "[${building.cityStrength}] vs [${originalBuilding.cityStrength}]".tr(), indent=1)
|
||||
if (building.cityHealth != originalBuilding.cityHealth)
|
||||
textList += FormattedLine("{City health} ".tr() + "[${building.cityHealth}] vs [${originalBuilding.cityHealth}]".tr(), indent=1)
|
||||
textList += FormattedLine()
|
||||
} else if (building.replaces != null) {
|
||||
textList += FormattedLine("Replaces [${building.replaces}], which is not found in the ruleset!", indent=1)
|
||||
} else {
|
||||
textList += FormattedLine(building.getShortDescription(ruleset), indent=1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmName("addUniqueUnitsText1")
|
||||
private fun addUniqueUnitsText(textList: ArrayList<FormattedLine>, ruleset: Ruleset) {
|
||||
for (unit in ruleset.units.values) {
|
||||
if (unit.uniqueTo != name || "Will not be displayed in Civilopedia" in unit.uniques) continue
|
||||
textList += FormattedLine("{${unit.name}} -", link="Unit/${unit.name}")
|
||||
if (unit.replaces != null && ruleset.units.containsKey(unit.replaces!!)) {
|
||||
val originalUnit = ruleset.units[unit.replaces!!]!!
|
||||
textList += FormattedLine("Replaces [${originalUnit.name}]", link="Unit/${originalUnit.name}", indent=1)
|
||||
if (unit.cost != originalUnit.cost)
|
||||
textList += FormattedLine("{Cost} ".tr() + "[${unit.cost}] vs [${originalUnit.cost}]".tr(), indent=1)
|
||||
if (unit.strength != originalUnit.strength)
|
||||
textList += FormattedLine("${Fonts.strength} " + "[${unit.strength}] vs [${originalUnit.strength}]".tr(), indent=1)
|
||||
if (unit.rangedStrength != originalUnit.rangedStrength)
|
||||
textList += FormattedLine("${Fonts.rangedStrength} " + "[${unit.rangedStrength}] vs [${originalUnit.rangedStrength}]".tr(), indent=1)
|
||||
if (unit.range != originalUnit.range)
|
||||
textList += FormattedLine("${Fonts.range} " + "[${unit.range}] vs [${originalUnit.range}]".tr(), indent=1)
|
||||
if (unit.movement != originalUnit.movement)
|
||||
textList += FormattedLine("${Fonts.movement} " + "[${unit.movement}] vs [${originalUnit.movement}]".tr(), indent=1)
|
||||
for (resource in originalUnit.getResourceRequirements().keys)
|
||||
if (!unit.getResourceRequirements().containsKey(resource)) {
|
||||
textList += FormattedLine("[$resource] not required", link="Resource/$resource", indent=1)
|
||||
}
|
||||
// This does not use the auto-linking FormattedLine(Unique) for two reasons:
|
||||
// would look a little chaotic as unit uniques unlike most uniques are a HashSet and thus do not preserve order
|
||||
// No .copy() factory on FormattedLine and no FormattedLine(Unique, all other val's) constructor either
|
||||
for (unique in unit.uniques.filterNot { it in originalUnit.uniques })
|
||||
textList += FormattedLine(unique, indent=1)
|
||||
for (unique in originalUnit.uniques.filterNot { it in unit.uniques })
|
||||
textList += FormattedLine("Lost ability".tr() + " (" + "vs [${originalUnit.name}]".tr() + "): " +
|
||||
unique.tr(), indent=1)
|
||||
for (promotion in unit.promotions.filter { it !in originalUnit.promotions }) {
|
||||
val effect = ruleset.unitPromotions[promotion]!!.effect
|
||||
// "{$promotion} ({$effect})" won't work as effect may contain [] and tr() does not support that kind of nesting
|
||||
textList += FormattedLine(
|
||||
if (effect.isEmpty()) promotion
|
||||
else "${promotion.tr()} (${effect.tr()})",
|
||||
link = "Promotion/$promotion", indent = 1 )
|
||||
}
|
||||
} else if (unit.replaces != null) {
|
||||
textList += FormattedLine("Replaces [${unit.replaces}], which is not found in the ruleset!", indent=1)
|
||||
} else {
|
||||
textList += unit.getCivilopediaTextLines(ruleset).map {
|
||||
FormattedLine(it.text, link=it.link, indent = it.indent + 1, color=it.color)
|
||||
}
|
||||
}
|
||||
|
||||
textList += FormattedLine()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmName("addUniqueImprovementsText1")
|
||||
private fun addUniqueImprovementsText(textList: ArrayList<FormattedLine>, ruleset: Ruleset) {
|
||||
for (improvement in ruleset.tileImprovements.values) {
|
||||
if (improvement.uniqueTo != name ) continue
|
||||
|
||||
textList += FormattedLine(improvement.name, link="Improvement/${improvement.name}")
|
||||
textList += FormattedLine(improvement.clone().toString(), indent=1) // = (improvement as Stats).toString minus import plus copy overhead
|
||||
if (improvement.terrainsCanBeBuiltOn.isNotEmpty()) {
|
||||
improvement.terrainsCanBeBuiltOn.withIndex().forEach {
|
||||
textList += FormattedLine(if (it.index == 0) "{Can be built on} {${it.value}}" else "or [${it.value}]",
|
||||
link="Terrain/${it.value}", indent=if (it.index == 0) 1 else 2)
|
||||
}
|
||||
}
|
||||
for (unique in improvement.uniques)
|
||||
textList += FormattedLine(unique, indent=1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ class BaseUnit : INamed, IConstruction, CivilopediaText() {
|
||||
stats += "$rangedStrength${Fonts.rangedStrength}"
|
||||
stats += "$range${Fonts.range}"
|
||||
}
|
||||
if (movement != 0) stats += "$movement${Fonts.movement}"
|
||||
if (movement != 0 && !movesLikeAirUnits()) stats += "$movement${Fonts.movement}"
|
||||
if (cost != 0) stats += "{Cost}: $cost"
|
||||
if (stats.isNotEmpty())
|
||||
textList += FormattedLine(stats.joinToString(", "))
|
||||
|
@ -4,22 +4,32 @@ import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.Unique
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.civilopedia.ICivilopediaText
|
||||
|
||||
class Promotion : INamed{
|
||||
|
||||
class Promotion : INamed, ICivilopediaText {
|
||||
override lateinit var name: String
|
||||
var prerequisites = listOf<String>()
|
||||
var effect = ""
|
||||
var unitTypes = listOf<String>() // The json parser wouldn't agree to deserialize this as a list of UnitTypes. =(
|
||||
|
||||
var uniques = ArrayList<String>()
|
||||
val uniqueObjects: List<Unique> by lazy { uniques.map { Unique(it) } + Unique(effect) }
|
||||
private fun uniquesWithEffect() = sequence {
|
||||
if (effect.isNotEmpty()) yield(effect)
|
||||
yieldAll(uniques)
|
||||
}
|
||||
val uniqueObjects: List<Unique> by lazy { uniquesWithEffect().map { Unique(it) }.toList() }
|
||||
|
||||
fun getDescription(promotionsForUnitType: Collection<Promotion>, forCivilopedia:Boolean=false, ruleSet:Ruleset? = null):String {
|
||||
// we translate it before it goes in to get uniques like "vs units in rough terrain" and after to get "vs city
|
||||
val stringBuilder = StringBuilder()
|
||||
override var civilopediaText = listOf<FormattedLine>()
|
||||
|
||||
for (unique in uniques + effect) {
|
||||
stringBuilder.appendLine(unique.tr())
|
||||
|
||||
/** Used to describe a Promotion on the PromotionPickerScreen */
|
||||
fun getDescription(promotionsForUnitType: Collection<Promotion>):String {
|
||||
val textList = ArrayList<String>()
|
||||
|
||||
for (unique in uniquesWithEffect()) {
|
||||
textList += unique.tr()
|
||||
}
|
||||
|
||||
if (prerequisites.isNotEmpty()) {
|
||||
@ -27,22 +37,103 @@ class Promotion : INamed{
|
||||
for (i in prerequisites.filter { promotionsForUnitType.any { promotion -> promotion.name == it } }) {
|
||||
prerequisitesString.add(i.tr())
|
||||
}
|
||||
stringBuilder.appendLine("{Requires}: ".tr() + prerequisitesString.joinToString(" OR ".tr()))
|
||||
textList += "{Requires}: ".tr() + prerequisitesString.joinToString(" OR ".tr())
|
||||
}
|
||||
if(forCivilopedia){
|
||||
if (unitTypes.isNotEmpty()) {
|
||||
val unitTypesString = unitTypes.joinToString(", ") { it.tr() }
|
||||
stringBuilder.appendLine("Available for [$unitTypesString]".tr())
|
||||
return textList.joinToString("\n")
|
||||
}
|
||||
|
||||
if (ruleSet!=null) {
|
||||
val freeforUnits = ruleSet.units.filter { it.value.promotions.contains(name) }
|
||||
if (freeforUnits.isNotEmpty()) {
|
||||
val freeforString = freeforUnits.map { it.value.name }.joinToString(", ") { it.tr() }
|
||||
stringBuilder.appendLine("Free for [$freeforString]".tr())
|
||||
override fun makeLink() = "Promotion/$name"
|
||||
override fun hasCivilopediaTextLines() = true
|
||||
override fun replacesCivilopediaDescription() = true
|
||||
|
||||
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
||||
val textList = ArrayList<FormattedLine>()
|
||||
|
||||
for (unique in uniqueObjects) {
|
||||
textList += FormattedLine(unique)
|
||||
}
|
||||
|
||||
val filteredPrerequisites = prerequisites.mapNotNull {
|
||||
ruleset.unitPromotions[it]
|
||||
}
|
||||
if (filteredPrerequisites.isNotEmpty()) {
|
||||
textList += FormattedLine()
|
||||
if (filteredPrerequisites.size == 1) {
|
||||
filteredPrerequisites[0].let {
|
||||
textList += FormattedLine("Requires [${it.name}]", link = it.makeLink())
|
||||
}
|
||||
} else {
|
||||
textList += FormattedLine("Requires at least one of the following:")
|
||||
filteredPrerequisites.forEach {
|
||||
textList += FormattedLine(it.name, link = it.makeLink())
|
||||
}
|
||||
}
|
||||
}
|
||||
return stringBuilder.toString()
|
||||
|
||||
if (unitTypes.isNotEmpty()) {
|
||||
textList += FormattedLine()
|
||||
// This separates the linkable (corresponding to a BaseUnit name) unitFilter entries
|
||||
// from the others - `first` collects those for which the predicate is `true`.
|
||||
val types = unitTypes.partition { it in ruleset.units }
|
||||
if (unitTypes.size == 1) {
|
||||
if (types.first.isNotEmpty())
|
||||
types.first.first().let {
|
||||
textList += FormattedLine("Available for [${it.tr()}]", link = "Unit/$it")
|
||||
}
|
||||
else
|
||||
textList += FormattedLine("Available for [${types.second.first().tr()}]")
|
||||
} else {
|
||||
textList += FormattedLine("Available for:")
|
||||
types.first.forEach {
|
||||
textList += FormattedLine(it, indent = 1, link = "Unit/$it")
|
||||
}
|
||||
types.second.forEach {
|
||||
textList += FormattedLine(it, indent = 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val freeForUnits = ruleset.units.filter { it.value.promotions.contains(name) }.map { it.key }
|
||||
if (freeForUnits.isNotEmpty()) {
|
||||
textList += FormattedLine()
|
||||
if (freeForUnits.size == 1) {
|
||||
freeForUnits[0].let {
|
||||
textList += FormattedLine("Free for [$it]", link = "Unit/$it")
|
||||
}
|
||||
} else {
|
||||
textList += FormattedLine("Free for:")
|
||||
freeForUnits.forEach {
|
||||
textList += FormattedLine(it, link = "Unit/$it")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val grantors = ruleset.buildings.values.filter {
|
||||
building -> building.uniqueObjects.any {
|
||||
it.placeholderText == "All newly-trained [] units [] receive the [] promotion"
|
||||
&& it.params[2] == name
|
||||
}
|
||||
} + ruleset.terrains.values.filter {
|
||||
// once that unique is parameterized, this will be the efficient order of checks
|
||||
terrain -> terrain.uniques.any {
|
||||
it == "Grants Rejuvenation (all healing effects doubled) to adjacent military land units for the rest of the game"
|
||||
&& name == "Rejuvenation"
|
||||
}
|
||||
}
|
||||
if (grantors.isNotEmpty()) {
|
||||
textList += FormattedLine()
|
||||
if (grantors.size == 1) {
|
||||
grantors[0].let {
|
||||
textList += FormattedLine("Granted by [${it.name}]", link = it.makeLink())
|
||||
}
|
||||
} else {
|
||||
textList += FormattedLine("Granted by:")
|
||||
grantors.forEach {
|
||||
textList += FormattedLine(it.name, link = it.makeLink(), indent = 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return textList
|
||||
}
|
||||
}
|
@ -242,7 +242,7 @@ class CivilopediaScreen(
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
it.name,
|
||||
it.getUniqueString(ruleset, false),
|
||||
"",
|
||||
CivilopediaCategories.Nation.getImage?.invoke(it.name, imageSize),
|
||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
||||
)
|
||||
@ -260,7 +260,7 @@ class CivilopediaScreen(
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
it.name,
|
||||
it.getDescription(ruleset.unitPromotions.values, true, ruleset),
|
||||
"",
|
||||
CivilopediaCategories.Promotion.getImage?.invoke(it.name, imageSize),
|
||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
||||
)
|
||||
|
@ -138,6 +138,8 @@ class FormattedLine (
|
||||
const val iconPad = 5f
|
||||
/** Padding distance per [indent] level */
|
||||
const val indentPad = 30f
|
||||
/** Where indent==1 will be, measured as icon count */
|
||||
const val indentOneAtNumIcons = 3
|
||||
|
||||
// Helper for constructor(Unique)
|
||||
private fun getUniqueLink(unique: Unique): String {
|
||||
@ -259,7 +261,9 @@ class FormattedLine (
|
||||
centered -> -usedWidth
|
||||
indent == 0 && iconCount == 0 -> 0f
|
||||
indent == 0 -> iconPad
|
||||
else -> (indent-1) * indentPad + 3 * minIconSize + 4 * iconPad - usedWidth
|
||||
noLinkImages -> indent * indentPad - usedWidth
|
||||
else -> (indent-1) * indentPad +
|
||||
indentOneAtNumIcons * (minIconSize + iconPad) + iconPad - usedWidth
|
||||
}
|
||||
val label = if (fontSize == defaultSize && labelColor == defaultColor) textToDisplay.toLabel()
|
||||
else textToDisplay.toLabel(labelColor,fontSize)
|
||||
|
Loading…
Reference in New Issue
Block a user