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,
"settlerPopulation": 1,
"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"],
"baseUnitBuyCost": 200,
"embarkDefense": 6,
@ -123,6 +126,7 @@
"Religious": ["Provides [+12 Faith] per turn"],
"Militaristic": ["Provides military units every ≈[17] turns"]
},
"uniques": ["Every major Civilization gains a spy once a civilization enters this era"],
"iconRGB": [104, 58, 183]
},
{
@ -160,7 +164,8 @@
"iconRGB": [63, 81, 182],
"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])",
"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],
"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])",
"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],
"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])",
"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,
"embarkDefense": 20,
"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",
"friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"],
@ -284,7 +289,8 @@
"iconRGB": [76, 176, 81],
"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])",
"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.
@ -328,7 +334,8 @@
"iconRGB": [76, 176, 81],
"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])",
"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",
"Ellasar","Erech","Kutha","Sirpurla","Neribtum","Ashur","Ninveh","Nimrud","Arbela","Nuzi",
"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",
@ -66,7 +67,8 @@
"Eretria","Pergamon","Miletos","Megara","Phocaea","Sicyon","Tiryns","Samos","Mytilene","Chios",
"Paros","Elis","Syracuse","Herakleia","Gortyn","Chalkis","Pylos","Pella","Naxos","Sicyon",
"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",
@ -91,7 +93,9 @@
"cities": ["Beijing","Shanghai","Guangzhou","Nanjing","Xian","Chengdu","Hangzhou","Tianjin","Macau","Shandong",
"Kaifeng","Ningbo","Baoding","Yangzhou","Harbin","Chongqing","Luoyang","Kunming","Taipei","Shenyang",
"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",
@ -122,7 +126,8 @@
"Hieraconpolis","Abydos","Asyut","Avaris","Lisht","Buto","Edfu","Pithom","Busiris","Kahun","Athribis",
"Mendes","Elashmunein","Tanis","Bubastis","Oryx","Sebennytus","Akhmin","Karnak","Luxor","El Kab","Armant",
"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",
@ -148,7 +153,8 @@
"cities": ["London","York","Nottingham","Hastings","Canterbury","Coventry","Warwick","Newcastle","Oxford","Liverpool",
"Dover","Brighton","Norwich","Leeds","Reading","Birmingham","Richmond","Exeter","Cambridge","Gloucester",
"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",
@ -173,7 +179,8 @@
"cities": ["Paris","Orleans","Lyon","Troyes","Tours","Marseille","Chartres","Avignon","Rouen","Grenoble",
"Dijon","Amiens","Cherbourg","Poitiers","Toulouse","Bayonne","Strasbourg","Brest","Bordeaux","Rennes",
"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",
@ -200,7 +207,8 @@
"cities": ["Moscow","St. Petersburg","Novgorod","Rostov","Yaroslavl","Yekaterinburg","Yakutsk","Vladivostok","Smolensk","Orenburg",
"Krasnoyarsk","Khabarovsk","Bryansk","Tver","Novosibirsk","Magadan","Murmansk","Irkutsk","Chita","Samara",
"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",
@ -227,7 +235,8 @@
"cities": ["Rome","Antium","Cumae","Neapolis","Ravenna","Arretium","Mediolanum","Arpinum","Circei","Setia",
"Satricum","Ardea","Ostia","Velitrae","Viroconium","Tarentum","Brundisium","Caesaraugusta","Caesarea","Palmyra",
"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",
@ -252,7 +261,9 @@
"uniques": ["[+1 Gold] from each Trade Route", "Double quantity of [Oil] produced"],
"cities": ["Mecca","Medina","Damascus","Baghdad","Najran","Kufah","Basra","Khurasan","Anjar","Fustat",
"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",
@ -279,7 +290,8 @@
"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",
"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",
@ -305,7 +317,8 @@
"cities": ["Kyoto","Osaka","Tokyo","Satsuma","Kagoshima","Nara","Nagoya","Izumo","Nagasaki","Yokohama",
"Shimonoseki","Matsuyama","Sapporo","Hakodate","Ise","Toyama","Fukushima","Suo","Bizen","Echizen",
"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",
@ -330,7 +343,8 @@
"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",
"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",
@ -358,7 +372,8 @@
"Münster","Rostock","Chemnitz","Braunschweig","Halle","Mönchengladbach","Kiel","Wuppertal","Freiburg","Hagen",
"Erfurt","Kaiserslautern","Kassel","Oberhausen","Hamm","Saarbrücken","Krefeld","Pirmasens","Potsdam","Solingen",
"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",
"Mersin","Antalya","Zonguldak","Denizli","Ordu","Muğla","Eskişehir","Inebolu","Sinop","Adana","Artvin",
"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",
@ -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"],
"cities": ["Seoul","Busan","Jeonju","Daegu","Pyongyang","Kaesong","Suwon","Gwangju","Gangneung","Hamhung","Wonju","Ulsan",
"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",
"Canandaigua Lake","Lake Simcoe","Salamanca","Gowanda","Cuba","Akron","Kanesatake","Ganienkeh","Cayuga Castle",
"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",
@ -467,7 +485,8 @@
"Dura Europos","Aleppo","Qatna","Kabul","Capisa","Kyreskhata","Marakanda","Peshawar","Van","Pteira","Arshada",
"Artakaona","Aspabota","Autiyara","Bagastana","Baxtri","Darmasa","Daphnai","Drapsaka","Eion","Gandutava",
"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",
@ -493,7 +512,8 @@
"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",
"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",
@ -519,7 +539,8 @@
"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",
"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",
@ -546,7 +567,8 @@
"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",
"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",
@ -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"],
"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",
"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",
@ -597,7 +620,8 @@
"cities": ["Karakorum","Beshbalik","Turfan","Hsia","Old Sarai","New Sarai","Tabriz","Tiflis","Otrar","Sanchu","Kazan",
"Almarikh","Ulaanbaatar","Hovd","Darhan","Dalandzadgad","Mandalgovi","Choybalsan","Erdenet","Tsetserieg",
"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",
@ -627,7 +651,9 @@
"Atzcapotzalco","Tzintzuntzan","Malinalco","Tula","Tamuin","Teayo","Cempoala","Chalco","Tlalmanalco",
"Ixtapaluca","Huexotla","Tepexpan","Tepetlaoxtoc","Chiconautla","Zitlaltepec","Coyotepec","Tequixquiac",
"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",
@ -667,7 +693,8 @@
"cities": ["Cuzco","Tiwanaku","Machu","Ollantaytambo","Corihuayrachina","Huamanga","Rumicucho","Vilcabamba","Vitcos",
"Andahuaylas","Ica","Arequipa","Nasca","Atico","Juli","Chuito","Chuquiapo","Huanuco Pampa","Tamboccocha",
"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",
@ -695,7 +722,8 @@
"Bergen","Faeroerne","Reykjavik","Trondheim","Godthab","Helluland","Lillehammer","Markland","Elsinore",
"Sarpsborg","Odense","Aalborg","Stavanger","Vorbasse","Schleswig","Kristiansand","Halogaland","Randers",
"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",
@ -718,7 +746,8 @@
"favoredReligion": "Tengriism",
"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"],
"cities": ["Atilla's Court"]
"cities": ["Atilla's Court"],
"spyNames": ["Balamber", "Uldin", "Donatus", "Charato", "Octar", "Bleda", "Ellac", "Dengizik", "Hildico", "Gudrun"]
},
{
"name": "The Netherlands",
@ -741,7 +770,8 @@
"favoredReligion": "Christianity",
"uniqueName": "Dutch East India Company",
"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",
"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",
"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",
@ -800,7 +832,8 @@
"St. Pölten", "Eisenstadt", "Villach", "Zwettl", "Traun", "Wels", "Dornbirn", "Feldkirch",
"Amstetten", "Bad Ischl", "Wolfsberg", "Kufstein", "Leoben", "Klosterneuburg", "Leonding",
"Kapfenberg", "Hallein", "Bischofshofen", "Waidhofen", "Saalbach", "Lienz", "Steyr"
]
],
"spyNames": ["Ferdinand", "Johanna", "Franz-Josef", "Astrid", "Anna", "Hubert", "Alois", "Natter", "Georg", "Arnold",]
},
{
"name": "Carthage",
@ -828,7 +861,8 @@
"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",
"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",
@ -855,7 +889,8 @@
"cities": ["Constantinople", "Adrianople", "Nicaea", "Antioch", "Varna", "Ohrid", "Nicomedia", "Trebizond", "Cherson", "Sardica",
"Ani", "Dyrrachium", "Edessa", "Chalcedon", "Naissus", "Bari", "Iconium", "Prilep", "Samosata", "Kars", "Nicopolis", "Theodosiopolis",
"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",
@ -895,6 +930,7 @@
"Belfast","Caernarfon","Newquay","Saint-Nazaire","Castletown","Stirling","Galway","Conwy",
"St. Austell","Saint-Malo","Onchan","Dundee","Londonderry","Llanfairpwllgwyngyll","Falmouth","Lorient"]
// Llanfairpwllgwyngyll should actually be Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch
"spyNames": ["Crìsdean", "Siobhán", "Seamus", "Ffion", "Pádraig", "Deirdre", "Mr. Quinn", "Éadaoin", "Alwyn", "Col Ceathar"]
},
{
"name": "Ethiopia",
@ -931,7 +967,8 @@
"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",
"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",
@ -972,7 +1009,8 @@
"cities": ["Palenque","Tikal","Chichen Itza","Uxmal","Tulum","Copan","Coba","El Mirador","Calakmul",
"Edzna","Lamanai","Izapa","Uaxactun","Comalcalco","Piedras Negras","Cancuen","Yaxha","Quirigua",
"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",
"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,
"goldCostModifier": 0.67,
"scienceCostModifier": 0.67,

View File

@ -378,7 +378,7 @@ Rectangular =
Height =
Width =
Radius =
Enable Religion =
Enable Espionage =
Resource Setting =
Sparse =
@ -811,6 +811,8 @@ Your [ourUnit] captured an enemy [theirUnit]! =
Your [ourUnit] plundered [amount] [Stat] from [theirUnit] =
We have captured a barbarian encampment and recovered [goldAmount] gold! =
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
A barbarian [unitType] has joined us! =

View File

@ -155,6 +155,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
var religionManager = ReligionManager()
var goldenAges = GoldenAgeManager()
var greatPeople = GreatPersonManager()
var espionageManager = EspionageManager()
var victoryManager = VictoryManager()
var ruinsManager = RuinsManager()
var diplomacy = HashMap<String, DiplomacyManager>()
@ -261,6 +262,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
toReturn.goldenAges = goldenAges.clone()
toReturn.greatPeople = greatPeople.clone()
toReturn.ruinsManager = ruinsManager.clone()
toReturn.espionageManager = espionageManager.clone()
toReturn.victoryManager = victoryManager.clone()
toReturn.allyCivName = allyCivName
for (diplomacyManager in diplomacy.values.map { it.clone() })
@ -833,6 +835,8 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
diplomacyManager.updateHasOpenBorders()
}
espionageManager.setTransients(this)
victoryManager.civInfo = this
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 {
// 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 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 Diplomacy = "OtherIcons/Diplomacy"
const val City = "ImprovementIcons/City center"
const val Citadel = "ImprovementIcons/Citadel"
const val Faith = "StatIcons/Faith"
const val Food = "StatIcons/Food"
const val Gold = "StatIcons/Gold"
const val Growth = "StatIcons/Population"
const val Happiness = "StatIcons/Happiness"
const val Population = "StatIcons/Population"
const val CityState = "OtherIcons/CityState"
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 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)) {
triggerGlobalAlerts(
policy, unique.params[0]
)
triggerGlobalAlerts(policy, unique.params[0])
}
for (unique in policy.uniqueObjects) UniqueTriggerActivation.triggerCivwideUnique(
unique, civInfo
)
for (unique in policy.uniqueObjects)
UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo)
// 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()
@ -223,7 +221,7 @@ class PolicyManager : IsPartOfGameInfoSerialization {
) {
var extraNotificationTextCopy = extraNotificationText
if (extraNotificationText != "") {
extraNotificationTextCopy = "\n${extraNotificationText}"
extraNotificationTextCopy = " ${extraNotificationText}"
}
for (civ in civInfo.gameInfo.civilizations.filter { it.isMajorCiv() }) {
if (civ == civInfo) continue

View File

@ -1,4 +1,5 @@
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.civilization.CivilizationInfo

View File

@ -238,9 +238,6 @@ class TechManager : IsPartOfGameInfoSerialization {
}
fun addTechnology(techName: String) {
techsInProgress.remove(techName)
val previousEra = civInfo.getEra()
techsResearched.add(techName)
// 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.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) {
for (revealedResource in getRuleset().tileResources.values.filter { techName == it.revealedBy }) {
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)
}
val previousEra = civInfo.getEra()
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() {

View File

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

View File

@ -13,6 +13,11 @@ import com.unciv.models.ruleset.unique.UniqueTarget
* @see com.unciv.models.TutorialTrigger
*/
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
/** These lines will be displayed (when the Tutorial is _triggered_) one after another,

View File

@ -477,8 +477,26 @@ object UniqueTriggerActivation {
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()
return true // not fully correct
}
else -> {}
}

View File

@ -18,7 +18,6 @@ enum class UniqueTarget(val inheritsFrom: UniqueTarget? = null) {
// Civilization-specific
Nation(Global),
Era(Global),
Speed(Global),
Tech(Global),
Policy(Global),
FounderBelief(Global),
@ -46,6 +45,7 @@ enum class UniqueTarget(val inheritsFrom: UniqueTarget? = null) {
Ruins(Triggerable),
// Other
Speed,
Tutorial,
CityState,
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),
//endregion
///////////////////////////////////////// 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),
//endregion
///////////////////////////////////////// region UNIT UNIQUES /////////////////////////////////////////
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),
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
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),
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"
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 [Shock I] promotion"
@ -75,7 +70,7 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Triggerable
??? 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
??? example "[stats]"
@ -810,6 +805,9 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "Starting in this era disables religion"
Applicable to: Era
??? example "Every major Civilization gains a spy once a civilization enters this era"
Applicable to: Era
## Tech uniques
??? example "Starting tech"
Applicable to: Tech
@ -820,6 +818,12 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "Cannot be hurried"
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
??? example "[stats] for each global city following this religion"
Example: "[+1 Gold, +2 Production] for each global city following this religion"