Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Felix Corvus
2020-07-26 23:47:21 +03:00
75 changed files with 1088 additions and 837 deletions

Before

Width:  |  Height:  |  Size: 516 B

After

Width:  |  Height:  |  Size: 516 B

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

+4 -3
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io page with PC downloads
link.google-play.description = Google Play store listing link.google-play.description = Google Play store listing
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid catalogue listing
link.wiki.description = Official Mindustry wiki link.wiki.description = Official Mindustry wiki
link.feathub.description = Suggest new features link.suggestions.description = Suggest new features
linkfail = Failed to open link!\nThe URL has been copied to your clipboard. linkfail = Failed to open link!\nThe URL has been copied to your clipboard.
screenshot = Screenshot saved to {0} screenshot = Screenshot saved to {0}
screenshot.invalid = Map too large, potentially not enough memory for screenshot. screenshot.invalid = Map too large, potentially not enough memory for screenshot.
@@ -459,7 +459,7 @@ locked = Locked
complete = [lightgray]Complete: complete = [lightgray]Complete:
requirement.wave = Reach Wave {0} in {1} requirement.wave = Reach Wave {0} in {1}
requirement.core = Destroy Enemy Core in {0} requirement.core = Destroy Enemy Core in {0}
requirement.unlock = Unlock {0} requirement.research = Research {0}
resume = Resume Zone:\n[lightgray]{0} resume = Resume Zone:\n[lightgray]{0}
bestwave = [lightgray]Best Wave: {0} bestwave = [lightgray]Best Wave: {0}
#TODO fix/remove this #TODO fix/remove this
@@ -634,6 +634,7 @@ unit.percent = %
unit.items = items unit.items = items
unit.thousands = k unit.thousands = k
unit.millions = mil unit.millions = mil
unit.billions = b
category.general = General category.general = General
category.power = Power category.power = Power
category.liquids = Liquids category.liquids = Liquids
@@ -1073,7 +1074,7 @@ block.mass-conveyor.name = Mass Conveyor
block.payload-router.name = Payload Router block.payload-router.name = Payload Router
block.disassembler.name = Disassembler block.disassembler.name = Disassembler
block.silicon-crucible.name = Silicon Crucible block.silicon-crucible.name = Silicon Crucible
block.large-overdrive-projector.name = Large Overdrive Projector block.overdrive-dome.name = Overdrive Dome
team.blue.name = blue team.blue.name = blue
team.crux.name = red team.crux.name = red
team.sharded.name = orange team.sharded.name = orange
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Старонка itch.io з загрузкамi гу
link.google-play.description = Спампаваць для Android з Google Play link.google-play.description = Спампаваць для Android з Google Play
link.f-droid.description = Спампаваць для Android з F-Droid link.f-droid.description = Спампаваць для Android з F-Droid
link.wiki.description = Афіцыйная вікі link.wiki.description = Афіцыйная вікі
link.feathub.description = Прапанаваць новыя функцыі link.suggestions.description = Прапанаваць новыя функцыі
linkfail = Не атрымалася адкрыць спасылку!\nURL-адрэс быў скапіяваны ў буфер абмена. linkfail = Не атрымалася адкрыць спасылку!\nURL-адрэс быў скапіяваны ў буфер абмена.
screenshot = Cкрыншот захаваны ў {0} screenshot = Cкрыншот захаваны ў {0}
screenshot.invalid = Карта занадта вялікая, магчыма, не хапае памяці для скрыншота. screenshot.invalid = Карта занадта вялікая, магчыма, не хапае памяці для скрыншота.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Stránka na itch.io s odkazy na stažení hry
link.google-play.description = Obchod Google Play link.google-play.description = Obchod Google Play
link.f-droid.description = Katalog F-Droid link.f-droid.description = Katalog F-Droid
link.wiki.description = Oficiální Wiki Mindustry link.wiki.description = Oficiální Wiki Mindustry
link.feathub.description = Navrhni něco nového do hry! link.suggestions.description = Navrhni něco nového do hry!
linkfail = Nepodařilo se otevřít odkaz!\nAdresa URL byla zkopírována do schránky. linkfail = Nepodařilo se otevřít odkaz!\nAdresa URL byla zkopírována do schránky.
screenshot = Snímek obrazovky uložen {0} screenshot = Snímek obrazovky uložen {0}
screenshot.invalid = Mapa je moc velká, nemusí být dost paměti pro získání snímku obrazovky. screenshot.invalid = Mapa je moc velká, nemusí být dost paměti pro získání snímku obrazovky.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io side med PC downloads
link.google-play.description = Google Play store link.google-play.description = Google Play store
link.f-droid.description = F-Droid katalog link.f-droid.description = F-Droid katalog
link.wiki.description = Det officielle Mindustry wiki link.wiki.description = Det officielle Mindustry wiki
link.feathub.description = Foreslå nye ændringer link.suggestions.description = Foreslå nye ændringer
linkfail = Kunne ikke åbne link!\n Linkets URL er kopieret til din udklipsholder. linkfail = Kunne ikke åbne link!\n Linkets URL er kopieret til din udklipsholder.
screenshot = Screenshot gemt i {0} screenshot = Screenshot gemt i {0}
screenshot.invalid = Banen er for stor, der er ikke nok hukommelse til screenshot. screenshot.invalid = Banen er for stor, der er ikke nok hukommelse til screenshot.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io-Seite mit Downloads und der Web-Version des S
link.google-play.description = Google Play Store-Seite link.google-play.description = Google Play Store-Seite
link.f-droid.description = F-Droid-Seite link.f-droid.description = F-Droid-Seite
link.wiki.description = Offizelles Mindustry-Wiki link.wiki.description = Offizelles Mindustry-Wiki
link.feathub.description = Neue Ideen einbringen link.suggestions.description = Neue Ideen einbringen
linkfail = Fehler beim Öffnen des Links!\nDie URL wurde in die Zwischenablage kopiert. linkfail = Fehler beim Öffnen des Links!\nDie URL wurde in die Zwischenablage kopiert.
screenshot = Screenshot gespeichert unter {0} screenshot = Screenshot gespeichert unter {0}
screenshot.invalid = Karte zu groß! Eventuell nicht ausreichend Arbeitsspeicher für Screenshot. screenshot.invalid = Karte zu groß! Eventuell nicht ausreichend Arbeitsspeicher für Screenshot.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io es la página donde podes descargar las versi
link.google-play.description = Ficha en la Google Play Store link.google-play.description = Ficha en la Google Play Store
link.f-droid.description = Página de F-Droid del juego link.f-droid.description = Página de F-Droid del juego
link.wiki.description = Wiki oficial de Mindustry link.wiki.description = Wiki oficial de Mindustry
link.feathub.description = Sugerir nuevas funciones link.suggestions.description = Sugerir nuevas funciones
linkfail = ¡Error al abrir el enlace!\nLa URL ha sido copiada a su portapapeles. linkfail = ¡Error al abrir el enlace!\nLa URL ha sido copiada a su portapapeles.
screenshot = Captura de pantalla guardada en {0} screenshot = Captura de pantalla guardada en {0}
screenshot.invalid = Mapa demasiado grande, no hay suficiente memoria para la captura de pantalla. screenshot.invalid = Mapa demasiado grande, no hay suficiente memoria para la captura de pantalla.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Kõik PC-platvormide versioonid
link.google-play.description = Androidi versioon Google Play poes link.google-play.description = Androidi versioon Google Play poes
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid catalogue listing
link.wiki.description = Mängu ametlik viki link.wiki.description = Mängu ametlik viki
link.feathub.description = Suggest new features link.suggestions.description = Suggest new features
linkfail = Lingi avamine ebaõnnestus!\nVeebiaadress kopeeriti. linkfail = Lingi avamine ebaõnnestus!\nVeebiaadress kopeeriti.
screenshot = Kuvatõmmis salvestati: {0} screenshot = Kuvatõmmis salvestati: {0}
screenshot.invalid = Maailm on liiga suur: kuvatõmmise salvestamiseks ei pruugi olla piisavalt mälu. screenshot.invalid = Maailm on liiga suur: kuvatõmmise salvestamiseks ei pruugi olla piisavalt mälu.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = PC deskargen itch.io orria
link.google-play.description = Google Play dendako sarrera link.google-play.description = Google Play dendako sarrera
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid catalogue listing
link.wiki.description = Mindustry wiki ofiziala link.wiki.description = Mindustry wiki ofiziala
link.feathub.description = Suggest new features link.suggestions.description = Suggest new features
linkfail = Huts egin du esteka irekitzean!\nURL-a zure arbelera kopiatu da. linkfail = Huts egin du esteka irekitzean!\nURL-a zure arbelera kopiatu da.
screenshot = Pantaila-argazkia {0} helbidean gorde da screenshot = Pantaila-argazkia {0} helbidean gorde da
screenshot.invalid = Mapa handiegia, baliteke pantaila-argazkirako memoria nahiko ez egotea. screenshot.invalid = Mapa handiegia, baliteke pantaila-argazkirako memoria nahiko ez egotea.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io -sivu tietokoneversion latausten kanssa
link.google-play.description = Google Play Kauppa -sivu link.google-play.description = Google Play Kauppa -sivu
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid catalogue listing
link.wiki.description = Virallinen Mindustry wiki link.wiki.description = Virallinen Mindustry wiki
link.feathub.description = Ehdota uusia ominaisuuksia link.suggestions.description = Ehdota uusia ominaisuuksia
linkfail = Linkin avaaminen epäonnistui!\nOsoite on kopioitu leikepöydällesi. linkfail = Linkin avaaminen epäonnistui!\nOsoite on kopioitu leikepöydällesi.
screenshot = Kuvankaappaus tallennettu sijaintiin {0} screenshot = Kuvankaappaus tallennettu sijaintiin {0}
screenshot.invalid = Kartta liian laaja, kuvankaappaukselle ei mahdollisesti ole tarpeeksi tilaa. screenshot.invalid = Kartta liian laaja, kuvankaappaukselle ei mahdollisesti ole tarpeeksi tilaa.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Page itch.io avec lien de téléchargement pour PC
link.google-play.description = Google Play Store link.google-play.description = Google Play Store
link.f-droid.description = Catalogue F-Droid link.f-droid.description = Catalogue F-Droid
link.wiki.description = Le wiki officiel de Mindustry link.wiki.description = Le wiki officiel de Mindustry
link.feathub.description = Suggérer de nouvelles fonctionnalités link.suggestions.description = Suggérer de nouvelles fonctionnalités
linkfail = Erreur lors de l'ouverture du lien !\nL'URL a été copiée dans votre presse-papier. linkfail = Erreur lors de l'ouverture du lien !\nL'URL a été copiée dans votre presse-papier.
screenshot = Capture d'écran sauvegardée à {0} screenshot = Capture d'écran sauvegardée à {0}
screenshot.invalid = La carte est trop large, il n'y a potentiellement pas assez de mémoire pour la capture d'écran. screenshot.invalid = La carte est trop large, il n'y a potentiellement pas assez de mémoire pour la capture d'écran.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Site itch.io avec les versions téléchargeables pour
link.google-play.description = Page Google Play du jeu link.google-play.description = Page Google Play du jeu
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid catalogue listing
link.wiki.description = Wiki officiel de Mindustry link.wiki.description = Wiki officiel de Mindustry
link.feathub.description = Suggest new features link.suggestions.description = Suggest new features
linkfail = L'ouverture du lien a échoué!\nL'URL a été copiée dans votre presse-papier. linkfail = L'ouverture du lien a échoué!\nL'URL a été copiée dans votre presse-papier.
screenshot = Capture d'écran enregistrée sur {0} screenshot = Capture d'écran enregistrée sur {0}
screenshot.invalid = Carte trop grande, potentiellement pas assez de mémoire pour la capture d'écran. screenshot.invalid = Carte trop grande, potentiellement pas assez de mémoire pour la capture d'écran.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io oldal PC letöltésekkel
link.google-play.description = Google Play áruház listázás link.google-play.description = Google Play áruház listázás
link.f-droid.description = F-Droid katalógus listázás link.f-droid.description = F-Droid katalógus listázás
link.wiki.description = Hivatalos Mindustry wiki link.wiki.description = Hivatalos Mindustry wiki
link.feathub.description = Új funkciók ajánlása link.suggestions.description = Új funkciók ajánlása
linkfail = Nem sikerült megnyitni a linket!\nAz URL a vágólapra lett másolva. linkfail = Nem sikerült megnyitni a linket!\nAz URL a vágólapra lett másolva.
screenshot = Képernyőkép mentve ide: {0} screenshot = Képernyőkép mentve ide: {0}
screenshot.invalid = Túl nagy a térkép, nincsen elég memória a képernyőképhez. screenshot.invalid = Túl nagy a térkép, nincsen elég memória a képernyőképhez.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Halaman itch.io dengan unduhan PC dan versi situs jar
link.google-play.description = Google Play Store link.google-play.description = Google Play Store
link.f-droid.description = Daftar katalog F-Droid link.f-droid.description = Daftar katalog F-Droid
link.wiki.description = Wiki Mindustry resmi link.wiki.description = Wiki Mindustry resmi
link.feathub.description = Saran fitur baru link.suggestions.description = Saran fitur baru
linkfail = Gagal membuka tautan!\nURL disalin ke papan ke papan klip. linkfail = Gagal membuka tautan!\nURL disalin ke papan ke papan klip.
screenshot = Tangkapan layar disimpan di {0} screenshot = Tangkapan layar disimpan di {0}
screenshot.invalid = Peta terlalu besar, tidak cukup memori untuk menangkap layar. screenshot.invalid = Peta terlalu besar, tidak cukup memori untuk menangkap layar.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Pagina di itch.io con download per PC e versione web
link.google-play.description = Elenco di Google Play Store link.google-play.description = Elenco di Google Play Store
link.f-droid.description = Catalogo F-Droid link.f-droid.description = Catalogo F-Droid
link.wiki.description = Wiki ufficiale di Mindustry link.wiki.description = Wiki ufficiale di Mindustry
link.feathub.description = Suggerisci nuove funzionalità link.suggestions.description = Suggerisci nuove funzionalità
linkfail = Impossibile aprire il link! L'URL è stato copiato negli appunti. linkfail = Impossibile aprire il link! L'URL è stato copiato negli appunti.
screenshot = Screenshot salvato a {0} screenshot = Screenshot salvato a {0}
screenshot.invalid = Mappa troppo pesante, probabilmente non c'è abbastanza spazio sul disco. screenshot.invalid = Mappa troppo pesante, probabilmente non c'è abbastanza spazio sul disco.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io でゲームをダウンロード
link.google-play.description = Google Play ストアを開く link.google-play.description = Google Play ストアを開く
link.f-droid.description = F-Droid を開く link.f-droid.description = F-Droid を開く
link.wiki.description = 公式 Mindustry Wiki link.wiki.description = 公式 Mindustry Wiki
link.feathub.description = 新機能を提案する link.suggestions.description = 新機能を提案する
linkfail = リンクを開けませんでした!\nURLをクリップボードにコピーしました。 linkfail = リンクを開けませんでした!\nURLをクリップボードにコピーしました。
screenshot = スクリーンショットを {0} に保存しました。 screenshot = スクリーンショットを {0} に保存しました。
screenshot.invalid = マップが広すぎます。スクリーンショットに必要なメモリが足りない可能性があります。 screenshot.invalid = マップが広すぎます。スクリーンショットに必要なメモリが足りない可能性があります。
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = PC 다운로드가 있는 itch.io 페이지
link.google-play.description = Google Play 스토어 목록 link.google-play.description = Google Play 스토어 목록
link.f-droid.description = F-Droid 카탈로그 목록 link.f-droid.description = F-Droid 카탈로그 목록
link.wiki.description = 공식 Mindustry 위키 link.wiki.description = 공식 Mindustry 위키
link.feathub.description = 새로운 기능 제안 link.suggestions.description = 새로운 기능 제안
linkfail = 링크를 열지 못했습니다!\nURL이 클립보드에 복사되었습니다. linkfail = 링크를 열지 못했습니다!\nURL이 클립보드에 복사되었습니다.
screenshot = 스크린 샷이 {0} 에 저장되었습니다. screenshot = 스크린 샷이 {0} 에 저장되었습니다.
screenshot.invalid = 맵이 너무 커서 스크린샷을 할 메모리가 부족할 수 있습니다. screenshot.invalid = 맵이 너무 커서 스크린샷을 할 메모리가 부족할 수 있습니다.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io puslapis su PC atsisiuntimu
link.google-play.description = Google Play parduotuvės elementas link.google-play.description = Google Play parduotuvės elementas
link.f-droid.description = F-Droid katalogo elementas link.f-droid.description = F-Droid katalogo elementas
link.wiki.description = Oficialus Mindustry wiki link.wiki.description = Oficialus Mindustry wiki
link.feathub.description = Pasiūlykite naujas funkcijas link.suggestions.description = Pasiūlykite naujas funkcijas
linkfail = Nepavyko atidaryti nuorodos!\nURL nukopijuotas į jūsų iškarpinę. linkfail = Nepavyko atidaryti nuorodos!\nURL nukopijuotas į jūsų iškarpinę.
screenshot = Ekrano kopija išsaugota į {0} screenshot = Ekrano kopija išsaugota į {0}
screenshot.invalid = Žemėlapis yra per didelis, potencialiai nepakanka vietos išsaugoti ekrano kopiją. screenshot.invalid = Žemėlapis yra per didelis, potencialiai nepakanka vietos išsaugoti ekrano kopiją.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io pagina met pc-downloads
link.google-play.description = Google Play store vermelding link.google-play.description = Google Play store vermelding
link.f-droid.description = F-Droid catalogus vermelding link.f-droid.description = F-Droid catalogus vermelding
link.wiki.description = Officiële Mindustry wiki link.wiki.description = Officiële Mindustry wiki
link.feathub.description = Stel iets voor link.suggestions.description = Stel iets voor
linkfail = Kan link niet openen!\nDe URL is gekopieerd naar je klembord linkfail = Kan link niet openen!\nDe URL is gekopieerd naar je klembord
screenshot = Schermafbeeling opgeslagen in {0} screenshot = Schermafbeeling opgeslagen in {0}
screenshot.invalid = Map is te groot, Mogelijk niet genoeg geheugen beschikbaar voor een schermafbeelding. screenshot.invalid = Map is te groot, Mogelijk niet genoeg geheugen beschikbaar voor een schermafbeelding.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Itch.io pagina met de PC downloads en online versie
link.google-play.description = Mindustry op Google Play link.google-play.description = Mindustry op Google Play
link.f-droid.description = F-Droid catalogus link.f-droid.description = F-Droid catalogus
link.wiki.description = Officiële Mindustry-wiki link.wiki.description = Officiële Mindustry-wiki
link.feathub.description = Suggest new features link.suggestions.description = Suggest new features
linkfail = Openen van link mislukt!\nDe link is gekopiëerd naar je klembord. linkfail = Openen van link mislukt!\nDe link is gekopiëerd naar je klembord.
screenshot = Locatie screenshot: {0} screenshot = Locatie screenshot: {0}
screenshot.invalid = Kaart te groot, mogelijks te weinig geheugen voor een screenshot te kunnen maken. screenshot.invalid = Kaart te groot, mogelijks te weinig geheugen voor een screenshot te kunnen maken.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Strona itch.io z oficjanymi wersjami do pobrania
link.google-play.description = Strona w sklepie Google Play link.google-play.description = Strona w sklepie Google Play
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid catalogue listing
link.wiki.description = Oficjana Wiki Mindustry link.wiki.description = Oficjana Wiki Mindustry
link.feathub.description = Zaproponuj nowe funkcje link.suggestions.description = Zaproponuj nowe funkcje
linkfail = Nie udało się otworzyć linku!\nURL został skopiowany. linkfail = Nie udało się otworzyć linku!\nURL został skopiowany.
screenshot = Zapisano zdjęcie w {0} screenshot = Zapisano zdjęcie w {0}
screenshot.invalid = Zrzut ekranu jest zbyt duży. Najprawdopodobniej brakuje miejsca w pamięci urządzenia. screenshot.invalid = Zrzut ekranu jest zbyt duży. Najprawdopodobniej brakuje miejsca w pamięci urządzenia.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Página do Itch.io com os downloads
link.google-play.description = Página da Google Play store link.google-play.description = Página da Google Play store
link.f-droid.description = Listamento de catalogo do F-Droid link.f-droid.description = Listamento de catalogo do F-Droid
link.wiki.description = Wiki oficial do Mindustry link.wiki.description = Wiki oficial do Mindustry
link.feathub.description = Sugira novos conteúdos link.suggestions.description = Sugira novos conteúdos
linkfail = Falha ao abrir o link\nO Url foi copiado para a área de transferência. linkfail = Falha ao abrir o link\nO Url foi copiado para a área de transferência.
screenshot = Screenshot salvo para {0} screenshot = Screenshot salvo para {0}
screenshot.invalid = Este mapa é grande demais, você pode estar potencialmente sem memória suficiente para captura de tela. screenshot.invalid = Este mapa é grande demais, você pode estar potencialmente sem memória suficiente para captura de tela.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Pagina da Itch.io com os Descarregamentos
link.google-play.description = Listamento do google play store link.google-play.description = Listamento do google play store
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid catalogue listing
link.wiki.description = Wiki oficial do Mindustry link.wiki.description = Wiki oficial do Mindustry
link.feathub.description = Sugerir novas funcionalidades link.suggestions.description = Sugerir novas funcionalidades
linkfail = Falha ao abrir a ligação\nO Url foi copiado linkfail = Falha ao abrir a ligação\nO Url foi copiado
screenshot = Screenshot gravado para {0} screenshot = Screenshot gravado para {0}
screenshot.invalid = Mapa grande demais, Potencialmente sem memória suficiente para captura. screenshot.invalid = Mapa grande demais, Potencialmente sem memória suficiente para captura.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io med nedladdningar
link.google-play.description = Mindustry på Google Play link.google-play.description = Mindustry på Google Play
link.f-droid.description = F-Droid katalog listning link.f-droid.description = F-Droid katalog listning
link.wiki.description = Officiell wiki-sida för Mindustry link.wiki.description = Officiell wiki-sida för Mindustry
link.feathub.description = Föreslå nya funktioner link.suggestions.description = Föreslå nya funktioner
linkfail = Kunde inte öppna länken!\nLänken har kopierats till ditt urklipp. linkfail = Kunde inte öppna länken!\nLänken har kopierats till ditt urklipp.
screenshot = Skärmdump har sparats till {0} screenshot = Skärmdump har sparats till {0}
screenshot.invalid = Karta för stor, potentiellt inte tillräckligt minne för skärmdump. screenshot.invalid = Karta för stor, potentiellt inte tillräckligt minne för skärmdump.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io page with PC downloads
link.google-play.description = Google Play store listing link.google-play.description = Google Play store listing
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid catalogue listing
link.wiki.description = Official Mindustry wiki link.wiki.description = Official Mindustry wiki
link.feathub.description = Suggest new features link.suggestions.description = Suggest new features
linkfail = ไม่สามารถเปิดลิ้งค์ได้\nคัดลอก URL ลงในคลิปบอร์ดแล้ว linkfail = ไม่สามารถเปิดลิ้งค์ได้\nคัดลอก URL ลงในคลิปบอร์ดแล้ว
screenshot = Screenshot บันทึกที่ {0} screenshot = Screenshot บันทึกที่ {0}
screenshot.invalid = แมพใหญ่เกินไป, หน่วยความจำอาจจะไม่พอสำหรับ screenshot. screenshot.invalid = แมพใหญ่เกินไป, หน่วยความจำอาจจะไม่พอสำหรับ screenshot.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Bilgisayar ve Site versiyonunun bulundugu Site
link.google-play.description = Google Play magaza sayfasi link.google-play.description = Google Play magaza sayfasi
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid catalogue listing
link.wiki.description = Orjinal Mindustry Bilgilendirme Sayfasi link.wiki.description = Orjinal Mindustry Bilgilendirme Sayfasi
link.feathub.description = Suggest new features link.suggestions.description = Suggest new features
linkfail = Link Acilamadi!\nLink sizin icin kopyalandi. linkfail = Link Acilamadi!\nLink sizin icin kopyalandi.
screenshot = Screenshot saved to {0} screenshot = Screenshot saved to {0}
screenshot.invalid = Map too large, potentially not enough memory for screenshot. screenshot.invalid = Map too large, potentially not enough memory for screenshot.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io sayfası
link.google-play.description = Google Play mağaza sayfası link.google-play.description = Google Play mağaza sayfası
link.f-droid.description = F-Droid kataloğu link.f-droid.description = F-Droid kataloğu
link.wiki.description = Resmi Mindustry wikisi link.wiki.description = Resmi Mindustry wikisi
link.feathub.description = Yeni özellikler öner link.suggestions.description = Yeni özellikler öner
linkfail = Link açılamadı!\nURL kopyalandı. linkfail = Link açılamadı!\nURL kopyalandı.
screenshot = Ekran görüntüsü {0} konumuna kaydedildi screenshot = Ekran görüntüsü {0} konumuna kaydedildi
screenshot.invalid = Harita çok büyük, muhtemelen ekran görüntüsü için yeterli bellek yok. screenshot.invalid = Harita çok büyük, muhtemelen ekran görüntüsü için yeterli bellek yok.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = Завантажити гру з Itch.io (окрім
link.google-play.description = Завантажити для Android з Google Play link.google-play.description = Завантажити для Android з Google Play
link.f-droid.description = Завантажити для Android з F-Droid link.f-droid.description = Завантажити для Android з F-Droid
link.wiki.description = Офіційна ігрова Wiki link.wiki.description = Офіційна ігрова Wiki
link.feathub.description = Запропонувати нові функції link.suggestions.description = Запропонувати нові функції
linkfail = Не вдалося відкрити посилання!\nURL-адреса скопійована в буфер обміну. linkfail = Не вдалося відкрити посилання!\nURL-адреса скопійована в буфер обміну.
screenshot = Зняток мапи збережено до {0} screenshot = Зняток мапи збережено до {0}
screenshot.invalid = Мапа занадто велика, тому, мабуть, не вистачає пам’яті для знятку мапи. screenshot.invalid = Мапа занадто велика, тому, мабуть, не вистачає пам’яті для знятку мапи.
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io 上的 PC 版下载
link.google-play.description = Google Play 页面 link.google-play.description = Google Play 页面
link.f-droid.description = F-Droid 页面 link.f-droid.description = F-Droid 页面
link.wiki.description = Mindustry 官方 Wiki link.wiki.description = Mindustry 官方 Wiki
link.feathub.description = 提出新特性的建议 link.suggestions.description = 提出新特性的建议
linkfail = 打开链接失败!\n网址已复制到您的剪贴板。 linkfail = 打开链接失败!\n网址已复制到您的剪贴板。
screenshot = 屏幕截图已保存到 {0} screenshot = 屏幕截图已保存到 {0}
screenshot.invalid = 地图太大,可能没有足够的内存用于截图。 screenshot.invalid = 地图太大,可能没有足够的内存用于截图。
+1 -1
View File
@@ -12,7 +12,7 @@ link.itch.io.description = itch.io 電腦版下載網頁
link.google-play.description = Google Play 商店頁面 link.google-play.description = Google Play 商店頁面
link.f-droid.description = F-Droid 目錄頁面 link.f-droid.description = F-Droid 目錄頁面
link.wiki.description = 官方 Mindustry 維基 link.wiki.description = 官方 Mindustry 維基
link.feathub.description = 建議新功能 link.suggestions.description = 建議新功能
linkfail = 無法打開連結!\n我們已將該網址複製到您的剪貼簿。 linkfail = 無法打開連結!\n我們已將該網址複製到您的剪貼簿。
screenshot = 截圖保存到{0} screenshot = 截圖保存到{0}
screenshot.invalid = 地圖太大了,可能沒有足夠的內存用於截圖。 screenshot.invalid = 地圖太大了,可能沒有足夠的內存用於截圖。
+1
View File
@@ -279,3 +279,4 @@
63465=gamma|unit-gamma-medium 63465=gamma|unit-gamma-medium
63464=block|unit-block-medium 63464=block|unit-block-medium
63463=risso|unit-risso-medium 63463=risso|unit-risso-medium
63462=overdrive-dome|block-overdrive-dome-medium
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 KiB

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 KiB

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

+37 -38
View File
@@ -52,7 +52,7 @@ public class Blocks implements ContentList{
//defense //defense
copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, plastaniumWall, plastaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge, copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, plastaniumWall, plastaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge,
phaseWall, phaseWallLarge, surgeWall, surgeWallLarge, mender, mendProjector, overdriveProjector, largeOverdriveProjector, forceProjector, shockMine, phaseWall, phaseWallLarge, surgeWall, surgeWallLarge, mender, mendProjector, overdriveProjector, overdriveDome, forceProjector, shockMine,
scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet
//transport //transport
@@ -121,6 +121,7 @@ public class Blocks implements ContentList{
cliff = new Cliff("cliff"){{ cliff = new Cliff("cliff"){{
inEditor = false; inEditor = false;
saveRotation = true;
}}; }};
//Registers build blocks //Registers build blocks
@@ -855,8 +856,7 @@ public class Blocks implements ContentList{
consumes.item(Items.phasefabric).boost(); consumes.item(Items.phasefabric).boost();
}}; }};
//TODO better name overdriveDome = new OverdriveProjector("overdrive-dome"){{
largeOverdriveProjector = new OverdriveProjector("large-overdrive-projector"){{
requirements(Category.effect, with(Items.lead, 200, Items.titanium, 130, Items.silicon, 130, Items.plastanium, 80, Items.surgealloy, 120)); requirements(Category.effect, with(Items.lead, 200, Items.titanium, 130, Items.silicon, 130, Items.plastanium, 80, Items.surgealloy, 120));
consumes.power(10f); consumes.power(10f);
size = 3; size = 3;
@@ -911,9 +911,8 @@ public class Blocks implements ContentList{
plastaniumConveyor = new StackConveyor("plastanium-conveyor"){{ plastaniumConveyor = new StackConveyor("plastanium-conveyor"){{
requirements(Category.distribution, with(Items.plastanium, 1, Items.silicon, 1, Items.graphite, 1)); requirements(Category.distribution, with(Items.plastanium, 1, Items.silicon, 1, Items.graphite, 1));
health = 75; health = 75;
speed = 3.5f / 60f; speed = 3f / 60f;
itemCapacity = 10; itemCapacity = 10;
displayedSpeed = 30f;
}}; }};
armoredConveyor = new ArmoredConveyor("armored-conveyor"){{ armoredConveyor = new ArmoredConveyor("armored-conveyor"){{
@@ -1485,6 +1484,21 @@ public class Blocks implements ContentList{
shootSound = Sounds.spark; shootSound = Sounds.spark;
}}; }};
parallax = new TractorBeamTurret("parallax"){{
requirements(Category.turret, with(Items.silicon, 120, Items.titanium, 90, Items.graphite, 30));
hasPower = true;
size = 2;
force = 2.5f;
scaledForce = 5f;
range = 170f;
damage = 0.08f;
health = 160 * size * size;
rotateSpeed = 10;
consumes.power(3f);
}};
swarmer = new ItemTurret("swarmer"){{ swarmer = new ItemTurret("swarmer"){{
requirements(Category.turret, with(Items.graphite, 35, Items.titanium, 35, Items.plastanium, 45, Items.silicon, 30)); requirements(Category.turret, with(Items.graphite, 35, Items.titanium, 35, Items.plastanium, 45, Items.silicon, 30));
ammo( ammo(
@@ -1528,6 +1542,18 @@ public class Blocks implements ContentList{
shootSound = Sounds.shootBig; shootSound = Sounds.shootBig;
}}; }};
segment = new PointDefenseTurret("segment"){{
requirements(Category.turret, with(Items.silicon, 130, Items.thorium, 80, Items.phasefabric, 50));
hasPower = true;
consumes.power(3f);
size = 2;
shootLength = 5f;
bulletDamage = 12f;
reloadTime = 25f;
health = 190 * size * size;
}};
fuse = new ItemTurret("fuse"){{ fuse = new ItemTurret("fuse"){{
requirements(Category.turret, with(Items.copper, 225, Items.graphite, 225, Items.thorium, 100)); requirements(Category.turret, with(Items.copper, 225, Items.graphite, 225, Items.thorium, 100));
@@ -1657,33 +1683,6 @@ public class Blocks implements ContentList{
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.5f)).update(false); consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.5f)).update(false);
}}; }};
segment = new PointDefenseTurret("segment"){{
requirements(Category.turret, with(Items.silicon, 80, Items.thorium, 80, Items.surgealloy, 50));
hasPower = true;
consumes.power(3f);
size = 2;
shootLength = 5f;
bulletDamage = 12f;
reloadTime = 25f;
health = 190 * size * size;
}};
parallax = new TractorBeamTurret("parallax"){{
requirements(Category.turret, with(Items.silicon, 120, Items.titanium, 90));
hasPower = true;
size = 2;
force = 2.5f;
scaledForce = 5f;
range = 170f;
damage = 0.08f;
health = 160 * size * size;
rotateSpeed = 10;
consumes.power(3f);
}};
//endregion //endregion
//region units //region units
@@ -1719,7 +1718,7 @@ public class Blocks implements ContentList{
}}; }};
additiveReconstructor = new Reconstructor("additive-reconstructor"){{ additiveReconstructor = new Reconstructor("additive-reconstructor"){{
requirements(Category.units, with(Items.copper, 50, Items.lead, 120, Items.silicon, 230)); requirements(Category.units, with(Items.copper, 200, Items.lead, 120, Items.silicon, 90));
size = 3; size = 3;
consumes.power(3f); consumes.power(3f);
@@ -1728,7 +1727,7 @@ public class Blocks implements ContentList{
constructTime = 60f * 10f; constructTime = 60f * 10f;
upgrades = new UnitType[][]{ upgrades = new UnitType[][]{
{UnitTypes.nova, UnitTypes.quasar}, {UnitTypes.nova, UnitTypes.pulsar},
{UnitTypes.dagger, UnitTypes.mace}, {UnitTypes.dagger, UnitTypes.mace},
{UnitTypes.crawler, UnitTypes.atrax}, {UnitTypes.crawler, UnitTypes.atrax},
{UnitTypes.flare, UnitTypes.horizon}, {UnitTypes.flare, UnitTypes.horizon},
@@ -1738,7 +1737,7 @@ public class Blocks implements ContentList{
}}; }};
multiplicativeReconstructor = new Reconstructor("multiplicative-reconstructor"){{ multiplicativeReconstructor = new Reconstructor("multiplicative-reconstructor"){{
requirements(Category.units, with(Items.copper, 50, Items.lead, 120, Items.silicon, 230)); requirements(Category.units, with(Items.lead, 650, Items.silicon, 350, Items.titanium, 350, Items.thorium, 650));
size = 5; size = 5;
consumes.power(6f); consumes.power(6f);
@@ -1751,13 +1750,13 @@ public class Blocks implements ContentList{
{UnitTypes.mace, UnitTypes.fortress}, {UnitTypes.mace, UnitTypes.fortress},
{UnitTypes.poly, UnitTypes.mega}, {UnitTypes.poly, UnitTypes.mega},
{UnitTypes.minke, UnitTypes.bryde}, {UnitTypes.minke, UnitTypes.bryde},
{UnitTypes.quasar, UnitTypes.pulsar}, {UnitTypes.pulsar, UnitTypes.quasar},
{UnitTypes.atrax, UnitTypes.spiroct}, {UnitTypes.atrax, UnitTypes.spiroct},
}; };
}}; }};
exponentialReconstructor = new Reconstructor("exponential-reconstructor"){{ exponentialReconstructor = new Reconstructor("exponential-reconstructor"){{
requirements(Category.units, with(Items.copper, 50, Items.lead, 120, Items.silicon, 230)); requirements(Category.units, with(Items.lead, 2000, Items.silicon, 750, Items.titanium, 950, Items.thorium, 450, Items.plastanium, 350, Items.phasefabric, 250));
size = 7; size = 7;
consumes.power(12f); consumes.power(12f);
@@ -1773,7 +1772,7 @@ public class Blocks implements ContentList{
}}; }};
tetrativeReconstructor = new Reconstructor("tetrative-reconstructor"){{ tetrativeReconstructor = new Reconstructor("tetrative-reconstructor"){{
requirements(Category.units, with(Items.copper, 50, Items.lead, 120, Items.silicon, 230)); requirements(Category.units, with(Items.lead, 4000, Items.silicon, 1500, Items.thorium, 500, Items.plastanium, 50, Items.phasefabric, 600, Items.surgealloy, 500));
size = 9; size = 9;
consumes.power(25f); consumes.power(25f);
+1 -1
View File
@@ -31,7 +31,7 @@ public class Items implements ContentList{
}}; }};
sand = new Item("sand", Color.valueOf("f7cba4")){{ sand = new Item("sand", Color.valueOf("f7cba4")){{
alwaysUnlocked = true;
}}; }};
coal = new Item("coal", Color.valueOf("272727")){{ coal = new Item("coal", Color.valueOf("272727")){{
+1
View File
@@ -13,6 +13,7 @@ public class Liquids implements ContentList{
water = new Liquid("water", Color.valueOf("596ab8")){{ water = new Liquid("water", Color.valueOf("596ab8")){{
heatCapacity = 0.4f; heatCapacity = 0.4f;
effect = StatusEffects.wet; effect = StatusEffects.wet;
alwaysUnlocked = true;
}}; }};
slag = new Liquid("slag", Color.valueOf("ffa166")){{ slag = new Liquid("slag", Color.valueOf("ffa166")){{
+24 -24
View File
@@ -33,8 +33,8 @@ public class SectorPresets implements ContentList{
new SectorWave(groundZero, 60), new SectorWave(groundZero, 60),
//new Unlock(Blocks.daggerFactory), //new Unlock(Blocks.daggerFactory),
//new Unlock(Blocks.draugFactory), //new Unlock(Blocks.draugFactory),
new Unlock(Blocks.door), new Research(Blocks.door),
new Unlock(Blocks.waterExtractor) new Research(Blocks.waterExtractor)
); );
}}; }};
@@ -42,8 +42,8 @@ public class SectorPresets implements ContentList{
conditionWave = 10; conditionWave = 10;
requirements = with( requirements = with(
new SectorWave(groundZero, 10), new SectorWave(groundZero, 10),
new Unlock(Blocks.junction), new Research(Blocks.junction),
new Unlock(Blocks.router) new Research(Blocks.router)
); );
}}; }};
@@ -51,8 +51,8 @@ public class SectorPresets implements ContentList{
conditionWave = 10; conditionWave = 10;
requirements = with( requirements = with(
new SectorWave(frozenForest, 10), new SectorWave(frozenForest, 10),
new Unlock(Blocks.mender), new Research(Blocks.mender),
new Unlock(Blocks.combustionGenerator) new Research(Blocks.combustionGenerator)
); );
}}; }};
@@ -62,10 +62,10 @@ public class SectorPresets implements ContentList{
requirements = with( requirements = with(
new SectorWave(groundZero, 20), new SectorWave(groundZero, 20),
new SectorWave(craters, 15), new SectorWave(craters, 15),
new Unlock(Blocks.graphitePress), new Research(Blocks.graphitePress),
new Unlock(Blocks.combustionGenerator), new Research(Blocks.combustionGenerator),
new Unlock(Blocks.kiln), new Research(Blocks.kiln),
new Unlock(Blocks.mechanicalPump) new Research(Blocks.mechanicalPump)
); );
}}; }};
@@ -74,9 +74,9 @@ public class SectorPresets implements ContentList{
launchPeriod = 10; launchPeriod = 10;
requirements = with( requirements = with(
new SectorWave(frozenForest, 15), new SectorWave(frozenForest, 15),
new Unlock(Blocks.pneumaticDrill), new Research(Blocks.pneumaticDrill),
new Unlock(Blocks.powerNode), new Research(Blocks.powerNode),
new Unlock(Blocks.turbineGenerator) new Research(Blocks.turbineGenerator)
); );
}}; }};
@@ -85,8 +85,8 @@ public class SectorPresets implements ContentList{
new SectorWave(stainedMountains, 15), new SectorWave(stainedMountains, 15),
//new Unlock(Blocks.daggerFactory), //new Unlock(Blocks.daggerFactory),
//new Unlock(Blocks.crawlerFactory), //new Unlock(Blocks.crawlerFactory),
new Unlock(Blocks.door), new Research(Blocks.door),
new Unlock(Blocks.siliconSmelter) new Research(Blocks.siliconSmelter)
); );
}}; }};
@@ -96,8 +96,8 @@ public class SectorPresets implements ContentList{
requirements = with( requirements = with(
new SectorWave(craters, 40), new SectorWave(craters, 40),
new Launched(fungalPass), new Launched(fungalPass),
new Unlock(Blocks.cultivator), new Research(Blocks.cultivator),
new Unlock(Blocks.sporePress) new Research(Blocks.sporePress)
//new Unlock(Blocks.titanFactory), //new Unlock(Blocks.titanFactory),
//new Unlock(Blocks.wraithFactory) //new Unlock(Blocks.wraithFactory)
); );
@@ -108,9 +108,9 @@ public class SectorPresets implements ContentList{
launchPeriod = 10; launchPeriod = 10;
requirements = with( requirements = with(
new SectorWave(ruinousShores, 20), new SectorWave(ruinousShores, 20),
new Unlock(Blocks.coalCentrifuge), new Research(Blocks.coalCentrifuge),
new Unlock(Blocks.conduit), new Research(Blocks.conduit),
new Unlock(Blocks.wave) new Research(Blocks.wave)
); );
}}; }};
@@ -119,8 +119,8 @@ public class SectorPresets implements ContentList{
launchPeriod = 2; launchPeriod = 2;
requirements = with( requirements = with(
new SectorWave(tarFields, 20), new SectorWave(tarFields, 20),
new Unlock(Blocks.thermalGenerator), new Research(Blocks.thermalGenerator),
new Unlock(Blocks.thoriumReactor) new Research(Blocks.thoriumReactor)
); );
}}; }};
@@ -130,8 +130,8 @@ public class SectorPresets implements ContentList{
launchPeriod = 15; launchPeriod = 15;
requirements = with( requirements = with(
new Launched(fungalPass), new Launched(fungalPass),
new Unlock(Blocks.thermalGenerator), new Research(Blocks.thermalGenerator),
new Unlock(Blocks.laserDrill) new Research(Blocks.laserDrill)
); );
}}; }};
+274 -144
View File
@@ -4,12 +4,14 @@ import arc.*;
import arc.math.*; import arc.math.*;
import arc.struct.*; import arc.struct.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
import mindustry.core.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.game.Objectives.*; import mindustry.game.Objectives.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*; import mindustry.world.*;
import static mindustry.content.Blocks.*; import static mindustry.content.Blocks.*;
import static mindustry.content.UnitTypes.*;
public class TechTree implements ContentList{ public class TechTree implements ContentList{
private static ObjectMap<UnlockableContent, TechNode> map = new ObjectMap<>(); private static ObjectMap<UnlockableContent, TechNode> map = new ObjectMap<>();
@@ -19,9 +21,7 @@ public class TechTree implements ContentList{
@Override @Override
public void load(){ public void load(){
TechNode.context = null; setup();
map = new ObjectMap<>();
all = new Seq<>();
root = node(coreShard, () -> { root = node(coreShard, () -> {
@@ -30,9 +30,6 @@ public class TechTree implements ContentList{
node(junction, () -> { node(junction, () -> {
node(router, () -> { node(router, () -> {
node(launchPad, () -> { node(launchPad, () -> {
node(launchPadLarge, () -> {
});
}); });
node(distributor); node(distributor);
@@ -58,12 +55,16 @@ public class TechTree implements ContentList{
}); });
}); });
node(plastaniumConveyor, () -> { node(payloadConveyor, () -> {
node(payloadRouter, () -> {
});
}); });
node(armoredConveyor, () -> { node(armoredConveyor, () -> {
node(plastaniumConveyor, () -> {
});
}); });
}); });
}); });
@@ -77,99 +78,29 @@ public class TechTree implements ContentList{
}); });
}); });
node(duo, () -> {
node(scatter, () -> {
node(hail, () -> {
node(salvo, () -> {
node(swarmer, () -> {
node(cyclone, () -> {
node(spectre, () -> {
});
});
});
node(ripple, () -> {
node(fuse, () -> {
});
});
});
});
});
node(scorch, () -> {
node(arc, () -> {
node(wave, () -> {
});
node(lancer, () -> {
node(meltdown, () -> {
});
node(shockMine, () -> {
});
});
});
});
node(copperWall, () -> {
node(copperWallLarge, () -> {
node(titaniumWall, () -> {
node(titaniumWallLarge);
node(door, () -> {
node(doorLarge);
});
node(plastaniumWall, () -> {
node(plastaniumWallLarge, () -> {
});
});
node(thoriumWall, () -> {
node(thoriumWallLarge);
node(surgeWall, () -> {
node(surgeWallLarge);
node(phaseWall, () -> {
node(phaseWallLarge);
});
});
});
});
});
});
});
node(mechanicalDrill, () -> { node(mechanicalDrill, () -> {
node(Liquids.water, () -> { node(mechanicalPump, () -> {
node(mechanicalPump, () -> { node(conduit, () -> {
node(conduit, () -> { node(liquidJunction, () -> {
node(liquidJunction, () -> { node(liquidRouter, () -> {
node(liquidRouter, () -> { node(liquidTank);
node(liquidTank);
node(bridgeConduit); node(bridgeConduit);
node(pulseConduit, () -> { node(pulseConduit, () -> {
node(phaseConduit, () -> { node(phaseConduit, () -> {
});
node(platedConduit, () -> {
});
}); });
node(rotaryPump, () -> { node(platedConduit, () -> {
node(thermalPump, () -> {
});
});
node(rotaryPump, () -> {
node(thermalPump, () -> {
});
}); });
}); });
}); });
@@ -178,70 +109,104 @@ public class TechTree implements ContentList{
}); });
node(Items.coal, () -> { node(Items.coal, () -> {
node(graphitePress, () -> { node(Items.graphite, () -> {
node(pneumaticDrill, () -> { node(graphitePress, () -> {
node(cultivator, () -> { node(Items.titanium, () -> {
node(pneumaticDrill, () -> {
}); node(Items.sporePod, () -> {
node(cultivator, () -> {
node(laserDrill, () -> {
node(blastDrill, () -> {
});
node(waterExtractor, () -> {
node(oilExtractor, () -> {
});
});
});
});
node(pyratiteMixer, () -> {
node(blastMixer, () -> {
});
});
node(siliconSmelter, () -> {
node(sporePress, () -> {
node(coalCentrifuge, () -> {
});
node(multiPress, () -> {
});
node(plastaniumCompressor, () -> {
node(phaseWeaver, () -> {
});
});
});
node(kiln, () -> {
node(incinerator, () -> {
node(melter, () -> {
node(surgeSmelter, () -> {
}); });
});
node(separator, () -> { node(Items.thorium, () -> {
node(pulverizer, () -> { node(laserDrill, () -> {
node(blastDrill, () -> {
}); });
node(waterExtractor, () -> {
node(oilExtractor, () -> {
});
});
}); });
});
});
});
node(cryofluidMixer, () -> { node(Items.pyratite, () -> {
node(pyratiteMixer, () -> {
node(Items.blastCompound, () -> {
node(blastMixer, () -> {
}); });
}); });
}); });
}); });
node(Items.silicon, () -> {
node(siliconSmelter, () -> {
node(Liquids.oil, () -> {
node(sporePress, () -> {
node(coalCentrifuge, () -> {
node(multiPress, () -> {
node(siliconCrucible, () -> {
});
});
});
node(Items.plastanium, () -> {
node(plastaniumCompressor, () -> {
node(Items.phasefabric, () -> {
node(phaseWeaver, () -> {
});
});
});
});
});
});
node(Items.metaglass, () -> {
node(kiln, () -> {
node(incinerator, () -> {
node(Items.scrap, () -> {
node(Liquids.slag, () -> {
node(melter, () -> {
node(Items.surgealloy, () -> {
node(surgeSmelter, () -> {
});
});
node(separator, () -> {
node(pulverizer, () -> {
node(disassembler, () -> {
});
});
});
node(Liquids.cryofluid, () -> {
node(cryofluidMixer, () -> {
});
});
});
});
});
});
});
});
});
});
}); });
}); });
node(combustionGenerator, () -> { node(combustionGenerator, () -> {
node(powerNode, () -> { node(powerNode, () -> {
node(powerNodeLarge, () -> { node(powerNodeLarge, () -> {
@@ -262,7 +227,9 @@ public class TechTree implements ContentList{
node(mendProjector, () -> { node(mendProjector, () -> {
node(forceProjector, () -> { node(forceProjector, () -> {
node(overdriveProjector, () -> { node(overdriveProjector, () -> {
node(overdriveDome, () -> {
});
}); });
}); });
@@ -297,9 +264,166 @@ public class TechTree implements ContentList{
}); });
}); });
}); });
node(duo, () -> {
node(copperWall, () -> {
node(copperWallLarge, () -> {
node(titaniumWall, () -> {
node(titaniumWallLarge);
node(door, () -> {
node(doorLarge);
});
node(plastaniumWall, () -> {
node(plastaniumWallLarge, () -> {
});
});
node(thoriumWall, () -> {
node(thoriumWallLarge);
node(surgeWall, () -> {
node(surgeWallLarge);
node(phaseWall, () -> {
node(phaseWallLarge);
});
});
});
});
});
});
node(scatter, () -> {
node(hail, () -> {
node(salvo, () -> {
node(swarmer, () -> {
node(cyclone, () -> {
node(spectre, () -> {
});
});
});
node(ripple, () -> {
node(fuse, () -> {
});
});
});
});
});
node(scorch, () -> {
node(arc, () -> {
node(wave, () -> {
node(parallax, () -> {
node(segment, () -> {
});
});
});
node(lancer, () -> {
node(meltdown, () -> {
});
node(shockMine, () -> {
});
});
});
});
});
node(groundFactory, () -> {
node(dagger, () -> {
node(mace, () -> {
node(fortress, () -> {
});
});
node(nova, () -> {
node(pulsar, () -> {
node(quasar, () -> {
});
});
});
node(crawler, () -> {
node(atrax, () -> {
node(spiroct, () -> {
});
});
});
});
node(airFactory, () -> {
node(flare, () -> {
node(horizon, () -> {
node(zenith, () -> {
node(antumbra, () -> {
node(eclipse, () -> {
});
});
});
});
node(mono, () -> {
node(poly, () -> {
node(mega, () -> {
});
});
});
});
node(navalFactory, () -> {
node(risso, () -> {
node(minke, () -> {
node(bryde, () -> {
});
});
});
});
});
node(additiveReconstructor, () -> {
node(multiplicativeReconstructor, () -> {
node(exponentialReconstructor, () -> {
node(tetrativeReconstructor, () -> {
});
});
});
});
});
//TODO research sectors
/*
node(SectorPresets.groundZero, () -> {
node(SectorPresets.nuclearComplex, () -> {
node(SectorPresets.craters, () -> {
node(SectorPresets.saltFlats, () -> {
});
});
});
});
*/
}); });
} }
private static void setup(){
TechNode.context = null;
map = new ObjectMap<>();
all = new Seq<>();
}
private static TechNode node(UnlockableContent content, Runnable children){ private static TechNode node(UnlockableContent content, Runnable children){
ItemStack[] requirements; ItemStack[] requirements;
@@ -308,7 +432,9 @@ public class TechTree implements ContentList{
requirements = new ItemStack[block.requirements.length]; requirements = new ItemStack[block.requirements.length];
for(int i = 0; i < requirements.length; i++){ for(int i = 0; i < requirements.length; i++){
requirements[i] = new ItemStack(block.requirements[i].item, 40 + Mathf.round(Mathf.pow(block.requirements[i].amount, 1.25f) * 20, 10)); int quantity = 40 + Mathf.round(Mathf.pow(block.requirements[i].amount, 1.25f) * 20, 10);
requirements[i] = new ItemStack(block.requirements[i].item, UI.roundAmount(quantity));
} }
}else{ }else{
requirements = ItemStack.empty; requirements = ItemStack.empty;
@@ -346,9 +472,9 @@ public class TechTree implements ContentList{
/** Item requirements for this content. */ /** Item requirements for this content. */
public ItemStack[] requirements; public ItemStack[] requirements;
/** Extra objectives needed to research this. TODO implement */ /** Extra objectives needed to research this. TODO implement */
public Objective[] objectives = {}; public Seq<Objective> objectives = new Seq<>();
/** Time required to research this content, in seconds. */ /** Time required to research this content, in seconds. */
public float time = 60; public float time;
/** Nodes that depend on this node. */ /** Nodes that depend on this node. */
public final Seq<TechNode> children = new Seq<>(); public final Seq<TechNode> children = new Seq<>();
/** Research progress, in seconds. */ /** Research progress, in seconds. */
@@ -364,6 +490,10 @@ public class TechTree implements ContentList{
this.requirements = requirements; this.requirements = requirements;
this.depth = parent == null ? 0 : parent.depth + 1; this.depth = parent == null ? 0 : parent.depth + 1;
this.progress = Core.settings == null ? 0 : Core.settings.getFloat("research-" + content.name, 0f); this.progress = Core.settings == null ? 0 : Core.settings.getFloat("research-" + content.name, 0f);
this.time = Seq.with(requirements).mapFloat(i -> i.item.cost * i.amount).sum() * 10;
//add dependencies as objectives.
content.getDependencies(d -> objectives.add(new Research(d)));
map.put(content, this); map.put(content, this);
context = this; context = this;
+2 -2
View File
@@ -36,10 +36,10 @@ public class ContentLoader{
new UnitTypes(), new UnitTypes(),
new Blocks(), new Blocks(),
new Loadouts(), new Loadouts(),
new TechTree(),
new Weathers(), new Weathers(),
new Planets(), new Planets(),
new SectorPresets() new SectorPresets(),
new TechTree(),
}; };
public ContentLoader(){ public ContentLoader(){
+26 -4
View File
@@ -488,10 +488,14 @@ public class UI implements ApplicationListener, Loadable{
dialog.show(); dialog.show();
} }
public String formatAmount(int number){ //TODO move?
if(number >= 1000000){
return Strings.fixed(number / 1000000f, 1) + "[gray]" + Core.bundle.get("unit.millions") + "[]"; public static String formatAmount(long number){
}else if(number >= 10000){ if(number >= 1_000_000_000){
return Strings.fixed(number / 1_000_000_000f, 1) + "[gray]" + Core.bundle.get("unit.billions") + "[]";
}else if(number >= 1_000_000){
return Strings.fixed(number / 1_000_000f, 1) + "[gray]" + Core.bundle.get("unit.millions") + "[]";
}else if(number >= 10_000){
return number / 1000 + "[gray]" + Core.bundle.get("unit.thousands") + "[]"; return number / 1000 + "[gray]" + Core.bundle.get("unit.thousands") + "[]";
}else if(number >= 1000){ }else if(number >= 1000){
return Strings.fixed(number / 1000f, 1) + "[gray]" + Core.bundle.get("unit.thousands") + "[]"; return Strings.fixed(number / 1000f, 1) + "[gray]" + Core.bundle.get("unit.thousands") + "[]";
@@ -499,4 +503,22 @@ public class UI implements ApplicationListener, Loadable{
return number + ""; return number + "";
} }
} }
public static int roundAmount(int number){
if(number >= 1_000_000_000){
return Mathf.round(number, 100_000_000);
}else if(number >= 1_000_000){
return Mathf.round(number, 100_000);
}else if(number >= 10_000){
return Mathf.round(number, 1000);
}else if(number >= 1000){
return Mathf.round(number, 100);
}else if(number >= 100){
return Mathf.round(number, 100);
}else if(number >= 10){
return Mathf.round(number, 10);
}else{
return number;
}
}
} }
@@ -1,6 +1,7 @@
package mindustry.ctype; package mindustry.ctype;
import arc.*; import arc.*;
import arc.func.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
@@ -42,6 +43,10 @@ public abstract class UnlockableContent extends MappableContent{
} }
public String emoji(){
return Fonts.getUnicodeStr(name);
}
/** Returns a specific content icon, or the region {contentType}-{name} if not found.*/ /** Returns a specific content icon, or the region {contentType}-{name} if not found.*/
public TextureRegion icon(Cicon icon){ public TextureRegion icon(Cicon icon){
if(cicons[icon.ordinal()] == null){ if(cicons[icon.ordinal()] == null){
@@ -55,6 +60,12 @@ public abstract class UnlockableContent extends MappableContent{
return cicons[icon.ordinal()]; return cicons[icon.ordinal()];
} }
/** Iterates through any implicit dependencies of this content.
* For blocks, this would be the items required to build it. */
public void getDependencies(Cons<UnlockableContent> cons){
}
/** This should show all necessary info about this content in the specified table. */ /** This should show all necessary info about this content in the specified table. */
public abstract void displayInfo(Table table); public abstract void displayInfo(Table table);
@@ -28,6 +28,7 @@ public class ContinuousLaserBulletType extends BulletType{
pierce = true; pierce = true;
hittable = false; hittable = false;
hitColor = colors[2]; hitColor = colors[2];
collidesTiles = false;
incendAmount = 1; incendAmount = 1;
incendSpread = 5; incendSpread = 5;
incendChance = 0.4f; incendChance = 0.4f;
+8 -8
View File
@@ -3,29 +3,29 @@ package mindustry.game;
import arc.*; import arc.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
import mindustry.ctype.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*;
/** Holds objective classes. */ /** Holds objective classes. */
public class Objectives{ public class Objectives{
public static class Unlock implements Objective{ public static class Research implements Objective{
public @NonNull Block block; public @NonNull UnlockableContent content;
public Unlock(Block block){ public Research(UnlockableContent content){
this.block = block; this.content = content;
} }
protected Unlock(){} protected Research(){}
@Override @Override
public boolean complete(){ public boolean complete(){
return block.unlocked(); return content.unlocked();
} }
@Override @Override
public String display(){ public String display(){
return Core.bundle.format("requirement.unlock", block.localizedName); return Core.bundle.format("requirement.research", content.emoji() + " " + content.localizedName);
} }
} }
+1 -1
View File
@@ -81,7 +81,7 @@ public class SectorInfo{
state.rules.sector.setTimeSpent(internalTimeSpent); state.rules.sector.setTimeSpent(internalTimeSpent);
} }
/** Update averages of various stats. /** Update averages of various stats, updates some special sector logic.
* Called every frame. */ * Called every frame. */
public void update(){ public void update(){
internalTimeSpent += Time.delta; internalTimeSpent += Time.delta;
@@ -35,32 +35,35 @@ public class OverlayRenderer{
public void drawTop(){ public void drawTop(){
if(Core.settings.getBool("playerindicators")){ if(!player.dead()){
for(Player player : Groups.player){ if(Core.settings.getBool("playerindicators")){
if(Vars.player != player && Vars.player.team() == player.team()){ for(Player player : Groups.player){
if(!rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f) if(Vars.player != player && Vars.player.team() == player.team()){
.setCenter(Core.camera.position.x, Core.camera.position.y).contains(player.x, player.y)){ if(!rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f)
.setCenter(Core.camera.position.x, Core.camera.position.y).contains(player.x, player.y)){
Tmp.v1.set(player.x, player.y).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength); Tmp.v1.set(player.x, player.y).sub(player).setLength(indicatorLength);
Lines.stroke(2f, player.team().color); Lines.stroke(2f, player.team().color);
Lines.lineAngle(Core.camera.position.x + Tmp.v1.x, Core.camera.position.y + Tmp.v1.y, Tmp.v1.angle(), 4f); Lines.lineAngle(player.x + Tmp.v1.x, player.y + Tmp.v1.y, Tmp.v1.angle(), 4f);
Draw.reset(); Draw.reset();
}
} }
} }
} }
}
if(Core.settings.getBool("indicators")){ if(Core.settings.getBool("indicators")){
Groups.unit.each(unit -> { Groups.unit.each(unit -> {
if(!unit.isLocal() && unit.team() != player.team() && !rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f).setCenter(Core.camera.position.x, Core.camera.position.y).contains(unit.x(), unit.y())){ if(!unit.isLocal() && unit.team != player.team() && !rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f)
Tmp.v1.set(unit.x(), unit.y()).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength); .setCenter(Core.camera.position.x, Core.camera.position.y).contains(unit.x, unit.y)){
Tmp.v1.set(unit.x, unit.y).sub(player).setLength(indicatorLength);
Lines.stroke(1f, unit.team().color); Lines.stroke(1f, unit.team().color);
Lines.lineAngle(Core.camera.position.x + Tmp.v1.x, Core.camera.position.y + Tmp.v1.y, Tmp.v1.angle(), 3f); Lines.lineAngle(player.x + Tmp.v1.x, player.y + Tmp.v1.y, Tmp.v1.angle(), 3f);
Draw.reset(); Draw.reset();
} }
}); });
}
} }
if(player.dead()) return; //dead players don't draw if(player.dead()) return; //dead players don't draw
+13 -3
View File
@@ -168,8 +168,11 @@ public abstract class SaveVersion extends SaveFileReader{
Tile tile = world.rawTile(i % world.width(), i / world.width()); Tile tile = world.rawTile(i % world.width(), i / world.width());
stream.writeShort(tile.blockID()); stream.writeShort(tile.blockID());
//make note of whether there was an entity here boolean saverot = tile.block().saveRotation;
stream.writeBoolean(tile.build != null); byte packed = (byte)((tile.build != null ? 1 : 0) | (saverot ? 2 : 0));
//make note of whether there was an entity/rotation here
stream.writeByte(packed);
//only write the entity for multiblocks once - in the center //only write the entity for multiblocks once - in the center
if(tile.build != null){ if(tile.build != null){
@@ -182,6 +185,8 @@ public abstract class SaveVersion extends SaveFileReader{
}else{ }else{
stream.writeBoolean(false); stream.writeBoolean(false);
} }
}else if(saverot){
stream.writeByte(tile.rotation());
}else{ }else{
//write consecutive non-entity blocks //write consecutive non-entity blocks
int consecutives = 0; int consecutives = 0;
@@ -237,7 +242,9 @@ public abstract class SaveVersion extends SaveFileReader{
Tile tile = context.tile(i); Tile tile = context.tile(i);
if(block == null) block = Blocks.air; if(block == null) block = Blocks.air;
boolean isCenter = true; boolean isCenter = true;
boolean hadEntity = stream.readBoolean(); byte packedCheck = stream.readByte();
boolean hadEntity = (packedCheck & 1) != 0;
boolean hadRotation = (packedCheck & 2) != 0;
if(hadEntity){ if(hadEntity){
isCenter = stream.readBoolean(); isCenter = stream.readBoolean();
@@ -264,6 +271,9 @@ public abstract class SaveVersion extends SaveFileReader{
skipChunk(stream, true); skipChunk(stream, true);
} }
} }
}else if(hadRotation){
tile.setBlock(block);
tile.rotation(stream.readByte());
}else{ }else{
int consecutives = stream.readUnsignedByte(); int consecutives = stream.readUnsignedByte();
+5 -5
View File
@@ -41,7 +41,7 @@ public class Scripts implements Disposable{
.setModuleScriptProvider(new SoftCachingModuleScriptProvider(new ScriptModuleProvider())) .setModuleScriptProvider(new SoftCachingModuleScriptProvider(new ScriptModuleProvider()))
.setSandboxed(true).createRequire(context, scope).install(scope); .setSandboxed(true).createRequire(context, scope).install(scope);
if(!run(Core.files.internal("scripts/global.js").readString(), "global.js")){ if(!run(Core.files.internal("scripts/global.js").readString(), "global.js", false)){
errored = true; errored = true;
} }
Log.debug("Time to load script engine: @", Time.elapsed()); Log.debug("Time to load script engine: @", Time.elapsed());
@@ -82,18 +82,18 @@ public class Scripts implements Disposable{
public void run(LoadedMod mod, Fi file){ public void run(LoadedMod mod, Fi file){
currentMod = mod; currentMod = mod;
run(file.readString(), file.name()); run(file.readString(), file.name(), true);
currentMod = null; currentMod = null;
} }
private boolean run(String script, String file){ private boolean run(String script, String file, boolean wrap){
try{ try{
if(currentMod != null){ if(currentMod != null){
//inject script info into file (TODO maybe rhino handles this?) //inject script info into file
context.evaluateString(scope, "modName = \"" + currentMod.name + "\"\nscriptName = \"" + file + "\"", "initscript.js", 1, null); context.evaluateString(scope, "modName = \"" + currentMod.name + "\"\nscriptName = \"" + file + "\"", "initscript.js", 1, null);
} }
context.evaluateString(scope, context.evaluateString(scope,
"(function(){\n" + script + "\n})();", wrap ? "(function(){\n" + script + "\n})();" : script,
file, 0, null); file, 0, null);
return true; return true;
}catch(Throwable t){ }catch(Throwable t){
@@ -2,6 +2,7 @@ package mindustry.type;
import arc.*; import arc.*;
import arc.func.*; import arc.func.*;
import arc.graphics.g2d.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
@@ -9,7 +10,9 @@ import mindustry.ctype.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.Objectives.*; import mindustry.game.Objectives.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*;
import mindustry.maps.generators.*; import mindustry.maps.generators.*;
import mindustry.ui.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@@ -82,6 +85,11 @@ public class SectorPreset extends UnlockableContent{
return true; return true;
} }
@Override
public TextureRegion icon(Cicon c){
return Icon.terrain.getRegion();
}
@Override @Override
public boolean isHidden(){ public boolean isHidden(){
return true; return true;
+19
View File
@@ -24,8 +24,10 @@ import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.environment.*; import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.payloads.*; import mindustry.world.blocks.payloads.*;
import mindustry.world.blocks.units.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@@ -150,6 +152,23 @@ public class UnitType extends UnlockableContent{
} }
@Override
public void getDependencies(Cons<UnlockableContent> cons){
//units require reconstructors being researched
for(Block block : content.blocks()){
if(block instanceof Reconstructor){
Reconstructor r = (Reconstructor)block;
for(UnitType[] recipe : r.upgrades){
//result of reconstruction is this, so it must be a dependency
if(recipe[1] == this){
cons.get(block);
}
}
}
}
}
@Override @Override
public void displayInfo(Table table){ public void displayInfo(Table table){
ContentDisplay.displayUnit(table, this); ContentDisplay.displayUnit(table, this);
+2 -1
View File
@@ -3,6 +3,7 @@ package mindustry.ui;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import mindustry.*; import mindustry.*;
import mindustry.core.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.blocks.storage.CoreBlock.*; import mindustry.world.blocks.storage.CoreBlock.*;
@@ -41,7 +42,7 @@ public class CoreItemsDisplay extends Table{
for(Item item : content.items()){ for(Item item : content.items()){
if(usedItems.contains(item)){ if(usedItems.contains(item)){
image(item.icon(Cicon.small)).padRight(3); image(item.icon(Cicon.small)).padRight(3);
label(() -> core == null ? "0" : ui.formatAmount(core.items.get(item))).padRight(3); label(() -> core == null ? "0" : UI.formatAmount(core.items.get(item))).padRight(3);
if(++i % 4 == 0){ if(++i % 4 == 0){
row(); row();
+3 -2
View File
@@ -3,6 +3,7 @@ package mindustry.ui;
import arc.graphics.*; import arc.graphics.*;
import arc.scene.ui.*; import arc.scene.ui.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import mindustry.core.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
@@ -52,10 +53,10 @@ public class ItemsDisplay extends Table{
private String format(Item item){ private String format(Item item){
builder.setLength(0); builder.setLength(0);
builder.append("[TODO implement]"); builder.append("[TODO implement]");
//builder.append(ui.formatAmount(data.getItem(item))); //builder.append(UI.formatAmount(data.getItem(item)));
if(state.isGame() && player.team().data().hasCore() && player.team().core().items.get(item) > 0){ if(state.isGame() && player.team().data().hasCore() && player.team().core().items.get(item) > 0){
builder.append(" [unlaunched]+ "); builder.append(" [unlaunched]+ ");
builder.append(ui.formatAmount(state.teams.get(player.team()).core().items.get(item))); builder.append(UI.formatAmount(state.teams.get(player.team()).core().items.get(item)));
} }
return builder.toString(); return builder.toString();
} }
+1 -1
View File
@@ -16,7 +16,7 @@ public class Links{
new LinkEntry("changelog", "https://github.com/Anuken/Mindustry/releases", Icon.list, Pal.accent.cpy()), new LinkEntry("changelog", "https://github.com/Anuken/Mindustry/releases", Icon.list, Pal.accent.cpy()),
new LinkEntry("trello", "https://trello.com/b/aE2tcUwF", Icon.trello, Color.valueOf("026aa7")), new LinkEntry("trello", "https://trello.com/b/aE2tcUwF", Icon.trello, Color.valueOf("026aa7")),
new LinkEntry("wiki", "https://mindustrygame.github.io/wiki/", Icon.book, Color.valueOf("0f142f")), new LinkEntry("wiki", "https://mindustrygame.github.io/wiki/", Icon.book, Color.valueOf("0f142f")),
new LinkEntry("feathub", "https://github.com/Anuken/Mindustry-Suggestions/issues/new/choose/", Icon.add, Color.valueOf("ebebeb")), new LinkEntry("suggestions", "https://github.com/Anuken/Mindustry-Suggestions/issues/new/choose/", Icon.add, Color.valueOf("ebebeb")),
new LinkEntry("reddit", "https://www.reddit.com/r/Mindustry/", Icon.redditAlien, Color.valueOf("ee593b")), new LinkEntry("reddit", "https://www.reddit.com/r/Mindustry/", Icon.redditAlien, Color.valueOf("ee593b")),
new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Icon.itchio, Color.valueOf("fa5c5c")), new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Icon.itchio, Color.valueOf("fa5c5c")),
new LinkEntry("google-play", "https://play.google.com/store/apps/details?id=io.anuke.mindustry", Icon.googleplay, Color.valueOf("689f38")), new LinkEntry("google-play", "https://play.google.com/store/apps/details?id=io.anuke.mindustry", Icon.googleplay, Color.valueOf("689f38")),
@@ -14,6 +14,7 @@ import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
import mindustry.core.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -327,7 +328,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
int total = (int)(stat.mean * 60); int total = (int)(stat.mean * 60);
if(total > 1){ if(total > 1){
t.image(item.icon(Cicon.small)).padRight(3); t.image(item.icon(Cicon.small)).padRight(3);
t.add(ui.formatAmount(total) + " /min").color(Color.lightGray); t.add(UI.formatAmount(total) + " /min").color(Color.lightGray);
t.row(); t.row();
} }
}); });
@@ -348,7 +349,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
int amount = Math.min(map.get(item), sector.save.meta.secinfo.storageCapacity); int amount = Math.min(map.get(item), sector.save.meta.secinfo.storageCapacity);
if(amount > 0){ if(amount > 0){
res.image(item.icon(Cicon.small)).padRight(3); res.image(item.icon(Cicon.small)).padRight(3);
res.add(ui.formatAmount(amount)).color(Color.lightGray); res.add(UI.formatAmount(amount)).color(Color.lightGray);
if(++i % 2 == 0){ if(++i % 2 == 0){
res.row(); res.row();
} }
@@ -16,6 +16,7 @@ import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.content.TechTree.*; import mindustry.content.TechTree.*;
import mindustry.core.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.Objectives.*; import mindustry.game.Objectives.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -170,12 +171,17 @@ public class ResearchDialog extends BaseDialog{
void checkNodes(TechTreeNode node){ void checkNodes(TechTreeNode node){
boolean locked = locked(node.node); boolean locked = locked(node.node);
if(!locked) node.visible = true; if(!locked) node.visible = true;
node.selectable = selectable(node.node);
for(TechTreeNode l : node.children){ for(TechTreeNode l : node.children){
l.visible = !locked; l.visible = !locked;
checkNodes(l); checkNodes(l);
} }
} }
boolean selectable(TechNode node){
return !node.objectives.contains(i -> !i.complete());
}
void showToast(String info){ void showToast(String info){
Table table = new Table(); Table table = new Table();
table.actions(Actions.fadeOut(0.5f, Interp.fade), Actions.remove()); table.actions(Actions.fadeOut(0.5f, Interp.fade), Actions.remove());
@@ -207,7 +213,7 @@ public class ResearchDialog extends BaseDialog{
class TechTreeNode extends TreeNode<TechTreeNode>{ class TechTreeNode extends TreeNode<TechTreeNode>{
final TechNode node; final TechNode node;
boolean visible = true; boolean visible = true, selectable = true;
TechTreeNode(TechNode node, TechTreeNode parent){ TechTreeNode(TechNode node, TechTreeNode parent){
this.node = node; this.node = node;
@@ -256,7 +262,7 @@ public class ResearchDialog extends BaseDialog{
} }
}); });
} }
}else if(items().has(node.node.requirements) && locked(node.node)){ }else if(canUnlock(node.node) && locked(node.node)){
unlock(node.node); unlock(node.node);
} }
}); });
@@ -278,10 +284,10 @@ public class ResearchDialog extends BaseDialog{
button.update(() -> { button.update(() -> {
float offset = (Core.graphics.getHeight() % 2) / 2f; float offset = (Core.graphics.getHeight() % 2) / 2f;
button.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f + offset, Align.center); button.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f + offset, Align.center);
button.getStyle().up = !locked(node.node) ? Tex.buttonOver : !items().has(node.node.requirements) ? Tex.buttonRed : Tex.button; button.getStyle().up = !locked(node.node) ? Tex.buttonOver : selectable(node.node) && !items().has(node.node.requirements) ? Tex.buttonRed : Tex.button;
((TextureRegionDrawable)button.getStyle().imageUp)
.setRegion(node.visible ? node.node.content.icon(Cicon.medium) : Icon.lock.getRegion()); ((TextureRegionDrawable)button.getStyle().imageUp).setRegion(node.selectable ? node.node.content.icon(Cicon.medium) : Icon.lock.getRegion());
button.getImage().setColor(!locked(node.node) ? Color.white : Color.gray); button.getImage().setColor(!locked(node.node) ? Color.white : node.selectable ? Color.gray : Pal.gray);
}); });
addChild(button); addChild(button);
} }
@@ -313,6 +319,10 @@ public class ResearchDialog extends BaseDialog{
panY = ry - bounds.y - oy; panY = ry - bounds.y - oy;
} }
boolean canUnlock(TechNode node){
return items().has(node.requirements) && selectable(node);
}
void unlock(TechNode node){ void unlock(TechNode node){
node.content.unlock(); node.content.unlock();
items().remove(node.requirements); items().remove(node.requirements);
@@ -349,37 +359,42 @@ public class ResearchDialog extends BaseDialog{
infoTable.left(); infoTable.left();
infoTable.background(Tex.button).margin(8f); infoTable.background(Tex.button).margin(8f);
boolean selectable = selectable(node);
infoTable.table(b -> { infoTable.table(b -> {
b.margin(0).left().defaults().left(); b.margin(0).left().defaults().left();
b.button(Icon.info, Styles.cleari, () -> ui.content.show(node.content)).growY().width(50f); if(selectable){
b.button(Icon.info, Styles.cleari, () -> ui.content.show(node.content)).growY().width(50f);
}
b.add().grow(); b.add().grow();
b.table(desc -> { b.table(desc -> {
desc.left().defaults().left(); desc.left().defaults().left();
desc.add(node.content.localizedName); desc.add(selectable ? node.content.localizedName : "[accent]???");
desc.row(); desc.row();
if(locked(node)){ if(locked(node)){
desc.table(t -> { desc.table(t -> {
t.left(); t.left();
for(ItemStack req : node.requirements){ if(selectable){
t.table(list -> { for(ItemStack req : node.requirements){
list.left(); t.table(list -> {
list.image(req.item.icon(Cicon.small)).size(8 * 3).padRight(3); list.left();
list.add(req.item.localizedName).color(Color.lightGray); list.image(req.item.icon(Cicon.small)).size(8 * 3).padRight(3);
list.label(() -> " " + (player.team().core() != null ? Math.min(player.team().core().items.get(req.item), req.amount) + " / " : "") + req.amount) list.add(req.item.localizedName).color(Color.lightGray);
.update(l -> l.setColor(items().has(req.item, req.amount) ? Color.lightGray : Color.scarlet));//TODO list.label(() -> " " + (player.team().core() != null ? UI.formatAmount(Math.min(player.team().core().items.get(req.item), req.amount)) + " / " : "") + UI.formatAmount(req.amount))
}).fillX().left(); .update(l -> l.setColor(items().has(req.item, req.amount) ? Color.lightGray : Color.scarlet));//TODO
t.row(); }).fillX().left();
} t.row();
}
//TODO test if this works }else if(node.objectives.size > 0){
if(node.objectives.length > 0){
t.table(r -> { t.table(r -> {
r.add("$complete").colspan(2).left(); r.add("$complete").colspan(2).left();
r.row(); r.row();
for(Objective o : node.objectives){ for(Objective o : node.objectives){
r.image(Icon.right).padRight(4); if(o.complete()) continue;
r.add(o.display()).color(Color.lightGray);
r.add("> " + o.display()).color(Color.lightGray).left();
r.image(o.complete() ? Icon.ok : Icon.cancel, o.complete() ? Color.lightGray : Color.scarlet).padLeft(3); r.image(o.complete() ? Icon.ok : Icon.cancel, o.complete() ? Color.lightGray : Color.scarlet).padLeft(3);
r.row(); r.row();
} }
@@ -395,12 +410,12 @@ public class ResearchDialog extends BaseDialog{
if(mobile && locked(node)){ if(mobile && locked(node)){
b.row(); b.row();
b.button("$research", Icon.ok, Styles.nodet, () -> unlock(node)) b.button("$research", Icon.ok, Styles.nodet, () -> unlock(node))
.disabled(i -> !items().has(node.requirements)).growX().height(44f).colspan(3); .disabled(i -> !canUnlock(node)).growX().height(44f).colspan(3);
} }
}); });
infoTable.row(); infoTable.row();
if(node.content.description != null){ if(node.content.description != null && selectable){
infoTable.table(t -> t.margin(3f).left().labelWrap(node.content.displayDescription()).color(Color.lightGray).growX()).fillX(); infoTable.table(t -> t.margin(3f).left().labelWrap(node.content.displayDescription()).color(Color.lightGray).growX()).fillX();
} }
@@ -413,13 +428,16 @@ public class ResearchDialog extends BaseDialog{
public void drawChildren(){ public void drawChildren(){
clamp(); clamp();
float offsetX = panX + width / 2f, offsetY = panY + height / 2f; float offsetX = panX + width / 2f, offsetY = panY + height / 2f;
Draw.sort(true);
for(TechTreeNode node : nodes){ for(TechTreeNode node : nodes){
if(!node.visible) continue; if(!node.visible) continue;
for(TechTreeNode child : node.children){ for(TechTreeNode child : node.children){
if(!child.visible) continue; if(!child.visible) continue;
boolean lock = locked(node.node) || locked(child.node);
Draw.z(lock ? 1f : 2f);
Lines.stroke(Scl.scl(4f), locked(node.node) || locked(child.node) ? Pal.gray : Pal.accent); Lines.stroke(Scl.scl(4f), lock ? Pal.gray : Pal.accent);
Draw.alpha(parentAlpha); Draw.alpha(parentAlpha);
if(Mathf.equal(Math.abs(node.y - child.y), Math.abs(node.x - child.x), 1f) && Mathf.dstm(node.x, node.y, child.x, child.y) <= node.width*3){ if(Mathf.equal(Math.abs(node.y - child.y), Math.abs(node.x - child.x), 1f) && Mathf.dstm(node.x, node.y, child.x, child.y) <= node.width*3){
Lines.line(node.x + offsetX, node.y + offsetY, child.x + offsetX, child.y + offsetY); Lines.line(node.x + offsetX, node.y + offsetY, child.x + offsetX, child.y + offsetY);
@@ -430,6 +448,7 @@ public class ResearchDialog extends BaseDialog{
} }
} }
Draw.sort(false);
Draw.reset(); Draw.reset();
super.drawChildren(); super.drawChildren();
} }
@@ -12,6 +12,7 @@ import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
import arc.util.*; import arc.util.*;
import mindustry.core.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
@@ -325,7 +326,7 @@ public class PlacementFragment extends Fragment{
int stackamount = Math.round(stack.amount * state.rules.buildCostMultiplier); int stackamount = Math.round(stack.amount * state.rules.buildCostMultiplier);
String color = (amount < stackamount / 2f ? "[red]" : amount < stackamount ? "[accent]" : "[white]"); String color = (amount < stackamount / 2f ? "[red]" : amount < stackamount ? "[accent]" : "[white]");
return color + ui.formatAmount(amount) + "[white]/" + stackamount; return color + UI.formatAmount(amount) + "[white]/" + stackamount;
}).padLeft(5); }).padLeft(5);
}).left(); }).left();
req.row(); req.row();
+10
View File
@@ -74,6 +74,8 @@ public class Block extends UnlockableContent{
public boolean solidifes; public boolean solidifes;
/** whether this is rotateable */ /** whether this is rotateable */
public boolean rotate; public boolean rotate;
/** for static blocks only: if true, rotation is saved in world data. */
public boolean saveRotation;
/** whether you can break this with rightclick */ /** whether you can break this with rightclick */
public boolean breakable; public boolean breakable;
/** whether to add this block to brokenblocks */ /** whether to add this block to brokenblocks */
@@ -584,6 +586,14 @@ public class Block extends UnlockableContent{
} }
} }
@Override
public void getDependencies(Cons<UnlockableContent> cons){
//just requires items
for(ItemStack stack : requirements){
cons.get(stack.item);
}
}
@Override @Override
public void displayInfo(Table table){ public void displayInfo(Table table){
ContentDisplay.displayBlock(table, this); ContentDisplay.displayBlock(table, this);
@@ -33,7 +33,7 @@ public class ForceProjector extends Block{
private static ForceProjectorEntity paramEntity; private static ForceProjectorEntity paramEntity;
private static final Cons<Shielderc> shieldConsumer = trait -> { private static final Cons<Shielderc> shieldConsumer = trait -> {
if(trait.team() != paramEntity.team() && Intersector.isInsideHexagon(paramEntity.x, paramEntity.y, paramEntity.realRadius() * 2f, trait.x(), trait.y())){ if(trait.team() != paramEntity.team && Intersector.isInsideHexagon(paramEntity.x, paramEntity.y, paramEntity.realRadius() * 2f, trait.x(), trait.y())){
trait.absorb(); trait.absorb();
Fx.absorb.at(trait); Fx.absorb.at(trait);
paramEntity.hit = 1f; paramEntity.hit = 1f;
@@ -26,7 +26,7 @@ public class StackConveyor extends Block implements Autotiler{
public float speed = 0f; public float speed = 0f;
public boolean splitOut = true; public boolean splitOut = true;
public float displayedSpeed = 30f; public float recharge = 2f;
public StackConveyor(String name){ public StackConveyor(String name){
super(name); super(name);
@@ -47,7 +47,7 @@ public class StackConveyor extends Block implements Autotiler{
public void setStats(){ public void setStats(){
super.setStats(); super.setStats();
stats.add(BlockStat.itemsMoved, displayedSpeed, StatUnit.itemsSecond); stats.add(BlockStat.itemsMoved, Mathf.round(itemCapacity * speed * 60), StatUnit.itemsSecond);
} }
@Override @Override
@@ -166,7 +166,7 @@ public class StackConveyor extends Block implements Autotiler{
@Override @Override
public void updateTile(){ public void updateTile(){
// reel in crater // reel in crater
if(cooldown > 0f) cooldown = Mathf.clamp(cooldown - speed * edelta()); if(cooldown > 0f) cooldown = Mathf.clamp(cooldown - speed * edelta(), 0f, recharge);
if(link == -1){ if(link == -1){
return; return;
@@ -200,7 +200,7 @@ public class StackConveyor extends Block implements Autotiler{
link = -1; link = -1;
items.clear(); items.clear();
cooldown = 1f; cooldown = recharge;
e.cooldown = 1; e.cooldown = 1;
} }
} }
@@ -249,7 +249,7 @@ public class StackConveyor extends Block implements Autotiler{
@Override @Override
public boolean acceptItem(Building source, Item item){ public boolean acceptItem(Building source, Item item){
if(this == source) return true; // player threw items if(this == source) return true; // player threw items
if(cooldown > 0) return false; // still cooling down if(cooldown > recharge - 1f) return false; // still cooling down
return !((state != stateLoad) // not a loading dock return !((state != stateLoad) // not a loading dock
|| (items.total() > 0 && !items.has(item)) // incompatible items || (items.total() > 0 && !items.has(item)) // incompatible items
|| (items.total() >= getMaximumAccepted(item)) // filled to capacity || (items.total() >= getMaximumAccepted(item)) // filled to capacity
@@ -10,6 +10,7 @@ import arc.struct.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
import arc.util.*; import arc.util.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.core.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -99,7 +100,7 @@ public class PowerNode extends PowerBlock{
bars.add("batteries", entity -> new Bar(() -> bars.add("batteries", entity -> new Bar(() ->
Core.bundle.format("bar.powerstored", Core.bundle.format("bar.powerstored",
(ui.formatAmount((int)entity.power.graph.getBatteryStored())), ui.formatAmount((int)entity.power.graph.getTotalBatteryCapacity())), (UI.formatAmount((int)entity.power.graph.getBatteryStored())), UI.formatAmount((int)entity.power.graph.getTotalBatteryCapacity())),
() -> Pal.powerBar, () -> Pal.powerBar,
() -> Mathf.clamp(entity.power.graph.getBatteryStored() / entity.power.graph.getTotalBatteryCapacity()))); () -> Mathf.clamp(entity.power.graph.getBatteryStored() / entity.power.graph.getTotalBatteryCapacity())));
} }
@@ -39,11 +39,6 @@ public class Fracker extends SolidPump{
@Override @Override
public void drawCracks(){} public void drawCracks(){}
@Override
public boolean shouldConsume(){
return liquids.get(result) < liquidCapacity - 0.01f;
}
@Override @Override
public void draw(){ public void draw(){
Draw.rect(region, x, y); Draw.rect(region, x, y);
@@ -113,6 +113,11 @@ public class Pump extends LiquidBlock{
} }
} }
@Override
public boolean shouldConsume(){
return liquidDrop != null && liquids.get(liquidDrop) < liquidCapacity - 0.01f;
}
@Override @Override
public void updateTile(){ public void updateTile(){
if(consValid() && liquidDrop != null){ if(consValid() && liquidDrop != null){
@@ -101,6 +101,11 @@ public class SolidPump extends Pump{
Draw.rect(topRegion, x, y); Draw.rect(topRegion, x, y);
} }
@Override
public boolean shouldConsume(){
return liquids.get(result) < liquidCapacity - 0.01f;
}
@Override @Override
public void updateTile(){ public void updateTile(){
float fraction = 0f; float fraction = 0f;
@@ -9,6 +9,7 @@ import arc.struct.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.core.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.*; import mindustry.game.*;
@@ -77,10 +78,10 @@ public class CoreBlock extends StorageBlock{
bars.add("capacity", (CoreEntity e) -> bars.add("capacity", (CoreEntity e) ->
new Bar( new Bar(
() -> Core.bundle.format("bar.capacity", ui.formatAmount(e.storageCapacity)), () -> Core.bundle.format("bar.capacity", UI.formatAmount(e.storageCapacity)),
() -> Pal.items, () -> Pal.items,
() -> e.items.total() / ((float)e.storageCapacity * content.items().count(i -> i.unlockedNow())) () -> e.items.total() / ((float)e.storageCapacity * content.items().count(i -> i.unlockedNow()))
)); ));
} }
@Override @Override
@@ -150,7 +150,8 @@ public class Reconstructor extends UnitBlock{
} }
public boolean hasUpgrade(UnitType type){ public boolean hasUpgrade(UnitType type){
return upgrade(type) != null; UnitType t = upgrade(type);
return t != null && t.unlockedNow();
} }
public UnitType upgrade(UnitType type){ public UnitType upgrade(UnitType type){
@@ -127,9 +127,13 @@ public class UnitFactory extends UnitBlock{
@Override @Override
public void buildConfiguration(Table table){ public void buildConfiguration(Table table){
Seq<UnitType> units = Seq.with(plans).map(u -> u.unit); Seq<UnitType> units = Seq.with(plans).map(u -> u.unit).filter(u -> u.unlockedNow());
ItemSelection.buildTable(table, units, () -> currentPlan == -1 ? null : plans[currentPlan].unit, unit -> configure(units.indexOf(unit))); if(units.any()){
ItemSelection.buildTable(table, units, () -> currentPlan == -1 ? null : plans[currentPlan].unit, unit -> configure(units.indexOf(unit)));
}else{
table.table(Styles.black3, t -> t.add("$none").color(Color.lightGray));
}
} }
@Override @Override
+1 -1
View File
@@ -1,3 +1,3 @@
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=e3078d7782509f39e5b0ee6989c5f7eeea0ad1b7 archash=9758a12fe9090a08fead6186fe49b7c347180f2e