Basic version of EspionageManger, added a unique to gain spies (#7641)

* Handfull of comment questions, small refactorings

* Code changes

* Reworded a unique, removed a file

* Added spy names for all nations, minor consistency change

* Removed debug output

* Added an empty constructor so gdx can reconstruct it
This commit is contained in:
Xander Lenstra
2022-08-13 21:45:16 +02:00
committed by GitHub
parent 89979748a1
commit 202e0bcf47
18 changed files with 1077 additions and 922 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -71,6 +71,9 @@
"startingCulture": 200, "startingCulture": 200,
"settlerPopulation": 1, "settlerPopulation": 1,
"settlerBuildings": ["Shrine","Monument"], "settlerBuildings": ["Shrine","Monument"],
// So theoretically this is always just all the wonders at least 2 eras old. So we could just use that.
// But where is the modularity? The excluding of very specific wonders? That is no fun.
// So we just write down the entire long list (sorted by era!) every time instead.
"startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus"], "startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus"],
"baseUnitBuyCost": 200, "baseUnitBuyCost": 200,
"embarkDefense": 6, "embarkDefense": 6,
@ -123,6 +126,7 @@
"Religious": ["Provides [+12 Faith] per turn"], "Religious": ["Provides [+12 Faith] per turn"],
"Militaristic": ["Provides military units every ≈[17] turns"] "Militaristic": ["Provides military units every ≈[17] turns"]
}, },
"uniques": ["Every major Civilization gains a spy once a civilization enters this era"],
"iconRGB": [104, 58, 183] "iconRGB": [104, 58, 183]
}, },
{ {
@ -160,7 +164,8 @@
"iconRGB": [63, 81, 182], "iconRGB": [63, 81, 182],
"uniques": ["May not generate great prophet equivalents naturally", "uniques": ["May not generate great prophet equivalents naturally",
"May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])", "May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])",
"Starting in this era disables religion" "Starting in this era disables religion",
"Every major Civilization gains a spy once a civilization enters this era"
] ]
}, },
{ {
@ -199,7 +204,8 @@
"iconRGB": [33, 150, 243], "iconRGB": [33, 150, 243],
"uniques": ["May not generate great prophet equivalents naturally", "uniques": ["May not generate great prophet equivalents naturally",
"May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])", "May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])",
"Starting in this era disables religion" "Starting in this era disables religion",
"Every major Civilization gains a spy once a civilization enters this era"
] ]
}, },
{ {
@ -239,7 +245,8 @@
"iconRGB": [0, 150, 136], "iconRGB": [0, 150, 136],
"uniques": ["May not generate great prophet equivalents naturally", "uniques": ["May not generate great prophet equivalents naturally",
"May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])", "May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])",
"Starting in this era disables religion" "Starting in this era disables religion",
"Every major Civilization gains a spy once a civilization enters this era"
] ]
}, },
{ {
@ -262,9 +269,7 @@
"baseUnitBuyCost": 1000, "baseUnitBuyCost": 1000,
"embarkDefense": 20, "embarkDefense": 20,
"startPercent": 80, "startPercent": 80,
// So theoretically this is always just all the wonders at least 2 eras old. So we could just use that.
// But where is the modularity? The excluding of very specific wonders? That is no fun.
// So we just write down the entire long list (sorted by era!) instead.
"citySound": "cityInformation", "citySound": "cityInformation",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
@ -284,7 +289,8 @@
"iconRGB": [76, 176, 81], "iconRGB": [76, 176, 81],
"uniques": ["May not generate great prophet equivalents naturally", "uniques": ["May not generate great prophet equivalents naturally",
"May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])", "May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])",
"Starting in this era disables religion" "Starting in this era disables religion",
"Every major Civilization gains a spy once a civilization enters this era"
] ]
}, },
{ // Technically, this Era doesn't exist in the original game. { // Technically, this Era doesn't exist in the original game.
@ -328,7 +334,8 @@
"iconRGB": [76, 176, 81], "iconRGB": [76, 176, 81],
"uniques": ["May not generate great prophet equivalents naturally", "uniques": ["May not generate great prophet equivalents naturally",
"May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])", "May buy [Great Prophet] units for [200] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([100])",
"Starting in this era disables religion" "Starting in this era disables religion",
"Every major Civilization gains a spy once a civilization enters this era"
] ]
} }
] ]

View File

@ -35,7 +35,8 @@
"cities": ["Babylon","Akkad","Dur-Kurigalzu","Nippur","Borsippa","Sippar","Opis","Mari","Shushan","Eshnunna", "cities": ["Babylon","Akkad","Dur-Kurigalzu","Nippur","Borsippa","Sippar","Opis","Mari","Shushan","Eshnunna",
"Ellasar","Erech","Kutha","Sirpurla","Neribtum","Ashur","Ninveh","Nimrud","Arbela","Nuzi", "Ellasar","Erech","Kutha","Sirpurla","Neribtum","Ashur","Ninveh","Nimrud","Arbela","Nuzi",
"Arrapkha","Tutub","Shaduppum","Rapiqum","Mashkan Shapir","Tuttul","Ramad","Ana","Haradum","Agrab", "Arrapkha","Tutub","Shaduppum","Rapiqum","Mashkan Shapir","Tuttul","Ramad","Ana","Haradum","Agrab",
"Uqair","Gubba","Hafriyat","Nagar","Shubat Enlil","Urhai","Urkesh","Awan","Riblah","Tayma"] "Uqair","Gubba","Hafriyat","Nagar","Shubat Enlil","Urhai","Urkesh","Awan","Riblah","Tayma"],
"spyNames": ["Rim-Sin II", "Smerdis", "Ilum-ma-ili", "Peshgaldaramesh", "Ur-zigurumaš", "Semiramis", "Em", "Ishtar", "Bilit Taauth", "Aruru"]
}, },
{ {
"name": "Greece", "name": "Greece",
@ -66,7 +67,8 @@
"Eretria","Pergamon","Miletos","Megara","Phocaea","Sicyon","Tiryns","Samos","Mytilene","Chios", "Eretria","Pergamon","Miletos","Megara","Phocaea","Sicyon","Tiryns","Samos","Mytilene","Chios",
"Paros","Elis","Syracuse","Herakleia","Gortyn","Chalkis","Pylos","Pella","Naxos","Sicyon", "Paros","Elis","Syracuse","Herakleia","Gortyn","Chalkis","Pylos","Pella","Naxos","Sicyon",
"Larissa","Apollonia","Messene","Orchomenos","Ambracia","Kos","Knidos","Amphipolis", "Larissa","Apollonia","Messene","Orchomenos","Ambracia","Kos","Knidos","Amphipolis",
"Patras","Lamia","Nafplion","Apolyton"] "Patras","Lamia","Nafplion","Apolyton"],
"spyNames": ["Jason", "Helena", "Alexa", "Cletus", "Kassandra", "Andres", "Desdemona", "Anthea", "Aeneas", "Leander",]
}, },
{ {
"name": "China", "name": "China",
@ -91,7 +93,9 @@
"cities": ["Beijing","Shanghai","Guangzhou","Nanjing","Xian","Chengdu","Hangzhou","Tianjin","Macau","Shandong", "cities": ["Beijing","Shanghai","Guangzhou","Nanjing","Xian","Chengdu","Hangzhou","Tianjin","Macau","Shandong",
"Kaifeng","Ningbo","Baoding","Yangzhou","Harbin","Chongqing","Luoyang","Kunming","Taipei","Shenyang", "Kaifeng","Ningbo","Baoding","Yangzhou","Harbin","Chongqing","Luoyang","Kunming","Taipei","Shenyang",
"Taiyuan","Tainan","Dalian","Lijiang","Wuxi","Suzhou","Maoming","Shaoguan","Yangjiang","Heyuan","Huangshi", "Taiyuan","Tainan","Dalian","Lijiang","Wuxi","Suzhou","Maoming","Shaoguan","Yangjiang","Heyuan","Huangshi",
"Yichang","Yingtian","Xinyu","Xinzheng","Handan","Dunhuang","Gaoyu","Nantong","Weifang","Xikang"] "Yichang","Yingtian","Xinyu","Xinzheng","Handan","Dunhuang","Gaoyu","Nantong","Weifang","Xikang"],
"spyNames": ["Li", "Chen", "Zhang", "Liu", "Yang", "Huang", "Zhao", "Wu", "Zhou", "Sun"]
}, },
{ {
"name": "Egypt", "name": "Egypt",
@ -122,7 +126,8 @@
"Hieraconpolis","Abydos","Asyut","Avaris","Lisht","Buto","Edfu","Pithom","Busiris","Kahun","Athribis", "Hieraconpolis","Abydos","Asyut","Avaris","Lisht","Buto","Edfu","Pithom","Busiris","Kahun","Athribis",
"Mendes","Elashmunein","Tanis","Bubastis","Oryx","Sebennytus","Akhmin","Karnak","Luxor","El Kab","Armant", "Mendes","Elashmunein","Tanis","Bubastis","Oryx","Sebennytus","Akhmin","Karnak","Luxor","El Kab","Armant",
"Balat","Ellahun","Hawara","Dashur","Damanhur","Ellahun","Abusir","Ellahun","Herakleopolis","Akoris", "Balat","Ellahun","Hawara","Dashur","Damanhur","Ellahun","Abusir","Ellahun","Herakleopolis","Akoris",
"Benihasan","Badari","Hermopolis","Amrah","Koptos","Ombos","Naqada","Semna","Soleb"] "Benihasan","Badari","Hermopolis","Amrah","Koptos","Ombos","Naqada","Semna","Soleb"],
"spyNames": ["Refaat", "Heba", "Salah", "Ahmed", "Zakaria", "Bastet", "Ma'at", "Nebhet", "Tefenet", "Neuth"]
}, },
{ {
"name": "England", "name": "England",
@ -148,7 +153,8 @@
"cities": ["London","York","Nottingham","Hastings","Canterbury","Coventry","Warwick","Newcastle","Oxford","Liverpool", "cities": ["London","York","Nottingham","Hastings","Canterbury","Coventry","Warwick","Newcastle","Oxford","Liverpool",
"Dover","Brighton","Norwich","Leeds","Reading","Birmingham","Richmond","Exeter","Cambridge","Gloucester", "Dover","Brighton","Norwich","Leeds","Reading","Birmingham","Richmond","Exeter","Cambridge","Gloucester",
"Manchester","Bristol","Leicester","Carlisle","Ipswich","Portsmouth","Berwick","Bath","Mumbles","Southampton", "Manchester","Bristol","Leicester","Carlisle","Ipswich","Portsmouth","Berwick","Bath","Mumbles","Southampton",
"Sheffield","Salisbury","Colchester","Plymouth","Lancaster","Blackpool","Winchester","Hull"] "Sheffield","Salisbury","Colchester","Plymouth","Lancaster","Blackpool","Winchester","Hull"],
"spyNames": ["James", "Scarlett", "Mycroft", "Charlotte", "Gwendolyn", "Mr. Eks", "Dr. Grey", "Andrew", "Scott", "Anne"]
}, },
{ {
"name": "France", "name": "France",
@ -173,7 +179,8 @@
"cities": ["Paris","Orleans","Lyon","Troyes","Tours","Marseille","Chartres","Avignon","Rouen","Grenoble", "cities": ["Paris","Orleans","Lyon","Troyes","Tours","Marseille","Chartres","Avignon","Rouen","Grenoble",
"Dijon","Amiens","Cherbourg","Poitiers","Toulouse","Bayonne","Strasbourg","Brest","Bordeaux","Rennes", "Dijon","Amiens","Cherbourg","Poitiers","Toulouse","Bayonne","Strasbourg","Brest","Bordeaux","Rennes",
"Nice","Saint Etienne","Nantes","Reims","Le Mans","Montpellier","Limoges","Nancy","Lille","Caen","Toulon", "Nice","Saint Etienne","Nantes","Reims","Le Mans","Montpellier","Limoges","Nancy","Lille","Caen","Toulon",
"Le Havre","Lourdes","Cannes","Aix-En-Provence","La Rochelle","Bourges","Calais"] "Le Havre","Lourdes","Cannes","Aix-En-Provence","La Rochelle","Bourges","Calais"],
"spyNames": ["Jean-Paul", "Martine", "Lucien", "François", "Augustine", "Monsieur X", "Dr. Dupont", "Vipère", "Yvette", "Renard"]
}, },
{ {
"name": "Russia", "name": "Russia",
@ -200,7 +207,8 @@
"cities": ["Moscow","St. Petersburg","Novgorod","Rostov","Yaroslavl","Yekaterinburg","Yakutsk","Vladivostok","Smolensk","Orenburg", "cities": ["Moscow","St. Petersburg","Novgorod","Rostov","Yaroslavl","Yekaterinburg","Yakutsk","Vladivostok","Smolensk","Orenburg",
"Krasnoyarsk","Khabarovsk","Bryansk","Tver","Novosibirsk","Magadan","Murmansk","Irkutsk","Chita","Samara", "Krasnoyarsk","Khabarovsk","Bryansk","Tver","Novosibirsk","Magadan","Murmansk","Irkutsk","Chita","Samara",
"Arkhangelsk","Chelyabinsk","Tobolsk","Vologda","Omsk","Astrakhan","Kursk","Saratov","Tula","Vladimir","Perm", "Arkhangelsk","Chelyabinsk","Tobolsk","Vologda","Omsk","Astrakhan","Kursk","Saratov","Tula","Vladimir","Perm",
"Voronezh","Pskov","Starayarussa","Kostoma","Nizhniy Novgorod","Suzdal","Magnitogorsk"] "Voronezh","Pskov","Starayarussa","Kostoma","Nizhniy Novgorod","Suzdal","Magnitogorsk"],
"spyNames": ["Alexei", "Lena", "Dmitry", "Anastasia", "Tatiana", "Boris", "Doktor Seriy", "Mikhail", "Natacha", "Zmeya"]
}, },
{ {
"name": "Rome", "name": "Rome",
@ -227,7 +235,8 @@
"cities": ["Rome","Antium","Cumae","Neapolis","Ravenna","Arretium","Mediolanum","Arpinum","Circei","Setia", "cities": ["Rome","Antium","Cumae","Neapolis","Ravenna","Arretium","Mediolanum","Arpinum","Circei","Setia",
"Satricum","Ardea","Ostia","Velitrae","Viroconium","Tarentum","Brundisium","Caesaraugusta","Caesarea","Palmyra", "Satricum","Ardea","Ostia","Velitrae","Viroconium","Tarentum","Brundisium","Caesaraugusta","Caesarea","Palmyra",
"Signia","Aquileia","Clusium","Sutrium","Cremona","Placentia","Hispalis","Artaxata","Aurelianorum","Nicopolis", "Signia","Aquileia","Clusium","Sutrium","Cremona","Placentia","Hispalis","Artaxata","Aurelianorum","Nicopolis",
"Agrippina","Verona","Corfinium","Treverii","Sirmium","Augustadorum","Curia","Interrama","Adria"] "Agrippina","Verona","Corfinium","Treverii","Sirmium","Augustadorum","Curia","Interrama","Adria"],
"spyNames": ["Flavius", "Regula", "Servius", "Lucia", "Cornelius", "Licina", "Canus", "Serpens", "Agrippa", "Brutus",]
}, },
{ {
"name": "Arabia", "name": "Arabia",
@ -252,7 +261,9 @@
"uniques": ["[+1 Gold] from each Trade Route", "Double quantity of [Oil] produced"], "uniques": ["[+1 Gold] from each Trade Route", "Double quantity of [Oil] produced"],
"cities": ["Mecca","Medina","Damascus","Baghdad","Najran","Kufah","Basra","Khurasan","Anjar","Fustat", "cities": ["Mecca","Medina","Damascus","Baghdad","Najran","Kufah","Basra","Khurasan","Anjar","Fustat",
"Aden","Yamama","Muscat","Mansura","Bukhara","Fez","Shiraz","Merw","Balkh","Mosul", "Aden","Yamama","Muscat","Mansura","Bukhara","Fez","Shiraz","Merw","Balkh","Mosul",
"Aydab","Bayt","Suhar","Taif","Hama","Tabuk","Sana'a","Shihr","Tripoli","Tunis","Kairouan","Algiers","Oran"] "Aydab","Bayt","Suhar","Taif","Hama","Tabuk","Sana'a","Shihr","Tripoli","Tunis","Kairouan","Algiers","Oran"],
"spyNames": ["Solhofaat", "Khenzeer", "Zarafah", "Temsaah", "Abyadh", "Mostafa", "Yusuf", "Waddah", "Sameera", "Gamal"]
}, },
{ {
"name": "America", "name": "America",
@ -279,7 +290,8 @@
"Cleveland","Kansas City","San Diego","Richmond","Las Vegas","Phoenix","Albuquerque","Minneapolis","Pittsburgh", "Cleveland","Kansas City","San Diego","Richmond","Las Vegas","Phoenix","Albuquerque","Minneapolis","Pittsburgh",
"Oakland","Tampa Bay","Orlando","Tacoma","Santa Fe","Olympia","Hunt Valley","Springfield","Palo Alto","Centralia", "Oakland","Tampa Bay","Orlando","Tacoma","Santa Fe","Olympia","Hunt Valley","Springfield","Palo Alto","Centralia",
"Spokane","Jacksonville","Svannah","Charleston","San Antonio","Birmingham","Anchorage","Sacramento","Reno", "Spokane","Jacksonville","Svannah","Charleston","San Antonio","Birmingham","Anchorage","Sacramento","Reno",
"Salt Lake City","Boise","Milwaukee","Santa Cruz","Little Rock"] "Salt Lake City","Boise","Milwaukee","Santa Cruz","Little Rock"],
"spyNames": ["Cousin", "Felix", "Dennis", "Edward", "Prof. Rex", "Eliza", "Mary", "Virginia", "Scarlett", "Barbara"]
}, },
{ {
"name": "Japan", "name": "Japan",
@ -305,7 +317,8 @@
"cities": ["Kyoto","Osaka","Tokyo","Satsuma","Kagoshima","Nara","Nagoya","Izumo","Nagasaki","Yokohama", "cities": ["Kyoto","Osaka","Tokyo","Satsuma","Kagoshima","Nara","Nagoya","Izumo","Nagasaki","Yokohama",
"Shimonoseki","Matsuyama","Sapporo","Hakodate","Ise","Toyama","Fukushima","Suo","Bizen","Echizen", "Shimonoseki","Matsuyama","Sapporo","Hakodate","Ise","Toyama","Fukushima","Suo","Bizen","Echizen",
"Izumi","Omi","Echigo","Kozuke","Sado","Kobe","Nagano","Hiroshima","Takayama","Akita","Fukuoka","Aomori", "Izumi","Omi","Echigo","Kozuke","Sado","Kobe","Nagano","Hiroshima","Takayama","Akita","Fukuoka","Aomori",
"Kamakura","Kochi","Naha","Sendai","Gifu","Yamaguchi","Ota","Tottori"] "Kamakura","Kochi","Naha","Sendai","Gifu","Yamaguchi","Ota","Tottori"],
"spyNames": ["Akaishi", "Oki", "Hattori", "Morozumi", "Momochi", "Kawashima", "Orin", "Sakanishi", "Kaede", "Mochizuki"]
}, },
{ {
"name": "India", "name": "India",
@ -330,7 +343,8 @@
"uniques": ["Unhappiness from number of Cities doubled", "[-50]% Unhappiness from [Population] [in all cities]"], "uniques": ["Unhappiness from number of Cities doubled", "[-50]% Unhappiness from [Population] [in all cities]"],
"cities": ["Delhi","Mumbai","Vijayanagara","Pataliputra","Varanasi","Agra","Calcutta","Lahore","Bangalore","Hyderabad","Madurai","Ahmedabad", "cities": ["Delhi","Mumbai","Vijayanagara","Pataliputra","Varanasi","Agra","Calcutta","Lahore","Bangalore","Hyderabad","Madurai","Ahmedabad",
"Kolhapur","Prayaga","Ayodhya","Indraprastha","Mathura","Ujjain","Gulbarga","Jaunpur","Rajagriha","Sravasti","Tiruchirapalli","Thanjavur", "Kolhapur","Prayaga","Ayodhya","Indraprastha","Mathura","Ujjain","Gulbarga","Jaunpur","Rajagriha","Sravasti","Tiruchirapalli","Thanjavur",
"Bodhgaya","Kushinagar","Amaravati","Gaur","Gwalior","Jaipur","Karachi"] "Bodhgaya","Kushinagar","Amaravati","Gaur","Gwalior","Jaipur","Karachi"],
"spyNames": ["Ashok", "Shanx", "Hormis", "Sanjeev", "Ananda", "Rani", "Parvati", "Mukta", "Karishma", "Jyotsna"]
}, },
{ {
"name": "Germany", "name": "Germany",
@ -358,7 +372,8 @@
"Münster","Rostock","Chemnitz","Braunschweig","Halle","Mönchengladbach","Kiel","Wuppertal","Freiburg","Hagen", "Münster","Rostock","Chemnitz","Braunschweig","Halle","Mönchengladbach","Kiel","Wuppertal","Freiburg","Hagen",
"Erfurt","Kaiserslautern","Kassel","Oberhausen","Hamm","Saarbrücken","Krefeld","Pirmasens","Potsdam","Solingen", "Erfurt","Kaiserslautern","Kassel","Oberhausen","Hamm","Saarbrücken","Krefeld","Pirmasens","Potsdam","Solingen",
"Osnabrück","Ludwigshafen","Leverkusen","Oldenburg","Neuss","Mülheim","Darmstadt","Herne","Würzburg", "Osnabrück","Ludwigshafen","Leverkusen","Oldenburg","Neuss","Mülheim","Darmstadt","Herne","Würzburg",
"Recklinghausen","Göttingen","Wolfsburg","Koblenz","Hildesheim","Erlangen"] "Recklinghausen","Göttingen","Wolfsburg","Koblenz","Hildesheim","Erlangen"],
"spyNames": ["Johann", "Marlene", "Wilhelm", "Eva", "Heinz", "Horst", "Carl", "Viper", "Albrecht", "Anton"]
}, },
{ {
@ -386,7 +401,8 @@
"cities": ["Istanbul","Edirne","Ankara","Bursa","Konya","Samsun","Gaziantep","Diyarbakır","Izmir","Kayseri","Malatya", "cities": ["Istanbul","Edirne","Ankara","Bursa","Konya","Samsun","Gaziantep","Diyarbakır","Izmir","Kayseri","Malatya",
"Mersin","Antalya","Zonguldak","Denizli","Ordu","Muğla","Eskişehir","Inebolu","Sinop","Adana","Artvin", "Mersin","Antalya","Zonguldak","Denizli","Ordu","Muğla","Eskişehir","Inebolu","Sinop","Adana","Artvin",
"Bodrum","Eregli","Silifke","Sivas","Amasya","Marmaris","Trabzon","Erzurum","Urfa","Izmit","Afyonkarahisar", "Bodrum","Eregli","Silifke","Sivas","Amasya","Marmaris","Trabzon","Erzurum","Urfa","Izmit","Afyonkarahisar",
"Bitlis","Yalova"] "Bitlis","Yalova"],
"spyNames": ["Ibrahim", "Bayezid", "Sokollu", "Mahmut", "Uveys", "Roxelana", "Safiye", "Hafsa", "Kosem", "Nurbanu"]
}, },
{ {
"name": "Korea", "name": "Korea",
@ -412,7 +428,8 @@
"uniques": ["[+2 Science] from every specialist [in all cities]", "[+2 Science] from every [Great Improvement]","Receive a tech boost when scientific buildings/wonders are built in capital"], "uniques": ["[+2 Science] from every specialist [in all cities]", "[+2 Science] from every [Great Improvement]","Receive a tech boost when scientific buildings/wonders are built in capital"],
"cities": ["Seoul","Busan","Jeonju","Daegu","Pyongyang","Kaesong","Suwon","Gwangju","Gangneung","Hamhung","Wonju","Ulsan", "cities": ["Seoul","Busan","Jeonju","Daegu","Pyongyang","Kaesong","Suwon","Gwangju","Gangneung","Hamhung","Wonju","Ulsan",
"Changwon","Andong","Gongju","Haeju","Cheongju","Mokpo","Dongducheon","Geoje","Suncheon","Jinju","Sangju", "Changwon","Andong","Gongju","Haeju","Cheongju","Mokpo","Dongducheon","Geoje","Suncheon","Jinju","Sangju",
"Rason","Gyeongju","Chungju","Sacheon","Gimje","Anju"] "Rason","Gyeongju","Chungju","Sacheon","Gimje","Anju"],
"spyNames": ["Kim", "Park", "Han", "Na", "Kong", "Yu", "Ahn", "Na", "Da", "Eun"]
}, },
{ {
@ -439,7 +456,8 @@
"cities": ["Onondaga","Osininka","Grand River","Akwesasme","Buffalo Creek","Brantford","Montreal","Genesse River", "cities": ["Onondaga","Osininka","Grand River","Akwesasme","Buffalo Creek","Brantford","Montreal","Genesse River",
"Canandaigua Lake","Lake Simcoe","Salamanca","Gowanda","Cuba","Akron","Kanesatake","Ganienkeh","Cayuga Castle", "Canandaigua Lake","Lake Simcoe","Salamanca","Gowanda","Cuba","Akron","Kanesatake","Ganienkeh","Cayuga Castle",
"Chondote","Canajoharie","Nedrow","Oneida Lake","Kanonwalohale","Green Bay","Southwold","Mohawk Valley", "Chondote","Canajoharie","Nedrow","Oneida Lake","Kanonwalohale","Green Bay","Southwold","Mohawk Valley",
"Schoharie","Bay of Quinte","Kanawale","Kanatsiokareke","Tyendinaga","Hahta"] "Schoharie","Bay of Quinte","Kanawale","Kanatsiokareke","Tyendinaga","Hahta"],
"spyNames": ["Onatah", "Oneida", "Oshadagea", "Otetiani", "Genesee", "Dadgayadoh", "Otwtiani", "Kateri", "Onondakai", "Honanyawus"]
}, },
{ {
"name": "Persia", "name": "Persia",
@ -467,7 +485,8 @@
"Dura Europos","Aleppo","Qatna","Kabul","Capisa","Kyreskhata","Marakanda","Peshawar","Van","Pteira","Arshada", "Dura Europos","Aleppo","Qatna","Kabul","Capisa","Kyreskhata","Marakanda","Peshawar","Van","Pteira","Arshada",
"Artakaona","Aspabota","Autiyara","Bagastana","Baxtri","Darmasa","Daphnai","Drapsaka","Eion","Gandutava", "Artakaona","Aspabota","Autiyara","Bagastana","Baxtri","Darmasa","Daphnai","Drapsaka","Eion","Gandutava",
"Gaugamela","Harmozeia","Ekatompylos","Izata","Kampada","Kapisa","Karmana","Kounaxa","Kuganaka","Nautaka", "Gaugamela","Harmozeia","Ekatompylos","Izata","Kampada","Kapisa","Karmana","Kounaxa","Kuganaka","Nautaka",
"Paishiyauvada","Patigrbana","Phrada"] "Paishiyauvada","Patigrbana","Phrada"],
"spyNames": ["Azi", "Dabir", "Firuz", "Gaspar", "Shahzad", "Aga", "Marjane", "Peri", "Sartaj ", "Yasmin"]
}, },
{ {
"name": "Polynesia", "name": "Polynesia",
@ -493,7 +512,8 @@
"cities": ["Honolulu","Samoa","Tonga","Nuku Hiva","Raiatea","Aotearoa","Tahiti","Hilo","Te Wai Pounamu","Rapa Nui", "cities": ["Honolulu","Samoa","Tonga","Nuku Hiva","Raiatea","Aotearoa","Tahiti","Hilo","Te Wai Pounamu","Rapa Nui",
"Tuamotu","Rarotonga","Tuvalu","Tubuai","Mangareva","Oahu","Kiritimati","Ontong Java","Niue","Rekohu", "Tuamotu","Rarotonga","Tuvalu","Tubuai","Mangareva","Oahu","Kiritimati","Ontong Java","Niue","Rekohu",
"Rakahanga","Bora Bora","Kailua","Uvea","Futuna","Rotuma","Tokelau","Lahaina","Bellona","Mungava","Tikopia", "Rakahanga","Bora Bora","Kailua","Uvea","Futuna","Rotuma","Tokelau","Lahaina","Bellona","Mungava","Tikopia",
"Emae","Kapingamarangi","Takuu","Nukuoro","Sikaiana","Anuta","Nuguria","Pileni","Nukumanu"] "Emae","Kapingamarangi","Takuu","Nukuoro","Sikaiana","Anuta","Nuguria","Pileni","Nukumanu"],
"spyNames": ["Tiki", "Hotu Matua", "Rongo-ma-tane", "Kupe", "Haloti", "Degei", "Babamik", "Kulu Lau", "Nangananga", "Turua"]
}, },
{ {
"name": "Siam", "name": "Siam",
@ -519,7 +539,8 @@
"cities": ["Sukhothai","Si Satchanalai","Muang Saluang","Lampang","Phitsanulok","Kamphaeng Pet","Nakhom Chum","Vientiane", "cities": ["Sukhothai","Si Satchanalai","Muang Saluang","Lampang","Phitsanulok","Kamphaeng Pet","Nakhom Chum","Vientiane",
"Nakhon Si Thammarat","Martaban","Nakhon Sawan","Chainat","Luang Prabang","Uttaradit","Chiang Thong","Phrae", "Nakhon Si Thammarat","Martaban","Nakhon Sawan","Chainat","Luang Prabang","Uttaradit","Chiang Thong","Phrae",
"Nan","Tak","Suphanburi","Hongsawadee","Thawaii","Ayutthaya","Taphan Hin","Uthai Thani","Lap Buri","Ratchasima", "Nan","Tak","Suphanburi","Hongsawadee","Thawaii","Ayutthaya","Taphan Hin","Uthai Thani","Lap Buri","Ratchasima",
"Ban Phai","Loci","Khon Kaen","Surin"] "Ban Phai","Loci","Khon Kaen","Surin"],
"spyNames": ["Aran", "Chanarong", "Kiet", "Niran", "Virote", "Kulap", "Mayuree", "Phueng", "Ratana", "Tola"]
}, },
{ {
"name": "Spain", "name": "Spain",
@ -546,7 +567,8 @@
"cities": ["Madrid","Barcelona","Seville","Cordoba","Toledo","Santiago","Salamanca","Murcia","Valencia","Zaragoza","Pamplona", "cities": ["Madrid","Barcelona","Seville","Cordoba","Toledo","Santiago","Salamanca","Murcia","Valencia","Zaragoza","Pamplona",
"Vitoria","Santander","Oviedo","Jaen","Logroño","Valladolid","Palma","Teruel","Almeria","Leon","Zamora","Mida", "Vitoria","Santander","Oviedo","Jaen","Logroño","Valladolid","Palma","Teruel","Almeria","Leon","Zamora","Mida",
"Lugo","Alicante","Càdiz","Eiche","Alcorcon","Burgos","Vigo","Badajoz","La Coruña","Guadalquivir","Bilbao", "Lugo","Alicante","Càdiz","Eiche","Alcorcon","Burgos","Vigo","Badajoz","La Coruña","Guadalquivir","Bilbao",
"San Sebastian","Granada","Mérida","Huelva","Ibiza","Las Palmas","Tenerife"] "San Sebastian","Granada","Mérida","Huelva","Ibiza","Las Palmas","Tenerife"],
"spyNames": ["Rodrigo", "Esmeralda", "Leon", "Mathilda", "Ramona", "Señor X", "Topolino", "Serpiente", "Garcia", "El Lobo"]
}, },
{ {
"name": "Songhai", "name": "Songhai",
@ -571,7 +593,8 @@
"uniques": ["Receive triple Gold from Barbarian encampments and pillaging Cities", "Defense bonus when embarked <for [All] units>", "[Land] units gain the [Amphibious] promotion"], "uniques": ["Receive triple Gold from Barbarian encampments and pillaging Cities", "Defense bonus when embarked <for [All] units>", "[Land] units gain the [Amphibious] promotion"],
"cities": ["Gao","Tombouctu","Jenne","Taghaza","Tondibi","Kumbi Saleh","Kukia","Walata","Tegdaoust","Argungu","Gwandu", "cities": ["Gao","Tombouctu","Jenne","Taghaza","Tondibi","Kumbi Saleh","Kukia","Walata","Tegdaoust","Argungu","Gwandu",
"Kebbi","Boussa","Motpi","Bamako","Wa","Kayes","Awdaghost","Ouadane","Dakar","Tadmekket","Tekedda","Kano", "Kebbi","Boussa","Motpi","Bamako","Wa","Kayes","Awdaghost","Ouadane","Dakar","Tadmekket","Tekedda","Kano",
"Agadez","Niamey","Torodi","Ouatagouna","Dori","Bamba","Segou"] "Agadez","Niamey","Torodi","Ouatagouna","Dori","Bamba","Segou"],
"spyNames": ["Ahmadou", "Ayub", "Badru", "Bokhari", "Guedado", "Adhiambo", "Chinaka", "Laila", "Mariama", "Oni"]
}, },
{ {
"name": "Mongolia", "name": "Mongolia",
@ -597,7 +620,8 @@
"cities": ["Karakorum","Beshbalik","Turfan","Hsia","Old Sarai","New Sarai","Tabriz","Tiflis","Otrar","Sanchu","Kazan", "cities": ["Karakorum","Beshbalik","Turfan","Hsia","Old Sarai","New Sarai","Tabriz","Tiflis","Otrar","Sanchu","Kazan",
"Almarikh","Ulaanbaatar","Hovd","Darhan","Dalandzadgad","Mandalgovi","Choybalsan","Erdenet","Tsetserieg", "Almarikh","Ulaanbaatar","Hovd","Darhan","Dalandzadgad","Mandalgovi","Choybalsan","Erdenet","Tsetserieg",
"Baruun-Urt","Ereen","Batshireet","Choyr","Ulaangom","Tosontsengel","Altay","Uliastay","Bayanhongor", "Baruun-Urt","Ereen","Batshireet","Choyr","Ulaangom","Tosontsengel","Altay","Uliastay","Bayanhongor",
"Har-Ayrag","Nalayh","Tes"] "Har-Ayrag","Nalayh","Tes"],
"spyNames": ["Asashōryū", "Tömöriin", "Zevegiin", "Jigjidiin", "Enkhbat", "Mönkhbayar", "Gündegmaa", "Ssima", "Batachikhan", "Chulunny"]
}, },
{ {
"name": "Aztecs", "name": "Aztecs",
@ -627,7 +651,9 @@
"Atzcapotzalco","Tzintzuntzan","Malinalco","Tula","Tamuin","Teayo","Cempoala","Chalco","Tlalmanalco", "Atzcapotzalco","Tzintzuntzan","Malinalco","Tula","Tamuin","Teayo","Cempoala","Chalco","Tlalmanalco",
"Ixtapaluca","Huexotla","Tepexpan","Tepetlaoxtoc","Chiconautla","Zitlaltepec","Coyotepec","Tequixquiac", "Ixtapaluca","Huexotla","Tepexpan","Tepetlaoxtoc","Chiconautla","Zitlaltepec","Coyotepec","Tequixquiac",
"Jilotzingo","Tlapanaloya","Tultitan","Ecatepec","Coatepec","Chalchiuites","Chiauhita","Chapultepec", "Jilotzingo","Tlapanaloya","Tultitan","Ecatepec","Coatepec","Chalchiuites","Chiauhita","Chapultepec",
"Itzapalapa","Ayotzinco","Iztapam"] "Itzapalapa","Ayotzinco","Iztapam"],
"spyNames": ["Metztli", "Xitllali", "Chimalli", "Quauhtli", "Teyacapan", "Yaotl", "Coatl", "Huitzilin", "Itzli", "Tepin"]
}, },
{ {
"name": "Inca", "name": "Inca",
@ -667,7 +693,8 @@
"cities": ["Cuzco","Tiwanaku","Machu","Ollantaytambo","Corihuayrachina","Huamanga","Rumicucho","Vilcabamba","Vitcos", "cities": ["Cuzco","Tiwanaku","Machu","Ollantaytambo","Corihuayrachina","Huamanga","Rumicucho","Vilcabamba","Vitcos",
"Andahuaylas","Ica","Arequipa","Nasca","Atico","Juli","Chuito","Chuquiapo","Huanuco Pampa","Tamboccocha", "Andahuaylas","Ica","Arequipa","Nasca","Atico","Juli","Chuito","Chuquiapo","Huanuco Pampa","Tamboccocha",
"Huaras","Riobamba","Caxamalca","Sausa","Tambo Colorado","Huaca","Tumbes","Chan Chan","Sipan","Pachacamac", "Huaras","Riobamba","Caxamalca","Sausa","Tambo Colorado","Huaca","Tumbes","Chan Chan","Sipan","Pachacamac",
"Llactapata","Pisac","Kuelap","Pajaten","Chucuito","Choquequirao"] "Llactapata","Pisac","Kuelap","Pajaten","Chucuito","Choquequirao"],
"spyNames": ["Amaru", "Apichu", "Pariapichiu", "Puma", "Quenti", "Suyuntu", "Uturuncu", "Uturuncu", "Purutu", "Ozcollo"]
}, },
{ {
"name": "Denmark", "name": "Denmark",
@ -695,7 +722,8 @@
"Bergen","Faeroerne","Reykjavik","Trondheim","Godthab","Helluland","Lillehammer","Markland","Elsinore", "Bergen","Faeroerne","Reykjavik","Trondheim","Godthab","Helluland","Lillehammer","Markland","Elsinore",
"Sarpsborg","Odense","Aalborg","Stavanger","Vorbasse","Schleswig","Kristiansand","Halogaland","Randers", "Sarpsborg","Odense","Aalborg","Stavanger","Vorbasse","Schleswig","Kristiansand","Halogaland","Randers",
"Fredrikstad","Kolding","Horsens","Tromsoe","Vejle","Koge","Sandnes","Holstebro","Slagelse","Drammen", "Fredrikstad","Kolding","Horsens","Tromsoe","Vejle","Koge","Sandnes","Holstebro","Slagelse","Drammen",
"Hillerod","Sonderborg","Skien","Svendborg","Holbaek","Hjorring","Fladstrand","Haderslev","Ringsted","Skrive"] "Hillerod","Sonderborg","Skien","Svendborg","Holbaek","Hjorring","Fladstrand","Haderslev","Ringsted","Skrive"],
"spyNames": ["Jørgen", "Mette", "Henrik", "Niels", "Helle", "Frederik", "Ida", "Thea", "Freja", "Morten"]
}, },
{ {
"name": "The Huns", "name": "The Huns",
@ -718,7 +746,8 @@
"favoredReligion": "Tengriism", "favoredReligion": "Tengriism",
"uniqueName": "Scourge of God", "uniqueName": "Scourge of God",
"uniques": ["[+1 Production] from every [Pasture]", "Cities are razed [2] times as fast", "Starts with [Animal Husbandry]", "\"Borrows\" city names from other civilizations in the game"], "uniques": ["[+1 Production] from every [Pasture]", "Cities are razed [2] times as fast", "Starts with [Animal Husbandry]", "\"Borrows\" city names from other civilizations in the game"],
"cities": ["Atilla's Court"] "cities": ["Atilla's Court"],
"spyNames": ["Balamber", "Uldin", "Donatus", "Charato", "Octar", "Bleda", "Ellac", "Dengizik", "Hildico", "Gudrun"]
}, },
{ {
"name": "The Netherlands", "name": "The Netherlands",
@ -741,7 +770,8 @@
"favoredReligion": "Christianity", "favoredReligion": "Christianity",
"uniqueName": "Dutch East India Company", "uniqueName": "Dutch East India Company",
"uniques": ["Retain [50]% of the happiness from a luxury after the last copy has been traded away"], "uniques": ["Retain [50]% of the happiness from a luxury after the last copy has been traded away"],
"cities": ["Amsterdam", "Rotterdam", "Utrecht", "Groningen", "Breda", "Nijmegen", "Den Haag", "Haarlem", "Arnhem", "Zutphen", "Maastricht", "Tilburg", "Eindhoven", "Dordrecht", "Leiden", "'s Hertogenbosch", "Almere", "Alkmaar", "Brielle", "Vlissingen", "Apeldoorn", "Enschede", "Amersfoort", "Zwolle", "Venlo", "Uden", "Grave", "Delft", "Gouda", "Nieuwstadt", "Weesp", "Coevorden", "Kerkrade"] "cities": ["Amsterdam", "Rotterdam", "Utrecht", "Groningen", "Breda", "Nijmegen", "Den Haag", "Haarlem", "Arnhem", "Zutphen", "Maastricht", "Tilburg", "Eindhoven", "Dordrecht", "Leiden", "'s Hertogenbosch", "Almere", "Alkmaar", "Brielle", "Vlissingen", "Apeldoorn", "Enschede", "Amersfoort", "Zwolle", "Venlo", "Uden", "Grave", "Delft", "Gouda", "Nieuwstadt", "Weesp", "Coevorden", "Kerkrade"],
"spyNames": ["Joost", "Hendrika", "Marten", "Anke", "Guus", "Mr. X", "Dr. Grijs", "Willem", "Thijs", "Neef"]
}, },
{ {
@ -771,7 +801,9 @@
"Visby","Falun","Norrköping","Gävle","Halmstad","Karlskrona","Hudiksvall","Örebro","Umeå","Karlstad", "Visby","Falun","Norrköping","Gävle","Halmstad","Karlskrona","Hudiksvall","Örebro","Umeå","Karlstad",
"Helsingborg","Härnösand","Vadstena","Lund","Västervik","Enköping","Skövde","Eskilstuna","Luleå","Lidköping", "Helsingborg","Härnösand","Vadstena","Lund","Västervik","Enköping","Skövde","Eskilstuna","Luleå","Lidköping",
"Södertälje","Mariestad","Östersund","Borås","Sundsvall","Vimmerby","Köping","Mora","Arboga","Växjö","Gränna", "Södertälje","Mariestad","Östersund","Borås","Sundsvall","Vimmerby","Köping","Mora","Arboga","Växjö","Gränna",
"Kiruna","Borgholm","Strängnäs","Sveg"] "Kiruna","Borgholm","Strängnäs","Sveg"
],
"spyNames": ["Leif", "Ingegard", "Sören", "Ragnhild", "Lars", "Lina", "Herr Grå", "Magnus", "Vilma", "Kusin"]
}, },
{ {
"name": "Austria", "name": "Austria",
@ -800,7 +832,8 @@
"St. Pölten", "Eisenstadt", "Villach", "Zwettl", "Traun", "Wels", "Dornbirn", "Feldkirch", "St. Pölten", "Eisenstadt", "Villach", "Zwettl", "Traun", "Wels", "Dornbirn", "Feldkirch",
"Amstetten", "Bad Ischl", "Wolfsberg", "Kufstein", "Leoben", "Klosterneuburg", "Leonding", "Amstetten", "Bad Ischl", "Wolfsberg", "Kufstein", "Leoben", "Klosterneuburg", "Leonding",
"Kapfenberg", "Hallein", "Bischofshofen", "Waidhofen", "Saalbach", "Lienz", "Steyr" "Kapfenberg", "Hallein", "Bischofshofen", "Waidhofen", "Saalbach", "Lienz", "Steyr"
] ],
"spyNames": ["Ferdinand", "Johanna", "Franz-Josef", "Astrid", "Anna", "Hubert", "Alois", "Natter", "Georg", "Arnold",]
}, },
{ {
"name": "Carthage", "name": "Carthage",
@ -828,7 +861,8 @@
"cities": ["Carthage","Utique","Hippo Regius","Gades","Saguntum","Carthago Nova","Panormus","Lilybaeum","Hadrumetum","Zama Regia", "cities": ["Carthage","Utique","Hippo Regius","Gades","Saguntum","Carthago Nova","Panormus","Lilybaeum","Hadrumetum","Zama Regia",
"Karalis","Malaca","Leptis Magna","Hippo Diarrhytus","Motya","Sulci","Leptis Parva","Tharros","Soluntum","Lixus", "Karalis","Malaca","Leptis Magna","Hippo Diarrhytus","Motya","Sulci","Leptis Parva","Tharros","Soluntum","Lixus",
"Oea","Theveste","Ibossim","Thapsus","Aleria","Tingis","Abyla","Sabratha","Rusadir","Baecula", "Oea","Theveste","Ibossim","Thapsus","Aleria","Tingis","Abyla","Sabratha","Rusadir","Baecula",
"Saldae"] "Saldae"],
"spyNames": ["Hamilcar", "Mago", "Baalhaan", "Sophoniba", "Yzebel", "Similce", "Kandaulo", "Zinnridi", "Gisgo", "Fierelus"]
}, },
{ {
"name": "Byzantium", "name": "Byzantium",
@ -855,7 +889,8 @@
"cities": ["Constantinople", "Adrianople", "Nicaea", "Antioch", "Varna", "Ohrid", "Nicomedia", "Trebizond", "Cherson", "Sardica", "cities": ["Constantinople", "Adrianople", "Nicaea", "Antioch", "Varna", "Ohrid", "Nicomedia", "Trebizond", "Cherson", "Sardica",
"Ani", "Dyrrachium", "Edessa", "Chalcedon", "Naissus", "Bari", "Iconium", "Prilep", "Samosata", "Kars", "Nicopolis", "Theodosiopolis", "Ani", "Dyrrachium", "Edessa", "Chalcedon", "Naissus", "Bari", "Iconium", "Prilep", "Samosata", "Kars", "Nicopolis", "Theodosiopolis",
"Tyana", "Gaza", "Kerkyra", "Phoenice", "Selymbria", "Sillyon", "Chrysopolis", "Vodena", "Caesarea", "Traianoupoli", "Constantia", "Athens", "Tyana", "Gaza", "Kerkyra", "Phoenice", "Selymbria", "Sillyon", "Chrysopolis", "Vodena", "Caesarea", "Traianoupoli", "Constantia", "Athens",
"Patra", "Korinthos"] "Patra", "Korinthos"],
"spyNames": ["Basil", "Nikophoros", "Demetrios", "Philippos", "Theophylaktos", "Simonis", "Zoe", "Ioanno", "Xene", "Euphrosyne"]
}, },
{ {
"name": "Celts", "name": "Celts",
@ -895,6 +930,7 @@
"Belfast","Caernarfon","Newquay","Saint-Nazaire","Castletown","Stirling","Galway","Conwy", "Belfast","Caernarfon","Newquay","Saint-Nazaire","Castletown","Stirling","Galway","Conwy",
"St. Austell","Saint-Malo","Onchan","Dundee","Londonderry","Llanfairpwllgwyngyll","Falmouth","Lorient"] "St. Austell","Saint-Malo","Onchan","Dundee","Londonderry","Llanfairpwllgwyngyll","Falmouth","Lorient"]
// Llanfairpwllgwyngyll should actually be Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch // Llanfairpwllgwyngyll should actually be Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch
"spyNames": ["Crìsdean", "Siobhán", "Seamus", "Ffion", "Pádraig", "Deirdre", "Mr. Quinn", "Éadaoin", "Alwyn", "Col Ceathar"]
}, },
{ {
"name": "Ethiopia", "name": "Ethiopia",
@ -931,7 +967,8 @@
"cities": ["Addis Ababa","Harar","Adwa","Lalibela","Gondar","Axum","Dire Dawa","Bahir Dar","Adama", "cities": ["Addis Ababa","Harar","Adwa","Lalibela","Gondar","Axum","Dire Dawa","Bahir Dar","Adama",
"Mek'ele","Awasa","Jimma","Jijiga","Dessie","Debre Berhan","Shashamane","Debre Zeyit","Sodo","Hosaena", "Mek'ele","Awasa","Jimma","Jijiga","Dessie","Debre Berhan","Shashamane","Debre Zeyit","Sodo","Hosaena",
"Nekemte","Asella","Dila","Adigrat","Debre Markos","Kombolcha","Debre Tabor","Sebeta", "Nekemte","Asella","Dila","Adigrat","Debre Markos","Kombolcha","Debre Tabor","Sebeta",
"Shire","Ambo","Negele Arsi","Gambela","Ziway","Weldiya"] "Shire","Ambo","Negele Arsi","Gambela","Ziway","Weldiya"],
"spyNames": ["Mulu Ken", "Wendimu", "Li'ol", "Demeke", "Mulu Alem", "Abebech", "Zema", "Mihret", "Kebedech", "Alemnesh"]
}, },
{ {
"name": "The Maya", "name": "The Maya",
@ -972,7 +1009,8 @@
"cities": ["Palenque","Tikal","Chichen Itza","Uxmal","Tulum","Copan","Coba","El Mirador","Calakmul", "cities": ["Palenque","Tikal","Chichen Itza","Uxmal","Tulum","Copan","Coba","El Mirador","Calakmul",
"Edzna","Lamanai","Izapa","Uaxactun","Comalcalco","Piedras Negras","Cancuen","Yaxha","Quirigua", "Edzna","Lamanai","Izapa","Uaxactun","Comalcalco","Piedras Negras","Cancuen","Yaxha","Quirigua",
"Q'umarkaj","Nakbe","Cerros","Xunantunich","Takalik Abaj","Cival","San Bartolo","Altar de Sacrificios","Seibal", "Q'umarkaj","Nakbe","Cerros","Xunantunich","Takalik Abaj","Cival","San Bartolo","Altar de Sacrificios","Seibal",
"Caracol","Naranjo","Dos Pilas","Mayapan","Ixinche","Zaculeu","Kabah"] "Caracol","Naranjo","Dos Pilas","Mayapan","Ixinche","Zaculeu","Kabah"],
"spyNames": ["Camazotz", "Coyopa", "Gukumatz", "Hunahpu", "Huracan", "Ixchel", "Ixtab", "Kukulkán", "Xbalanque", "Zipacna"]
}, },

View File

@ -2,6 +2,24 @@
{ {
"name": "Quick", "name": "Quick",
"modifier": 0.67, "modifier": 0.67,
/*
Why are all of these raw values and not uniques? This is like EXACTLY what uniques are for,
and speeds even support uniques?
E.g.: [
"[-67]% Production cost of [All] buildings",
"[-67]% Produciton cost of [All] units",
"Gold cost of purchasing [All] units [-67]%"
"Gold cost of purchasing [All] buildings [-67]%"
"[-67]% Science cost of reseaching new Techs" // Needs to be added
"[-67]% Culture cost of adopting new policies"
etc.
I suppose this is how it is done in civ V, but uniques are one of the major features we have
that Civ V doesn't, so why are we not using them?
This approach requires adding these modifies for specific things that need to be added, while
uniques can just be added anywhere. Only need to change CivilizationInfo.getMatchingUniques()
to get the uniques of the current game speed and everything works out of the box.
-xlenstra
*/
"productionCostModifier": 0.67, "productionCostModifier": 0.67,
"goldCostModifier": 0.67, "goldCostModifier": 0.67,
"scienceCostModifier": 0.67, "scienceCostModifier": 0.67,

View File

@ -378,7 +378,7 @@ Rectangular =
Height = Height =
Width = Width =
Radius = Radius =
Enable Religion = Enable Espionage =
Resource Setting = Resource Setting =
Sparse = Sparse =
@ -811,6 +811,8 @@ Your [ourUnit] captured an enemy [theirUnit]! =
Your [ourUnit] plundered [amount] [Stat] from [theirUnit] = Your [ourUnit] plundered [amount] [Stat] from [theirUnit] =
We have captured a barbarian encampment and recovered [goldAmount] gold! = We have captured a barbarian encampment and recovered [goldAmount] gold! =
An enemy [unitType] has joined us! = An enemy [unitType] has joined us! =
After an unknown civilization entered the [eraName], we have recruited [spyName] as a spy! =
We have recruited [spyName] as a spy! =
# This might be needed for a rewrite of Germany's unique - see #7376 # This might be needed for a rewrite of Germany's unique - see #7376
A barbarian [unitType] has joined us! = A barbarian [unitType] has joined us! =

View File

@ -155,6 +155,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
var religionManager = ReligionManager() var religionManager = ReligionManager()
var goldenAges = GoldenAgeManager() var goldenAges = GoldenAgeManager()
var greatPeople = GreatPersonManager() var greatPeople = GreatPersonManager()
var espionageManager = EspionageManager()
var victoryManager = VictoryManager() var victoryManager = VictoryManager()
var ruinsManager = RuinsManager() var ruinsManager = RuinsManager()
var diplomacy = HashMap<String, DiplomacyManager>() var diplomacy = HashMap<String, DiplomacyManager>()
@ -261,6 +262,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
toReturn.goldenAges = goldenAges.clone() toReturn.goldenAges = goldenAges.clone()
toReturn.greatPeople = greatPeople.clone() toReturn.greatPeople = greatPeople.clone()
toReturn.ruinsManager = ruinsManager.clone() toReturn.ruinsManager = ruinsManager.clone()
toReturn.espionageManager = espionageManager.clone()
toReturn.victoryManager = victoryManager.clone() toReturn.victoryManager = victoryManager.clone()
toReturn.allyCivName = allyCivName toReturn.allyCivName = allyCivName
for (diplomacyManager in diplomacy.values.map { it.clone() }) for (diplomacyManager in diplomacy.values.map { it.clone() })
@ -833,6 +835,8 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
diplomacyManager.updateHasOpenBorders() diplomacyManager.updateHasOpenBorders()
} }
espionageManager.setTransients(this)
victoryManager.civInfo = this victoryManager.civInfo = this
thingsToFocusOnForVictory = getPreferredVictoryTypeObject()?.getThingsToFocus(this) ?: setOf() thingsToFocusOnForVictory = getPreferredVictoryTypeObject()?.getThingsToFocus(this) ?: setOf()

View File

@ -0,0 +1,50 @@
package com.unciv.logic.civilization
import com.unciv.logic.IsPartOfGameInfoSerialization
class Spy() : IsPartOfGameInfoSerialization {
lateinit var name: String
constructor(name: String) : this() {
this.name = name
}
fun clone(): Spy {
return Spy(name)
}
}
class EspionageManager : IsPartOfGameInfoSerialization {
var spyCount = 0
var spyList = mutableListOf<Spy>()
var erasSpyEarnedFor = mutableListOf<String>()
@Transient
lateinit var civInfo: CivilizationInfo
fun clone(): EspionageManager {
val toReturn = EspionageManager()
toReturn.spyCount = spyCount
toReturn.spyList.addAll(spyList.map { it.clone() })
toReturn.erasSpyEarnedFor.addAll(erasSpyEarnedFor)
return toReturn
}
fun setTransients(civInfo: CivilizationInfo) {
this.civInfo = civInfo
}
private fun getSpyName(): String {
val usedSpyNames = spyList.map { it.name }.toHashSet()
val validSpyNames = civInfo.nation.spyNames.filter { it !in usedSpyNames }
if (validSpyNames.isEmpty()) { return "Spy ${spyList.size+1}" } // +1 as non-programmers count from 1
return validSpyNames.random()
}
fun addSpy(): String {
val spyName = getSpyName()
spyList.add(Spy(spyName))
return spyName
}
}

View File

@ -14,28 +14,30 @@ import com.unciv.ui.worldscreen.WorldScreen
object NotificationIcon { object NotificationIcon {
// Remember: The typical white-on-transparency icon will not be visible on Notifications // Remember: The typical white-on-transparency icon will not be visible on Notifications
const val Barbarians = "ImprovementIcons/Barbarian encampment"
const val Citadel = "ImprovementIcons/Citadel"
const val City = "ImprovementIcons/City center"
const val CityState = "OtherIcons/CityState"
const val Crosshair = "OtherIcons/CrosshairB"
const val Culture = "StatIcons/Culture" const val Culture = "StatIcons/Culture"
const val Construction = "StatIcons/Production" const val Construction = "StatIcons/Production"
const val Growth = "StatIcons/Population"
const val War = "OtherIcons/Pillage"
const val Trade = "StatIcons/Acquire"
const val Science = "StatIcons/Science"
const val Gold = "StatIcons/Gold"
const val Death = "OtherIcons/DisbandUnit" const val Death = "OtherIcons/DisbandUnit"
const val Diplomacy = "OtherIcons/Diplomacy" const val Diplomacy = "OtherIcons/Diplomacy"
const val City = "ImprovementIcons/City center" const val Faith = "StatIcons/Faith"
const val Citadel = "ImprovementIcons/Citadel" const val Food = "StatIcons/Food"
const val Gold = "StatIcons/Gold"
const val Growth = "StatIcons/Population"
const val Happiness = "StatIcons/Happiness" const val Happiness = "StatIcons/Happiness"
const val Population = "StatIcons/Population" const val Population = "StatIcons/Population"
const val CityState = "OtherIcons/CityState"
const val Production = "StatIcons/Production" const val Production = "StatIcons/Production"
const val Food = "StatIcons/Food"
const val Faith = "StatIcons/Faith"
const val Crosshair = "OtherIcons/CrosshairB"
const val Scout = "UnitIcons/Scout"
const val Ruins = "ImprovementIcons/Ancient ruins"
const val Barbarians = "ImprovementIcons/Barbarian encampment"
const val Question = "OtherIcons/Question" const val Question = "OtherIcons/Question"
const val Ruins = "ImprovementIcons/Ancient ruins"
const val Science = "StatIcons/Science"
const val Scout = "UnitIcons/Scout"
const val Spy = "OtherIcons/Spy"
const val Trade = "StatIcons/Acquire"
const val War = "OtherIcons/Pillage"
} }
/** /**

View File

@ -193,15 +193,13 @@ class PolicyManager : IsPartOfGameInfoSerialization {
} }
} }
// Todo make this a triggerable unique for other objects
for (unique in policy.getMatchingUniques(UniqueType.OneTimeGlobalAlert)) { for (unique in policy.getMatchingUniques(UniqueType.OneTimeGlobalAlert)) {
triggerGlobalAlerts( triggerGlobalAlerts(policy, unique.params[0])
policy, unique.params[0]
)
} }
for (unique in policy.uniqueObjects) UniqueTriggerActivation.triggerCivwideUnique( for (unique in policy.uniqueObjects)
unique, civInfo UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo)
)
// This ALSO has the side-effect of updating the CivInfo statForNextTurn so we don't need to call it explicitly // This ALSO has the side-effect of updating the CivInfo statForNextTurn so we don't need to call it explicitly
for (cityInfo in civInfo.cities) cityInfo.cityStats.update() for (cityInfo in civInfo.cities) cityInfo.cityStats.update()
@ -223,7 +221,7 @@ class PolicyManager : IsPartOfGameInfoSerialization {
) { ) {
var extraNotificationTextCopy = extraNotificationText var extraNotificationTextCopy = extraNotificationText
if (extraNotificationText != "") { if (extraNotificationText != "") {
extraNotificationTextCopy = "\n${extraNotificationText}" extraNotificationTextCopy = " ${extraNotificationText}"
} }
for (civ in civInfo.gameInfo.civilizations.filter { it.isMajorCiv() }) { for (civ in civInfo.gameInfo.civilizations.filter { it.isMajorCiv() }) {
if (civ == civInfo) continue if (civ == civInfo) continue

View File

@ -1,4 +1,5 @@
package com.unciv.logic.civilization.RuinsManager package com.unciv.logic.civilization.RuinsManager
// Why is this the only file in its own package?
import com.unciv.logic.IsPartOfGameInfoSerialization import com.unciv.logic.IsPartOfGameInfoSerialization
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo

View File

@ -238,9 +238,6 @@ class TechManager : IsPartOfGameInfoSerialization {
} }
fun addTechnology(techName: String) { fun addTechnology(techName: String) {
techsInProgress.remove(techName)
val previousEra = civInfo.getEra()
techsResearched.add(techName) techsResearched.add(techName)
// this is to avoid concurrent modification problems // this is to avoid concurrent modification problems
@ -262,19 +259,6 @@ class TechManager : IsPartOfGameInfoSerialization {
civInfo.addNotification("Research of [$techName] has completed!", TechAction(techName), NotificationIcon.Science, techName) civInfo.addNotification("Research of [$techName] has completed!", TechAction(techName), NotificationIcon.Science, techName)
civInfo.popupAlerts.add(PopupAlert(AlertType.TechResearched, techName)) civInfo.popupAlerts.add(PopupAlert(AlertType.TechResearched, techName))
val currentEra = civInfo.getEra()
if (previousEra != currentEra) {
civInfo.addNotification("You have entered the [$currentEra]!", NotificationIcon.Science)
if (civInfo.isMajorCiv()) {
for (knownCiv in civInfo.getKnownCivs()) {
knownCiv.addNotification("[${civInfo.civName}] has entered the [$currentEra]!", civInfo.civName, NotificationIcon.Science)
}
}
for (it in getRuleset().policyBranches.values.filter { it.era == currentEra.name && civInfo.policies.isAdoptable(it) }) {
civInfo.addNotification("[" + it.name + "] policy branch unlocked!", NotificationIcon.Culture)
}
}
if (civInfo.playerType == PlayerType.Human) { if (civInfo.playerType == PlayerType.Human) {
for (revealedResource in getRuleset().tileResources.values.filter { techName == it.revealedBy }) { for (revealedResource in getRuleset().tileResources.values.filter { techName == it.revealedBy }) {
civInfo.gameInfo.notifyExploredResources(civInfo, revealedResource.name, 5, false) civInfo.gameInfo.notifyExploredResources(civInfo, revealedResource.name, 5, false)
@ -334,7 +318,23 @@ class TechManager : IsPartOfGameInfoSerialization {
civInfo.addNotification("You have unlocked [The Long Count]!", MayaLongCountAction(), MayaCalendar.notificationIcon) civInfo.addNotification("You have unlocked [The Long Count]!", MayaLongCountAction(), MayaCalendar.notificationIcon)
} }
val previousEra = civInfo.getEra()
updateEra() updateEra()
val currentEra = civInfo.getEra()
if (previousEra != currentEra) {
civInfo.addNotification("You have entered the [$currentEra]!", NotificationIcon.Science)
if (civInfo.isMajorCiv()) {
for (knownCiv in civInfo.getKnownCivs()) {
knownCiv.addNotification("[${civInfo.civName}] has entered the [$currentEra]!", civInfo.civName, NotificationIcon.Science)
}
}
for (policyBranch in getRuleset().policyBranches.values.filter { it.era == currentEra.name && civInfo.policies.isAdoptable(it) }) {
civInfo.addNotification("[" + policyBranch.name + "] policy branch unlocked!", NotificationIcon.Culture)
}
for (unique in currentEra.uniqueObjects) {
UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo)
}
}
} }
fun updateEra() { fun updateEra() {

View File

@ -48,6 +48,8 @@ class Nation : RulesetObject() {
var adjective = ArrayList<String>() var adjective = ArrayList<String>()
*/ */
var spyNames = ArrayList<String>()
var favoredReligion: String? = null var favoredReligion: String? = null
@Transient @Transient

View File

@ -13,6 +13,11 @@ import com.unciv.models.ruleset.unique.UniqueTarget
* @see com.unciv.models.TutorialTrigger * @see com.unciv.models.TutorialTrigger
*/ */
class Tutorial : RulesetObject() { class Tutorial : RulesetObject() {
// Why does this override RulesetObject()? The only unique it overrides is `Will not be displayed in Civilopedia`,
// so allowing it access to the full power of uniques is completely unnecessary.
// (Also, what even would it mean for this to have uniques like "[+10]% Production"? When should it even apply.)
// imo just having a flag for this (and maybe one if religion is disabled, but even then, that should be a ruleset choice) should suffice.
// -xlenstra
override var name = "" // overridden only to have the name seen first by TranslationFileWriter override var name = "" // overridden only to have the name seen first by TranslationFileWriter
/** These lines will be displayed (when the Tutorial is _triggered_) one after another, /** These lines will be displayed (when the Tutorial is _triggered_) one after another,

View File

@ -477,8 +477,26 @@ object UniqueTriggerActivation {
return true return true
} }
FreeStatBuildings, FreeSpecificBuildings -> OneTimeGlobalSpiesWhenEnteringEra -> {
if (!civInfo.isMajorCiv()) return false
val currentEra = civInfo.getEra().name
for (otherCiv in civInfo.gameInfo.getAliveMajorCivs()) {
if (currentEra !in otherCiv.espionageManager.erasSpyEarnedFor) {
val spyName = otherCiv.espionageManager.addSpy()
otherCiv.espionageManager.erasSpyEarnedFor.add(currentEra)
if (otherCiv == civInfo || otherCiv.knows(civInfo))
otherCiv.addNotification("We have recruited [${spyName}] as a spy!", NotificationIcon.Spy)
else
otherCiv.addNotification("After an unknown civilization entered the [${currentEra}], we have recruited [${spyName}] as a spy!", NotificationIcon.Spy)
}
}
return true
}
FreeStatBuildings, FreeSpecificBuildings -> {
civInfo.civConstructions.tryAddFreeBuildings() civInfo.civConstructions.tryAddFreeBuildings()
return true // not fully correct
}
else -> {} else -> {}
} }

View File

@ -18,7 +18,6 @@ enum class UniqueTarget(val inheritsFrom: UniqueTarget? = null) {
// Civilization-specific // Civilization-specific
Nation(Global), Nation(Global),
Era(Global), Era(Global),
Speed(Global),
Tech(Global), Tech(Global),
Policy(Global), Policy(Global),
FounderBelief(Global), FounderBelief(Global),
@ -46,6 +45,7 @@ enum class UniqueTarget(val inheritsFrom: UniqueTarget? = null) {
Ruins(Triggerable), Ruins(Triggerable),
// Other // Other
Speed,
Tutorial, Tutorial,
CityState, CityState,
ModOptions, ModOptions,
@ -314,7 +314,6 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
TriggersAlertOnCompletion("Triggers a global alert upon completion", UniqueTarget.Building, UniqueTarget.Unit), TriggersAlertOnCompletion("Triggers a global alert upon completion", UniqueTarget.Building, UniqueTarget.Unit),
//endregion //endregion
///////////////////////////////////////// region BUILDING UNIQUES ///////////////////////////////////////// ///////////////////////////////////////// region BUILDING UNIQUES /////////////////////////////////////////
@ -351,7 +350,6 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
CreatesOneImprovement("Creates a [improvementName] improvement on a specific tile", UniqueTarget.Building), CreatesOneImprovement("Creates a [improvementName] improvement on a specific tile", UniqueTarget.Building),
//endregion //endregion
///////////////////////////////////////// region UNIT UNIQUES ///////////////////////////////////////// ///////////////////////////////////////// region UNIT UNIQUES /////////////////////////////////////////
FoundCity("Founds a new city", UniqueTarget.Unit), FoundCity("Founds a new city", UniqueTarget.Unit),
@ -685,7 +683,8 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
OneTimeRevealSpecificMapTiles("Reveal up to [amount/'all'] [tileFilter] within a [amount] tile radius", UniqueTarget.Ruins), OneTimeRevealSpecificMapTiles("Reveal up to [amount/'all'] [tileFilter] within a [amount] tile radius", UniqueTarget.Ruins),
OneTimeRevealCrudeMap("From a randomly chosen tile [amount] tiles away from the ruins, reveal tiles up to [amount] tiles away with [amount]% chance", UniqueTarget.Ruins), OneTimeRevealCrudeMap("From a randomly chosen tile [amount] tiles away from the ruins, reveal tiles up to [amount] tiles away with [amount]% chance", UniqueTarget.Ruins),
OneTimeTriggerVoting("Triggers voting for the Diplomatic Victory", UniqueTarget.Triggerable), // used in Building OneTimeTriggerVoting("Triggers voting for the Diplomatic Victory", UniqueTarget.Triggerable), // used in Building
OneTimeGlobalAlert("Triggers the following global alert: [comment]", UniqueTarget.Triggerable), // used in Policy OneTimeGlobalAlert("Triggers the following global alert: [comment]", UniqueTarget.Policy), // used in Policy
OneTimeGlobalSpiesWhenEnteringEra("Every major Civilization gains a spy once a civilization enters this era", UniqueTarget.Era),
OneTimeUnitHeal("Heal this unit by [amount] HP", UniqueTarget.Promotion), OneTimeUnitHeal("Heal this unit by [amount] HP", UniqueTarget.Promotion),
OneTimeUnitGainXP("This Unit gains [amount] XP", UniqueTarget.Ruins), OneTimeUnitGainXP("This Unit gains [amount] XP", UniqueTarget.Ruins),

View File

@ -49,11 +49,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "Triggers voting for the Diplomatic Victory" ??? example "Triggers voting for the Diplomatic Victory"
Applicable to: Triggerable Applicable to: Triggerable
??? example "Triggers the following global alert: [comment]"
Example: "Triggers the following global alert: [comment]"
Applicable to: Triggerable
??? example "This Unit gains the [promotion] promotion" ??? example "This Unit gains the [promotion] promotion"
Example: "This Unit gains the [Shock I] promotion" Example: "This Unit gains the [Shock I] promotion"
@ -75,7 +70,7 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Triggerable Applicable to: Triggerable
??? example "Will not be displayed in Civilopedia" ??? example "Will not be displayed in Civilopedia"
Applicable to: Triggerable, Global, Nation, Era, Speed, Tech, Policy, FounderBelief, FollowerBelief, Building, Wonder, Unit, UnitType, Promotion, Terrain, Improvement, Resource, Ruins, Tutorial, CityState, ModOptions, Conditional Applicable to: Triggerable, Global, Nation, Era, Tech, Policy, FounderBelief, FollowerBelief, Building, Wonder, Unit, UnitType, Promotion, Terrain, Improvement, Resource, Ruins, Speed, Tutorial, CityState, ModOptions, Conditional
## Global uniques ## Global uniques
??? example "[stats]" ??? example "[stats]"
@ -810,6 +805,9 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "Starting in this era disables religion" ??? example "Starting in this era disables religion"
Applicable to: Era Applicable to: Era
??? example "Every major Civilization gains a spy once a civilization enters this era"
Applicable to: Era
## Tech uniques ## Tech uniques
??? example "Starting tech" ??? example "Starting tech"
Applicable to: Tech Applicable to: Tech
@ -820,6 +818,12 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "Cannot be hurried" ??? example "Cannot be hurried"
Applicable to: Tech, Building Applicable to: Tech, Building
## Policy uniques
??? example "Triggers the following global alert: [comment]"
Example: "Triggers the following global alert: [comment]"
Applicable to: Policy
## FounderBelief uniques ## FounderBelief uniques
??? example "[stats] for each global city following this religion" ??? example "[stats] for each global city following this religion"
Example: "[+1 Gold, +2 Production] for each global city following this religion" Example: "[+1 Gold, +2 Production] for each global city following this religion"