Merge remote-tracking branch 'fork_master/master'

This commit is contained in:
beito123
2018-12-15 15:48:39 +09:00
43 changed files with 683 additions and 520 deletions

View File

@@ -384,6 +384,8 @@ category.multiplayer.name = Multiplayer
command.attack = Attack
command.retreat = Retreat
command.patrol = Patrol
keybind.gridMode.name = Block Select
keybind.gridModeShift.name = Category Select
keybind.press = Press a key...
keybind.press.axis = Press an axis or key...
keybind.screenshot.name = Map Screenshot
@@ -406,7 +408,7 @@ keybind.toggle_menus.name = Toggle menus
keybind.chat_history_prev.name = Chat history prev
keybind.chat_history_next.name = Chat history next
keybind.chat_scroll.name = Chat scroll
keybind.drop_unit.name = drop unit
keybind.drop_unit.name = Drop Unit
keybind.zoom_minimap.name = Zoom minimap
mode.text.help.title = Description of modes
mode.waves.name = Waves

View File

@@ -7,7 +7,7 @@ text.link.github.description = Code source du jeu
text.link.dev-builds.description = Versions instables de développement
text.link.trello.description = Planning Trello officiel pour les fonctionnalités planifiées.
text.link.itch.io.description = Page web itch.io avec les versions ordinateurs téléchargeables et la version web
text.link.google-play.description = Page Google Play Store du jeu
text.link.google-play.description = Page Google Play du jeu
text.link.wiki.description = Wiki officiel de Mindustry
text.linkfail = L'ouverture du lien a échoué!\nL'URL a été copiée dans votre presse-papier.
text.screenshot = Capture d'écran enregistrée sur {0}
@@ -414,6 +414,8 @@ mode.freebuild.name = Construction libre
mode.freebuild.description = Ressources limitées et pas de compte à rebours pour les vagues.
mode.pvp.name = PvP
mode.pvp.description = Lutter contre d'autres joueurs pour gagner !
mode.attack.name = Attaque
mode.attack.descrption = Pas de vagues, le but est de détruire la base ennemie.
content.item.name = Objets
content.liquid.name = Liquides
content.unit.name = Unités

View File

@@ -1,4 +1,4 @@
text.credits.text = Создатель [ROYAL] Anuken. - [SKY]anukendev@gmail.com[][]\n\nЕсть недоработки в переводе?\nПишите в офф. discord-сервер mindustry в канал #русский.\n\nПереводчики на русский язык:\n[YELLOW]Prosta4ok_ua\n[GREEN]xga\n[BLACK]XZimur
text.credits.text = Создатель [ROYAL] Anuken. - [SKY]anukendev@gmail.com[][]\n\nЕсть недоработки в переводе?\nПишите в офф. discord-сервер mindustry в канал #русский.\n\nПереводчики на русский язык:\n[YELLOW]Prosta4ok_ua\n[GREEN]xga\n[BLACK]XZimur\n[BLUE]Beryllium
text.credits = Авторы
text.contributors = Переводчики и контрибьюторы
text.discord = Присоединяйтесь к нашему Discord!
@@ -23,9 +23,9 @@ text.level.select = Выбор карты
text.level.mode = Режим игры:
text.construction.desktop = Чтобы отменить выбор блока или остановить строительство, [accent] используйте пробел[].
text.construction.title = Руководство по размещению блоков
text.construction = Вы только что перешли в режим размещения[accent]блоков[].\n\nЧтобы начать размещение, просто коснитесь подходящего места рядом с вашим мехом.\nПосле того, как вы поставили несколько блоков, нажмите на галочку, чтобы подтвердить, и ваш мех начнет их строительство.\n\n- [accent]Удалите блоки [] из вашего плана строительства, нажав на них.n- [accent]Нажав Shift [] и, удерживая, перетащите любой выбранный блок.\n- [accent]Поместите блоки в линию [], нажимая и удерживая на пустое место, а затем перетаскивая в любом направлении.\n- [accent]Отмените размещение блоков [], нажав X в левом нижнем углу.
text.construction = Вы только что перешли в режим размещения[accent]блоков[].\n\nЧтобы начать размещение, просто коснитесь подходящего места рядом с вашим мехом.\nПосле того, как вы поставили несколько блоков, нажмите на галочку, чтобы подтвердить, и ваш мех начнет их строительство.\n\n- [accent]Удалите блоки [] из вашего плана строительства, нажав на них.n- [accent]Нажав Shift [] и, удерживая, перетащите любой выбранный блок.\n- [accent]Поместите блоки в линию [], нажимая и удерживая на пустое место, а затем перетаскивая в любом направлении.\n- [accent]Отмените размещение блоков [], нажав X в нижнем правом углу.
text.deconstruction.title = Руководство по разрушению блоков
text.deconstruction = Вы только что перешли в режим сноса[accent] блоков.[].\n\nЧтобы начать удалять, просто нажмите на блок рядом с вашим мехом.\nПосле того как вы выбрали несколько блоков, нажмите на галочку, чтобы подтвердить, и ваш мех начнёт их сносить.\n\n- [accent]Уберите блоки [] из вашего выбора, нажав на них.\n- [accent]Удалите блоки в области [], нажав и удерживая на пустом месте, а затем перетаскивая в нужном направлении.\n- [accent]Отменить снос или выбор [] можно нажав X в левом нижнем углу.
text.deconstruction = Вы только что перешли в режим сноса[accent] блоков.[].\n\nЧтобы начать удалять, просто нажмите на блок рядом с вашим мехом.\nПосле того как вы выбрали несколько блоков, нажмите на галочку, чтобы подтвердить, и ваш мех начнёт их сносить.\n\n- [accent]Уберите блоки [] из вашего выбора, нажав на них.\n- [accent]Удалите блоки в области [], нажав и удерживая на пустом месте, а затем перетаскивая в нужном направлении.\n- [accent]Отменить снос или выбор [] можно нажав X в нижнем правом углу.
text.showagain = Не показывать снова до следующей сессии
text.coreattack = < Ядро находится под атакой! >
text.unlocks = Разблокированные
@@ -39,13 +39,13 @@ text.sector = Выбранный сектор: [LIGHT_GRAY]{0}
text.sector.time = Время: [LIGHT_GRAY]{0}
text.sector.deploy = Высадиться
text.sector.abandon = Отступить
text.sector.abandon.confirm = Вы уверены, что хотите отступить?\nЭто не может быть отменено!
text.sector.abandon.confirm = Вы уверены, что хотите отступить?\nПрогресс на секторе нельзя восстановить!
text.sector.resume = Продолжить
text.sector.locked = [scarlet][[Не завершён]
text.sector.unexplored = [accent][[Неисследованный]
text.missions = Миссий:[LIGHT_GRAY] {0}
text.mission = Миссия:[LIGHT_GRAY] {0}
text.mission.main = Главная мисия:[LIGHT_GRAY] {0}
text.mission.main = Главная миссия:[LIGHT_GRAY] {0}
text.mission.info = Информация о миссии
text.mission.complete = Миссия выполнена!
text.mission.complete.body = Сектор {0},{1} был завоёван.
@@ -430,12 +430,12 @@ item.titanium.name = Титан
item.titanium.description = Редкий сверхлёгкий металл широко используется в производстве: транспорта, буров и самолётов.
item.thorium.name = Торий
item.thorium.description = Плотный радиоактивный металл используется в качестве структурной поддержки и ядерного топлива.
item.silicon.name = Кремень
item.silicon.name = Кремний
item.silicon.description = Очень полезный полупроводник с применениями в солнечных батареях и множестве сложной электроники.
item.plastanium.name = Пластиний
item.plastanium.description = Легкий, пластичный материал, используемый в современных самолетах и боеприпасах для фрагментации.
item.phase-fabric.name = Фазовая ткань
item.phase-fabric.description = Невесомое вещество, используемое в современной электронике и технологии самовосстановления. Непригодна для вышивания.
item.phase-fabric.description = Невесомое вещество, используемое в современной электронике и технологии самовосстановления. Не для вышивания.
item.surge-alloy.name = Высокопрочный сплав
item.surge-alloy.description = Передовой сплав с уникальными электрическими свойствами.
item.biomatter.name = Биоматерия
@@ -463,7 +463,7 @@ mech.tau-mech.weapon = Восстановительный лазер
mech.tau-mech.ability = Регенирирующая вспышка
mech.tau-mech.description = Мех поддержки. Чинит союзные блоки, стреляя в них. Может исцелить союзников радиусом с его способностью восстанавления.
mech.omega-mech.name = Омега
mech.omega-mech.weapon = Ракетомётный пулемётконфигурация
mech.omega-mech.weapon = Ракетомётный пулемёт
mech.omega-mech.ability = Защитная
mech.omega-mech.description = Громоздкий и хорошо бронированный мех, сделанный для фронтовых нападений. Его способность брони может блокировать до 90% входящего урона.
mech.dart-ship.name = Дротик
@@ -655,7 +655,7 @@ tutorial.conveyor = [accent]Конвейеры[] используются для
tutorial.morecopper = Требуется больше меди.\n\nЛибо добудьте её вручную, либо разместите больше буров.
tutorial.turret = Оборонительные сооружения должны быть созданы, чтобы отразить[LIGHT_GRAY] атаку противника[].Постройте двойную турель рядом с вашей базой.
tutorial.drillturret = Двойные турели требуют[accent] патронов из меди[] для стрельбы.\nРазместите бур рядом с турелью, чтобы снабдить её добытой медью.
tutorial.waves = [LIGHT_GRAY]Враг[] приближается.\n\nЗащитите своё ядро от 2-ух волн. Вам может понадобится больше турелей.
tutorial.waves = [LIGHT_GRAY]Враг[] приближается.\n\nЗащитите своё ядро от двух волн. Вам может понадобится больше турелей.
tutorial.lead = Осмотритесь! Магическим образом появились новые руды. Добудьте [accent] свинец[].\n\nПеретащите ресурс из своего устройства(юнита) в ядро для переноса ресурсов.
tutorial.smelter = Медь и свинец являются мягкими металлами.\nПревосходный[accent] плотный сплав[] может быть создан в плавильном заводе.\n\nПостройте один плавильный завод.
tutorial.densealloy = Теперь плавильный завод производит плотный сплав.\nСоздайте немного.\nУлучшите производство, если это необходимо.
@@ -664,7 +664,7 @@ tutorial.silicondrill = Для производства кремния треб
tutorial.generator = Эта технология требует энергии.\nПостройте [accent] генератор внутреннего сгорания[] для того, чтобы запитать устройство энергией.
tutorial.generatordrill = Генератор внутреннего сгорания нуждается в топливе.\nЗаправьте его углём.
tutorial.node = Энергия требует транспортировки.\nСоздайте [accent] силовой узел[] рядом с генератором внутреннего сгорания для передачи энергии.
tutorial.nodelink = Энергия может быть передана посредством соприкосновения блоков питания и генераторов или связанных силовых узлов.\n\nСоедините их энергией, нажав на силовой узел и выбрав генератор, а затем кремниевый завод.
tutorial.nodelink = Энергия может быть передана посредством соприкосновения блоков питания и генераторов или связанных силовых узлов.\n\nСоедините их, нажав на силовой узел и выбрав генератор, а затем кремниевый завод.
tutorial.silicon = Производство кремния началось. Получите немного.\nРекомендуется улучшить эту систему.
tutorial.daggerfactory = Постройте[accent] завод по производству "разведчиков".[]\n\nОн будет производить атакуюших мехов.
tutorial.router = Заводы нуждаются в ресурсах для работы.\nСоздайте маршрутизатор для разделения ресурсов конвейера.
@@ -773,8 +773,8 @@ block.bridge-conveyor.description = Улучшенный транспортны
block.alpha-mech-pad.description = Превращает вас в мех [accent] Альфа[]. Требует энергию.
block.itemsource.description = Бесконечно выводит предметы. Работает только в песочнице.
block.liquidsource.description = Бесконечно выводит жидкости. Работает только в песочнице.
block.itemvoid.description = Уничтожает любые предметы, которые входят в него, без использования энергии. Работает только в песочнице.
block.powerinfinite.description = Бесконечность — не предел. Бесконечно выводит энергию. Доступен только в песочнице.
block.itemvoid.description = Уничтожает любые предметы, которые входят в него, без использования энергии. Работает только в режиме песочницы.
block.powerinfinite.description = Бесконечность — не предел. Бесконечно выводит энергию. Доступен только в режиме песочницы.
block.powervoid.description = Энергия просто уходит в пустоту. Присутствует только в песочнице.
liquid.water.description = Намного лучше чем [BLUE]монооксид дигидрогена[].\n\n Для получения воды используйте помпу(насос) на источнике(блоке) или экстрактор воды.\n\n Эту жидкость можно подвести к бурам для ускорения скорости добычи или к турелям для ускорения стрельбы.
liquid.lava.description = [accent]Горячо...\nВещество расплавленное из горно-каменных пород.

View File

@@ -8,67 +8,69 @@ text.link.trello.description = Planlanan özellikler için resmi Trello Bülteni
text.link.itch.io.description = PC yüklemeleri ve web sürümü ile itch.io sayfası
text.link.google-play.description = Google Play mağaza sayfası
text.link.wiki.description = Resmi Mindustry Wikipedi'si
text.linkfail = Bağlantıılamadı! URL, yazı tahtanıza kopyalandı.
text.linkfail = Bağlantıılamadı\! URL, yazı tahtanıza kopyalandı.
text.editor.web = Web sürümü editörü desteklemiyor\! Editörü kullanmak için oyunu indirin.
text.web.unsupported = Site versiyonu bunu desteklemiyor\! Oyunu indirip dene.
text.gameover = Çekirdek yok edildi.
text.gameover.pvp = The[accent] {0}[] team is victorious!
text.sector.gameover = This sector has been lost. Re-deploy?
text.sector.retry = Retry
text.highscore = [SARI] Yeni yüksek puan!
text.wave.lasted = You lasted until wave [accent]{0}[].
text.level.highscore = Yüksek Puan: [accent] {0}
text.gameover.pvp = [accent] {0}[] takimi kazandi \!
text.sector.gameover = Sektor kaybedildi.
text.sector.retry = Tekrar dene
text.highscore = [SARI] Yeni yüksek puan\!
text.wave.lasted = Su dalgaya kadar yasadin: [accent]{0}[].
text.level.highscore = Yüksek Puan\: [accent] {0}
text.level.delete.title = Silmeyi onaylayın
text.map.delete = Are you sure you want to delete the map "[accent]{0}[]"?
text.map.delete = Su haritayi silmek istedigine emin misin? "[orange]{0}[]"?
text.level.select = Seviye Seç
text.level.mode = Oyun Modu
text.construction.desktop = Desktop controls have been changed.\nTo deselect a block or stop building, [accent]use space[].
text.construction.title = Block Construction Guide
text.construction = You've just selected [accent]block construction mode[].\n\nTo begin placing, simply tap a valid location near your ship.\nOnce you have selected some blocks, press the checkbox to confirm, and your ship will begin constructing them.\n\n- [accent]Remove blocks[] from your selection by tapping them.\n- [accent]Shift the selection[] by holding and dragging any block in the selection.\n- [accent]Place blocks in a line[] by tapping and holding an empty spot, then dragging in a direction.\n- [accent]Cancel construction or selection[] by pressing the X at the bottom left.
text.deconstruction.title = Block Deconstruction Guide
text.deconstruction = You've just selected [accent]block deconstruction mode[].\n\nTo begin breaking, simply tap a block near your ship.\nOnce you have selected some blocks, press the checkbox to confirm, and your ship will begin de-constructing them.\n\n- [accent]Remove blocks[] from your selection by tapping them.\n- [accent]Remove blocks in an area[] by tapping and holding an empty spot, then dragging in a direction.\n- [accent]Cancel deconstruction or selection[] by pressing the X at the bottom left.
text.showagain = Don't show again next session
text.coreattack = < Core is under attack! >
text.unlocks = Unlocks
text.construction.desktop = Masaustu kontrolleri degisti.\nSecmeyi birakip yapmayi kesmek icin, [accent]bosluga bas[].
text.construction.title = Blok Yapma Ogreticisi
text.construction = Sen su anda [accent]blok yapma moduna gectin[].\n\nYapmaya baslamak icin, geminin cevresinde uygun bir yere tikla.\nBiraz blok sectikten sonra, onaylamak icin "tik" tusuna bas, ve gemin onlari yapmaya baslayacaktir.\n\n- [accent]Blok kaldirmak[] icin onlari secme yerine gene tikla\n- [accent]Blok secmek icin[] onlara secme yerinde tikla.\n- [accent]Cizgi biciminde koymak icin[] bos bir yere bas, ve bir yere dogru surukle.\n- [accent]Yapma modundan cikmak icin[] alt kosedeki X tusuna bas
text.deconstruction.title = Blok Yikim Ogreticisi
text.deconstruction = Sen su anda [accent]blok yikim moduna gectin[].\n\nKirmaya baslamak icin, geminin cevresinde bir bloga tikla\nBiraz blok sectikten sonra, "tik" tusuna basarak onayla, ve gemin onlari yikmaya baslayacaktir.\n\n- [accent]Blok kaldirmak[] icin onlari secme yerine gene tikla\n- [accent]Bir alanin icinde blok kirmak icin[] bos bir yere tikla, ve surukle\n- [accent]Yikma modundan cikmak icin[] Kosedeki X tusuna bas
text.showagain = Bunu gene gosterme
text.coreattack = < Cekirdek saldiri altinda\! >
text.unlocks = Koleksiyon
text.savegame = Oyunu Kaydet
text.loadgame = Oyunu yükle
text.joingame = Oyuna katıl
text.addplayers = Add/Remove Players
text.customgame = Custom Game
text.sectors = Sectors
text.sector = Selected Sector: [LIGHT_GRAY]{0}
text.sector.time = Time: [LIGHT_GRAY]{0}
text.sector.deploy = Deploy
text.sector.abandon = Abandon
text.sector.abandon.confirm = Are you sure you want to abandon all progress at this sector?\nThis cannot be undone!
text.sector.resume = Resume
text.sector.locked = [scarlet][[Incomplete]
text.sector.unexplored = [accent][[Unexplored]
text.missions = Missions:[LIGHT_GRAY] {0}
text.mission = Mission:[LIGHT_GRAY] {0}
text.mission.main = Main Mission:[LIGHT_GRAY] {0}
text.mission.info = Mission Info
text.mission.complete = Mission complete!
text.mission.complete.body = Sector {0},{1} has been conquered.
text.mission.wave = Survive[accent] {0}/{1} []waves\nWave in {2}
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
text.mission.wave.menu = Survive[accent] {0} []waves
text.mission.battle = Destroy the enemy base.
text.mission.resource.menu = Obtain {0} x{1}
text.mission.resource = Obtain {0}:\n[accent]{1}/{2}[]
text.mission.block = Create {0}
text.mission.unit = Create {0} Unit
text.mission.command = Send Command {0} To Units
text.mission.linknode = Link Power Node
text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0}
text.mission.mech = Switch to mech[accent] {0}[]
text.mission.create = Create[accent] {0}[]
text.addplayers = Oyuncu ekle/cikar
text.customgame = Ozel oyun
text.sectors = Sektorler
text.sector = Su sektoru sectin\: [LIGHT_GRAY]{0}
text.sector.time = Zaman\: [LIGHT_GRAY]{0}
text.sector.deploy = Basla
text.sector.abandon = Terk et
text.sector.abandon.confirm = Buradaki ilerlemeni silmek istedigine emin misin\nBu geri alinamaz\!
text.sector.resume = Devam et
text.sector.locked = [scarlet][[Bitirilmedi]
text.sector.unexplored = [accent][[Kesvedilmedş]
text.missions = Gorevler\:[LIGHT_GRAY] {0}
text.mission = Gorev\:[LIGHT_GRAY] {0}
text.mission.main = Ana gorev\:[LIGHT_GRAY] {0}
text.mission.info = Gorev bilgisi
text.mission.complete = Gorev tamamlandi\!
text.mission.complete.body = Sektor {0},{1} ele gecirildi
text.mission.wave = [accent]{0}[] dalga hayatta kal
text.mission.wave.enemies = [accent] {0}/{1} []dalga hayatta kal\n{2} Dusman oldur
text.mission.wave.enemy = [accent] {0}/{1} []dalga hayatta kal\n{2} Dusman oldur
text.mission.wave.menu = [accent] {0} []dalga hayatta kal
text.mission.battle = Dusman temelini yok et
text.mission.resource.menu = Sunlari ele gecir {0} x{1}
text.mission.resource = Sunlari ele gecir {0}\:\n[accent]{1}/{2}[]
text.mission.block = Su kadar yarat {0}
text.mission.unit = {0} Kadar unit yarat
text.mission.command = {0} Unite komut yolla
text.mission.linknode = Guc nodu bagla
text.mission.display = [accent]Gorev\:\n[LIGHT_GRAY]{0}
text.mission.mech = Su gemiye degis[accent] {0}[]
text.mission.create = Su kadar yarat[accent] {0}[]
text.none = <none>
text.close = Close
text.close = Kapat
text.quit = Çık
text.maps = Maps
text.continue = Continue
text.nextmission = Next Mission
text.maps.none = [LIGHT_GRAY]No maps found!
text.maps = Haritalar
text.continue = Devam et
text.nextmission = Siradaki gorev
text.maps.none = [LIGHT_GRAY]Harita bulunamadi\!
text.about.button = Hakkında
text.name = Adı:
text.filename = File Name:

View File

@@ -1,5 +1,6 @@
text.credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!)
text.credits.text = [ROYAL]Anuken[]製作 - [SKY]anukendev@gmail.com[]
text.credits = 致謝名單
text.contributors = 翻譯員和貢獻者
text.discord = 加入 Mindustry 的 Discord 聊天室!
text.link.discord.description = 官方 Mindustry Discord 聊天室
text.link.github.description = 遊戲原始碼
@@ -9,8 +10,9 @@ text.link.itch.io.description = itch.io 電腦版下載與網頁版
text.link.google-play.description = Google Play 商店頁面
text.link.wiki.description = 官方 Mindustry 維基
text.linkfail = 無法打開連結!\n我們已將該網址複製到您的剪貼簿。
text.screenshot = 截圖保存到{0}
text.gameover = 核心已被摧毀。
text.gameover.pvp = [accent]{0}[]隊得到勝利
text.gameover.pvp = [accent]{0}[]隊獲勝
text.sector.gameover = 這個區域失守了,重新部署?
text.sector.retry = 重試
text.highscore = [accent]新的高分紀錄!
@@ -71,6 +73,7 @@ text.nextmission = 下一個任務
text.maps.none = [LIGHT_GRAY]找不到地圖!
text.about.button = 關於
text.name = 名稱:
text.noname = 先選擇一個[accent]玩家名稱[]。
text.filename = 檔案名稱︰
text.unlocked = 新方塊已解鎖!
text.unlocked.plural = 新方塊已解鎖!
@@ -250,7 +253,7 @@ text.menu = 主選單
text.play = 開始
text.load = 載入
text.save = 儲存
text.fps = 螢幕刷新率{0}
text.fps = FPS{0}
text.tps = TPS{0}
text.ping = 延遲:{0}ms
text.language.restart = 請重新啟動遊戲以使選取的語言生效。
@@ -259,6 +262,7 @@ text.tutorial = 教學
text.editor = 地圖編輯器
text.mapeditor = 地圖編輯器
text.donate = 贊助
text.connectfail = [crimson]無法連線到伺服器:[accent]{0}
text.error.unreachable = 無法到達伺服器。
text.error.invalidaddress = 無效地址。
@@ -267,6 +271,7 @@ text.error.mismatch = 包裹錯誤:\n客戶端/伺服器版本可能不匹配
text.error.alreadyconnected = 已連接。
text.error.mapnotfound = 找不到地圖!
text.error.any = 未知網絡錯誤。
text.settings.language = 語言
text.settings.reset = 重設為預設設定
text.settings.rebind = 重新綁定
@@ -289,7 +294,7 @@ text.error.crashtitle = 發生錯誤
text.blocks.unknown = [LIGHT_GRAY]???
text.blocks.blockinfo = 方塊資訊
text.blocks.powercapacity = 蓄電量
text.blocks.powershot = /射擊
text.blocks.powershot = /射擊
text.blocks.targetsair = 攻擊空中目標
text.blocks.itemspeed = 移動速度
text.blocks.shootrange = 範圍
@@ -297,13 +302,13 @@ text.blocks.size = 尺寸
text.blocks.liquidcapacity = 液體容量
text.blocks.maxitemssecond = 最高產量
text.blocks.powerrange = 輸出範圍
text.blocks.poweruse = 使用
text.blocks.powerdamage = /傷害
text.blocks.poweruse = 使用
text.blocks.powerdamage = /傷害
text.blocks.inputitemcapacity = 最大輸入
text.blocks.outputitemcapacity = 最大輸出
text.blocks.itemcapacity = 物品容量
text.blocks.basepowergeneration = 基本能量生产
text.blocks.powertransferspeed = 傳輸
text.blocks.powertransferspeed = 傳輸
text.blocks.craftspeed = 產生速度
text.blocks.inputliquid = 輸入液體
text.blocks.inputliquidaux = 輔助液體
@@ -319,8 +324,8 @@ text.blocks.coolant = 冷卻劑
text.blocks.coolantuse = 使用冷卻劑
text.blocks.inputliquidfuel = 輸入液體燃料
text.blocks.liquidfueluse = 使用液體燃料速度
text.blocks.boostitem = Boost Item
text.blocks.boostliquid = Boost Liquid
text.blocks.boostitem = 強化物品
text.blocks.boostliquid = 強化液體
text.blocks.health = 耐久度
text.blocks.inaccuracy = 誤差
text.blocks.shots = 射擊數
@@ -330,26 +335,27 @@ text.blocks.fuelburntime = 燃燒燃料時間
text.blocks.inputcapacity = 輸入容量
text.blocks.outputcapacity = 輸出容量
text.unit.blocks = 方塊
text.unit.powersecond = 單位/秒
text.unit.powersecond = 單位/秒
text.unit.liquidsecond = 液體單位/秒
text.unit.itemssecond = 物品/秒
text.unit.pixelssecond = 像素/秒
text.unit.liquidunits = 液體單位
text.unit.powerunits = 單位
text.unit.powerunits = 單位
text.unit.degrees =
text.unit.seconds =
text.unit.items = 物品
text.category.general = 一般
text.category.power =
text.category.power =
text.category.liquids = 液體
text.category.items = 物品
text.category.crafting = 合成
text.category.shooting = 射擊
text.category.optional = Optional Enhancements
text.category.optional = 可選的強化
setting.indicators.name = 盟友指標
setting.autotarget.name = 自動射擊
setting.fpscap.name = 最大螢幕刷新率
setting.fpscap.name = 最大FPS
setting.fpscap.none = 没有
setting.fpscap.text = {0}螢幕刷新率
setting.fpscap.text = {0}FPS
setting.difficulty.training = 訓練
setting.difficulty.easy = 簡單
setting.difficulty.normal = 普通
@@ -362,7 +368,7 @@ setting.sensitivity.name = 控制器靈敏度
setting.saveinterval.name = 自動存檔間隔
setting.seconds = {0}秒
setting.fullscreen.name = 全螢幕
setting.fps.name = 顯示螢幕刷新率
setting.fps.name = 顯示FPS
setting.vsync.name = 垂直同步
setting.lasers.name = 顯示雷射光束
setting.minimap.name = 顯示小地圖
@@ -370,7 +376,7 @@ setting.musicvol.name = 音樂音量
setting.mutemusic.name = 靜音
setting.sfxvol.name = 音效音量
setting.mutesound.name = 靜音
setting.crashreport.name = Send Anonymous Crash Reports
setting.crashreport.name = 發送匿名崩潰報告
text.keybind.title = 重新綁定按鍵
category.general.name = 一般
category.view.name = 查看
@@ -378,8 +384,9 @@ category.multiplayer.name = 多人
command.attack = 攻擊
command.retreat = 撤退
command.patrol = 巡邏
keybind.press = 按一下鍵
keybind.press.axis = 按一下軸心或鍵
keybind.press = 按一下鍵……
keybind.press.axis = 按一下軸心或鍵……
keybind.screenshot.name = 地圖截圖
keybind.move_x.name = 水平移動
keybind.move_y.name = 垂直移動
keybind.select.name = 選取
@@ -410,6 +417,8 @@ mode.freebuild.name = 自由建造
mode.freebuild.description = 有限的資源,與不倒數計時的波次。
mode.pvp.name = 對戰
mode.pvp.description = 和其他玩家鬥爭。
mode.attack.name = 攻擊
mode.attack.description = 沒有波次,目標是摧毀敵人的基地。
content.item.name = 物品
content.liquid.name = 液體
content.unit.name = 機組
@@ -535,8 +544,8 @@ block.sorter.name = 分類器
block.sorter.description = 對物品進行分類。如果物品與所選種類匹配,則允許其通過。否則,物品將從左邊和右邊輸出。
block.overflow-gate.name = 溢流器
block.overflow-gate.description = 分離器和分配器的組合。如果前面被擋住,則向從左邊和右邊輸出物品。
block.smelter.name =
block.arc-smelter.name = 電弧煉
block.smelter.name = 煉廠
block.arc-smelter.name = 電弧煉廠
block.silicon-smelter.name = 煉矽廠
block.phase-weaver.name = 相織布編織器
block.pulverizer.name = 粉碎機
@@ -546,8 +555,8 @@ block.incinerator.name = 焚化爐
block.biomattercompressor.name = 生物物質壓縮機
block.separator.name = 分離機
block.centrifuge.name = 離心機
block.power-node.name = 節點
block.power-node-large.name = 大型能節點
block.power-node.name = 節點
block.power-node-large.name = 大型能節點
block.battery.name = 電池
block.battery-large.name = 大型電池
block.combustion-generator.name = 燃燒發電機
@@ -568,9 +577,9 @@ block.tau-mech-pad.name = Tau機甲墊
block.conduit.name = 管線
block.mechanical-pump.name = 機械泵
block.itemsource.name = 物品源
block.itemvoid.name = 物品
block.itemvoid.name = 物品虚
block.liquidsource.name = 液體源
block.powervoid.name = 空虛
block.powervoid.name = 空虛
block.powerinfinite.name = 無限能量
block.unloader.name = 裝卸器
block.vault.name = 存儲庫
@@ -578,7 +587,7 @@ block.wave.name = 波浪炮
block.swarmer.name = 群炮
block.salvo.name = 齊射炮
block.ripple.name = 波紋炮
block.phase-conveyor.name = 相織傳送帶
block.phase-conveyor.name = 相織傳送帶
block.bridge-conveyor.name = 傳送帶橋
block.plastanium-compressor.name = 塑料壓縮機
block.pyratite-mixer.name = 硫混合器
@@ -587,21 +596,21 @@ block.solidifer.name = 凝固器
block.solar-panel.name = 太陽能板
block.solar-panel-large.name = 大型太陽能板
block.oil-extractor.name = 石油鑽井
block.spirit-factory.name = 精神無人機工廠
block.phantom-factory.name = Phantom Drone Factory
block.wraith-factory.name = Wraith Fighter Factory
block.ghoul-factory.name = Ghoul Bomber Factory
block.dagger-factory.name = Dagger Mech Factory
block.titan-factory.name = Titan Mech Factory
block.fortress-factory.name = Fortress Mech Factory
block.revenant-factory.name = Revenant Fighter Factory
block.spirit-factory.name = 輕型無人機工廠
block.phantom-factory.name = 幻影無人機工廠
block.wraith-factory.name = 怨靈戰鬥機工廠
block.ghoul-factory.name = 食屍鬼轟炸機工廠
block.dagger-factory.name = 匕首機甲工廠
block.titan-factory.name = 泰坦機甲工廠
block.fortress-factory.name = 堡壘機甲工廠
block.revenant-factory.name = 亡魂戰鬥機工廠
block.repair-point.name = 維修點
block.pulse-conduit.name = 脈衝管線
block.phase-conduit.name = 相織管線
block.liquid-router.name = 液體分配器
block.liquid-tank.name = 液體儲罐
block.liquid-junction.name = 液體連接點
block.bridge-conduit.name = 管橋
block.bridge-conduit.name =
block.rotary-pump.name = 迴旋泵
block.thorium-reactor.name = 釷反應堆
block.command-center.name = 指令中心
@@ -619,7 +628,7 @@ block.shock-mine.name = 休克地雷
block.overdrive-projector.name = 超速投影器
block.force-projector.name = 力牆投影器
block.arc.name = 電弧
block.rtg-generator.name = 放射性同位素熱發電機
block.rtg-generator.name = 放射性同位素熱發電機
block.spectre.name = 幽靈炮
block.meltdown.name = 熔毀炮
block.container.name = 容器
@@ -631,150 +640,150 @@ team.none.name = 灰
team.green.name =
team.purple.name =
unit.alpha-drone.name = 阿爾法無人機
unit.spirit.name = 精神無人機
unit.spirit.description = The starter drone unit. Spawns in the core by default. Automatically mines ores, collects items and repairs blocks.
unit.phantom.name = Phantom Drone
unit.phantom.description = An advanced drone unit. Automatically mines ores, collects items and repairs blocks. Significantly more effective than a drone.
unit.dagger.name = Dagger
unit.dagger.description = A basic ground unit. Useful in swarms.
unit.titan.name = Titan
unit.titan.description = An advanced armored ground unit. Uses carbide as ammo. Attacks both ground and air targets.
unit.ghoul.name = Ghoul Bomber
unit.ghoul.description = A heavy carpet bomber. Uses blast compound or pyratite as ammo.
unit.wraith.name = Wraith Fighter
unit.wraith.description = A fast, hit-and-run interceptor unit.
unit.fortress.name = Fortress
unit.fortress.description = A heavy artillery ground unit.
unit.revenant.name = Revenant
unit.revenant.description = A heavy laser platform.
tutorial.begin = Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this.
tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein.
tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.
tutorial.morecopper = More copper is required.\n\nEither mine it manually, or place more drills.
tutorial.turret = Defensive structures must be built to repel the[LIGHT_GRAY] enemy[].\nBuild a duo turret near your base.
tutorial.drillturret = Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill next to the turret to supply it with mined copper.
tutorial.waves = The[LIGHT_GRAY] enemy[] approaches.\n\nDefend your core for 2 waves. Build more turrets.
tutorial.lead = More ores are available. Explore and mine[accent] lead[].\n\nDrag from your unit to the core to transfer resources.
tutorial.smelter = Copper and lead are weak metals.\nSuperior[accent] Dense Alloy[] can be created in a smelter.\n\nBuild one.
tutorial.densealloy = The smelter will now produce alloy.\nGet some.\nImprove the production if necessary.
tutorial.siliconsmelter = The core will now create a[accent] spirit drone[] for mining and repairing blocks.\n\nFactories for other units can be created with [accent] silicon.\nMake a silicon smelter.
tutorial.silicondrill = Silicon requires[accent] coal[] and[accent] sand[].\nStart by making drills.
tutorial.generator = This technology requires power.\nCreate a[accent] combustion generator[] for it.
tutorial.generatordrill = Combustion generators need fuel.\nFuel it with coal from a drill.
tutorial.node = Power requires transport.\nCreate a[accent] power node[] next to your combustion generator to transfer its power.
tutorial.nodelink = Power can be transferred through contacting power blocks and generators, or by linked power nodes.\n\nLink power by tapping the node and selecting the generator and silicon smelter.
tutorial.silicon = Silicon is being produced. Get some.\n\nImproving the production system is advised.
tutorial.daggerfactory = Construct a[accent] dagger mech factory.[]\n\nThis will be used to create attack mechs.
tutorial.router = Factories need resources to function.\nCreate a router to split conveyor resources.
tutorial.dagger = Link power nodes to the factory.\nOnce requirements are met, a mech will be created.\n\nCreate more drills, generators and conveyors as necessary.
tutorial.battle = The[LIGHT_GRAY] enemy[] has revealed their core.\nDestroy it with your unit and dagger mechs.
block.copper-wall.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.
block.copper-wall-large.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.\nSpans multiple tiles.
block.dense-alloy-wall.description = A standard defensive block.\nAdequate protection from enemies.
block.dense-alloy-wall-large.description = A standard defensive block.\nAdequate protection from enemies.\nSpans multiple tiles.
block.thorium-wall.description = A strong defensive block.\nGood protection from enemies.
block.thorium-wall-large.description = A strong defensive block.\nGood protection from enemies.\nSpans multiple tiles.
block.phase-wall.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful.
block.phase-wall-large.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful.\nSpans multiple tiles.
block.surge-wall.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.
block.surge-wall-large.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.\nSpans multiple tiles.
block.door.description = A small door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through.
block.door-large.description = A large door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through.\nSpans multiple tiles.
block.mend-projector.description = Periodically heals buildings in its vicinity.
block.overdrive-projector.description = Increases the speed of nearby buildings like drills and conveyors.
block.force-projector.description = Creates a hexagonal force field around itself, protecting buildings and units inside from damage through bullets.
block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy.
block.duo.description = A small, cheap turret.
block.arc.description = A small turret which shoots electricity in a random arc towards the enemy.
block.hail.description = A small artillery turret.
block.lancer.description = A medium-sized turret which shoots charged electricity beams.
block.wave.description = A medium-sized rapid-fire turret which shoots liquid bubbles.
block.salvo.description = A medium-sized turret which fires shots in salvos.
block.swarmer.description = A medium-sized turret which shoots burst missiles.
block.ripple.description = A large artillery turret which fires several shots simultaneously.
block.cyclone.description = A large rapid fire turret.
block.fuse.description = A large turret which shoots powerful short-range beams.
block.spectre.description = A large turret which shoots two powerful bullets at once.
block.meltdown.description = A large turret which shoots powerful long-range beams.
block.conveyor.description = Basic item transport block. Moved items forward and automatically deposits them into turrets or crafters. Rotatable.
block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors.
block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles.
block.junction.description = Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations.
block.mass-driver.description = Ultimate item transport block. Collects several items and then shoots them to another mass driver over a long range.
block.smelter.description = Burns coal for smelting copper and lead into dense alloy.
block.arc-smelter.description = Smelts copper and lead into dense alloy by using an external power source.
block.silicon-smelter.description = Reduces sand with highly pure coke in order to produce silicon.
block.plastanium-compressor.description = Produces plastanium from oil and titanium.
block.phase-weaver.description = Produces phase fabric from radioactive thorium and high amounts of sand.
block.alloy-smelter.description = Produces surge alloy from titanium, lead, silicon and copper.
block.pulverizer.description = Crushes stone into sand. Useful when there is a lack of natural sand.
block.pyratite-mixer.description = Mixes coal, lead and sand into highly flammable pyratite.
block.blast-mixer.description = Uses oil for transforming pyratite into the less flammable but more explosive blast compound.
block.cryofluidmixer.description = Combines water and titanium into cryofluid which is much more efficient for cooling.
block.solidifer.description = Cools lava to stone at a fast pace.
block.melter.description = Heats up stone to very high temperatures to obtain lava.
block.incinerator.description = Gets rid of any excess item or liquid.
block.biomattercompressor.description = Compresses biomatter in order to retrieve oil.
block.separator.description = Exposes stone to water pressure in order to obtain various minerals contained in the stone.
block.centrifuge.description = More efficient than the separator, but also more expensive to build and requires power.
block.power-node.description = Transmits power to connected nodes. Up to four power sources, sinks or nodes can be connected. The node will receive power from or supply power to any adjacent blocks.
block.power-node-large.description = Has a larger radius than the power node and connects to up to six power sources, sinks or nodes.
block.battery.description = Stores power whenever there is an abundance and provides power whenever there is a shortage, as long as there is capacity left.
block.battery-large.description = Stores much more power than a regular battery.
block.combustion-generator.description = Generates power by burning oil or flammable materials.
block.turbine-generator.description = More efficient than a combustion generator, but requires additional water.
block.thermal-generator.description = Generates a large amount of power from lava.
block.solar-panel.description = Provides a small amount of power from the sun.
block.solar-panel-large.description = Provides much better power supply than a standard solar panel, but is also much more expensive to build.
block.thorium-reactor.description = Generates huge amounts of power from highly radioactive thorium. Requires constant cooling. Will explode violently if insufficient amounts of coolant are supplied.
block.rtg-generator.description = A radioisotope thermoelectric generator which does not require cooling but provides less power than a thorium reactor.
block.unloader.description = Unloads items from a container, vault or core onto a conveyor or directly into an adjacent block. The type of item to be unloaded can be changed by tapping on the unloader.
block.container.description = Stores a small amount of items. Use it for creating buffers when there is a non-constant demand of materials. An[LIGHT_GRAY] unloader[] can be used to retrieve items from the container.
block.vault.description = Stores a large amount of items. Use it for creating buffers when there is a non-constant demand of materials. An[LIGHT_GRAY] unloader[] can be used to retrieve items from the vault.
block.mechanical-drill.description = A cheap drill. When placed on appropriate tiles, outputs items at a slow pace indefinitely.
block.pneumatic-drill.description = An improved drill which is faster and able to process harder materials by making use of air pressure.
block.laser-drill.description = Allows drilling even faster through laser technology, but requires power. Additionally, radioactive thorium can be retrieved with this drill.
block.blast-drill.description = The ultimate drill. Requires large amounts of power.
block.water-extractor.description = Extracts water from the ground. Use it when there is no lake nearby.
block.cultivator.description = Cultivates the soil with water in order to obtain biomatter.
block.oil-extractor.description = Uses large amounts of power in order to extract oil from sand. Use it when there is no direct source of oil nearby.
block.dart-ship-pad.description = Leave your current vessel and change into a basic fighter aircraft.\nUse the pad by double tapping while standing on it.
block.trident-ship-pad.description = Leave your current vessel and change into a reasonably well armored heavy bomber.\nUse the pad by double tapping while standing on it.
block.javelin-ship-pad.description = Leave your current vessel and change into a strong and fast interceptor with lightning weapons.\nUse the pad by double tapping while standing on it.
block.glaive-ship-pad.description = Leave your current vessel and change into a large, well-armored gunship.\nUse the pad by double tapping while standing on it.
block.tau-mech-pad.description = Leave your current vessel and change into a support mech which can heal friendly buildings and units.\nUse the pad by double tapping while standing on it.
block.delta-mech-pad.description = Leave your current vessel and change into a fast, lightly-armored mech made for hit-and-run attacks.\nUse the pad by double tapping while standing on it.
block.omega-mech-pad.description = Leave your current vessel and change into a bulky and well-armored mech, made for front-line assaults.\nUse the pad by double tapping while standing on it.
block.spirit-factory.description = Produces light drones which mine ore and repair blocks.
block.phantom-factory.description = Produces advanced drone units which are significantly more effective than a spirit drone.
block.wraith-factory.description = Produces fast, hit-and-run interceptor units.
block.ghoul-factory.description = Produces heavy carpet bombers.
block.dagger-factory.description = Produces basic ground units.
block.titan-factory.description = Produces advanced, armored ground units.
block.fortress-factory.description = Produces heavy artillery ground units.
block.revenant-factory.description = Produces heavy laser ground units.
block.repair-point.description = Continuously heals the closest damaged unit in its vicinity.
block.command-center.description = Allows changing friendly AI behavior. Currently, attack, retreat and patrol commands are supported.
block.conduit.description = Basic liquid transport block. Works like a conveyor, but with liquids. Best used with extractors, pumps or other conduits.
block.pulse-conduit.description = Advanced liquid transport block. Transports liquids faster and stores more than standard conduits.
block.phase-conduit.description = Advanced liquid transport block. Uses power to teleport liquids to a connected phase conduit over several tiles.
block.liquid-router.description = Accepts liquids from one direction and outputs them to up to 3 other directions equally. Can also store a certain amount of liquid. Useful for splitting the liquids from one source to multiple targets.
block.liquid-tank.description = Stores a large amount of liquids. Use it for creating buffers when there is a non-constant demand of materials or as a safeguard for cooling vital blocks.
block.liquid-junction.description = Acts as a bridge for two crossing conduits. Useful in situations with two different conduits carrying different liquids to different locations.
block.bridge-conduit.description = Advanced liquid transport block. Allows transporting liquids over up to 3 tiles of any terrain or building.
block.mechanical-pump.description = A cheap pump with slow output, but no power consumption.
block.rotary-pump.description = An advanced pump which doubles up speed by using power.
block.thermal-pump.description = The ultimate pump. Three times as fast as a mechanical pump and the only pump which is able to retrieve lava.
block.router.description = Accepts items from one direction and outputs them to up to 3 other directions equally. Useful for splitting the materials from one source to multiple targets.
block.distributor.description = An advanced router which splits items to up to 7 other directions equally.
block.bridge-conveyor.description = Advanced item transport block. Allows transporting items over up to 3 tiles of any terrain or building.
block.alpha-mech-pad.description = When given enough power, rebuilds your ship into the[accent] Alpha[] mech.
block.itemsource.description = Infinitely outputs items. Sandbox only.
block.liquidsource.description = Infinitely outputs liquids. Sandbox only.
block.itemvoid.description = Destroys any items which go into it without using power. Sandbox only.
block.powerinfinite.description = Infinitely outputs power. Sandbox only.
block.powervoid.description = Voids all power inputted into it. Sandbox only.
liquid.water.description = Commonly used for cooling machines and waste processing.
liquid.lava.description = Can be transformed into[LIGHT_GRAY] stone[], used for generating power or used as ammo for certain turrets.
liquid.oil.description = Can be burnt, exploded or used as a coolant.
liquid.cryofluid.description = The most efficient liquid for cooling things down.
unit.spirit.name = 輕型無人機
unit.spirit.description = 起始的無人機。默認在核心產生。自動挖掘礦石、收集物品和修理方塊。
unit.phantom.name = 幻影無人機
unit.phantom.description = 一種高級的無人機。自動挖掘礦石、收集物品和修理方塊。比輕型無人機明顯更有效。
unit.dagger.name = 匕首
unit.dagger.description = 一種基本的地面單位。最好一群地使用。
unit.titan.name = 泰坦
unit.titan.description = 一種高級的具有裝甲的地面單位。使用碳化物作為彈藥。攻擊地面單位和空中單位。
unit.ghoul.name = 食屍鬼轟炸機
unit.ghoul.description = 一種重型的鋪蓋性的轟炸機。使用爆炸化合物或黃鐵礦作為彈藥。
unit.wraith.name = 怨靈戰鬥機
unit.wraith.description = 一種快速、打了就跑的攔截機。
unit.fortress.name = 堡壘
unit.fortress.description = 一種具有重型大砲的地面單位。
unit.revenant.name = 亡魂
unit.revenant.description = 一種重型的激光平台。
tutorial.begin = 你的任務是毀滅[LIGHT_GRAY]敵人[]\n\n首先[accent]挖掘銅礦[]。點擊核心附近的銅脈以開始。
tutorial.drill = 手動挖掘礦石是低效率的。\n[accent]鑽頭[]能夠自動挖掘礦石。\n在銅脈上放置一個鑽頭。
tutorial.conveyor = [accent]輸送帶[]能夠將物品運輸到核心。\n製作一條從鑽頭開始到核心的輸送帶。
tutorial.morecopper = 需要更多銅。\n\n請手動挖掘銅礦或放置更多鑽頭。
tutorial.turret = 防禦建築是必須的以擊退[LIGHT_GRAY]敵人[]\n於核心附近建造一個雙炮。
tutorial.drillturret = 雙炮需要[accent]銅彈[]以射擊。\n在雙炮旁邊放置一個鑽頭以供應銅。
tutorial.waves = [LIGHT_GRAY]敵人[]來臨。\n\n防衛核心2波。建造更多的砲塔以防衛。
tutorial.lead = 有更多的礦石可用。探索和挖掘[accent][]\n\n點擊您的單位拖動到核心以傳輸資源。
tutorial.smelter = 銅和鉛是柔軟的金屬。\n優良的[accent]稠密合金[]可以在冶煉廠中生產。\n\n建造一個冶煉廠。
tutorial.densealloy = 冶煉廠現在將生產稠密合金。\n請獲取更多的稠密合金。\n必要時改善生產系統。
tutorial.siliconsmelter = 核心現在將製作一個[accent]輕型無人機[]以挖掘礦石和修理方塊。\n\n製作其他單位的工廠可以使用[accent]矽[]以建造。\n建造一個冶矽廠。
tutorial.silicondrill = 矽需要[accent]煤[]和[accent]沙[]以製作。\n放置鑽頭以開始。
tutorial.generator = 這項技術需要能量。\n建造一個[accent]燃燒發電機[]。
tutorial.generatordrill = 燃燒發電機需要燃料。\n用鑽頭挖的煤為它加燃料。
tutorial.node = 電源需要運輸。\n在燃燒發電機旁邊建造一個[accent]能量節點[]以傳遞其能量。
tutorial.nodelink = 能量可透過接觸的能量方塊和發電機,或者通過連接的能量節點傳遞。\n\n點擊能量節點並選擇發電機和冶矽廠以連接能量。
tutorial.silicon = 正在製作矽。請獲取更多的矽。\n\n建議改善生產系統。
tutorial.daggerfactory = 建造一個[accent]匕首機甲工廠[]\n\n這將製作攻擊機甲。
tutorial.router = 工廠需要資源以運作。\n建造一個分配器以均分輸送帶的資源。
tutorial.dagger = 連接能量節點至工廠。\n一旦要求滿足將製作一個機甲。\n\n根據需要建造更多鑽頭、發電機和輸送帶。發電機和輸送帶。
tutorial.battle = [LIGHT_GRAY]敵人[]透露了他們的核心。\n用你的單位和匕首機甲以摧毀它。
block.copper-wall.description = 一種便宜的防衛方塊。\n用於前幾波防衛核心和砲塔。
block.copper-wall-large.description = 一種便宜的防衛方塊。\n用於前幾波防衛核心和砲塔\n佔據多個方塊。
block.dense-alloy-wall.description = 一種標準的防衛方塊。\n充分地防衛敵人。
block.dense-alloy-wall-large.description = 一種標準的防衛方塊。\n充分地防衛敵人。\n佔據多個方塊。
block.thorium-wall.description = 一種堅強的防衛方塊。\n良好地防衛敵人。
block.thorium-wall-large.description = 一種堅強的防衛方塊。\n良好地防衛敵人。\n佔據多個方塊。
block.phase-wall.description = 沒有釷牆那麼強但會使不太強的子彈偏離。
block.phase-wall-large.description = 沒有釷牆那麼強但會使不太強的子彈偏離。\n佔據多個方塊。
block.surge-wall.description = 最強的防衛方塊。\n有小的機會對攻擊者觸發閃電。
block.surge-wall-large.description = 最強的防衛方塊。\n有小的機會對攻擊者觸發閃電。\n佔據多個方塊。
block.door.description = 可以通過點擊打開和關閉的一扇小門。\n如果打開敵人可以穿過它射擊和移動。
block.door-large.description = 可以通過點擊打開和關閉的一扇大門。\n如果打開敵人可以穿過它射擊和移動。\n佔據多個方塊。
block.mend-projector.description = 定期修復附近的建築物。
block.overdrive-projector.description = 提高附近建築物的速度,如鑽頭和輸送帶。
block.force-projector.description = 在自身周圍形成一個六角形力場,保護內部的建築物和單位免受子彈的傷害。
block.shock-mine.description = 傷害踩到地雷的敵人。敵人幾乎看不見。
block.duo.description = 一種小而便宜的砲塔。
block.arc.description = 一種向敵人射出隨機電弧的小砲塔。
block.hail.description = 一種小型火砲。
block.lancer.description = 一種射出電子束的中型砲塔。
block.wave.description = 一種可以快速射出液體氣泡的中型砲塔。
block.salvo.description = 一種齊射的中型砲塔。
block.swarmer.description = 一種射出爆炸導彈的中型砲塔。
block.ripple.description = 一種一次射出幾發子彈的大型火砲。
block.cyclone.description = 一種快速射擊的大型砲塔。
block.fuse.description = 一種射出強大的短程射線的大型砲塔。
block.spectre.description = 一種一次射出兩顆強大的子彈的大型砲塔。
block.meltdown.description = 一種射出強大的遠程光束的大型砲塔。
block.conveyor.description = 基本物品傳輸方塊。將物品向前移動並自動將它們放入砲塔或機器中。能夠旋轉方向。
block.titanium-conveyor.description = 高級物品傳輸方塊。比標準輸送帶更快地移動物品。
block.phase-conveyor.description = 高級物品傳輸方塊。使用能量將物品傳送到幾個方塊外連接的相織輸送帶。
block.junction.description = 作為兩個交叉輸送帶的橋樑。適用於兩條不同輸送帶將不同物品運送到不同位置的情況。
block.mass-driver.description = 終極物品運輸方塊。收集幾件物品,然後將它們射向另一個長距離的質量驅動器。
block.smelter.description = 燒煤以冶煉銅和鉛成稠密合金。
block.arc-smelter.description = 使用外部能量以冶煉銅和鉛成稠密合金。
block.silicon-smelter.description = 使用高純度焦炭還原沙子以生產矽。
block.plastanium-compressor.description = 使用油和鈦以生產塑料。
block.phase-weaver.description = 使用放射性的釷和大量的沙子以生產相織布。
block.alloy-smelter.description = 使用鈦、鉛、矽和銅以生產波動合金。
block.pulverizer.description = 將石頭壓成沙子。當缺少天然沙子時有用。
block.pyratite-mixer.description = 混合煤、鉛和沙子成為易燃的硫。
block.blast-mixer.description = 使用油將硫變成比較不易燃但更具爆炸性的爆炸混合器。
block.cryofluidmixer.description = 合水和鈦成冷卻效率更高的冷凍液。
block.solidifer.description = 快速冷卻熔岩至石頭。
block.melter.description = 將石頭加熱到很高的溫度以獲得熔岩。
block.incinerator.description = 清除任何多餘的物品或液體。
block.biomattercompressor.description = 壓縮生物物質以提取油。
block.separator.description = 將石頭暴露在水壓下以獲得石頭中的各種礦物質。
block.centrifuge.description = 比分離器更有效,但建造更昂貴和需要能量以操作。
block.power-node.description = 將能量傳輸到連接的節點。最多可連接四個能量來源、接收或節點。節點將從任何相鄰方塊接收能量或向其供能量。
block.power-node-large.description = 範圍大於能量節點,最多可連接六個能量來源、接收或節點。
block.battery.description = 有能量剩餘時,存儲電力並在能量短缺時提供能量。
block.battery-large.description = 比普通電池存儲更多的能量。
block.combustion-generator.description = 透過燃燒油或可燃物品以產生能量。
block.turbine-generator.description = 比燃燒發電機更有效,但需要水以操作。
block.thermal-generator.description = 使用熔岩產生大量的能量。
block.solar-panel.description = 透過太陽產生少量的能量。
block.solar-panel-large.description = 比標準太陽能板產生更多的能量,但建造起來昂貴得多。
block.thorium-reactor.description = 從高度放射性釷產生大量能量。需要持續冷卻。如果供應的冷卻劑不足,會劇烈爆炸。
block.rtg-generator.description = 一種放射性同位素熱發電機,不需要冷卻,但比釷反應堆產生的能量少。
block.unloader.description = 將物品從容器、存儲庫或核心卸載到傳輸帶上或直接卸載到相鄰的方塊中。透過點擊卸載器來更改要卸載的物品類型。
block.container.description = 存儲少量物品。當物品需求非恆定時,使用它來創建緩衝。使用[LIGHT_GRAY]裝卸器[]以從容器提取物品。
block.vault.description = 存儲大量物品。當物品需求非恆定時,使用它來創建緩衝。使用[LIGHT_GRAY]裝卸器[]以從存儲庫提取物品。
block.mechanical-drill.description = 一種便宜的鑽頭。當放置在適當的方塊上時,以緩慢的速度無限期地輸出物品。
block.pneumatic-drill.description = 一種改進的鑽頭。它挖掘更快,能夠利用氣壓挖掘更硬的材料。
block.laser-drill.description = 通過激光技術可以更快地挖掘,但需要能量。此外,這種鑽頭可以挖掘放射性釷。
block.blast-drill.description = 終極的鑽頭。需要大量能量。
block.water-extractor.description = 從地下提取水。當附近沒有湖泊時使用它。
block.cultivator.description = 用水培養土壤以獲得生物物質。
block.oil-extractor.description = 使用大量的能量從沙子中提取油。當附近沒有直接的石油來源時使用它。
block.dart-ship-pad.description = 離開現有的船隻,換成基本的戰鬥機。\n站在上面雙擊墊以使用它。
block.trident-ship-pad.description = 離開現在的船隻,換成具有相當不錯裝甲的重型轟炸機。\n站在上面雙擊墊以使用它。
block.javelin-ship-pad.description = 離開現在的船隻,換成具有閃電武器、強大而快速的攔截器。\n站在上面雙擊墊以使用它。
block.glaive-ship-pad.description = 離開現在的船隻,換成具有重裝甲的武裝直升機。\n站在上面雙擊墊以使用它。
block.tau-mech-pad.description = 離開現有的船隻,換成可以治愈友好的建築物和單位的支援機甲。\n站在上面雙擊墊以使用它。
block.delta-mech-pad.description = 離開現在的船隻,換成快速、具有輕裝甲的機甲,用於打了就跑的攻擊。\n站在上面雙擊墊以使用它。
block.omega-mech-pad.description = 離開現在的船隻,換成龐大、具有重裝甲的機甲,用於前線攻擊。\n站在上面雙擊墊以使用它。
block.spirit-factory.description = 生產輕型無人機,用於開採礦石和修復方塊。
block.phantom-factory.description = 生產高級的無人機,比輕型無人機明顯更有效。
block.wraith-factory.description = 生產快速、打了就跑的攔截機單位。
block.ghoul-factory.description = 生產重型鋪蓋轟炸機。
block.dagger-factory.description = 產生基本地面單位。
block.titan-factory.description = 生產具有裝甲的高級地面單位。
block.fortress-factory.description = 生產重型火砲地面單位。
block.revenant-factory.description = 生產重型激光地面單位。
block.repair-point.description = 持續治療附近最近的受損單位。
block.command-center.description = 允許更改友好的AI行為。目前支持攻擊、撤退和巡邏命令。
block.conduit.description = 基本液體運輸方塊。像輸送帶一樣工作,但是液體用的。最適用於提取器、泵或其他管線。
block.pulse-conduit.description = 高級的液體運輸方塊。比標準管線更快地輸送並儲存更多液體。
block.phase-conduit.description = 高級的液體運輸方塊。使用能量將液體傳送到多個方塊外連接的相織管線。
block.liquid-router.description = 接受來自一個方向的液體並將它們平均輸出到最多3個其他方向。可以儲存一定量的液體。用於將液體從一個來源分成多個目標。
block.liquid-tank.description = 存儲大量液體。當液體需求非恆定時,使用它來創建緩衝或作為冷卻重要方塊的保障。
block.liquid-junction.description = 作為兩個交叉管線的橋樑。適用於兩條不同管線將不同液體運送到不同位置的情況。
block.bridge-conduit.description = 高級的液體運輸方塊。允許跨過最多3個任何地形或建築物的方塊運輸液體。
block.mechanical-pump.description = 一種便宜的泵,輸出速度慢,但不使用能量。
block.rotary-pump.description = 高級的泵,透過使用能量使輸出速度加倍。
block.thermal-pump.description = 終極泵。輸出速度是機械泵的三倍並且是唯一能夠抽熔岩的泵。
block.router.description = 接受來自一個方向的物品並將它們平均輸出到最多3個其他方向。 用於將物品從一個來源分割為多個目標。
block.distributor.description = 高級的分配器可將物品均分到最多7個其他方向。
block.bridge-conveyor.description = 高級的物品運輸方塊。允許跨過最多3個任何地形或建築物的方塊運輸物品。
block.alpha-mech-pad.description = 當給予足夠能量時,將你的船重建為[accent]阿爾法[]機甲。
block.itemsource.description = 不限地輸出物品。僅限沙盒。
block.liquidsource.description = 不限地輸出液體。僅限沙盒。
block.itemvoid.description = 不使用能量銷毀任何進入它的物品。僅限沙盒。
block.powerinfinite.description = 不限地輸出能量。僅限沙盒。
block.powervoid.description = 銷毀所有輸入的能量。僅限沙盒。
liquid.water.description = 常用於冷卻機器和廢物處理。
liquid.lava.description = 可以轉換為[LIGHT_GRAY]石頭[]、用於發電或用作某些砲塔的彈藥。
liquid.oil.description = 可以燃燒、爆炸或用作冷卻劑。
liquid.cryofluid.description = 冷卻東西最有效的液體。

View File

@@ -26,7 +26,7 @@ TextButtonStyle: {
default: {over: button-over, disabled: button, font: default-font, fontColor: white, disabledFontColor: gray, down: button-down, up: button},
right: {over: button-right-over, font: default-font, fontColor: white, disabledFontColor: gray, down: button-right-down, up: button-right},
wave: {font: default-font, fontColor: white, disabledFontColor: gray, up: button-edge-4},
clear: {over: flat-over, font: default-font, fontColor: white, disabledFontColor: gray, down: pane, up: flat},
clear: {over: flat-over, font: default-font, fontColor: white, disabledFontColor: gray, down: flat-over, up: flat},
discord: {font: default-font, fontColor: white, up: discord-banner},
info: {font: default-font, fontColor: white, up: info-banner},
clear-partial: {down: white, up: button-select, over: flat-down, font: default-font, fontColor: white, disabledFontColor: gray },

View File

@@ -1,4 +1,8 @@
apply plugin: "java"
sourceCompatibility = 1.8
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
sourceSets.main.java.srcDirs = ["src/"]
sourceSets.main.java.srcDirs = ["src/"]
compileJava{
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}

View File

@@ -45,10 +45,9 @@ public class Recipes implements ContentList{
new Recipe(effect, StorageBlocks.container, new ItemStack(Items.densealloy, 200));
new Recipe(effect, StorageBlocks.vault, new ItemStack(Items.densealloy, 500), new ItemStack(Items.thorium, 250));
//core disabled due to being broken
new Recipe(effect, StorageBlocks.core,
new ItemStack(Items.copper, 2000), new ItemStack(Items.densealloy, 1500),
new ItemStack(Items.silicon, 1500), new ItemStack(Items.thorium, 500),
new ItemStack(Items.copper, 2000), new ItemStack(Items.densealloy, 2000),
new ItemStack(Items.silicon, 1750), new ItemStack(Items.thorium, 1000),
new ItemStack(Items.surgealloy, 500), new ItemStack(Items.phasefabric, 750)
);

View File

@@ -16,7 +16,8 @@ import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
public class Blocks extends BlockList implements ContentList{
public static Block air, blockpart, spawn, space, metalfloor, deepwater, water, lava, tar, stone, blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock;
public static Block air, blockpart, spawn, space, metalfloor, deepwater, water, lava, tar, stone,
blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock;
@Override
@@ -90,6 +91,7 @@ public class Blocks extends BlockList implements ContentList{
}};
lava = new Floor("lava"){{
drownTime = 100f;
liquidColor = Color.valueOf("ed5334");
speedMultiplier = 0.2f;
damageTaken = 0.5f;
@@ -103,6 +105,7 @@ public class Blocks extends BlockList implements ContentList{
}};
tar = new Floor("tar"){{
drownTime = 150f;
liquidColor = Color.valueOf("292929");
status = StatusEffects.tarred;
statusIntensity = 1f;

View File

@@ -1,10 +1,7 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
@@ -42,17 +39,13 @@ import static io.anuke.mindustry.Vars.*;
* This class is not created in the headless server.
*/
public class Control extends Module{
/** Minimum period of time between the same sound being played.*/
private static final long minSoundPeriod = 100;
public final Saves saves;
public final Unlocks unlocks;
private Timer timerRPC= new Timer(), timerUnlock = new Timer();
private Timer timerRPC = new Timer(), timerUnlock = new Timer();
private boolean hiscore = false;
private boolean wasPaused = false;
private InputHandler[] inputs = {};
private ObjectMap<Sound, Long> soundMap = new ObjectMap<>();
private Throwable error;
public Control(){
@@ -72,17 +65,6 @@ public class Control extends Module{
unlocks.load();
Sounds.setFalloff(9000f);
Sounds.setPlayer((sound, volume) -> {
long time = TimeUtils.millis();
long value = soundMap.get(sound, 0L);
if(TimeUtils.timeSinceMillis(value) >= minSoundPeriod){
threads.runGraphics(() -> sound.play(volume));
soundMap.put(sound, time);
}
});
DefaultKeybinds.load();
Settings.defaultList(

View File

@@ -40,7 +40,6 @@ import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import static io.anuke.mindustry.Vars.*;
@@ -96,26 +95,24 @@ public class MapEditorDialog extends Dialog implements Disposable{
t.addImageTextButton("$text.editor.import", "icon-load-map", isize, () ->
createDialog("$text.editor.import",
"$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Runnable) loadDialog::show,
"$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Runnable) () -> {
Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> {
ui.loadGraphics(() -> {
try{
DataInputStream stream = new DataInputStream(file.read());
"$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Runnable) () ->
Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> ui.loadGraphics(() -> {
try{
DataInputStream stream = new DataInputStream(file.read());
MapMeta meta = MapIO.readMapMeta(stream);
MapTileData data = MapIO.readTileData(stream, meta, false);
MapMeta meta = MapIO.readMapMeta(stream);
MapTileData data = MapIO.readTileData(stream, meta, false);
editor.beginEdit(data, meta.tags, false);
view.clearStack();
}catch(Exception e){
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e);
}
});
}, true, mapExtension);
},
"$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Runnable)() -> {
Platform.instance.showFileChooser("$text.loadimage", "Image Files", file -> {
editor.beginEdit(data, meta.tags, false);
view.clearStack();
}catch(Exception e){
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e);
}
}), true, mapExtension),
"$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Runnable)() ->
Platform.instance.showFileChooser("$text.loadimage", "Image Files", file ->
ui.loadGraphics(() -> {
try{
MapTileData data = MapIO.readLegacyPixmap(new Pixmap(file));
@@ -126,12 +123,11 @@ public class MapEditorDialog extends Dialog implements Disposable{
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e);
}
});
}, true, "png");
}));
}), true, "png")
));
t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export",
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Runnable) () -> {
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Runnable) () ->
Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> {
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
FileHandle result = file;
@@ -147,8 +143,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
Log.err(e);
}
});
}, false, mapExtension);
}));
}, false, mapExtension)));
t.row();
@@ -171,8 +166,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
});
loadDialog = new MapLoadDialog(map -> {
loadDialog = new MapLoadDialog(map ->
ui.loadGraphics(() -> {
try(DataInputStream stream = new DataInputStream(map.stream.get())){
MapMeta meta = MapIO.readMapMeta(stream);
@@ -180,12 +174,11 @@ public class MapEditorDialog extends Dialog implements Disposable{
editor.beginEdit(data, meta.tags, false);
view.clearStack();
}catch(IOException e){
}catch(Exception e){
ui.showError(Bundles.format("text.editor.errormapload", Strings.parseException(e, false)));
Log.err(e);
}
});
});
}));
setFillParent(true);
@@ -261,7 +254,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
* 2) icon name
* 3) listener
*/
private FloatingDialog createDialog(String title, Object... arguments){
private void createDialog(String title, Object... arguments){
FloatingDialog dialog = new FloatingDialog(title);
float h = 90f;
@@ -278,18 +271,15 @@ public class MapEditorDialog extends Dialog implements Disposable{
listenable.run();
dialog.hide();
menu.hide();
}).left().get();
}).left().margin(0).get();
button.clearChildren();
button.table("button", t -> {
t.addImage(iconname).size(16 * 3);
t.update(() -> t.background(button.getClickListener().isOver() ? "button-over" : "button"));
}).padLeft(-10).padBottom(-3).size(h);
button.addImage(iconname).size(16 * 3).padLeft(10);
button.table(t -> {
t.add(name).growX().wrap();
t.row();
t.add(description).color(Color.GRAY).growX().wrap();
}).growX().padLeft(8);
}).growX().pad(10f).padLeft(5);
button.row();
@@ -298,8 +288,6 @@ public class MapEditorDialog extends Dialog implements Disposable{
dialog.addCloseButton();
dialog.show();
return dialog;
}
@Override
@@ -562,9 +550,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
ImageButton button = new ImageButton("white", "clear-toggle");
button.clicked(() -> editor.setDrawBlock(block));
button.resizeImage(8 * 4f);
button.getImageCell().setActor(stack);
button.addChild(stack);
button.getImage().remove();
button.replaceImage(stack);
button.update(() -> button.setChecked(editor.getDrawBlock() == block));
group.add(button);
content.add(button).size(50f);

View File

@@ -283,9 +283,9 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
@Override
public void drawShadow(float offsetX, float offsetY){
float x = snappedX(), y = snappedY();
float scl = mech.flying ? 1f : boostHeat/2f;
float scl = mech.flying ? 1f : boostHeat / 2f;
Draw.rect(mech.iconRegion, x + offsetX*scl, y + offsetY*scl, rotation - 90);
Draw.rect(mech.iconRegion, x + offsetX * scl, y + offsetY * scl, rotation - 90);
}
@Override
@@ -317,9 +317,9 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
for(int i : Mathf.signs){
Draw.rect(mech.legRegion,
x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
y + Angles.trnsy(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
mech.legRegion.getRegionWidth() * i, mech.legRegion.getRegionHeight() - Mathf.clamp(ft * i, 0, 2), baseRotation - 90 + boostAng * i);
x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
y + Angles.trnsy(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
mech.legRegion.getRegionWidth() * i, mech.legRegion.getRegionHeight() - Mathf.clamp(ft * i, 0, 2), baseRotation - 90 + boostAng * i);
}
Draw.rect(mech.baseRegion, x, y, baseRotation - 90);
@@ -339,8 +339,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float tra = rotation - 90, trY = -mech.weapon.getRecoil(this, i > 0) + mech.weaponOffsetY;
float w = i > 0 ? -mech.weapon.equipRegion.getRegionWidth() : mech.weapon.equipRegion.getRegionWidth();
Draw.rect(mech.weapon.equipRegion,
x + Angles.trnsx(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY),
y + Angles.trnsy(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY), w, mech.weapon.equipRegion.getRegionHeight(), rotation - 90);
x + Angles.trnsx(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY),
y + Angles.trnsy(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY), w, mech.weapon.equipRegion.getRegionHeight(), rotation - 90);
}
float backTrns = 4f, itemSize = 5f;
@@ -352,9 +352,9 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 1, 60f);
float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 1f) - 1f;
Draw.rect(stack.item.region,
x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT),
y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT),
itemSize, itemSize, rotation);
x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT),
y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT),
itemSize, itemSize, rotation);
}
}
@@ -365,7 +365,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
public void drawStats(){
float x = snappedX(), y = snappedY();
Draw.color(Color.BLACK, team.color, healthf() + Mathf.absin(Timers.time(), healthf()*5f, 1f - healthf()));
Draw.color(Color.BLACK, team.color, healthf() + Mathf.absin(Timers.time(), healthf() * 5f, 1f - healthf()));
Draw.alpha(hitTime / hitDuration);
Draw.rect(getPowerCellRegion(), x + Angles.trnsx(rotation, mech.cellTrnsY, 0f), y + Angles.trnsy(rotation, mech.cellTrnsY, 0f), rotation - 90);
Draw.color();
@@ -380,7 +380,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
if(mech.flying || boostHeat > 0.001f){
float wobblyness = 0.6f;
if(!state.isPaused()) trail.update(x + Angles.trnsx(rotation + 180f, 5f) + Mathf.range(wobblyness),
y + Angles.trnsy(rotation + 180f, 5f) + Mathf.range(wobblyness));
y + Angles.trnsy(rotation + 180f, 5f) + Mathf.range(wobblyness));
trail.draw(Hue.mix(mech.trailColor, mech.trailColorTo, mech.flying ? 0f : boostHeat, Tmp.c1), 5f * (isFlying() ? 1f : boostHeat));
}else{
trail.clear();
@@ -422,7 +422,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
Core.font.setUseIntegerPositions(ints);
}
/**Draw all current build requests. Does not draw the beam effect, only the positions.*/
/** Draw all current build requests. Does not draw the beam effect, only the positions. */
public void drawBuildRequests(){
for(BuildRequest request : getPlaceQueue()){
if(getCurrentRequest() == request) continue;
@@ -438,16 +438,16 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1;
Lines.square(
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset() - 1,
rad);
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset() - 1,
rad);
Draw.color(Palette.remove);
Lines.square(
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset(),
rad);
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset(),
rad);
}else{
//draw place request
Lines.stroke(2f);
@@ -457,16 +457,16 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f;
Lines.square(
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset() - 1,
rad);
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset() - 1,
rad);
Draw.color(Palette.accent);
Lines.square(
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset(),
rad);
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset(),
rad);
}
}
@@ -601,9 +601,10 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float xa = Inputs.getAxis(section, "move_x");
float ya = Inputs.getAxis(section, "move_y");
movement.y += ya * speed;
movement.x += xa * speed;
if(!Inputs.keyDown("gridMode")){
movement.y += ya * speed;
movement.x += xa * speed;
}
Vector2 vec = Graphics.world(control.input(playerIndex).getMouseX(), control.input(playerIndex).getMouseY());
pointerX = vec.x;
@@ -695,8 +696,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
getHitbox(rect);
rect.x -= expansion;
rect.y -= expansion;
rect.width += expansion*2f;
rect.height += expansion*2f;
rect.width += expansion * 2f;
rect.height += expansion * 2f;
isBoosting = EntityQuery.collisions().overlapsTile(rect) || distanceTo(targetX, targetY) > 85f;
@@ -733,7 +734,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
if(target != null && distanceTo(target) > getWeapon().getAmmo().getRange()){
target = null;
}else if(target != null){
target = ((Tile)target).entity;
target = ((Tile) target).entity;
}
}
@@ -742,14 +743,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
}
}else if(target.isValid() || (target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team &&
mech.canHeal && distanceTo(target) < getWeapon().getAmmo().getRange())){
mech.canHeal && distanceTo(target) < getWeapon().getAmmo().getRange())){
//rotate toward and shoot the target
if(mech.turnCursor){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
}
Vector2 intercept =
Predict.intercept(x, y, target.getX(), target.getY(), target.getVelocity().x - velocity.x, target.getVelocity().y - velocity.y, getWeapon().getAmmo().bullet.speed);
Predict.intercept(x, y, target.getX(), target.getY(), target.getVelocity().x - velocity.x, target.getVelocity().y - velocity.y, getWeapon().getAmmo().bullet.speed);
pointerX = intercept.x;
pointerY = intercept.y;
@@ -760,7 +761,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}else if(isShooting()){
Vector2 vec = Graphics.world(control.input(playerIndex).getMouseX(),
control.input(playerIndex).getMouseY());
control.input(playerIndex).getMouseY());
pointerX = vec.x;
pointerY = vec.y;
@@ -773,7 +774,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
//region utility methods
/** Resets all values of the player.*/
/** Resets all values of the player. */
public void reset(){
resetNoAdd();
@@ -787,6 +788,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
placeQueue.clear();
dead = true;
trail.clear();
target = null;
moveTarget = null;
carrier = null;
health = maxHealth();
boostHeat = drownTime = hitTime = 0f;

View File

@@ -2,6 +2,7 @@ package io.anuke.mindustry.entities.traits;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Queue;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.blocks.Blocks;
@@ -29,9 +30,7 @@ import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Shapes;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
import java.io.DataInput;
import java.io.DataOutput;
@@ -47,6 +46,7 @@ public interface BuilderTrait extends Entity{
//these are not instance variables!
float placeDistance = 150f;
float mineDistance = 70f;
Array<BuildRequest> removal = new Array<>();
/**Returns the queue for storing build requests.*/
Queue<BuildRequest> getPlaceQueue();
@@ -171,6 +171,23 @@ public interface BuilderTrait extends Entity{
* This includes mining.
*/
default void updateBuilding(Unit unit){
//remove already completed build requests
removal.clear();
for(BuildRequest req : getPlaceQueue()){
removal.add(req);
}
getPlaceQueue().clear();
for(BuildRequest request : removal){
if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
(!request.breaking &&
(world.tile(request.x, request.y).getRotation() == request.rotation || !request.recipe.result.rotate)
&& world.tile(request.x, request.y).block() == request.recipe.result))){
getPlaceQueue().addLast(request);
}
}
BuildRequest current = getCurrentRequest();
//update mining here
@@ -373,5 +390,18 @@ public interface BuilderTrait extends Entity{
this.recipe = Recipe.getByResult(world.tile(x, y).block());
this.breaking = true;
}
@Override
public String toString(){
return "BuildRequest{" +
"x=" + x +
", y=" + y +
", rotation=" + rotation +
", recipe=" + recipe +
", breaking=" + breaking +
", progress=" + progress +
", initialized=" + initialized +
'}';
}
}
}

View File

@@ -76,7 +76,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
Effects.effect(ExplosionFx.explosion, unit);
Effects.shake(2f, 2f, unit);
//must run afterwards so the unit's group is not null
//must run afterwards so the unit's group is not null when sending the removal packet
threads.runDelay(unit::remove);
}

View File

@@ -22,8 +22,7 @@ import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.headless;
import static io.anuke.mindustry.Vars.players;
import static io.anuke.mindustry.Vars.*;
public class AlphaDrone extends FlyingUnit {
static final float followDistance = 80f;
@@ -62,7 +61,7 @@ public class AlphaDrone extends FlyingUnit {
}
}
if(!leader.isShooting && distanceTo(leader) < 8f){
if(!leader.isShooting && distanceTo(leader) < 7f){
Call.onAlphaDroneFade(AlphaDrone.this);
}
}
@@ -71,8 +70,9 @@ public class AlphaDrone extends FlyingUnit {
@Remote(called = Loc.server)
public static void onAlphaDroneFade(BaseUnit drone){
if(drone == null) return;
drone.remove();
Effects.effect(UnitFx.pickup, drone);
//must run afterwards so the unit's group is not null when sending the removal packet
threads.runDelay(drone::remove);
}
@Override

View File

@@ -352,7 +352,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
@Override
public boolean canCreateBlocks(){
return false;
return true;
}
@Override

View File

@@ -17,6 +17,8 @@ import io.anuke.ucore.util.Strings;
import io.anuke.ucore.util.ThreadArray;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static io.anuke.mindustry.Vars.*;
@@ -186,8 +188,12 @@ public class Saves{
return Strings.formatMillis(current == this ? totalPlaytime : meta.timePlayed);
}
public long getTimestamp(){
return meta.timestamp;
}
public String getDate(){
return meta.date;
return SimpleDateFormat.getDateTimeInstance().format(new Date(meta.timestamp));
}
public Map getMap(){

View File

@@ -65,6 +65,7 @@ public class Unlocks{
save();
}
@SuppressWarnings("unchecked")
public void load(){
unlocked = Settings.getObject("unlockset", ObjectMap.class, ObjectMap::new);
}

View File

@@ -25,6 +25,8 @@ public class DefaultKeybinds{
"rotate", new Axis(Input.SCROLL),
"dash", Input.SHIFT_LEFT,
"drop_unit", Input.SHIFT_LEFT,
"gridMode", Input.CONTROL_LEFT,
"gridModeShift", Input.SHIFT_LEFT,
new Category("view"),
"zoom_hold", Input.CONTROL_LEFT,
"zoom", new Axis(Input.SCROLL),

View File

@@ -215,10 +215,10 @@ public class DesktopInput extends InputHandler{
}else if(selected != null){
//only begin shooting if there's no cursor event
if (!tileTapped(selected) && !tryTapPlayer(Graphics.mouseWorld().x, Graphics.mouseWorld().y) && player.getPlaceQueue().size == 0 && !droppingItem &&
!tryBeginMine(selected) && player.getMineTile() == null) {
!tryBeginMine(selected) && player.getMineTile() == null && !ui.chatfrag.chatOpen()) {
player.isShooting = true;
}
}else{ //if it's out of bounds, shooting is just fine
}else if(!ui.chatfrag.chatOpen()){ //if it's out of bounds, shooting is just fine
player.isShooting = true;
}
}else if(Inputs.keyTap(section, "deselect") && (recipe != null || mode != none || player.isBuilding()) &&

View File

@@ -14,7 +14,7 @@ import java.util.zip.InflaterInputStream;
import static io.anuke.mindustry.Vars.*;
public class SaveIO{
public static final IntArray breakingVersions = IntArray.with(47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58);
public static final IntArray breakingVersions = IntArray.with(47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 63);
public static final IntMap<SaveFileVersion> versions = new IntMap<>();
public static final Array<SaveFileVersion> versionArray = Array.with(
new Save16()

View File

@@ -4,15 +4,12 @@ import io.anuke.mindustry.game.Difficulty;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.maps.Map;
import java.text.SimpleDateFormat;
import java.util.Date;
import static io.anuke.mindustry.Vars.world;
public class SaveMeta{
public int version;
public int build;
public String date;
public long timestamp;
public long timePlayed;
public int sector;
public GameMode mode;
@@ -20,10 +17,10 @@ public class SaveMeta{
public int wave;
public Difficulty difficulty;
public SaveMeta(int version, long date, long timePlayed, int build, int sector, int mode, String map, int wave, Difficulty difficulty){
public SaveMeta(int version, long timestamp, long timePlayed, int build, int sector, int mode, String map, int wave, Difficulty difficulty){
this.version = version;
this.build = build;
this.date = SimpleDateFormat.getDateTimeInstance().format(new Date(date));
this.timestamp = timestamp;
this.timePlayed = timePlayed;
this.sector = sector;
this.mode = GameMode.values()[mode];

View File

@@ -86,6 +86,10 @@ public class Sectors{
return grid.get(Bits.getLeftShort(position), Bits.getRightShort(position));
}
public Iterable<Sector> getSectors(){
return grid.values();
}
public Difficulty getDifficulty(Sector sector){
if(sector.difficulty == 0){
return Difficulty.hard;
@@ -150,6 +154,7 @@ public class Sectors{
save();
}
@SuppressWarnings("unchecked")
public void load(){
for(Sector sector : grid.values()){
sector.texture.dispose();

View File

@@ -261,6 +261,7 @@ public class Administration{
Settings.save();
}
@SuppressWarnings("unchecked")
private void load(){
playerInfo = Settings.getObject("player-info", ObjectMap.class, ObjectMap::new);
bannedIPs = Settings.getObject("banned-ips", Array.class, Array::new);

View File

@@ -25,11 +25,11 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
@SuppressWarnings("unchecked")
public class Net{
private static boolean server;
private static boolean active;
private static boolean clientLoaded;
private static String lastIP;
private static Array<Object> packetQueue = new Array<>();
private static ObjectMap<Class<?>, Consumer> clientListeners = new ObjectMap<>();
private static ObjectMap<Class<?>, BiConsumer<Integer, Object>> serverListeners = new ObjectMap<>();
@@ -106,7 +106,6 @@ public class Net{
*/
public static void connect(String ip, int port, Runnable success){
try{
lastIP = ip + ":" + port;
if(!active){
clientProvider.connect(ip, port, success);
active = true;
@@ -119,11 +118,6 @@ public class Net{
}
}
/**Returns the last IP connected to.*/
public static String getLastIP() {
return lastIP;
}
/**
* Host a server at an address.
*/

View File

@@ -11,7 +11,7 @@ public class ItemImage extends Stack{
public ItemImage(TextureRegion region, Supplier<CharSequence> text){
Table t = new Table().left().bottom();
t.label(text);
t.label(text).name("item-label");
add(new Image(region));
add(t);
@@ -22,7 +22,7 @@ public class ItemImage extends Stack{
if(stack.amount != 0){
Table t = new Table().left().bottom();
t.add(stack.amount + "");
t.add(stack.amount + "").name("item-label");
add(t);
}
}

View File

@@ -12,21 +12,15 @@ public class MenuButton extends TextButton{
public MenuButton(String icon, String text, String description, Runnable clicked){
super("default");
float s = 66f;
clicked(clicked);
clearChildren();
margin(0);
table(t -> {
t.addImage(icon).size(14 * 3);
t.update(() -> t.setBackground(getClickListener().isVisualPressed() ? "button-down" : getClickListener().isOver() ? "button-over" : "button"));
}).size(s - 5, s);
t.addImage(icon).size(14 * 3).padLeft(6);
table(t -> {
t.add(text).wrap().growX().get().setAlignment(Align.center, Align.left);
if(description != null){
t.row();

View File

@@ -9,20 +9,16 @@ import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.Element;
import io.anuke.ucore.scene.event.InputEvent;
import io.anuke.ucore.scene.event.InputListener;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Container;
import static io.anuke.mindustry.Vars.*;
public class Minimap extends Table{
public class Minimap extends Container<Element>{
public Minimap(){
super("pane");
super(new Element(){
TextureRegion r = new TextureRegion();
margin(5);
TextureRegion r = new TextureRegion();
Element elem = new Element(){
@Override
public void draw(){
if(renderer.minimap.getRegion() == null) return;
@@ -57,7 +53,12 @@ public class Minimap extends Table{
renderer.fog.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
}
}
};
});
background("pane");
size(140f);
margin(5f);
addListener(new InputListener(){
public boolean scrolled(InputEvent event, float x, float y, int amount){
@@ -66,7 +67,7 @@ public class Minimap extends Table{
}
});
elem.update(() -> {
update(() -> {
Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true);
if(e != null && e.isDescendantOf(this)){
@@ -75,7 +76,5 @@ public class Minimap extends Table{
Core.scene.setScrollFocus(null);
}
});
add(elem).size(140f, 140f);
}
}

View File

@@ -279,9 +279,7 @@ public class JoinDialog extends FloatingDialog{
button.left();
button.row();
button.add("[lightgray]" + (host.players != 1 ? Bundles.format("text.players", host.players) :
Bundles.format("text.players.single", host.players)));
button.row();
button.add("[lightgray]" + host.address).pad(4).left();
Bundles.format("text.players.single", host.players))).padBottom(5);
}
void connect(String ip, int port){
@@ -310,6 +308,7 @@ public class JoinDialog extends FloatingDialog{
return UIUtils.portrait() ? 350f : 500f;
}
@SuppressWarnings("unchecked")
private void loadServers(){
servers = Settings.getObject("server-list", Array.class, Array::new);
}

View File

@@ -159,6 +159,26 @@ public class SectorsDialog extends FloatingDialog{
});
clicked(() -> clicked = true);
this.focus();
}
private void focus(){
Sector focusSector = null;
long newestTimestamp = 0;
for(Sector sector : world.sectors.getSectors()){
if(sector.hasSave()){
long timestamp = sector.getSave().getTimestamp();
if(timestamp > newestTimestamp){
focusSector = sector;
newestTimestamp = timestamp;
}
}
}
if(focusSector != null) {
panX = (focusSector.x + 0.5f) * sectorSize;
panY = (focusSector.y + 0.5f) * sectorSize;
}
}
@Override

View File

@@ -109,7 +109,7 @@ public class HudFragment extends Fragment{
}
cont.update(() -> {
if(Inputs.keyTap("toggle_menus") && !ui.chatfrag.chatOpen()){
if(!Inputs.keyDown("gridMode") && Inputs.keyTap("toggle_menus") && !ui.chatfrag.chatOpen()){
toggleMenus();
}
});
@@ -139,7 +139,7 @@ public class HudFragment extends Fragment{
if(Net.hasClient()){
t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2);
}
}).size(-1).visible(() -> Settings.getBool("fps")).update(t -> t.setTranslation(0, (!waves.isVisible() ? wavetable.getHeight() : Math.min(wavetable.getTranslation().y, wavetable.getHeight())) )).get();
}).size(-1).visible(() -> Settings.getBool("fps")).update(t -> t.setTranslation(0, (!waves.isVisible() ? wavetable.getHeight() : Math.min(wavetable.getTranslation().y, wavetable.getHeight())))).get();
//make wave box appear below rest of menu
if(mobile){
@@ -149,7 +149,7 @@ public class HudFragment extends Fragment{
//minimap
parent.fill(t -> t.top().right().add(new Minimap())
.visible(() -> !state.is(State.menu) && Settings.getBool("minimap")));
.visible(() -> !state.is(State.menu) && Settings.getBool("minimap")));
//paused table
parent.fill(t -> {
@@ -198,7 +198,7 @@ public class HudFragment extends Fragment{
return coreAttackOpacity > 0;
});
t.table("button", top -> top.add("$text.coreattack").pad(2)
.update(label -> label.setColor(Hue.mix(Color.ORANGE, Color.SCARLET, Mathf.absin(Timers.time(), 2f, 1f)))));
.update(label -> label.setColor(Hue.mix(Color.ORANGE, Color.SCARLET, Mathf.absin(Timers.time(), 2f, 1f)))));
});
//'saving' indicator
@@ -218,7 +218,7 @@ public class HudFragment extends Fragment{
}
});
table.margin(12);
table.addImage("icon-check").size(16*2).pad(3);
table.addImage("icon-check").size(16 * 2).pad(3);
table.add(text).wrap().width(280f).get().setAlignment(Align.center, Align.center);
table.pack();
@@ -231,7 +231,7 @@ public class HudFragment extends Fragment{
Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.removeActor())));
}
/**Show unlock notification for a new recipe.*/
/** Show unlock notification for a new recipe. */
public void showUnlock(Recipe recipe){
//if there's currently no unlock notification...
@@ -268,11 +268,11 @@ public class HudFragment extends Fragment{
container.top().add(table);
container.setTranslation(0, table.getPrefHeight());
container.actions(Actions.translateBy(0, -table.getPrefHeight(), 1f, Interpolation.fade), Actions.delay(4f),
//nesting actions() calls is necessary so the right prefHeight() is used
Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.run(() -> {
lastUnlockTable = null;
lastUnlockLayout = null;
}), Actions.removeActor())));
//nesting actions() calls is necessary so the right prefHeight() is used
Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.run(() -> {
lastUnlockTable = null;
lastUnlockLayout = null;
}), Actions.removeActor())));
lastUnlockTable = container;
lastUnlockLayout = in;

View File

@@ -3,6 +3,7 @@ package io.anuke.mindustry.ui.fragments;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.game.EventType.WorldLoadGraphicsEvent;
@@ -17,6 +18,8 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.OreBlock;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.input.Input;
import io.anuke.ucore.scene.Group;
import io.anuke.ucore.scene.actions.Actions;
import io.anuke.ucore.scene.event.Touchable;
@@ -38,6 +41,19 @@ public class PlacementFragment extends Fragment{
boolean shown = true;
boolean lastGround;
//TODO make this configurable
final Input[] inputGrid = {
Input.NUM_1, Input.NUM_2, Input.NUM_3, Input.NUM_4,
Input.Q, Input.W, Input.E, Input.R,
Input.A, Input.S, Input.D, Input.F,
Input.Z, Input.X, Input.C, Input.V
}, inputCatGrid = {
Input.NUM_1, Input.NUM_2,
Input.Q, Input.W,
Input.A, Input.S,
Input.Z, Input.X, Input.C, Input.V
};
public PlacementFragment(){
Events.on(WorldLoadGraphicsEvent.class, event -> {
currentCategory = Category.turret;
@@ -47,6 +63,42 @@ public class PlacementFragment extends Fragment{
});
}
boolean gridUpdate(InputHandler input){
if(!Inputs.keyDown("gridMode") || ui.chatfrag.chatOpen()) return false;
if(Inputs.keyDown("gridModeShift")){ //select category
int i = 0;
for(Input key : inputCatGrid){
if(Inputs.keyDown(key)){
input.recipe = Recipe.getByCategory(Category.values()[i]).first();
currentCategory = input.recipe.category;
}
i++;
}
return true;
}else if(Inputs.keyDown("select")){ //mouse eyedropper select
Tile tile = world.tileWorld(Graphics.mouseWorld().x, Graphics.mouseWorld().y);
if(tile != null){
tile = tile.target();
Recipe tryRecipe = Recipe.getByResult(tile.block());
if(tryRecipe != null && control.unlocks.isUnlocked(tryRecipe)){
input.recipe = tryRecipe;
currentCategory = input.recipe.category;
return true;
}
}
}else{ //select block
int i = 0;
Array<Recipe> recipes = Recipe.getByCategory(currentCategory);
for(Input key : inputGrid){
if(Inputs.keyDown(key))
input.recipe = (i < recipes.size && control.unlocks.isUnlocked(recipes.get(i))) ? recipes.get(i) : null;
i++;
}
}
return false;
}
@Override
public void build(Group parent){
parent.fill(full -> {
@@ -74,7 +126,7 @@ public class PlacementFragment extends Fragment{
boolean[] unlocked = {false};
ImageButton button = blockTable.addImageButton("icon-locked", "select", 8*4, () -> {
ImageButton button = blockTable.addImageButton("icon-locked", "select", 8 * 4, () -> {
if(control.unlocks.isUnlocked(recipe)){
input.recipe = input.recipe == recipe ? null : recipe;
}
@@ -111,8 +163,8 @@ public class PlacementFragment extends Fragment{
frame.table("button-edge-2", top -> {
topTable = top;
top.add(new Table()).growX().update(topTable -> {
if((tileDisplayBlock() == null && lastDisplay == getSelected() && !lastGround) ||
(tileDisplayBlock() != null && lastDisplay == tileDisplayBlock() && lastGround)) return;
if((tileDisplayBlock() == null && lastDisplay == getSelected() && !lastGround) || (tileDisplayBlock() != null && lastDisplay == tileDisplayBlock() && lastGround))
return;
topTable.clear();
topTable.top().left().margin(5);
@@ -123,14 +175,14 @@ public class PlacementFragment extends Fragment{
if(lastDisplay != null){ //show selected recipe
topTable.table(header -> {
header.left();
header.add(new ImageStack(lastDisplay.getCompactIcon())).size(8*4);
header.add(new ImageStack(lastDisplay.getCompactIcon())).size(8 * 4);
header.labelWrap(() ->
!control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay)) ? Bundles.get("text.blocks.unknown") : lastDisplay.formalName)
.left().width(190f).padLeft(5);
!control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay)) ? Bundles.get("text.blocks.unknown") : lastDisplay.formalName)
.left().width(190f).padLeft(5);
header.add().growX();
if(control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay))){
header.addButton("?", "clear-partial", () -> ui.content.show(Recipe.getByResult(lastDisplay)))
.size(8 * 5).padTop(-5).padRight(-5).right().grow();
.size(8 * 5).padTop(-5).padRight(-5).right().grow();
}
}).growX().left();
topTable.row();
@@ -141,7 +193,7 @@ public class PlacementFragment extends Fragment{
for(ItemStack stack : Recipe.getByResult(lastDisplay).requirements){
req.table(line -> {
line.left();
line.addImage(stack.item.region).size(8*2);
line.addImage(stack.item.region).size(8 * 2);
line.add(stack.item.localizedName()).color(Color.LIGHT_GRAY).padLeft(2).left();
line.labelWrap(() -> {
TileEntity core = players[0].getClosestCore();
@@ -159,13 +211,13 @@ public class PlacementFragment extends Fragment{
}else if(tileDisplayBlock() != null){ //show selected tile
lastDisplay = tileDisplayBlock();
topTable.add(new ImageStack(lastDisplay.getDisplayIcon(hoverTile))).size(8*4);
topTable.add(new ImageStack(lastDisplay.getDisplayIcon(hoverTile))).size(8 * 4);
topTable.labelWrap(lastDisplay.getDisplayName(hoverTile)).left().width(190f).padLeft(5);
}
});
}).colspan(3).fillX().visible(() -> getSelected() != null || tileDisplayBlock() != null).touchable(Touchable.enabled);
frame.row();
frame.addImage("blank").color(Palette.accent).colspan(3).height(3*2).growX();
frame.addImage("blank").color(Palette.accent).colspan(3).height(3 * 2).growX();
frame.row();
frame.table("pane-2", blocksSelect -> {
blocksSelect.margin(4).marginTop(0);
@@ -181,21 +233,24 @@ public class PlacementFragment extends Fragment{
for(Category cat : Category.values()){
if(Recipe.getByCategory(cat).isEmpty()) continue;
categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16*2, () -> {
categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16 * 2, () -> {
currentCategory = cat;
rebuildCategory.run();
}).group(group).update(i -> i.setChecked(currentCategory == cat));
if(cat.ordinal() %2 == 1) categories.row();
if(cat.ordinal() % 2 == 1) categories.row();
}
}).touchable(Touchable.enabled);
rebuildCategory.run();
frame.update(() -> {
if(gridUpdate(input)) rebuildCategory.run();
});
});
});
}
/**Returns the currently displayed block in the top box.*/
/** Returns the currently displayed block in the top box. */
Block getSelected(){
Block toDisplay = null;
@@ -226,12 +281,12 @@ public class PlacementFragment extends Fragment{
return toDisplay;
}
/**Returns the block currently being hovered over in the world.*/
/** Returns the block currently being hovered over in the world. */
Block tileDisplayBlock(){
return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.floor() instanceof OreBlock ? hoverTile.floor() : null;
}
/**Show or hide the placement menu.*/
/** Show or hide the placement menu. */
void toggle(float t, Interpolation ip){
toggler.clearActions();
if(shown){

View File

@@ -45,9 +45,9 @@ public class Build{
for(int dx = 0; dx < previous.size; dx++){
for(int dy = 0; dy < previous.size; dy++){
int worldx = dx + offsetx + x;
int worldy = dy + offsety + y;
if(!(worldx == x && worldy == y)){
int worldx = dx + offsetx + tile.x;
int worldy = dy + offsety + tile.y;
if(!(worldx == tile.x && worldy == tile.y)){
Tile toplace = world.tile(worldx, worldy);
if(toplace != null){
toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety));

View File

@@ -101,6 +101,7 @@ public class Tile implements PosTrait, TargetTrait{
return -1;
}
@SuppressWarnings("unchecked")
public <T extends TileEntity> T entity(){
return (T) entity;
}

View File

@@ -35,7 +35,6 @@ public class Conveyor extends Block{
private TextureRegion[][] regions = new TextureRegion[7][4];
protected float speed = 0f;
protected float carryCapacity = 8f;
protected Conveyor(String name){
super(name);
@@ -359,9 +358,9 @@ public class Conveyor extends Block{
public Array<Object> getDebugInfo(Tile tile){
ConveyorEntity entity = tile.entity();
Array<Object> arr = super.getDebugInfo(tile);
arr.addAll(Array.with(
"clogHeat", entity.clogHeat,
"sleeping", entity.isSleeping()
arr.addAll(Array.<Object>with(
"clogHeat", entity.clogHeat,
"sleeping", entity.isSleeping()
));
return arr;
}

View File

@@ -87,6 +87,7 @@ public class Consumers{
return map.containsKey(type);
}
@SuppressWarnings("unchecked")
public <T extends Consume> T get(Class<T> type){
if(!map.containsKey(type)){
throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "'!");