diff --git a/android/assets/jsons/Civ V - Gods & Kings/TileImprovements.json b/android/assets/jsons/Civ V - Gods & Kings/TileImprovements.json index 14e2462483..845e7a4a21 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/TileImprovements.json +++ b/android/assets/jsons/Civ V - Gods & Kings/TileImprovements.json @@ -176,8 +176,18 @@ "uniques": ["Can be built outside your borders"], "shortcutKey": "." }, + // Purely for turnsToBuild and civilopediaText. Unbuildable so it doesn't show in ImprovementPicker + { + "name": "Repair", + "terrainsCanBeBuiltOn": ["Land"], + "turnsToBuild": 2, + "shortcutKey": "E", + "uniques": ["Unbuildable"], + "civilopediaText": [{"text":"Repairs a pillaged Improvement or Route"}] + }, - // Great Person improvements + + // Great Person improvements { "name": "Academy", "terrainsCanBeBuiltOn": ["Land"], diff --git a/android/assets/jsons/Civ V - Vanilla/TileImprovements.json b/android/assets/jsons/Civ V - Vanilla/TileImprovements.json index dab2c98199..1edf5df41b 100644 --- a/android/assets/jsons/Civ V - Vanilla/TileImprovements.json +++ b/android/assets/jsons/Civ V - Vanilla/TileImprovements.json @@ -176,6 +176,15 @@ "uniques": ["Can be built outside your borders"], "shortcutKey": "." }, + // Purely for turnsToBuild and civilopediaText. Unbuildable so it doesn't show in ImprovementPicker + { + "name": "Repair", + "terrainsCanBeBuiltOn": ["Land"], + "turnsToBuild": 2, + "uniques": ["Unbuildable"], + "shortcutKey": "E", + "civilopediaText": [{"text":"Repairs a pillaged Improvement or Route"}] + }, // Great Person improvements { diff --git a/android/assets/jsons/translations/Brazilian_Portuguese.properties b/android/assets/jsons/translations/Brazilian_Portuguese.properties index 7ad508442d..e4b3989f1c 100644 --- a/android/assets/jsons/translations/Brazilian_Portuguese.properties +++ b/android/assets/jsons/translations/Brazilian_Portuguese.properties @@ -938,6 +938,11 @@ Gift unit = Presentear unidade Explore = Explorar Stop exploration = Parar a exploração Pillage = Pilhar +Pillage [improvement] = Pilhar [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Aguarde Are you sure you want to pillage this [improvement]? = Tem certeza de que deseja pilhar esta [improvement]? We have looted [amount] from a [improvement] = Saqueamos [amount] de uma [improvement] @@ -4051,6 +4056,12 @@ Remove Railroad = Remover ferrovia Cancel improvement order = Cancelar ordem de melhoria + # Requires translation! +Repair = +Unbuildable = Não construível + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Academia Removes removable features when built = Remove recursos removíveis quando construído @@ -4074,7 +4085,6 @@ Terrace farm = Cultivo em terraços Ancient ruins = Ruínas antigas Unpillagable = Impossível pilhar Provides a random bonus when entered = Fornece um bônus aleatório quando inserido -Unbuildable = Não construível City ruins = Ruínas da cidade Will be replaced by automated workers = Será substituído por trabalhadores automatizados diff --git a/android/assets/jsons/translations/Bulgarian.properties b/android/assets/jsons/translations/Bulgarian.properties index a2b15cb106..e6c24d9f85 100644 --- a/android/assets/jsons/translations/Bulgarian.properties +++ b/android/assets/jsons/translations/Bulgarian.properties @@ -1289,6 +1289,11 @@ Gift unit = Explore = Изследване Stop exploration = Стоп изследване Pillage = Грабеж +Pillage [improvement] = Грабеж [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = # Requires translation! Wait = # Requires translation! @@ -6761,6 +6766,12 @@ Remove Railroad = # Requires translation! Cancel improvement order = + # Requires translation! +Repair = +Unbuildable = Непостроим + # Requires translation! +Repairs a pillaged Improvement or Route = + # Requires translation! Academy = # Requires translation! @@ -6798,7 +6809,6 @@ Ancient ruins = Unpillagable = # Requires translation! Provides a random bonus when entered = -Unbuildable = Непостроим # Requires translation! City ruins = diff --git a/android/assets/jsons/translations/Catalan.properties b/android/assets/jsons/translations/Catalan.properties index 9bf93cb0d4..28955fcaf7 100644 --- a/android/assets/jsons/translations/Catalan.properties +++ b/android/assets/jsons/translations/Catalan.properties @@ -938,6 +938,11 @@ Gift unit = Regala la unitat Explore = Explora Stop exploration = Cancel·la l’exploració Pillage = Saqueja +Pillage [improvement] = Saqueja [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Espera Are you sure you want to pillage this [improvement]? = Esteu segur que voleu saquejar la [improvement]? We have looted [amount] from a [improvement] = Hem saquejat [amount] de [improvement]. @@ -4051,6 +4056,12 @@ Remove Railroad = Treu el ferrocarril Cancel improvement order = Cancel·la l’ordre de millora + # Requires translation! +Repair = +Unbuildable = No es pot construir. + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Acadèmia Removes removable features when built = Quan es construeix, es treuen les característiques que es pugui. @@ -4074,7 +4085,6 @@ Terrace farm = Feixes Ancient ruins = Ruïnes antigues Unpillagable = No es pot saquejar. Provides a random bonus when entered = S’obté una bonificació aleatòria quan s’hi entra. -Unbuildable = No es pot construir. City ruins = Ruïnes de ciutat Will be replaced by automated workers = Els treballadors automatitzats les reemplaçaran. diff --git a/android/assets/jsons/translations/Czech.properties b/android/assets/jsons/translations/Czech.properties index 50726562f0..27c2457af2 100644 --- a/android/assets/jsons/translations/Czech.properties +++ b/android/assets/jsons/translations/Czech.properties @@ -1079,6 +1079,11 @@ Gift unit = Věnovat jednotku Explore = Prozkoumat Stop exploration = Konec průzkumu Pillage = Drancovat +Pillage [improvement] = Drancovat [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = # Requires translation! Wait = Are you sure you want to pillage this [improvement]? = Opravdu chcete vydrancovat toto vylepšení políčka [improvement]? @@ -4382,6 +4387,12 @@ Remove Railroad = Odstranit železnici Cancel improvement order = Zrušit vylepšování + # Requires translation! +Repair = +Unbuildable = Nelze vybudovat + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akademie # Requires translation! Removes removable features when built = @@ -4406,7 +4417,6 @@ Terrace farm = Terasovité pole Ancient ruins = Starobylé ruiny Unpillagable = Nelze drancovat Provides a random bonus when entered = Po vstupu poskytne jendorázový nahodný bonus -Unbuildable = Nelze vybudovat City ruins = Zřiceniny města # Requires translation! diff --git a/android/assets/jsons/translations/Dutch.properties b/android/assets/jsons/translations/Dutch.properties index 82daf83cfb..6625827ed0 100644 --- a/android/assets/jsons/translations/Dutch.properties +++ b/android/assets/jsons/translations/Dutch.properties @@ -997,6 +997,11 @@ Gift unit = Schenk eenheid Explore = Ontdekken Stop exploration = Stop ontdekken Pillage = Plunderen +Pillage [improvement] = Plunderen [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Wacht Are you sure you want to pillage this [improvement]? = Weet je zeker dat je deze [improvement] wilt plunderen? We have looted [amount] from a [improvement] = We plunderden [amount] van [improvement] @@ -4836,6 +4841,12 @@ Remove Railroad = Haal Spoorweg weg Cancel improvement order = Annuleer verbeteringsopdracht + # Requires translation! +Repair = +Unbuildable = Onbouwbaar + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Academie Removes removable features when built = Verwijdert wegneembare eigenschappen als het gebouwd wordt @@ -4861,7 +4872,6 @@ Terrace farm = Ancient ruins = Oude ruïnes Unpillagable = Kan niet worden geplunderd Provides a random bonus when entered = Geeft een willekeurige bonus bij het betreden -Unbuildable = Onbouwbaar City ruins = Ruïnes van de stad Will be replaced by automated workers = Wordt vervangen door geautomatiseerde werkers diff --git a/android/assets/jsons/translations/English.properties b/android/assets/jsons/translations/English.properties index 8347102599..4d52ccaeda 100644 --- a/android/assets/jsons/translations/English.properties +++ b/android/assets/jsons/translations/English.properties @@ -1760,6 +1760,12 @@ Stop exploration = # Requires translation! Pillage = # Requires translation! +Pillage [improvement] = + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = + # Requires translation! Wait = # Requires translation! Are you sure you want to pillage this [improvement]? = @@ -7520,6 +7526,13 @@ Remove Railroad = # Requires translation! Cancel improvement order = + # Requires translation! +Repair = + # Requires translation! +Unbuildable = + # Requires translation! +Repairs a pillaged Improvement or Route = + # Requires translation! Academy = # Requires translation! @@ -7558,8 +7571,6 @@ Ancient ruins = Unpillagable = # Requires translation! Provides a random bonus when entered = - # Requires translation! -Unbuildable = # Requires translation! City ruins = diff --git a/android/assets/jsons/translations/Filipino.properties b/android/assets/jsons/translations/Filipino.properties index 012741445f..1d3b255e96 100644 --- a/android/assets/jsons/translations/Filipino.properties +++ b/android/assets/jsons/translations/Filipino.properties @@ -942,6 +942,11 @@ Gift unit = Iregalo ang yunit Explore = Galugarin Stop exploration = Itigil ang paggalugad Pillage = Dambungin +Pillage [improvement] = Dambungin [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Maghintay Are you sure you want to pillage this [improvement]? = Sigurado ka ba na dadambungin mo itong [improvement]? We have looted [amount] from a [improvement] = Nagnakaw tayo ng [amount] mula sa [improvement]. @@ -4079,6 +4084,12 @@ Remove Railroad = Tanggalin ang Daambakal Cancel improvement order = Kanselahin ang ayos ng pagbubuti + # Requires translation! +Repair = +Unbuildable = Di kayang itayo + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akademya Removes removable features when built = Tinatanggal ang mga naaalis na tampok kapag binuo @@ -4102,7 +4113,6 @@ Terrace farm = Hagdanang Sakahan Ancient ruins = Sinaunang Guho Unpillagable = Di kayang nakawin Provides a random bonus when entered = Nagbibigay ng sapalarang bonus kapag napuntahan -Unbuildable = Di kayang itayo City ruins = Mga guho ng lungsod Will be replaced by automated workers = Mapapalitan ng mga awtomatikong manggagawa diff --git a/android/assets/jsons/translations/Finnish.properties b/android/assets/jsons/translations/Finnish.properties index 24622541bf..7643d6e6c7 100644 --- a/android/assets/jsons/translations/Finnish.properties +++ b/android/assets/jsons/translations/Finnish.properties @@ -1232,6 +1232,11 @@ Gift unit = Anna yksikkö lahjaksi Explore = Tiedustele Stop exploration = Lopeta tiedustelu Pillage = Ryöstä +Pillage [improvement] = Ryöstä [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = # Requires translation! Wait = Are you sure you want to pillage this [improvement]? = Haluatko totisesti tuhota parannuksen [improvement]? @@ -5675,6 +5680,12 @@ Remove Railroad = Poista Rautatie # Requires translation! Cancel improvement order = + # Requires translation! +Repair = +Unbuildable = Ei rakennettavissa + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akatemia # Requires translation! Removes removable features when built = @@ -5709,7 +5720,6 @@ Ancient ruins = Unpillagable = # Requires translation! Provides a random bonus when entered = -Unbuildable = Ei rakennettavissa # Requires translation! City ruins = diff --git a/android/assets/jsons/translations/French.properties b/android/assets/jsons/translations/French.properties index 82e6145195..ed78f1e719 100644 --- a/android/assets/jsons/translations/French.properties +++ b/android/assets/jsons/translations/French.properties @@ -938,6 +938,11 @@ Gift unit = Offrir une unité Explore = Explorer Stop exploration = Arrêter l'exploration Pillage = Pillage +Pillage [improvement] = Pillage [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Attendre Are you sure you want to pillage this [improvement]? = Voulez-vous vraiment piller ce(tte) [improvement] ? We have looted [amount] from a [improvement] = Nous avons récupéré [amount] dans un(e) [improvement] @@ -4051,6 +4056,12 @@ Remove Railroad = Retirer les rails Cancel improvement order = Annuler ordre d'aménagement + # Requires translation! +Repair = +Unbuildable = Non-constructible + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Académie Removes removable features when built = Détruit les caractéristiques supprimables quand construit @@ -4074,7 +4085,6 @@ Terrace farm = Culture en Terrasses Ancient ruins = Ruines Antiques Unpillagable = Non-pillable Provides a random bonus when entered = Offre un bonus aléatoire lorsque visité -Unbuildable = Non-constructible City ruins = Ruines Urbaines Will be replaced by automated workers = Sera remplacé par les ouvriers automatisés diff --git a/android/assets/jsons/translations/German.properties b/android/assets/jsons/translations/German.properties index 73948182a6..1c78cce8c6 100644 --- a/android/assets/jsons/translations/German.properties +++ b/android/assets/jsons/translations/German.properties @@ -938,6 +938,11 @@ Gift unit = Verschenke Einheiten Explore = Erkunden Stop exploration = Erkundung stoppen Pillage = Plündern +Pillage [improvement] = Plündern [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Warten Are you sure you want to pillage this [improvement]? = Bist du sicher, dass du die Feldverbesserung [improvement] plündern willst? We have looted [amount] from a [improvement] = Wir haben [amount] von der [improvement] Verbesserung geraubt @@ -4051,6 +4056,12 @@ Remove Railroad = Schienen entfernen Cancel improvement order = Stoppt Verbesserungsanweisung + # Requires translation! +Repair = +Unbuildable = nicht baubar + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akademie Removes removable features when built = Entfernt entfernbare Funktionen während des Baus @@ -4074,7 +4085,6 @@ Terrace farm = Terrassenfelder Ancient ruins = Altertümliche Ruinen Unpillagable = Darf nicht geplündert werden Provides a random bonus when entered = Bietet einen Zufallsbonus bei Betreten -Unbuildable = nicht baubar City ruins = Stadtruinen Will be replaced by automated workers = Wird durch automatisierte Arbeiter ersetzt diff --git a/android/assets/jsons/translations/Greek.properties b/android/assets/jsons/translations/Greek.properties index 4ea9dfcac4..f4ef11bebd 100644 --- a/android/assets/jsons/translations/Greek.properties +++ b/android/assets/jsons/translations/Greek.properties @@ -1477,6 +1477,11 @@ Explore = Εξερεύνηση # Requires translation! Stop exploration = Pillage = Λεηλασία +Pillage [improvement] = Λεηλασία [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = # Requires translation! Wait = # Requires translation! @@ -6781,6 +6786,13 @@ Remove Railroad = Αφαίρεσε σιδηρόδρομο # Requires translation! Cancel improvement order = + # Requires translation! +Repair = + # Requires translation! +Unbuildable = + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Ακαδημία # Requires translation! Removes removable features when built = @@ -6818,8 +6830,6 @@ Ancient ruins = Unpillagable = # Requires translation! Provides a random bonus when entered = - # Requires translation! -Unbuildable = # Requires translation! City ruins = diff --git a/android/assets/jsons/translations/Hungarian.properties b/android/assets/jsons/translations/Hungarian.properties index 8a55c475c6..1ddb236e6f 100644 --- a/android/assets/jsons/translations/Hungarian.properties +++ b/android/assets/jsons/translations/Hungarian.properties @@ -1209,6 +1209,11 @@ Gift unit = Egység ajándékozása Explore = Felfedezés Stop exploration = Felfedezés befejezése Pillage = Fosztogatás +Pillage [improvement] = Fosztogatás [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Vár # Requires translation! Are you sure you want to pillage this [improvement]? = @@ -5366,6 +5371,12 @@ Remove Railroad = Vasút eltávolítása # Requires translation! Cancel improvement order = + # Requires translation! +Repair = +Unbuildable = Megépíthetetlen + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akadémia # Requires translation! Removes removable features when built = @@ -5397,7 +5408,6 @@ Ancient ruins = Ősi romok Unpillagable = # Requires translation! Provides a random bonus when entered = -Unbuildable = Megépíthetetlen City ruins = Városromok # Requires translation! diff --git a/android/assets/jsons/translations/Indonesian.properties b/android/assets/jsons/translations/Indonesian.properties index 67849d0bfa..de54410f3c 100644 --- a/android/assets/jsons/translations/Indonesian.properties +++ b/android/assets/jsons/translations/Indonesian.properties @@ -938,6 +938,11 @@ Gift unit = Hadiahkan unit Explore = Jelajah Stop exploration = Hentikan penjelajahan Pillage = Jarah +Pillage [improvement] = Jarah [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Tunggu Are you sure you want to pillage this [improvement]? = Apakah kamu yakin ingin menjarah [improvement] ini? We have looted [amount] from a [improvement] = Kita telah menjarah [amount] dari suatu [improvement] @@ -4051,6 +4056,12 @@ Remove Railroad = Hancurkan Rel Kereta Cancel improvement order = Batalkan perintah peningkatan + # Requires translation! +Repair = +Unbuildable = Tidak dapat dibuat + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akademi Removes removable features when built = Menyingkirkan fitur-fitur yang dapat dihancurkan saat dibangun @@ -4074,7 +4085,6 @@ Terrace farm = Sawah bersengkedan Ancient ruins = Reruntuhan kuno Unpillagable = Tidak dapat dijarah Provides a random bonus when entered = Memberikan bonus acak ketika dijelajahi -Unbuildable = Tidak dapat dibuat City ruins = Reruntuhan kota Will be replaced by automated workers = Akan digantikan oleh pekerja otomatis diff --git a/android/assets/jsons/translations/Italian.properties b/android/assets/jsons/translations/Italian.properties index 250c8edad6..8c904bf429 100644 --- a/android/assets/jsons/translations/Italian.properties +++ b/android/assets/jsons/translations/Italian.properties @@ -943,6 +943,11 @@ Gift unit = Dona unità Explore = Esplora Stop exploration = Smetti di esplorare Pillage = Saccheggia +Pillage [improvement] = Saccheggia [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Attendi Are you sure you want to pillage this [improvement]? = Vuoi davvero saccheggiare [improvement]? We have looted [amount] from a [improvement] = Abbiamo saccheggiato [amount] da [improvement] @@ -4066,6 +4071,12 @@ Remove Railroad = Rimuovi Ferrovia Cancel improvement order = Annulla ordine miglioramento + # Requires translation! +Repair = +Unbuildable = Non costruibile + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Accademia Removes removable features when built = Rimuove caratteristica rimuovibile quando costruito @@ -4089,7 +4100,6 @@ Terrace farm = Terrazzamento Ancient ruins = Antiche rovine Unpillagable = Non saccheggiabile Provides a random bonus when entered = Concede un bonus casuale all'accesso -Unbuildable = Non costruibile City ruins = Rovine cittadine Will be replaced by automated workers = Rimpiazzabile da lavoratori automatizzati diff --git a/android/assets/jsons/translations/Japanese.properties b/android/assets/jsons/translations/Japanese.properties index 6dd36882bd..6e57b10752 100644 --- a/android/assets/jsons/translations/Japanese.properties +++ b/android/assets/jsons/translations/Japanese.properties @@ -1022,6 +1022,11 @@ Gift unit = ユニットを贈る Explore = 探索 Stop exploration = 探索をやめる Pillage = 略奪 +Pillage [improvement] = 略奪 [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = # Requires translation! Wait = Are you sure you want to pillage this [improvement]? = この[improvement]を略奪してもよろしいですか? @@ -4469,6 +4474,12 @@ Remove Railroad = 鉄道削除 Cancel improvement order = タイル整備をやめる + # Requires translation! +Repair = +Unbuildable = 建設不可 + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = アカデミー # Requires translation! Removes removable features when built = @@ -4497,7 +4508,6 @@ Ancient ruins = 古代遺跡 Unpillagable = 侵略不可 # Requires translation! Provides a random bonus when entered = -Unbuildable = 建設不可 City ruins = 都市の遺跡 # Requires translation! diff --git a/android/assets/jsons/translations/Korean.properties b/android/assets/jsons/translations/Korean.properties index 550969dcda..21ab4e2451 100644 --- a/android/assets/jsons/translations/Korean.properties +++ b/android/assets/jsons/translations/Korean.properties @@ -941,6 +941,11 @@ Gift unit = 유닛 선물하기 Explore = 탐색 Stop exploration = 탐색 중지 Pillage = 약탈 +Pillage [improvement] = 약탈 [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = 넘김 Are you sure you want to pillage this [improvement]? = [improvement]을(를) 약탈하겠습니까? We have looted [amount] from a [improvement] = [improvement]을(를) 약탈하여 [amount]를 얻었습니다. @@ -4069,6 +4074,12 @@ Remove Railroad = 철도 제거 Cancel improvement order = 시설 건설 취소 + # Requires translation! +Repair = +Unbuildable = 도시에서 직접 생산 불가 + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = 아카데미 Removes removable features when built = 건설시 제거가능한 추가지형을 제거함 @@ -4092,7 +4103,6 @@ Terrace farm = 계단식 농업 Ancient ruins = 고대 유적 Unpillagable = 약탈 불가 Provides a random bonus when entered = 타일 진입시 무작위 보너스 제공 -Unbuildable = 도시에서 직접 생산 불가 City ruins = 도시 폐허 Will be replaced by automated workers = 자동화한 노동자가 다른 시설로 대체함 diff --git a/android/assets/jsons/translations/Lithuanian.properties b/android/assets/jsons/translations/Lithuanian.properties index c03b1ea64a..b4cd16863a 100644 --- a/android/assets/jsons/translations/Lithuanian.properties +++ b/android/assets/jsons/translations/Lithuanian.properties @@ -939,6 +939,11 @@ Gift unit = Padovanoti dalinį Explore = Išžvalgyti Stop exploration = Stabdyti žvalgybą Pillage = Apiplėšti +Pillage [improvement] = Apiplėšti [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Palaukti Are you sure you want to pillage this [improvement]? = Ar tikrai norite apiplėšti: [improvement]? We have looted [amount] from a [improvement] = Išplėšėme [amount] iš: [improvement] @@ -4054,6 +4059,12 @@ Remove Railroad = Išardyti geležinkelį Cancel improvement order = Atšaukti patobulinimų eilę + # Requires translation! +Repair = +Unbuildable = Negalima pagaminti + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akademija Removes removable features when built = Pastačius pašalina šalinamus vietovės įpatumus @@ -4077,7 +4088,6 @@ Terrace farm = Terasinis ūkis Ancient ruins = Senoviniai griuvėsiai Unpillagable = Negalima apiplėšti Provides a random bonus when entered = Įeinant duoda atsitiktį priedą -Unbuildable = Negalima pagaminti City ruins = Miesto griuvėsiai Will be replaced by automated workers = Gali būti pakeista auto darbininkų diff --git a/android/assets/jsons/translations/Malay.properties b/android/assets/jsons/translations/Malay.properties index f9801ff90d..3253fc89b5 100644 --- a/android/assets/jsons/translations/Malay.properties +++ b/android/assets/jsons/translations/Malay.properties @@ -1261,6 +1261,11 @@ Gift unit = Unit hadiah Explore = Teroka Stop exploration = Henti penerokaan Pillage = Rompak +Pillage [improvement] = Rompak [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = # Requires translation! Wait = Are you sure you want to pillage this [improvement]? = Adakah anda pasti ingin merompak [improvement] ini? @@ -6385,6 +6390,12 @@ Remove Railroad = Buang Landasan # Requires translation! Cancel improvement order = + # Requires translation! +Repair = +Unbuildable = Tidak dapat dibina + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akademi # Requires translation! Removes removable features when built = @@ -6419,7 +6430,6 @@ Ancient ruins = Unpillagable = # Requires translation! Provides a random bonus when entered = -Unbuildable = Tidak dapat dibina # Requires translation! City ruins = diff --git a/android/assets/jsons/translations/Persian_(Pinglish-DIN).properties b/android/assets/jsons/translations/Persian_(Pinglish-DIN).properties index 57da8b98d5..8ce2e992eb 100644 --- a/android/assets/jsons/translations/Persian_(Pinglish-DIN).properties +++ b/android/assets/jsons/translations/Persian_(Pinglish-DIN).properties @@ -1374,6 +1374,11 @@ Gift unit = Explore = Kāvoš kardan Stop exploration = Tavağğof e kāvoš Pillage = Ğārat kardan +Pillage [improvement] = Ğārat kardan [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = # Requires translation! Wait = # Requires translation! @@ -6837,6 +6842,12 @@ Remove Railroad = # Requires translation! Cancel improvement order = + # Requires translation! +Repair = +Unbuildable = Ğeyr e ğābel e sāḵt + # Requires translation! +Repairs a pillaged Improvement or Route = + # Requires translation! Academy = # Requires translation! @@ -6875,7 +6886,6 @@ Ancient ruins = Unpillagable = # Requires translation! Provides a random bonus when entered = -Unbuildable = Ğeyr e ğābel e sāḵt # Requires translation! City ruins = diff --git a/android/assets/jsons/translations/Persian_(Pinglish-UN).properties b/android/assets/jsons/translations/Persian_(Pinglish-UN).properties index 574bbbefc5..02644c415b 100644 --- a/android/assets/jsons/translations/Persian_(Pinglish-UN).properties +++ b/android/assets/jsons/translations/Persian_(Pinglish-UN).properties @@ -1299,6 +1299,11 @@ Gift unit = Explore = Kaavosh kardan Stop exploration = Tavaghghof e kaavosh Pillage = Ghaarat kardan +Pillage [improvement] = Ghaarat kardan [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = # Requires translation! Wait = # Requires translation! @@ -6762,6 +6767,12 @@ Remove Railroad = # Requires translation! Cancel improvement order = + # Requires translation! +Repair = +Unbuildable = Gheyr e ghaabel e saakht + # Requires translation! +Repairs a pillaged Improvement or Route = + # Requires translation! Academy = # Requires translation! @@ -6800,7 +6811,6 @@ Ancient ruins = Unpillagable = # Requires translation! Provides a random bonus when entered = -Unbuildable = Gheyr e ghaabel e saakht # Requires translation! City ruins = diff --git a/android/assets/jsons/translations/Polish.properties b/android/assets/jsons/translations/Polish.properties index 2af51d4b05..15bb308bf7 100644 --- a/android/assets/jsons/translations/Polish.properties +++ b/android/assets/jsons/translations/Polish.properties @@ -938,6 +938,11 @@ Gift unit = Podaruj jednostkę Explore = Eksploruj Stop exploration = Zatrzymaj eksplorację Pillage = Splądruj +Pillage [improvement] = Splądruj [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Czekaj Are you sure you want to pillage this [improvement]? = Czy na pewno chcesz splądrować [improvement]? We have looted [amount] from a [improvement] = Zrabowaliśmy [amount] z [improvement] @@ -4054,6 +4059,12 @@ Remove Railroad = Usuwanie linii kolejowych Cancel improvement order = Przerwij aktualną pracę + # Requires translation! +Repair = +Unbuildable = Nie można wyprodukować. + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akademia Removes removable features when built = Podczas budowy usuwane są dodatkowe cechy terenu @@ -4077,7 +4088,6 @@ Terrace farm = Uprawa tarasowa Ancient ruins = Starożytne ruiny Unpillagable = Nie można splądrować. Provides a random bonus when entered = Po wejściu zapewnia losowy bonus -Unbuildable = Nie można wyprodukować. City ruins = Ruiny miasta Will be replaced by automated workers = Zostanie zastąpione przez zautomatyzowanych Robotników diff --git a/android/assets/jsons/translations/Portuguese.properties b/android/assets/jsons/translations/Portuguese.properties index 3cf7a4bf88..b008af3e84 100644 --- a/android/assets/jsons/translations/Portuguese.properties +++ b/android/assets/jsons/translations/Portuguese.properties @@ -1175,6 +1175,11 @@ Gift unit = Unidade de presente Explore = Explorar Stop exploration = Parar a exploração Pillage = Pilhar +Pillage [improvement] = Pilhar [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = # Requires translation! Wait = Are you sure you want to pillage this [improvement]? = Tens a certeza que desejas pilhar esta [improvement]? @@ -5333,6 +5338,12 @@ Remove Railroad = Remover ferrovia Cancel improvement order = Cancelar ordem de melhoria + # Requires translation! +Repair = +Unbuildable = Não construível + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Academia # Requires translation! Removes removable features when built = @@ -5365,7 +5376,6 @@ Ancient ruins = Ruínas antigas Unpillagable = # Requires translation! Provides a random bonus when entered = -Unbuildable = Não construível City ruins = Ruínas da cidade # Requires translation! diff --git a/android/assets/jsons/translations/Romanian.properties b/android/assets/jsons/translations/Romanian.properties index 28843c0c72..4a60cd3a77 100644 --- a/android/assets/jsons/translations/Romanian.properties +++ b/android/assets/jsons/translations/Romanian.properties @@ -986,6 +986,11 @@ Gift unit = Unitate cadou Explore = Explorează Stop exploration = Oprește explorarea Pillage = Jefuiește +Pillage [improvement] = Jefuiește [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Aștepta Are you sure you want to pillage this [improvement]? = Ești sigur că vrei să jefuiești aceasta [improvement]? We have looted [amount] from a [improvement] = Am jefuit [amount] dintr-o [improvement] @@ -4163,6 +4168,12 @@ Remove Railroad = Elimină cale ferată Cancel improvement order = Anulează comanda de îmbunătățire + # Requires translation! +Repair = +Unbuildable = De neconstruit + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Academie Removes removable features when built = Elimină caracteristici detașabile când este construit @@ -4195,7 +4206,6 @@ Ancient ruins = Ruine străvechi Unpillagable = # Requires translation! Provides a random bonus when entered = -Unbuildable = De neconstruit City ruins = Oraș în ruină # Requires translation! diff --git a/android/assets/jsons/translations/Russian.properties b/android/assets/jsons/translations/Russian.properties index f50abce9ac..07250737fa 100644 --- a/android/assets/jsons/translations/Russian.properties +++ b/android/assets/jsons/translations/Russian.properties @@ -939,6 +939,11 @@ Gift unit = Подарить юнита Explore = Исследовать Stop exploration = Остановить исследование Pillage = Разграбить +Pillage [improvement] = Разграбить [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Ждать Are you sure you want to pillage this [improvement]? = Вы уверены, что хотите разграбить: [improvement]? We have looted [amount] from a [improvement] = Мы добыли [amount] с улучшения [improvement] @@ -4053,6 +4058,12 @@ Remove Railroad = Убрать железную дорогу Cancel improvement order = Отменить задание + # Requires translation! +Repair = +Unbuildable = Нельзя построить + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Академия Removes removable features when built = Убирает очищаемые особенности при постройке @@ -4076,7 +4087,6 @@ Terrace farm = Террасная ферма Ancient ruins = Древние руины Unpillagable = Нельзя разграбить Provides a random bonus when entered = Предоставляет случайный бонус при заходе -Unbuildable = Нельзя построить City ruins = Руины города Will be replaced by automated workers = Заменяется автоматизированными рабочими diff --git a/android/assets/jsons/translations/Simplified_Chinese.properties b/android/assets/jsons/translations/Simplified_Chinese.properties index cfb4a46c9f..9f86e879ff 100644 --- a/android/assets/jsons/translations/Simplified_Chinese.properties +++ b/android/assets/jsons/translations/Simplified_Chinese.properties @@ -938,6 +938,11 @@ Gift unit = 礼品单位 Explore = 自由探索 Stop exploration = 停止探索 Pillage = 劫掠地块 +Pillage [improvement] = 劫掠地块 [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = 等待 Are you sure you want to pillage this [improvement]? = 你确定要劫掠这个[improvement]吗? We have looted [amount] from a [improvement] = 我们从[improvement]劫掠了[amount] @@ -4051,6 +4056,12 @@ Remove Railroad = 拆除铁路 Cancel improvement order = 取消建造设施 + # Requires translation! +Repair = +Unbuildable = 不可组建单位 + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = 学院 Removes removable features when built = 在建造时移除可移除地貌 @@ -4074,7 +4085,6 @@ Terrace farm = 梯田 Ancient ruins = 远古遗迹 Unpillagable = 不可劫掠的 Provides a random bonus when entered = 进入时提供随机奖励 -Unbuildable = 不可组建单位 City ruins = 城市废墟 Will be replaced by automated workers = 将会被自动工作的工人清理掉 diff --git a/android/assets/jsons/translations/Spanish.properties b/android/assets/jsons/translations/Spanish.properties index 3a2e1b8311..f74f798573 100644 --- a/android/assets/jsons/translations/Spanish.properties +++ b/android/assets/jsons/translations/Spanish.properties @@ -938,6 +938,11 @@ Gift unit = Regalar unidad Explore = Explorar Stop exploration = Detener exploración Pillage = Saquear +Pillage [improvement] = Saquear [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Esperar Are you sure you want to pillage this [improvement]? = ¿Seguro que quieres saquear este [improvement]? We have looted [amount] from a [improvement] = Hemos saqueado [amount] de un [improvement] @@ -4051,6 +4056,12 @@ Remove Railroad = Quitar Vía Férrea Cancel improvement order = Cancelar orden de mejora + # Requires translation! +Repair = +Unbuildable = Inedificable + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Academia Removes removable features when built = Quita las características removibles al ser construído @@ -4074,7 +4085,6 @@ Terrace farm = Terrazas de cultivo Ancient ruins = Ruinas Antiguas Unpillagable = Insaqueable Provides a random bonus when entered = Provee un bonus aleatorio al entrar -Unbuildable = Inedificable City ruins = Ciudad en ruinas Will be replaced by automated workers = Será reemplazada por trabajadores automatizados diff --git a/android/assets/jsons/translations/Swedish.properties b/android/assets/jsons/translations/Swedish.properties index 0f97ba7bf8..06eadef69f 100644 --- a/android/assets/jsons/translations/Swedish.properties +++ b/android/assets/jsons/translations/Swedish.properties @@ -978,6 +978,11 @@ Gift unit = Skänk enhet Explore = Utforska Stop exploration = Avsluta utforskning Pillage = Plundra +Pillage [improvement] = Plundra [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Vänta Are you sure you want to pillage this [improvement]? = Är du säker på att du vill plundra denna [improvement]? We have looted [amount] from a [improvement] = Vi har plundrat [amount] från en [improvement] @@ -4118,6 +4123,12 @@ Remove Railroad = Ta bort Järnväg Cancel improvement order = Avbryt förbättringsorder + # Requires translation! +Repair = +Unbuildable = Obyggbar + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akademi Removes removable features when built = Tar bort terrängdrag som kan tas bort vid bygge @@ -4141,7 +4152,6 @@ Terrace farm = Terassbondgård Ancient ruins = Antika ruiner Unpillagable = Oplundringsbar Provides a random bonus when entered = Ger en slumpmässig bonus då man går in i den -Unbuildable = Obyggbar City ruins = Stadsruiner # Requires translation! diff --git a/android/assets/jsons/translations/Traditional_Chinese.properties b/android/assets/jsons/translations/Traditional_Chinese.properties index c3916c9dee..4a3b0fb252 100644 --- a/android/assets/jsons/translations/Traditional_Chinese.properties +++ b/android/assets/jsons/translations/Traditional_Chinese.properties @@ -939,6 +939,11 @@ Gift unit = 禮品單位 Explore = 自由探索 Stop exploration = 停止探索 Pillage = 劫掠 +Pillage [improvement] = 劫掠 [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = 等待 Are you sure you want to pillage this [improvement]? = 你確定要劫掠這個[improvement]? We have looted [amount] from a [improvement] = 我們從[improvement]中掠奪[amount] @@ -4054,6 +4059,12 @@ Remove Railroad = 拆除鐵路 Cancel improvement order = 取消建造設施 + # Requires translation! +Repair = +Unbuildable = 不可訓練單位 + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = 學院 Removes removable features when built = 建造時刪除可移動功能 @@ -4077,7 +4088,6 @@ Terrace farm = 梯田 Ancient ruins = 遠古遺跡 Unpillagable = 不可掠奪的 Provides a random bonus when entered = 當進入時提供隨機獎勵 -Unbuildable = 不可訓練單位 City ruins = 城市廢墟 Will be replaced by automated workers = 會被自動工作的工人清除掉 diff --git a/android/assets/jsons/translations/Turkish.properties b/android/assets/jsons/translations/Turkish.properties index 0f70cffc81..41e30430e9 100644 --- a/android/assets/jsons/translations/Turkish.properties +++ b/android/assets/jsons/translations/Turkish.properties @@ -1070,6 +1070,11 @@ Gift unit = Birlik hediye et Explore = Keşfet Stop exploration = Keşfi bırak Pillage = Yağmala +Pillage [improvement] = Yağmala [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Bekle Are you sure you want to pillage this [improvement]? = bu[improvement]'i yağmalamak istediğinizden emin misiniz? # Requires translation! @@ -4542,6 +4547,12 @@ Remove Railroad = Demiryolunu ortadan kaldır Cancel improvement order = Geliştirme emrini iptal et + # Requires translation! +Repair = +Unbuildable = İnşa edilemez + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Akademi # Requires translation! Removes removable features when built = @@ -4568,7 +4579,6 @@ Terrace farm = Terrace Çiftliği Ancient ruins = Antik Kalıntılar Unpillagable = Yağmalanamaz Provides a random bonus when entered = Bulunduğu karoya girildiğinde rastgele bir ödül sağlar -Unbuildable = İnşa edilemez City ruins = Şehir Kalıntıları # Requires translation! diff --git a/android/assets/jsons/translations/Ukrainian.properties b/android/assets/jsons/translations/Ukrainian.properties index d8e0a3c7e8..6ea615cf94 100644 --- a/android/assets/jsons/translations/Ukrainian.properties +++ b/android/assets/jsons/translations/Ukrainian.properties @@ -939,6 +939,11 @@ Gift unit = Подарунковий підрозділ Explore = Розвідувати Stop exploration = Зупинити розвідку Pillage = Пограбувати +Pillage [improvement] = Пограбувати [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Зачекати Are you sure you want to pillage this [improvement]? = Ви впевнені, що хочете пограбувати цю(цей) [improvement]? We have looted [amount] from a [improvement] = Ми награбували [amount] з [improvement] @@ -4081,6 +4086,12 @@ Remove Railroad = Прибрати колію Cancel improvement order = Скасувати будівництво покращення + # Requires translation! +Repair = +Unbuildable = Неможливо створити + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Академія Removes removable features when built = Коли будується, прибирає риси, які можна прибрати @@ -4104,7 +4115,6 @@ Terrace farm = Терасна ферма Ancient ruins = Стародавні руїни Unpillagable = Не піддається грабунку Provides a random bonus when entered = Забезпечують випадковий бонус на вході -Unbuildable = Неможливо створити City ruins = Руїни міста Will be replaced by automated workers = Буде замінено автоматизованими робочими diff --git a/android/assets/jsons/translations/Vietnamese.properties b/android/assets/jsons/translations/Vietnamese.properties index 532d3b279a..a726514cf3 100644 --- a/android/assets/jsons/translations/Vietnamese.properties +++ b/android/assets/jsons/translations/Vietnamese.properties @@ -938,6 +938,11 @@ Gift unit = Đơn vị quà tặng Explore = Thám hiểm Stop exploration = Dừng thám hiểm Pillage = Cướp bóc +Pillage [improvement] = Cướp bóc [improvement] + # Requires translation! +[improvement] (Pillaged!) = + # Requires translation! +Repair [improvement] - [turns] = Wait = Chờ đã Are you sure you want to pillage this [improvement]? = Bạn có chắc chắn muốn tận dụng [improvement] này không? We have looted [amount] from a [improvement] = Chúng tôi đã cướp [amount] từ [improvement] @@ -4052,6 +4057,12 @@ Remove Railroad = Xóa đường sắt Cancel improvement order = Hủy cải tiến + # Requires translation! +Repair = +Unbuildable = Không thể tạo + # Requires translation! +Repairs a pillaged Improvement or Route = + Academy = Học viện Removes removable features when built = Loại bỏ các tính năng có thể tháo rời khi được xây dựng @@ -4075,7 +4086,6 @@ Terrace farm = Trang trại sân thượng Ancient ruins = Di tích cổ Unpillagable = Không thể gắn thẻ Provides a random bonus when entered = Cung cấp phần thưởng ngẫu nhiên khi nhập -Unbuildable = Không thể tạo City ruins = Tàn tích thành phố Will be replaced by automated workers = Sẽ được thay thế bởi công nhân tự động diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index f56172ed1f..5590c27c5a 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -942,6 +942,9 @@ Gift unit = Explore = Stop exploration = Pillage = +Pillage [improvement] = +[improvement] (Pillaged!) = +Repair [improvement] - [turns] = Wait = Are you sure you want to pillage this [improvement]? = We have looted [amount] from a [improvement] = diff --git a/core/src/com/unciv/Constants.kt b/core/src/com/unciv/Constants.kt index e4f5203042..739fea6624 100644 --- a/core/src/com/unciv/Constants.kt +++ b/core/src/com/unciv/Constants.kt @@ -75,6 +75,7 @@ object Constants { const val rising = "Rising" const val lowering = "Lowering" const val remove = "Remove " + const val repair = "Repair" const val uniqueOrDelimiter = "\" OR \"" diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 9793787d82..0afdac3125 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -66,7 +66,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion companion object { /** The current compatibility version of [GameInfo]. This number is incremented whenever changes are made to the save file structure that guarantee that * previous versions of the game will not be able to load or play a game normally. */ - const val CURRENT_COMPATIBILITY_NUMBER = 1 + const val CURRENT_COMPATIBILITY_NUMBER = 2 val CURRENT_COMPATIBILITY_VERSION = CompatibilityVersion(CURRENT_COMPATIBILITY_NUMBER, UncivGame.VERSION) diff --git a/core/src/com/unciv/logic/automation/Automation.kt b/core/src/com/unciv/logic/automation/Automation.kt index 1e45053213..34c5acffa3 100644 --- a/core/src/com/unciv/logic/automation/Automation.kt +++ b/core/src/com/unciv/logic/automation/Automation.kt @@ -352,10 +352,12 @@ object Automation { val stats = tile.getTileStats(null, civInfo) var rank = rankStatsValue(stats, civInfo) if (tile.improvement == null) rank += 0.5f // improvement potential! + if (tile.isPillaged()) rank += 0.6f if (tile.hasViewableResource(civInfo)) { val resource = tile.tileResource if (resource.resourceType != ResourceType.Bonus) rank += 1f // for usage if (tile.improvement == null) rank += 1f // improvement potential - resources give lots when improved! + if (tile.isPillaged()) rank += 1.1f // even better, repair is faster } return rank } diff --git a/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt b/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt index 9d5471017b..d851a31806 100644 --- a/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt @@ -282,7 +282,10 @@ object SpecificUnitAutomation { unit.movement.headTowards(chosenTile) if (unit.currentTile == chosenTile) - UnitActions.getImprovementConstructionActions(unit, unit.currentTile).firstOrNull()?.action?.invoke() + if (unit.currentTile.isPillaged()) + UnitActions.getRepairAction(unit).invoke() + else + UnitActions.getImprovementConstructionActions(unit, unit.currentTile).firstOrNull()?.action?.invoke() return } } diff --git a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt index 08d4ff323e..095443c75c 100644 --- a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt @@ -27,6 +27,8 @@ object UnitAutomation { && tile.neighbors.any { it.position !in unit.civInfo.exploredTiles } && (!unit.civInfo.isCityState() || tile.neighbors.any { it.getOwner() == unit.civInfo }) // Don't want city-states exploring far outside their borders && unit.getDamageFromTerrain(tile) <= 0 // Don't take unnecessary damage + && tile.getTilesInDistance(3) // don't walk in range of enemy units + .none { tile_it -> containsEnemyMilitaryUnit(unit, tile_it)} && unit.movement.canReach(tile) // expensive, evaluate last } diff --git a/core/src/com/unciv/logic/automation/unit/WorkerAutomation.kt b/core/src/com/unciv/logic/automation/unit/WorkerAutomation.kt index 38577cba40..b9ed7866c5 100644 --- a/core/src/com/unciv/logic/automation/unit/WorkerAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/WorkerAutomation.kt @@ -17,6 +17,7 @@ import com.unciv.logic.map.TileInfo import com.unciv.models.ruleset.tile.Terrain import com.unciv.models.ruleset.tile.TileImprovement import com.unciv.models.ruleset.unique.UniqueType +import com.unciv.ui.worldscreen.unit.UnitActions import com.unciv.utils.Log import com.unciv.utils.debug @@ -140,6 +141,29 @@ class WorkerAutomation( debug("WorkerAutomation: %s -> head towards %s", unit.label(), tileToWork) val reachedTile = unit.movement.headTowards(tileToWork) if (reachedTile != currentTile) unit.doAction() // otherwise, we get a situation where the worker is automated, so it tries to move but doesn't, then tries to automate, then move, etc, forever. Stack overflow exception! + // If there's move still left, perform action + // Unit may stop due to Enemy Unit within walking range during doAction() call + if (unit.currentMovement > 0 && reachedTile == tileToWork) { + if (reachedTile.isPillaged()) { + debug("WorkerAutomation: ${unit.label()} -> repairs $currentTile") + UnitActions.getRepairAction(unit).invoke() + return + } + if (currentTile.improvementInProgress == null && currentTile.isLand + && tileCanBeImproved(unit, currentTile) + ) { + debug("WorkerAutomation: ${unit.label()} -> start improving $currentTile") + return currentTile.startWorkingOnImprovement( + chooseImprovement(unit, currentTile)!!, civInfo, unit + ) + } + } + return + } + + if (currentTile.isPillaged()) { + debug("WorkerAutomation: ${unit.label()} -> repairs $currentTile") + UnitActions.getRepairAction(unit).invoke() return } @@ -155,7 +179,7 @@ class WorkerAutomation( val citiesToNumberOfUnimprovedTiles = HashMap() for (city in unit.civInfo.cities) { citiesToNumberOfUnimprovedTiles[city.id] = city.getTiles() - .count { it.isLand && it.civilianUnit == null && tileCanBeImproved(unit, it) } + .count { it.isLand && it.civilianUnit == null && (tileCanBeImproved(unit, it) || it.isPillaged()) } } val mostUndevelopedCity = unit.civInfo.cities.asSequence() @@ -213,7 +237,7 @@ class WorkerAutomation( if (!bfs.hasReachedTile(cityTile)) continue // we have a winner! val pathToCity = bfs.getPathTo(cityTile) - val roadableTiles = pathToCity.filter { it.roadStatus < bestRoadAvailable } + val roadableTiles = pathToCity.filter { it.getUnpillagedRoad() < bestRoadAvailable } val tileToConstructRoadOn: TileInfo if (currentTile in roadableTiles) tileToConstructRoadOn = currentTile @@ -257,9 +281,11 @@ class WorkerAutomation( .filter { (it.civilianUnit == null || it == currentTile) && (it.owningCity == null || it.getOwner()==civInfo) - && tileCanBeImproved(unit, it) - && it.getTilesInDistance(2) - .none { tile -> tile.isCityCenter() && tile.getCity()!!.civInfo.isAtWarWith(civInfo) } + && (tileCanBeImproved(unit, it) || it.isPillaged()) + && it.getTilesInDistance(2) // don't work in range of enemy cities + .none { tile -> tile.isCityCenter() && tile.getCity()!!.civInfo.isAtWarWith(civInfo) } + && it.getTilesInDistance(3) // don't work in range of enemy units + .none { tile -> tile.militaryUnit != null && tile.militaryUnit!!.civInfo.isAtWarWith(civInfo)} } .sortedByDescending { getPriority(it) } @@ -319,6 +345,7 @@ class WorkerAutomation( if (tileInfo.getOwner() == civInfo) { priority += 2 if (tileInfo.providesYield()) priority += 3 + if (tileInfo.isPillaged()) priority += 1 } // give a minor priority to tiles that we could expand onto else if (tileInfo.getOwner() == null && tileInfo.neighbors.any { it.getOwner() == civInfo }) diff --git a/core/src/com/unciv/logic/battle/Battle.kt b/core/src/com/unciv/logic/battle/Battle.kt index 83f10f2600..49d7f3aca0 100644 --- a/core/src/com/unciv/logic/battle/Battle.kt +++ b/core/src/com/unciv/logic/battle/Battle.kt @@ -775,15 +775,16 @@ object Battle { destroyIfDefeated(defender.getCivInfo(), attacker.getCivInfo()) } - // Pillage improvements, remove roads, add fallout - if (tile.improvement != null && !tile.getTileImprovement()!!.hasUnique(UniqueType.Irremovable)) { + // Pillage improvements, pillage roads, add fallout + if (tile.getUnpillagedImprovement() != null && !tile.getTileImprovement()!!.hasUnique(UniqueType.Irremovable)) { if (tile.getTileImprovement()!!.hasUnique(UniqueType.Unpillagable)) { tile.improvement = null } else { tile.setPillaged() } } - tile.roadStatus = RoadStatus.None + if (tile.getUnpillagedRoad() != RoadStatus.None) + tile.setPillaged() if (tile.isLand && !tile.isImpassible() && !tile.isCityCenter()) { if (tile.terrainHasUnique(UniqueType.DestroyableByNukesChance)) { for (terrainFeature in tile.terrainFeatureObjects) { diff --git a/core/src/com/unciv/logic/city/CityInfo.kt b/core/src/com/unciv/logic/city/CityInfo.kt index 7b23bdf87d..2f8843ca32 100644 --- a/core/src/com/unciv/logic/city/CityInfo.kt +++ b/core/src/com/unciv/logic/city/CityInfo.kt @@ -412,8 +412,8 @@ class CityInfo : IsPartOfGameInfoSerialization { for (tileInfo in getTiles()) { val stateForConditionals = StateForConditionals(civInfo, this, tile = tileInfo) - if (tileInfo.improvement == null) continue - val tileImprovement = tileInfo.getTileImprovement() + if (tileInfo.getUnpillagedImprovement() == null) continue + val tileImprovement = tileInfo.getUnpillagedTileImprovement() for (unique in tileImprovement!!.getMatchingUniques(UniqueType.ProvidesResources, stateForConditionals)) { val resource = getRuleset().tileResources[unique.params[1]] ?: continue cityResources.add( @@ -469,9 +469,9 @@ class CityInfo : IsPartOfGameInfoSerialization { }) return 0 } - if ((tileInfo.improvement != null && resource.isImprovedBy(tileInfo.improvement!!)) || tileInfo.isCityCenter() + if ((tileInfo.getUnpillagedImprovement() != null && resource.isImprovedBy(tileInfo.improvement!!)) || tileInfo.isCityCenter() // Per https://gaming.stackexchange.com/questions/53155/do-manufactories-and-customs-houses-sacrifice-the-strategic-or-luxury-resources - || resource.resourceType == ResourceType.Strategic && tileInfo.containsGreatImprovement() + || resource.resourceType == ResourceType.Strategic && tileInfo.containsUnpillagedGreatImprovement() ) { var amountToAdd = if (resource.resourceType == ResourceType.Strategic) tileInfo.resourceAmount else 1 diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 8397be13c2..c3a18e0ee7 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -346,7 +346,7 @@ class CityStats(val cityInfo: CityInfo) { .filter { cityInfo.location == it.position || cityInfo.isWorked(it) - || it.owningCity == cityInfo && (it.getTileImprovement() + || it.owningCity == cityInfo && (it.getUnpillagedTileImprovement() ?.hasUnique(UniqueType.TileProvidesYieldWithoutPopulation) == true || it.terrainHasUnique(UniqueType.TileProvidesYieldWithoutPopulation)) } diff --git a/core/src/com/unciv/logic/civilization/CapitalConnectionsFinder.kt b/core/src/com/unciv/logic/civilization/CapitalConnectionsFinder.kt index a1f549fefa..b457361aed 100644 --- a/core/src/com/unciv/logic/civilization/CapitalConnectionsFinder.kt +++ b/core/src/com/unciv/logic/civilization/CapitalConnectionsFinder.kt @@ -66,7 +66,7 @@ class CapitalConnectionsFinder(private val civInfo: CivilizationInfo) { check( cityToConnectFrom, transportType = railroad, - tileFilter = { tile -> tile.roadStatus == RoadStatus.Railroad } + tileFilter = { tile -> tile.getUnpillagedRoad() == RoadStatus.Railroad } ) } diff --git a/core/src/com/unciv/logic/civilization/CivInfoStats.kt b/core/src/com/unciv/logic/civilization/CivInfoStats.kt index 161e96e9fd..0540c0dd3a 100644 --- a/core/src/com/unciv/logic/civilization/CivInfoStats.kt +++ b/core/src/com/unciv/logic/civilization/CivInfoStats.kt @@ -86,10 +86,10 @@ class CivInfoStats(val civInfo: CivilizationInfo) { for (city in civInfo.cities) { for (tile in city.getTiles()) { if (tile.isCityCenter()) continue - if (tile.roadStatus == RoadStatus.None) continue // Cheap checks before pricey checks + if (tile.getUnpillagedRoad() == RoadStatus.None) continue // Cheap checks before pricey checks if (ignoredTileTypes.any { tile.matchesFilter(it, civInfo) }) continue - transportationUpkeep += tile.roadStatus.upkeep + transportationUpkeep += tile.getUnpillagedRoad().upkeep } } for (unique in civInfo.getMatchingUniques(UniqueType.RoadMaintenance)) diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index cf74c011fd..21b11db542 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -688,7 +688,8 @@ class MapUnit : IsPartOfGameInfoSerialization { if (enemyUnitsInWalkingDistance.isNotEmpty()) { if (isMoving()) // stop on enemy in sight action = null - return // Don't you dare move. + if (!(isExploring() || isAutomated())) // have fleeing code + return // Don't you dare move. } val currentTile = getTile() @@ -734,11 +735,13 @@ class MapUnit : IsPartOfGameInfoSerialization { ) { // We removed a terrain (e.g. Forest) and the improvement (e.g. Lumber mill) requires it! tile.improvement = null + tile.improvementIsPillaged = false if (tile.resource != null) civInfo.updateDetailedCivResources() // unlikely, but maybe a mod makes a resource improvement dependent on a terrain feature } - if (RoadStatus.values().any { tile.improvementInProgress == it.removeAction }) + if (RoadStatus.values().any { tile.improvementInProgress == it.removeAction }) { tile.roadStatus = RoadStatus.None - else { + tile.roadIsPillaged = false + } else { val removedFeatureObject = tile.ruleset.terrains[removedFeatureName] if (removedFeatureObject != null && removedFeatureObject.hasUnique(UniqueType.ProductionBonusWhenRemoved)) { tryProvideProductionToClosestCity(removedFeatureName) @@ -746,12 +749,14 @@ class MapUnit : IsPartOfGameInfoSerialization { tile.removeTerrainFeature(removedFeatureName) } } - tile.improvementInProgress == RoadStatus.Road.name -> tile.roadStatus = RoadStatus.Road - tile.improvementInProgress == RoadStatus.Railroad.name -> tile.roadStatus = RoadStatus.Railroad + tile.improvementInProgress == RoadStatus.Road.name -> { tile.roadStatus = RoadStatus.Road; tile.roadIsPillaged = false } + tile.improvementInProgress == RoadStatus.Railroad.name -> { tile.roadStatus = RoadStatus.Railroad; tile.roadIsPillaged = false } + tile.improvementInProgress == Constants.repair -> tile.setRepaired() else -> { val improvement = civInfo.gameInfo.ruleSet.tileImprovements[tile.improvementInProgress]!! improvement.handleImprovementCompletion(this) tile.improvement = tile.improvementInProgress + tile.improvementIsPillaged = false } } @@ -1185,7 +1190,7 @@ class MapUnit : IsPartOfGameInfoSerialization { val (citadelTile, damage) = currentTile.neighbors .filter { it.getOwner() != null - && it.improvement != null + && it.getUnpillagedImprovement() != null && civInfo.isAtWarWith(it.getOwner()!!) }.map { tile -> tile to tile.getTileImprovement()!!.getMatchingUniques(UniqueType.DamagesAdjacentEnemyUnits) @@ -1241,7 +1246,7 @@ class MapUnit : IsPartOfGameInfoSerialization { && improvement.name != Constants.cancelImprovementOrder && tile.improvementInProgress != improvement.name ) return false - + if (tile.improvementInProgress == Constants.repair) return true return getMatchingUniques(UniqueType.BuildImprovements) .any { improvement.matchesFilter(it.params[0]) || tile.matchesTerrainFilter(it.params[0]) } } diff --git a/core/src/com/unciv/logic/map/TileInfo.kt b/core/src/com/unciv/logic/map/TileInfo.kt index b6e2ff4628..084df4c33b 100644 --- a/core/src/com/unciv/logic/map/TileInfo.kt +++ b/core/src/com/unciv/logic/map/TileInfo.kt @@ -94,8 +94,10 @@ open class TileInfo : IsPartOfGameInfoSerialization { var resourceAmount: Int = 0 var improvement: String? = null var improvementInProgress: String? = null + var improvementIsPillaged = false var roadStatus = RoadStatus.None + var roadIsPillaged = false var turnsToImprovement: Int = 0 fun isHill() = baseTerrain == Constants.hill || terrainFeatures.contains(Constants.hill) @@ -133,7 +135,9 @@ open class TileInfo : IsPartOfGameInfoSerialization { toReturn.resourceAmount = resourceAmount toReturn.improvement = improvement toReturn.improvementInProgress = improvementInProgress + toReturn.improvementIsPillaged = improvementIsPillaged toReturn.roadStatus = roadStatus + toReturn.roadIsPillaged = roadIsPillaged toReturn.turnsToImprovement = turnsToImprovement toReturn.hasBottomLeftRiver = hasBottomLeftRiver toReturn.hasBottomRightRiver = hasBottomRightRiver @@ -148,6 +152,10 @@ open class TileInfo : IsPartOfGameInfoSerialization { return getTileImprovement()?.isGreatImprovement() == true } + fun containsUnpillagedGreatImprovement(): Boolean { + return getUnpillagedTileImprovement()?.isGreatImprovement() == true + } + fun containsUnfinishedGreatImprovement(): Boolean { if (improvementInProgress == null) return false return ruleset.tileImprovements[improvementInProgress!!]!!.isGreatImprovement() @@ -205,7 +213,55 @@ open class TileInfo : IsPartOfGameInfoSerialization { fun isImpassible() = getLastTerrain().impassable fun getTileImprovement(): TileImprovement? = if (improvement == null) null else ruleset.tileImprovements[improvement!!] + fun getUnpillagedTileImprovement(): TileImprovement? = if (getUnpillagedImprovement() == null) null else ruleset.tileImprovements[improvement!!] fun getTileImprovementInProgress(): TileImprovement? = if (improvementInProgress == null) null else ruleset.tileImprovements[improvementInProgress!!] + fun getImprovementToPillage(): TileImprovement? { + if (canPillageTileImprovement()) + return ruleset.tileImprovements[improvement]!! + if (canPillageRoad()) + return ruleset.tileImprovements[roadStatus.name]!! + return null + } + // same as above, but slightly quicker + fun getImprovementToPillageName(): String? { + if (canPillageTileImprovement()) + return improvement + if (canPillageRoad()) + return roadStatus.name + return null + } + fun getImprovementToRepair(): TileImprovement? { + if (improvement != null && improvementIsPillaged) + return ruleset.tileImprovements[improvement]!! + if (roadStatus != RoadStatus.None && roadIsPillaged) + return ruleset.tileImprovements[roadStatus.name]!! + return null + } + fun canPillageTile(): Boolean { + return canPillageTileImprovement() || canPillageRoad() + } + private fun canPillageTileImprovement(): Boolean { + return improvement != null && !improvementIsPillaged + && !ruleset.tileImprovements[improvement]!!.hasUnique(UniqueType.Unpillagable) + && !ruleset.tileImprovements[improvement]!!.hasUnique(UniqueType.Irremovable) + } + private fun canPillageRoad(): Boolean { + return roadStatus != RoadStatus.None && !roadIsPillaged + && !ruleset.tileImprovements[roadStatus.name]!!.hasUnique(UniqueType.Unpillagable) + && !ruleset.tileImprovements[roadStatus.name]!!.hasUnique(UniqueType.Irremovable) + } + fun getUnpillagedImprovement(): String? { + return if (improvementIsPillaged) + null + else + improvement + } + fun getUnpillagedRoad(): RoadStatus { + return if (roadIsPillaged) + RoadStatus.None + else + roadStatus + } fun getShownImprovement(viewingCiv: CivilizationInfo?): String? { return if (viewingCiv == null || viewingCiv.playerType == PlayerType.AI || viewingCiv.isSpectator()) @@ -274,7 +330,7 @@ open class TileInfo : IsPartOfGameInfoSerialization { /** Get all uniques of this type that any part of this tile has: terrains, improvement, resource */ fun getMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(tile=this)): Sequence { var uniques = getTerrainMatchingUniques(uniqueType, stateForConditionals) - if (improvement != null){ + if (getUnpillagedImprovement() != null){ val tileImprovement = getTileImprovement() if (tileImprovement != null) { uniques += tileImprovement.getMatchingUniques(uniqueType, stateForConditionals) @@ -292,7 +348,7 @@ open class TileInfo : IsPartOfGameInfoSerialization { fun isWorked(): Boolean = getWorkingCity() != null fun providesYield() = getCity() != null && (isCityCenter() || isWorked() - || getTileImprovement()?.hasUnique(UniqueType.TileProvidesYieldWithoutPopulation) == true + || getUnpillagedTileImprovement()?.hasUnique(UniqueType.TileProvidesYieldWithoutPopulation) == true || terrainHasUnique(UniqueType.TileProvidesYieldWithoutPopulation)) fun isLocked(): Boolean { @@ -357,7 +413,7 @@ open class TileInfo : IsPartOfGameInfoSerialization { // resource base if (hasViewableResource(observingCiv)) stats.add(tileResource) - val improvement = getTileImprovement() + val improvement = getUnpillagedTileImprovement() if (improvement != null) stats.add(getImprovementStats(improvement, observingCiv, city, localUniqueCache)) @@ -500,7 +556,7 @@ open class TileInfo : IsPartOfGameInfoSerialization { val adjacent = unique.params[1] val numberOfBonuses = neighbors.count { it.matchesFilter(adjacent, observingCiv) - || it.roadStatus.name == adjacent + || it.getUnpillagedRoad().name == adjacent } stats.add(unique.stats.times(numberOfBonuses.toFloat())) } @@ -776,7 +832,7 @@ open class TileInfo : IsPartOfGameInfoSerialization { /** Implements [UniqueParameterType.TileFilter][com.unciv.models.ruleset.unique.UniqueParameterType.TileFilter] */ fun matchesFilter(filter: String, civInfo: CivilizationInfo? = null): Boolean { if (matchesTerrainFilter(filter, civInfo)) return true - if (improvement != null && ruleset.tileImprovements[improvement]!!.matchesFilter(filter)) return true + if (improvement != null && !improvementIsPillaged && ruleset.tileImprovements[improvement]!!.matchesFilter(filter)) return true return improvement == null && filter == "unimproved" } @@ -984,11 +1040,15 @@ open class TileInfo : IsPartOfGameInfoSerialization { } if (naturalWonder != null) lineList += FormattedLine(naturalWonder!!, link="Terrain/$naturalWonder") - if (roadStatus !== RoadStatus.None && !isCityCenter()) - lineList += FormattedLine(roadStatus.name, link="Improvement/${roadStatus.name}") + if (roadStatus !== RoadStatus.None && !isCityCenter()) { + val pillageText = if (roadIsPillaged) " (Pillaged!)" else "" + lineList += FormattedLine("[${roadStatus.name}]$pillageText", link = "Improvement/${roadStatus.name}") + } val shownImprovement = getShownImprovement(viewingCiv) - if (shownImprovement != null) - lineList += FormattedLine(shownImprovement, link="Improvement/$shownImprovement") + if (shownImprovement != null) { + val pillageText = if (improvementIsPillaged) " (Pillaged!)" else "" + lineList += FormattedLine("[$shownImprovement]$pillageText", link = "Improvement/$shownImprovement") + } if (improvementInProgress != null && isViewableToPlayer) { // Negative turnsToImprovement is used for UniqueType.CreatesOneImprovement @@ -1030,7 +1090,7 @@ open class TileInfo : IsPartOfGameInfoSerialization { } fun hasConnection(civInfo: CivilizationInfo) = - roadStatus != RoadStatus.None || forestOrJungleAreRoads(civInfo) + getUnpillagedRoad() != RoadStatus.None || forestOrJungleAreRoads(civInfo) private fun forestOrJungleAreRoads(civInfo: CivilizationInfo) = @@ -1195,15 +1255,43 @@ open class TileInfo : IsPartOfGameInfoSerialization { /** Sets tile improvement to pillaged (without prior checks for validity) * and ensures that matching [UniqueType.CreatesOneImprovement] queued buildings are removed. */ fun setPillaged() { + if (!canPillageTile()) + return // http://well-of-souls.com/civ/civ5_improvements.html says that naval improvements are destroyed upon pillage // and I can't find any other sources so I'll go with that - if (isLand) { - // Setting turnsToImprovement might interfere with UniqueType.CreatesOneImprovement - removeCreatesOneImprovementMarker() - improvementInProgress = improvement - turnsToImprovement = 2 + if (!isLand) { improvement = null; return } + + // Setting turnsToImprovement might interfere with UniqueType.CreatesOneImprovement + removeCreatesOneImprovementMarker() + improvementInProgress = null // remove any in progress work as well + turnsToImprovement = 0 + // if no Repair action, destroy improvements instead + if (ruleset.tileImprovements[Constants.repair] == null) { + if (canPillageTileImprovement()) + improvement = null + else + roadStatus = RoadStatus.None + } else { + // otherwise use pillage/repair systems + if (canPillageTileImprovement()) { + improvementIsPillaged = true + } else { + roadIsPillaged = true + } } - improvement = null + } + + fun isPillaged(): Boolean { + return improvementIsPillaged || roadIsPillaged + } + + fun setRepaired() { + improvementInProgress = null + turnsToImprovement = 0 + if (improvementIsPillaged) + improvementIsPillaged = false + else + roadIsPillaged = false } /** Marks tile as target tile for a building with a [UniqueType.CreatesOneImprovement] unique */ diff --git a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt index 5c7db26384..8433239b60 100644 --- a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt +++ b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt @@ -38,7 +38,7 @@ class UnitMovementAlgorithms(val unit: MapUnit) { civInfo.isAtWarWith(toOwner) ) toOwner.getEnemyMovementPenalty(unit) else 0f - if (from.roadStatus == RoadStatus.Railroad && to.roadStatus == RoadStatus.Railroad) + if (from.getUnpillagedRoad() == RoadStatus.Railroad && to.getUnpillagedRoad() == RoadStatus.Railroad) return RoadStatus.Railroad.movement + extraCost // Each of these two function calls `hasUnique(UniqueType.CityStateTerritoryAlwaysFriendly)` diff --git a/core/src/com/unciv/models/UnitAction.kt b/core/src/com/unciv/models/UnitAction.kt index a7ea4549dd..54068491da 100644 --- a/core/src/com/unciv/models/UnitAction.kt +++ b/core/src/com/unciv/models/UnitAction.kt @@ -109,6 +109,8 @@ enum class UnitActionType( { ImageGetter.getUnitIcon(Constants.settler) }, 'c', UncivSound.Silent), ConstructImprovement("Construct improvement", { ImageGetter.getUnitIcon(Constants.worker) }, 'i'), + Repair(Constants.repair, + { ImageGetter.getUnitIcon(Constants.worker) }, 'r', UncivSound.Construction), Create("Create", null, 'i', UncivSound.Chimes), HurryResearch("Hurry Research", diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index fa596c7271..9e63ea62d5 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -628,8 +628,8 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { it.resource != null && requiredNearbyImprovedResources!!.contains(it.resource!!) && it.getOwner() == civInfo - && ((it.improvement != null && it.tileResource.isImprovedBy(it.improvement!!)) || it.isCityCenter() - || (it.getTileImprovement()?.isGreatImprovement() == true && it.tileResource.resourceType == ResourceType.Strategic) + && ((it.getUnpillagedImprovement() != null && it.tileResource.isImprovedBy(it.improvement!!)) || it.isCityCenter() + || (it.getUnpillagedTileImprovement()?.isGreatImprovement() == true && it.tileResource.resourceType == ResourceType.Strategic) ) } if (!containsResourceWithImprovement) diff --git a/core/src/com/unciv/ui/cityscreen/CityScreen.kt b/core/src/com/unciv/ui/cityscreen/CityScreen.kt index 2eb658bef8..41f625ad58 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreen.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreen.kt @@ -213,7 +213,7 @@ class CityScreen( if (tileInfo.improvement == null) return false val civInfo = city.civInfo val existingStats = tileInfo.getImprovementStats( - tileInfo.getTileImprovement()!!, + tileInfo.getUnpillagedTileImprovement()!!, civInfo, city, cityUniqueCache diff --git a/core/src/com/unciv/ui/overviewscreen/ResourcesOverviewTable.kt b/core/src/com/unciv/ui/overviewscreen/ResourcesOverviewTable.kt index fdae8f5119..7282ffc4d4 100644 --- a/core/src/com/unciv/ui/overviewscreen/ResourcesOverviewTable.kt +++ b/core/src/com/unciv/ui/overviewscreen/ResourcesOverviewTable.kt @@ -235,7 +235,7 @@ class ResourcesOverviewTab( if (!tile.hasViewableResource(viewingPlayer)) continue val tileResource = tile.tileResource if (tileResource.resourceType == ResourceType.Bonus) continue - if (tile.improvement != null && tileResource.isImprovedBy(tile.improvement!!)) continue + if (tile.getUnpillagedImprovement() != null && tileResource.isImprovedBy(tile.improvement!!)) continue if (tileResource.resourceType == ResourceType.Strategic && tile.getTileImprovement()?.isGreatImprovement() == true) continue newResourceSupplyList.add(tileResource, ExtraInfoOrigin.Unimproved.name) } diff --git a/core/src/com/unciv/ui/tilegroups/TileGroup.kt b/core/src/com/unciv/ui/tilegroups/TileGroup.kt index 8b422aeacc..1eaeb45a67 100644 --- a/core/src/com/unciv/ui/tilegroups/TileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/TileGroup.kt @@ -587,14 +587,20 @@ open class TileGroup( private fun updateTileColor(isViewable: Boolean) { val baseTerrainColor = when { + isViewable && tileInfo.isPillaged() && tileSetStrings.tileSetConfig.useColorAsBaseTerrain -> tileInfo.getBaseTerrain().getColor().lerp(Color.BROWN, 0.6f) + isViewable && tileInfo.isPillaged() -> Color.WHITE.cpy().lerp(Color.BROWN, 0.6f) tileSetStrings.tileSetConfig.useColorAsBaseTerrain && !isViewable -> tileInfo.getBaseTerrain().getColor().lerp(tileSetStrings.tileSetConfig.fogOfWarColor, 0.6f) tileSetStrings.tileSetConfig.useColorAsBaseTerrain -> tileInfo.getBaseTerrain().getColor() !isViewable -> Color.WHITE.cpy().lerp(tileSetStrings.tileSetConfig.fogOfWarColor, 0.6f) else -> Color.WHITE.cpy() } - val color = if (!isViewable) Color.WHITE.cpy().lerp(tileSetStrings.tileSetConfig.fogOfWarColor, 0.6f) - else Color.WHITE.cpy() + val color = when { + isViewable && tileInfo.isPillaged() -> Color.WHITE.cpy().lerp(Color.RED.cpy(),0.5f) + (!isViewable) -> Color.WHITE.cpy() + .lerp(tileSetStrings.tileSetConfig.fogOfWarColor, 0.6f) + else -> Color.WHITE.cpy() + } for((index, image) in tileBaseImages.withIndex()) image.color = if (index == 0) baseTerrainColor else color diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt index dd1ff7e345..f2a9a5f568 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt @@ -26,6 +26,7 @@ import com.unciv.ui.pickerscreens.ImprovementPickerScreen import com.unciv.ui.pickerscreens.PromotionPickerScreen import com.unciv.ui.popup.ConfirmPopup import com.unciv.ui.popup.hasOpenPopups +import com.unciv.ui.utils.Fonts import com.unciv.ui.utils.extensions.toPercent import com.unciv.ui.worldscreen.WorldScreen import kotlin.math.min @@ -61,6 +62,7 @@ object UnitActions { addSetupAction(unit, actionList) addFoundCityAction(unit, actionList, tile) addBuildingImprovementsAction(unit, actionList, tile, worldScreen, unitTable) + addRepairAction(unit, actionList) addCreateWaterImprovements(unit, actionList) addGreatPersonActions(unit, actionList, tile) addFoundReligionAction(unit, actionList) @@ -187,6 +189,8 @@ object UnitActions { unit.civInfo.addCity(tile.position) if (tile.ruleset.tileImprovements.containsKey("City center")) tile.improvement = "City center" + tile.improvementIsPillaged = false + tile.roadIsPillaged = false unit.destroy() UncivGame.Current.worldScreen!!.shouldUpdate = true } @@ -287,10 +291,13 @@ object UnitActions { val pillageAction = getPillageAction(unit) ?: return if (pillageAction.action == null) - actionList += UnitAction(UnitActionType.Pillage, action = null) - else actionList += UnitAction(type = UnitActionType.Pillage) { + actionList += UnitAction(UnitActionType.Pillage, + title = "${UnitActionType.Pillage} [${unit.currentTile.getImprovementToPillageName()!!}]", + action = null) + else actionList += UnitAction(type = UnitActionType.Pillage, + title = "${UnitActionType.Pillage} [${unit.currentTile.getImprovementToPillageName()!!}]") { if (!worldScreen.hasOpenPopups()) { - val pillageText = "Are you sure you want to pillage this [${unit.currentTile.improvement}]?" + val pillageText = "Are you sure you want to pillage this [${unit.currentTile.getImprovementToPillageName()!!}]?" ConfirmPopup( UncivGame.Current.worldScreen!!, pillageText, @@ -306,14 +313,22 @@ object UnitActions { fun getPillageAction(unit: MapUnit): UnitAction? { val tile = unit.currentTile - if (unit.isCivilian() || tile.improvement == null || tile.getOwner() == unit.civInfo) return null - + if (unit.isCivilian() || !tile.canPillageTile() || tile.getOwner() == unit.civInfo) return null return UnitAction(UnitActionType.Pillage, action = { - tile.getOwner()?.addNotification("An enemy [${unit.baseUnit.name}] has pillaged our [${tile.improvement}]", tile.position, "ImprovementIcons/${tile.improvement!!}", NotificationIcon.War, unit.baseUnit.name) + val pillagedImprovement = unit.currentTile.getImprovementToPillageName()!! + val pillageText = "An enemy [${unit.baseUnit.name}] has pillaged our [$pillagedImprovement]" + val icon = "ImprovementIcons/$pillagedImprovement" + tile.getOwner()?.addNotification( + pillageText, + tile.position, + icon, + NotificationIcon.War, + unit.baseUnit.name + ) + pillageLooting(tile, unit) tile.setPillaged() - unit.civInfo.lastSeenImprovement.remove(tile.position) if (tile.resource != null) tile.getOwner()?.updateDetailedCivResources() // this might take away a resource tile.getCity()?.updateCitizens = true @@ -330,7 +345,7 @@ object UnitActions { val globalPillageYield = Stats() val toCityPillageYield = Stats() val closestCity = unit.civInfo.cities.minByOrNull { it.getCenterTile().aerialDistanceTo(tile) } - val improvement = tile.ruleset.tileImprovements[tile.improvement]!! + val improvement = tile.getImprovementToPillage()!! for (unique in improvement.getMatchingUniques(UniqueType.PillageYieldRandom)) { for (stat in unique.stats) { @@ -482,6 +497,55 @@ object UnitActions { ) } + private fun getRepairTurns(unit: MapUnit): Int { + val tile = unit.currentTile + if (!tile.isPillaged()) return 0 + if (tile.improvementInProgress == Constants.repair) return tile.turnsToImprovement + var repairTurns = tile.ruleset.tileImprovements[Constants.repair]!!.getTurnsToBuild(unit.civInfo, unit) + + val pillagedImprovement = tile.getImprovementToPillage()!! + val turnsToBuild = pillagedImprovement.getTurnsToBuild(unit.civInfo, unit) + // cap repair to number of turns to build original improvement + if (turnsToBuild < repairTurns) repairTurns = turnsToBuild + return repairTurns + } + + private fun addRepairAction(unit: MapUnit, actionList: ArrayList) { + if (unit.currentTile.ruleset.tileImprovements[Constants.repair] == null) return + if (!unit.hasUniqueToBuildImprovements) return + if (unit.isEmbarked()) return + val tile = unit.getTile() + if (tile.isCityCenter()) return + if (!tile.isPillaged()) return + + val couldConstruct = unit.currentMovement > 0 + && !tile.isCityCenter() + + val turnsToBuild = getRepairTurns(unit) + + actionList += UnitAction(UnitActionType.Repair, + title = "${UnitActionType.Repair} [${unit.currentTile.getImprovementToRepair()!!.name}] - [${turnsToBuild}${Fonts.turn}]", + action = getRepairAction(unit).takeIf { couldConstruct } + ) + } + + fun getRepairAction(unit: MapUnit): () -> Unit { + return { + unit.currentMovement = 0f + val tile = unit.currentTile + val repairTurns = getRepairTurns(unit) - 1 + if (repairTurns == 0) { // handle instant fix + tile.setRepaired() + unit.civInfo.updateDetailedCivResources() // maybe just restored a resource + unit.civInfo.transients() + .updateCitiesConnectedToCapital() // check for connections to capital + } else { + tile.improvementInProgress = Constants.repair + tile.turnsToImprovement = repairTurns + } + } + } + private fun addAutomateBuildingImprovementsAction(unit: MapUnit, actionList: ArrayList) { if (!unit.hasUniqueToBuildImprovements) return if (unit.isAutomated()) return @@ -829,9 +893,7 @@ object UnitActions { fun canPillage(unit: MapUnit, tile: TileInfo): Boolean { if (unit.isTransported) return false - val tileImprovement = tile.getTileImprovement() - // City ruins, Ancient Ruins, Barbarian Camp, City Center marked in json - if (tileImprovement == null || tileImprovement.hasUnique(UniqueType.Unpillagable)) return false + if (!tile.canPillageTile()) return false val tileOwner = tile.getOwner() // Can't pillage friendly tiles, just like you can't attack them - it's an 'act of war' thing return tileOwner == null || unit.civInfo.isAtWarWith(tileOwner)