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:
SomeTroglodyte 2021-07-30 14:55:17 +02:00 committed by GitHub
parent 4bcf821879
commit 130c318ae0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 311 additions and 52 deletions

View File

@ -152,8 +152,7 @@
{ {
"name": "Medic II", "name": "Medic II",
"prerequisites": ["Medic"], "prerequisites": ["Medic"],
"uniques": ["[+5] HP when healing", "All adjacent units heal [5] HP when healing", "uniques": ["[+5] HP when healing", "[+5] HP when healing in [Foreign Land] tiles", "All adjacent units heal [5] HP when healing"],
"[+5] HP when healing in [Foreign Land] tiles"],
"unitTypes": ["Melee","Mounted","Scout"] "unitTypes": ["Melee","Mounted","Scout"]
}, },

View File

@ -48,6 +48,7 @@ Required tech: [requiredTech] = Benötigt Technologie: [requiredTech]
Requires [PolicyOrNationalWonder] = Benötigt [PolicyOrNationalWonder] Requires [PolicyOrNationalWonder] = Benötigt [PolicyOrNationalWonder]
Cannot be purchased = Kann nicht gekauft werden Cannot be purchased = Kann nicht gekauft werden
See also = Siehe auch See also = Siehe auch
Requires at least one of the following: = Benötigt eine der folgenden Vorraussetzungen:
Current construction = Aktuelle Produktion Current construction = Aktuelle Produktion
Construction queue = Produktionswarteschlange 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 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 Units that consume this resource = Einheiten welche diese Ressource verbrauchen
Can be built on = Kann gebaut werden auf Can be built on = Kann gebaut werden auf
or [terrainType] = oder [terrainType]
Can be constructed by = Kann erbaut werden von Can be constructed by = Kann erbaut werden von
Defence bonus = Verteidigungsbonus Defence bonus = Verteidigungsbonus
Movement cost = Bewegungskosten 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 # Other civilopedia things
Nations = Nationen Nations = Nationen
Available for [unitTypes] = Verfügbar für [unitTypes] Available for [unitTypes] = Verfügbar für [unitTypes]
Available for: = Verfügbar für:
Free promotion: = Freie Beförderung: Free promotion: = Freie Beförderung:
Free promotions: = Freie Beförderungen: Free promotions: = Freie Beförderungen:
Free for [units] = Frei für [units] 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] [bonus] with [tech] = [bonus] mit [tech]
Difficulty levels = Schwierigkeitsgrade Difficulty levels = Schwierigkeitsgrade
@ -978,7 +984,7 @@ Siege = Belagerung
WaterCivilian = Wasser-Zivilist WaterCivilian = Wasser-Zivilist
WaterMelee = Wassernahkampf WaterMelee = Wassernahkampf
WaterRanged = Wasserfernkampf WaterRanged = Wasserfernkampf
WaterSubmarine = Wasser-U-Boot WaterSubmarine = U-Boote
WaterAircraftCarrier = Flugzeugträger WaterAircraftCarrier = Flugzeugträger
Fighter = Jagdflugzeug 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 '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 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 The Great Library = Die Große Bibliothek
Circus = Zirkus 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. 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? 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 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. 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? 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 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? 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. Welcome. = Willkommen.
Father Governs Children = Vater und Kinder 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! 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? 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 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 '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 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 '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. '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 Satellites = Satelliten
Reveals the entire map = Enthüllt die gesamte Weltkarte Reveals the entire map = Enthüllt die gesamte Weltkarte
@ -3687,7 +3694,7 @@ Barrage III = Sperrfeuer III
Volley = Salve Volley = Salve
Extended Range = erweiterte Reichweite Extended Range = Erhöhte Reichweite
[amount] Range = [amount] Reichweite [amount] Range = [amount] Reichweite
Indirect Fire = Indirektes Feuer 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 All adjacent units heal [amount] HP when healing = Beim Heilen werden alle benachbarten Einheiten um [amount] LP geheilt
Medic II = Sanitäter II 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 Scouting I = Spähen I
[amount] Visibility Range = [amount] Sichtweite [amount] Visibility Range = [amount] Sichtweite
@ -3753,12 +3760,12 @@ Boarding Party II = Enterkommando II
Boarding Party III = Enterkommando III 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] 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 Targeting I = Gezielter Schlag I
@ -3787,7 +3794,7 @@ Flight Deck II = Flugdeck II
Flight Deck III = Flugdeck III Flight Deck III = Flugdeck III
Supply = Versorgung 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 Siege I = Belagerung I
@ -3810,7 +3817,7 @@ Air Targeting I = Luftangriff I
Air Targeting II = Luftangriff II Air Targeting II = Luftangriff II
Sortie = Lufteinsatz 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 Operational Range = Einsatzreichweite
@ -3938,7 +3945,7 @@ Knight = Ritter
Camel Archer = Kamel-Bogenschütze Camel Archer = Kamel-Bogenschütze
Conquistador = Eroberer Conquistador = Konquistador
Defense bonus when embarked = Verteidigungsbonus wenn Eingeschifft Defense bonus when embarked = Verteidigungsbonus wenn Eingeschifft
Naresuan's Elephant = Naresuans Elefant Naresuan's Elephant = Naresuans Elefant
@ -4052,7 +4059,7 @@ Zero = Zero
B17 = B-17 B17 = B-17
Paratrooper = Fallschirmjäger 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 Tank = Panzer

View File

@ -48,6 +48,7 @@ Required tech: [requiredTech] =
Requires [PolicyOrNationalWonder] = Requires [PolicyOrNationalWonder] =
Cannot be purchased = Cannot be purchased =
See also = See also =
Requires at least one of the following: =
Current construction = Current construction =
Construction queue = Construction queue =
@ -856,6 +857,7 @@ Buildings that consume this resource =
Buildings that require this resource worked near the city = Buildings that require this resource worked near the city =
Units that consume this resource = Units that consume this resource =
Can be built on = Can be built on =
or [terrainType] =
Can be constructed by = Can be constructed by =
Defence bonus = Defence bonus =
Movement cost = Movement cost =
@ -927,9 +929,13 @@ Gold reward for clearing barbarian camps =
# Other civilopedia things # Other civilopedia things
Nations = Nations =
Available for [unitTypes] = Available for [unitTypes] =
Available for: =
Free promotion: = Free promotion: =
Free promotions: = Free promotions: =
Free for [units] = Free for [units] =
Free for: =
Granted by [param] =
Granted by: =
[bonus] with [tech] = [bonus] with [tech] =
Difficulty levels = Difficulty levels =

View File

@ -575,7 +575,7 @@ open class TileInfo {
} }
fun toMarkup(viewingCiv: CivilizationInfo?): ArrayList<FormattedLine> { 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 val isViewableToPlayer = viewingCiv == null || UncivGame.Current.viewEntireMapForDebug
|| viewingCiv.viewableTiles.contains(this) || viewingCiv.viewableTiles.contains(this)

View File

@ -3,8 +3,14 @@
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.unciv.Constants import com.unciv.Constants
import com.unciv.logic.civilization.CityStateType import com.unciv.logic.civilization.CityStateType
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.stats.INamed 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.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.Fonts
import com.unciv.ui.utils.colorFromRGB import com.unciv.ui.utils.colorFromRGB
@ -15,7 +21,7 @@ enum class VictoryType {
Scientific Scientific
} }
class Nation : INamed { class Nation : INamed, ICivilopediaText {
override lateinit var name: String override lateinit var name: String
var leaderName = "" var leaderName = ""
@ -49,6 +55,8 @@ class Nation : INamed {
var adjective = ArrayList<String>() var adjective = ArrayList<String>()
*/ */
override var civilopediaText = listOf<FormattedLine>()
@Transient @Transient
private lateinit var outerColorObject: Color private lateinit var outerColorObject: Color
fun getOuterColor(): Color = outerColorObject fun getOuterColor(): Color = outerColorObject
@ -88,14 +96,10 @@ class Nation : INamed {
lateinit var cities: ArrayList<String> 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>() val textList = ArrayList<String>()
if (leaderName.isNotEmpty() && !forPickerScreen) {
textList += getLeaderDisplayName().tr()
textList += ""
}
if (uniqueName != "") textList += uniqueName.tr() + ":" if (uniqueName != "") textList += uniqueName.tr() + ":"
if (uniqueText != "") { if (uniqueText != "") {
textList += " " + uniqueText.tr() textList += " " + uniqueText.tr()
@ -190,4 +194,152 @@ class Nation : INamed {
textList += " " + unique.tr() 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)
}
}
} }

View File

@ -94,7 +94,7 @@ class BaseUnit : INamed, IConstruction, CivilopediaText() {
stats += "$rangedStrength${Fonts.rangedStrength}" stats += "$rangedStrength${Fonts.rangedStrength}"
stats += "$range${Fonts.range}" 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 (cost != 0) stats += "{Cost}: $cost"
if (stats.isNotEmpty()) if (stats.isNotEmpty())
textList += FormattedLine(stats.joinToString(", ")) textList += FormattedLine(stats.joinToString(", "))

View File

@ -4,45 +4,136 @@ import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.Unique import com.unciv.models.ruleset.Unique
import com.unciv.models.stats.INamed import com.unciv.models.stats.INamed
import com.unciv.models.translations.tr 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 override lateinit var name: String
var prerequisites = listOf<String>() var prerequisites = listOf<String>()
var effect = "" var effect = ""
var unitTypes = listOf<String>() // The json parser wouldn't agree to deserialize this as a list of UnitTypes. =( var unitTypes = listOf<String>() // The json parser wouldn't agree to deserialize this as a list of UnitTypes. =(
var uniques = ArrayList<String>() 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 { override var civilopediaText = listOf<FormattedLine>()
// 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()
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()) { if (prerequisites.isNotEmpty()) {
val prerequisitesString: ArrayList<String> = arrayListOf() val prerequisitesString: ArrayList<String> = arrayListOf()
for (i in prerequisites.filter { promotionsForUnitType.any { promotion -> promotion.name == it } }) { for (i in prerequisites.filter { promotionsForUnitType.any { promotion -> promotion.name == it } }) {
prerequisitesString.add(i.tr()) prerequisitesString.add(i.tr())
} }
stringBuilder.appendLine("{Requires}: ".tr() + prerequisitesString.joinToString(" OR ".tr())) textList += "{Requires}: ".tr() + prerequisitesString.joinToString(" OR ".tr())
} }
if(forCivilopedia){ return textList.joinToString("\n")
if (unitTypes.isNotEmpty()) {
val unitTypesString = unitTypes.joinToString(", ") { it.tr() }
stringBuilder.appendLine("Available for [$unitTypesString]".tr())
} }
if (ruleSet!=null) { override fun makeLink() = "Promotion/$name"
val freeforUnits = ruleSet.units.filter { it.value.promotions.contains(name) } override fun hasCivilopediaTextLines() = true
if (freeforUnits.isNotEmpty()) { override fun replacesCivilopediaDescription() = true
val freeforString = freeforUnits.map { it.value.name }.joinToString(", ") { it.tr() }
stringBuilder.appendLine("Free for [$freeforString]".tr()) 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
} }
} }

View File

@ -242,7 +242,7 @@ class CivilopediaScreen(
.map { .map {
CivilopediaEntry( CivilopediaEntry(
it.name, it.name,
it.getUniqueString(ruleset, false), "",
CivilopediaCategories.Nation.getImage?.invoke(it.name, imageSize), CivilopediaCategories.Nation.getImage?.invoke(it.name, imageSize),
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() } (it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
) )
@ -260,7 +260,7 @@ class CivilopediaScreen(
.map { .map {
CivilopediaEntry( CivilopediaEntry(
it.name, it.name,
it.getDescription(ruleset.unitPromotions.values, true, ruleset), "",
CivilopediaCategories.Promotion.getImage?.invoke(it.name, imageSize), CivilopediaCategories.Promotion.getImage?.invoke(it.name, imageSize),
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() } (it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
) )

View File

@ -138,6 +138,8 @@ class FormattedLine (
const val iconPad = 5f const val iconPad = 5f
/** Padding distance per [indent] level */ /** Padding distance per [indent] level */
const val indentPad = 30f const val indentPad = 30f
/** Where indent==1 will be, measured as icon count */
const val indentOneAtNumIcons = 3
// Helper for constructor(Unique) // Helper for constructor(Unique)
private fun getUniqueLink(unique: Unique): String { private fun getUniqueLink(unique: Unique): String {
@ -259,7 +261,9 @@ class FormattedLine (
centered -> -usedWidth centered -> -usedWidth
indent == 0 && iconCount == 0 -> 0f indent == 0 && iconCount == 0 -> 0f
indent == 0 -> iconPad 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() val label = if (fontSize == defaultSize && labelColor == defaultColor) textToDisplay.toLabel()
else textToDisplay.toLabel(labelColor,fontSize) else textToDisplay.toLabel(labelColor,fontSize)