diff --git a/.gitignore b/.gitignore index fdf2b4f464..cfa73a21a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ ##Packr, build stuff +logs/ /core/assets/mindustry-saves/ /core/assets/mindustry-maps/ /core/assets/bundles/output/ @@ -25,6 +26,7 @@ /core/assets/version.properties /core/assets/locales /ios/src/io/anuke/mindustry/gen/ +/core/src/io/anuke/mindustry/gen/ *.gif version.properties diff --git a/android/src/io/anuke/mindustry/TextFieldDialogListener.java b/android/src/io/anuke/mindustry/TextFieldDialogListener.java index be1cc6d924..c603fbff05 100644 --- a/android/src/io/anuke/mindustry/TextFieldDialogListener.java +++ b/android/src/io/anuke/mindustry/TextFieldDialogListener.java @@ -42,12 +42,13 @@ public class TextFieldDialogListener extends ClickListener{ AndroidTextFieldDialog dialog = new AndroidTextFieldDialog(); - dialog.setTextPromptListener(text -> { - field.clearText(); - field.appendText(text); - field.fire(new ChangeListener.ChangeEvent()); - Gdx.graphics.requestRendering(); - }); + dialog.setTextPromptListener(text -> + Gdx.app.postRunnable(() -> { + field.clearText(); + field.appendText(text); + field.fire(new ChangeListener.ChangeEvent()); + Gdx.graphics.requestRendering(); + })); if(type == 0){ dialog.setInputType(InputType.TYPE_CLASS_TEXT); diff --git a/build.gradle b/build.gradle index 1dc92a9b97..8bc3fca889 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ allprojects { appName = 'Mindustry' gdxVersion = '1.9.8' roboVMVersion = '2.3.0' - uCoreVersion = 'eb1503dfb786f5f727bdb4b6a302718490444335' + uCoreVersion = '8919cb7b6881d040fb720149779fcf58c1927893' getVersionString = { String buildVersion = getBuildVersion() @@ -120,7 +120,7 @@ project(":ios") { } } - build.dependsOn(copyGen) + //build.dependsOn(copyGen) dependencies { compile project(":core") @@ -131,6 +131,7 @@ project(":ios") { compile "com.badlogicgames.gdx:gdx-backend-robovm:$gdxVersion" compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-ios" compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-ios" + compileOnly project(":annotations") } } diff --git a/core/assets-raw/sprites/ui/empty-sector.png b/core/assets-raw/sprites/ui/empty-sector.png index 905ec6eea2..347b3bfc8d 100644 Binary files a/core/assets-raw/sprites/ui/empty-sector.png and b/core/assets-raw/sprites/ui/empty-sector.png differ diff --git a/core/assets-raw/sprites/ui/sector-edge.png b/core/assets-raw/sprites/ui/sector-edge.png index bd32c3dfc7..293d9bee79 100644 Binary files a/core/assets-raw/sprites/ui/sector-edge.png and b/core/assets-raw/sprites/ui/sector-edge.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index d50ec7eb18..0bb62bbc96 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -263,7 +263,7 @@ text.mapeditor = Map Editor text.donate = Donate text.connectfail = [crimson]Failed to connect to server\:\n\n[accent]{0} -text.error.unreachable = Server unreachable. +text.error.unreachable = Server unreachable.\nIs the address spelled correctly? text.error.invalidaddress = Invalid address. text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! text.error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! @@ -372,6 +372,7 @@ setting.musicvol.name = Music Volume setting.mutemusic.name = Mute Music setting.sfxvol.name = SFX Volume setting.mutesound.name = Mute Sound +setting.crashreport.name = Send Anonymous Crash Reports text.keybind.title = Rebind Keys category.general.name = General category.view.name = View diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties index 0dd7373d4c..5e5df2b1e3 100644 --- a/core/assets/bundles/bundle_de.properties +++ b/core/assets/bundles/bundle_de.properties @@ -2,55 +2,55 @@ text.credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[ text.credits = Danksagungen text.discord = Trete dem Mindustry Discord bei! text.link.discord.description = Der offizielle Mindustry Discord Chatroom -text.link.github.description = Spiel Source Code -text.link.dev-builds.description = Entwicklungs- Builds (instabil) +text.link.github.description = Quellcode des Spiels +text.link.dev-builds.description = Entwicklungs-Builds (instabil) text.link.trello.description = Offizielles Trello Board für geplante Features -text.link.itch.io.description = itch.io Seite mit downloads und der Web-Version des Spiels -text.link.google-play.description = Google Play store listing -text.link.wiki.description = offizelles Mindustry wiki -text.linkfail = Fehler beim Öffnen des Links!\nThe URL wurde in die Zwischenablage kopiert. +text.link.itch.io.description = itch.io Seite mit Downloads und der Web-Version des Spiels +text.link.google-play.description = Google Play Store Seite +text.link.wiki.description = Offizelles Mindustry Wiki +text.linkfail = Fehler beim Öffnen des Links!\nDie URL wurde in die Zwischenablage kopiert. text.editor.web = Die Web-Version unterstützt den Editor nicht!\nLade das Spiel herunter um ihn zu benutzen. -text.web.unsupported = Die Web-Version unterstützt den editor nicht! Lade das Spiel herunter um ihn zu benutzen. +text.web.unsupported = Die Web-Version unterstützt dieses Feature nicht! Lade das Spiel herunter um es zu benutzen. text.gameover = Der Kern wurde zerstört. -text.gameover.pvp = Das[accent] {0}[] Team ist Siegreich! +text.gameover.pvp = Das[accent] {0}[] Team ist siegreich! text.sector.gameover = Du hast diesen Sektor verloren. Erneuter Einsatz? -text.sector.retry = Erneut Versuchen +text.sector.retry = Erneut versuchen text.highscore = [YELLOW] Neuer Highscore! -text.wave.lasted = Du hast es bis Welle[accent]{0}[] ausgehalten. -text.level.highscore = High Score: [accent] {0} +text.wave.lasted = Du hast es bis Welle [accent]{0}[] ausgehalten. +text.level.highscore = High Score: [accent]{0} text.level.delete.title = Löschen bestätigen -text.map.delete = Bist du sicher das du die Karte "[accent]{0}[]" löschen möchtest? +text.map.delete = Bist du sicher, dass du die Karte "[accent]{0}[]" löschen möchtest? text.level.select = Level Auswahl text.level.mode = Spielmodus: -text.construction.desktop = Die Desktop Steuerung wurde geändert.\n Zum deselektieren eines Blocks oder das Bauen abzubrechen benutze die [accent] Space Taste[]. -text.construction.title = Block Konstruktions-Anleitung -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 Dekonstructions Anleitung -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 = Zeige die nächste Session nicht nochmal -text.coreattack = < Der Kern wird angegriffen! > +text.construction.desktop = Um einen Block zu deselektieren oder den Bau abzubrechen, [accent]verwende die Leertaste[]. +text.construction.title = Bauanleitung für Blöcke. +text.construction = Du hast soeben den [accent]Block-Baumodus[] ausgewählt.\n\nTippe einfach auf einen gültigen Platz in der Nähe deines Schiffs, um den Bau zu planen.\nSobald du einige Blöcke platziert hast, drücke zum Bestätigen auf den Haken, und dein Schiff wird mit dem Bau beginnen.\n\n- [accent]Entferne Blöcke[] von deiner Auswahl, indem du darauf tippst.\n- [accent]Verschiebe die Selektion[], indem du einen beliebigen Block in der Auswahl gedrückt hältst und verschiebst.\n- [accent]Platziere Blöcke in einer Linie[], indem du einen leeren Platz gedrückt hältst, und in eine Richtung ziehst.\n- [accent]Breche den Bau oder die Auswahl ab[], indem du das X links unten drückst. +text.deconstruction.title = Abbruchanleitung für Blöcke +text.deconstruction = Du hast soeben den [accent]Abbruchmodus für Blöcke[] aktiviert.\n\nUm mit dem Abriss zu beginnen, tippe einfach auf einen Block in der Nähe deines Schiffs.\nSobald du einige Blöcke ausgewählt hast, drücke zum Bestätigen auf den Haken, und dein Schiff wird mit dem Abriss beginnen.\n\n- [accent]Entferne einen Block[] von deiner Selektion, indem du darauf tippst.\n- [accent]Reiße Blöcke in einem Gebiet ab[], indem du einen leeren Platz gedrückt hältst, und in eine Richtung ziehst.\n- [accent]Breche den Abriss or die Selektion ab[], indem du das X links unten drückst. +text.showagain = Nächstes mal nicht mehr anzeigen +text.coreattack = < Die Basis wird angegriffen! > text.unlocks = Freigeschaltet text.savegame = Spiel speichern text.loadgame = Spiel laden text.joingame = Spiel beitreten text.addplayers = Hinzufügen/Entfernen von Spielern -text.customgame = Custom Game +text.customgame = Benutzerdefiniertes Spiel text.sectors = Sektoren -text.sector = Ausgewählter Sektor: [LIGHT_GRAY]{0} +text.sector = Sektor: [LIGHT_GRAY]{0} text.sector.time = Zeit: [LIGHT_GRAY]{0} text.sector.deploy = Einsatz text.sector.abandon = Aufgeben -text.sector.abandon.confirm = Bist du sicher das du allen Fortschritt in diesem Sektor aufgeben willst?\n Diese Aktion kann nicht Rückgängig gemacht werden! +text.sector.abandon.confirm = Bist du sicher, dass du den gesamten Fortschritt in diesem Sektor aufgeben willst?\n Diese Aktion kann nicht rückgängig gemacht werden! text.sector.resume = Fortsetzen text.sector.locked = [scarlet][[Unvollständig] text.sector.unexplored = [accent][[Unerforscht] text.missions = Missionen:[LIGHT_GRAY] {0} text.mission = Mission:[LIGHT_GRAY] {0} -text.mission.main = Haupt Mission:[LIGHT_GRAY] {0} -text.mission.info = Mission Info +text.mission.main = Hauptmission:[LIGHT_GRAY] {0} +text.mission.info = Missionsbeschreibung text.mission.complete = Mission erfolgreich! text.mission.complete.body = Sektor {0},{1} wurde erobert. -text.mission.wave = Überlebe [accent]{0}[] Wellen. +text.mission.wave = Überlebe [accent]{0}/{1}[] Wellen\nWelle in {2} text.mission.wave.enemies = Überlebe[accent] {0}/{1} []Wellen\n{2} Gegner text.mission.wave.enemy = Überlebe[accent] {0}/{1} []Wellen\n{2} Gegner text.mission.wave.menu = Überlebe[accent] {0} []Wellen @@ -59,10 +59,10 @@ text.mission.resource.menu = Erlange {0} x{1} text.mission.resource = Sammele {0}:\n[accent]{1}/{2}[] text.mission.block = Erstelle {0} text.mission.unit = Erstelle {0} Einheiten -text.mission.command = Sende Command {0} an Einheiten -text.mission.linknode = Verbinde Power Knoten +text.mission.command = Sende {0}-Kommando an Einheiten +text.mission.linknode = Verbinde Stromknoten text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0} -text.mission.mech = Wechsele zu Mech[accent] {0}[] +text.mission.mech = Wechsle zum [accent] {0}[]-Mech text.mission.create = Platziere[accent] {0}[] text.none = text.close = Schließen @@ -81,17 +81,17 @@ text.players.single = {0} Spieler online text.server.closing = [accent]Schließe den Server... text.server.kicked.kick = Du wurdest vom Server gekickt! text.server.kicked.serverClose = Server geschlossen. -text.server.kicked.sectorComplete = Sektor komplett. +text.server.kicked.sectorComplete = Sektor abgeschlossen. text.server.kicked.sectorComplete.text = Deine Mission ist abgeschlossen.\nDer Server wird nun in einen neuen Sektor wechseln. text.server.kicked.clientOutdated = Veralteter Client! Aktualisiere dein Spiel! text.server.kicked.serverOutdated = Veralteter Server! Bitte den Host um ein Update! text.server.kicked.banned = Du wurdest vom Server verbannt. text.server.kicked.recentKick = Du wurdest gerade gekickt.\nWarte bevor du dich wieder verbindest. -text.server.kicked.nameInUse = Da ist bereits ein Spieler \nmit diesem Namen auf dem Server. -text.server.kicked.nameEmpty = Dein Name muss zumindest ein Buchstaben oder eine Zahl enthalten. +text.server.kicked.nameInUse = Es ist bereits ein Spieler \nmit diesem Namen auf dem Server. +text.server.kicked.nameEmpty = Dein Name muss zumindest einen Buchstaben oder eine Zahl enthalten. text.server.kicked.idInUse = Du bist bereits auf dem Server! Anmeldungen mit zwei Accounts sind nicht gestattet. text.server.kicked.customClient = Der Server akzeptiert keine Custom Builds von Mindustry. Lade dir die offizielle Version herunter. -text.host.info = Der [accent]host[] Knopf startet einen Server auf den Ports [scarlet]6567[] und [scarlet]6568.[]\nJeder im gleichen [LIGHT_GRAY]W-Lan oder lokalem Netzwerk[] sollte deinen Server in seiner Server Liste sehen können.\n\nWenn du Leuten die Verbindung über IP ermöglichen willst, benötigst du [accent]Port-Forwarding[].\n\n[LIGHT_GRAY]Hinweis: Falls es Probleme mit der Verbindung im Netzwerk gibt, stell sicher das Mindustry in deinen Firewall Einstellungen Zugriff auf das lokale Netzwerk hat. +text.host.info = Der [accent]host[] Knopf startet einen Server auf den Ports [scarlet]6567[] und [scarlet]6568.[]\nJeder im gleichen [LIGHT_GRAY]W-Lan oder lokalem Netzwerk[] sollte deinen Server in seiner Server Liste sehen können.\n\nWenn du Leuten die Verbindung über IP ermöglichen willst, benötigst du [accent]Port-Forwarding[].\n\n[LIGHT_GRAY]Hinweis: Falls es Probleme mit der Verbindung im Netzwerk gibt, stell sicher, dass Mindustry in deinen Firewall Einstellungen Zugriff auf das lokale Netzwerk hat. text.join.info = Hier kannst du eine [accent]Server IP[] eingeben um dich zu verbinden oder Server im [accent]lokalem Netzwerk[] entdecken und dich mit ihnen verbinden.\nSowohl Spielen über das lokale Netzwerk als auch Spielen über das Internet werden unterstützt.\n\n[LIGHT_GRAY]Hinweis: Es gibt keine globale Server Liste; Wenn du dich mit jemand per IP verbinden willst musst du den Host nach seiner IP fragen. text.hostserver = Server hosten text.hostserver.mobile = Host\nGame @@ -102,48 +102,48 @@ text.hosts.discovering = Suche nach LAN-Spielen text.server.refreshing = Server wird aktualisiert text.hosts.none = [lightgray] Keine LAN Spiele gefunden! text.host.invalid = [scarlet] Kann keine Verbindung zum Host herstellen. -text.trace = Trace Player -text.trace.playername = Player name: [accent]{0} +text.trace = Spieler verfolgen +text.trace.playername = Spielername: [accent]{0} text.trace.ip = IP: [accent]{0} -text.trace.id = Unique ID: [accent]{0} +text.trace.id = Eindeutige ID: [accent]{0} text.trace.android = Android Client: [accent]{0} text.trace.modclient = Custom Client: [accent]{0} -text.trace.totalblocksbroken = Total blocks broken: [accent]{0} -text.trace.structureblocksbroken = Structure blocks broken: [accent]{0} -text.trace.lastblockbroken = Last block broken: [accent]{0} -text.trace.totalblocksplaced = Total blocks placed: [accent]{0} -text.trace.lastblockplaced = Last block placed: [accent]{0} -text.invalidid = Invalid client ID! Submit a bug report. +text.trace.totalblocksbroken = Anzahl zerstörter Blöcke: [accent]{0} +text.trace.structureblocksbroken = Anzahl zerstörter Gebäude-Blöcke: [accent]{0} +text.trace.lastblockbroken = Letzter zerstörter Block: [accent]{0} +text.trace.totalblocksplaced = Anzahl platzierter Blöcke: [accent]{0} +text.trace.lastblockplaced = Letzter platzierter Block: [accent]{0} +text.invalidid = Ungültige Client ID! Berichte den Bug. text.server.bans = Bans text.server.bans.none = Keine gebannten Spieler gefunden! text.server.admins = Admins text.server.admins.none = Keine Admins gefunden! text.server.add = Server hinzufügen -text.server.delete = Bist du dir sicher das du diesen Server löschen möchtest? +text.server.delete = Bist du dir sicher, dass du diesen Server löschen möchtest? text.server.hostname = Host: {0} text.server.edit = Server bearbeiten text.server.outdated = [crimson]Veralteter Server![] text.server.outdated.client = [crimson]Veralteter Client![] text.server.version = [lightgray]Version: {0} text.server.custombuild = [yellow]Custom Build -text.confirmban = Bist du sicher das du diesen Spieler verbannen möchtest? -text.confirmkick = Bist du sicher das du diesen Spieler kicken willst? +text.confirmban = Bist du sicher, dass du diesen Spieler verbannen möchtest? +text.confirmkick = Bist du sicher, dass du diesen Spieler kicken willst? text.confirmunban = Bist du sicher, dass du die Verbannung des Spielers rückgängig machen willst? text.confirmadmin = Bist du sicher, dass du diesen Spieler zu einem Admin machen möchtest? text.confirmunadmin = Bis du sicher, dass dieser Spieler kein Admin mehr sein soll? text.joingame.title = Spiel beitreten text.joingame.ip = IP: text.disconnect = Verbindung unterbrochen. -text.disconnect.data = Fehler beim Laden der Welt Daten! -text.connecting = [accent] Verbindet... -text.connecting.data = [accent] Welt Daten werden geladen... +text.disconnect.data = Fehler beim Laden der Welt! +text.connecting = [accent] Verbinde... +text.connecting.data = [accent] Welt wird geladen... text.server.port = Port: -text.server.addressinuse = Adresse bereits in Benutzung! +text.server.addressinuse = Adresse bereits in Verwendung! text.server.invalidport = Falscher Port! text.server.error = [crimson] Fehler beim Hosten des Servers: [accent] {0} -text.save.old = This save is for an older version of the game, and can no longer be used.\n\n[LIGHT_GRAY]Save backwards compatibility will be implemented in the full 4.0 release. +text.save.old = Dieser Spielstand ist von einer älteren Version des Spiels, und kann nicht mehr verwendet werden.\n\n[LIGHT_GRAY]Abwärtskompatibilität von Speicherständen wird in der 4.0 Vollversion hinzugefügt. text.save.new = Neuer Spielstand -text.save.overwrite = Möchten du diesen Spielstand wirklich überschreiben? +text.save.overwrite = Möchtest du diesen Spielstand wirklich überschreiben? text.overwrite = Überschreiben text.save.none = Keine Spielstände gefunden! text.saveload = [accent] Speichern ... @@ -181,26 +181,26 @@ text.copylink = Kopiere Link text.back = Zurück text.quit.confirm = Willst du wirklich aufhören? text.changelog.title = Changelog -text.changelog.loading = Lade Changelog... -text.changelog.error.android = [accent]Beachte: Das Changelog funktioniert manchmal nicht auf Android 4.4 (und älter)!\nDies resultiert aus einem Android bug. -text.changelog.error.ios = [accent]Das Changelog wird aktuell nicht von IOS unterstützt. -text.changelog.error = [scarlet]Fehler beim Laden des Changelog!\nPrüfe deine Internet Verbindung. +text.changelog.loading = Lade Änderungshistorie... +text.changelog.error.android = [accent]Beachte: Die Änderungshistorie funktioniert manchmal nicht auf Android 4.4 (und älter)!\nDies liegt an einem Android bug. +text.changelog.error.ios = [accent]Die Änderungshistorie wird aktuell nicht von IOS unterstützt. +text.changelog.error = [scarlet]Fehler beim Laden der Änderungshistorie!\nPrüfe deine Internetverbindung. text.changelog.current = [yellow][[Current version] text.changelog.latest = [accent][[Latest version] -text.loading = [accent] Wird geladen ... +text.loading = [accent]Wird geladen ... text.saving = [accent]Speichere... -text.wave = [accent] Welle {0} +text.wave = [accent]Welle {0} text.wave.waiting = Welle in {0} text.waiting = Warten... text.waiting.players = Warte auf Spieler... -text.wave.enemies = [LIGHT_GRAY]{0} Gegner Verbleiben -text.wave.enemy = [LIGHT_GRAY]{0} Gegner Verbleiben +text.wave.enemies = [LIGHT_GRAY]{0} Gegner verbleiben +text.wave.enemy = [LIGHT_GRAY]{0} Gegner verbleiben text.loadimage = Bild laden text.saveimage = Bild speichern text.unknown = Unbekannt -text.custom = Custom -text.builtin = Built-In -text.map.delete.confirm = Bist du sicher das du diese Karte löschen willst? Die Aktion kann nicht rückgänig gemacht werden! +text.custom = Benutzerdefiniert +text.builtin = Enthalten +text.map.delete.confirm = Bist du sicher, dass du diese Karte löschen willst? Die Aktion kann nicht rückgänig gemacht werden! text.map.random = [accent]Zufällige Karte text.map.nospawn = Diese Karte hat keine Kerne in denen die Spieler beginnen können! Füge einen [ROYAL]blue[] Kern zu dieser Karte im Editor hinzu. text.map.nospawn.pvp = Diese Karte hat keine gegnerischen Kerne wo Gegner starten könnten! Füge über den Editor [SCARLET] rote[] Kerne zu dieser Karte hinzu. @@ -244,7 +244,7 @@ text.editor.unsaved = [crimson] Du hast Änderungen nicht gespeichert [] Möchte text.editor.resizemap = Grösse der Karte ändern text.editor.mapname = Karten Name text.editor.overwrite = [accent] Warnung! Dies überschreibt eine vorhandene Karte. -text.editor.overwrite.confirm = [scarlet]Warnung![] Eine Karte mit diesem Namen existiert bereits. Bist du sicher das du sie überschreiben willst? +text.editor.overwrite.confirm = [scarlet]Warnung![] Eine Karte mit diesem Namen existiert bereits. Bist du sicher, dass du sie überschreiben willst? text.editor.selectmap = Wähle eine Karte zum Laden: text.width = Breite: text.height = Höhe: @@ -262,13 +262,12 @@ text.editor = Editor text.mapeditor = Karten Editor text.donate = Spenden text.connectfail = [crimson] Verbindung zum Server konnte nicht hergestellt werden: [accent]{0} -text.error.unreachable = Server unreachable. -text.error.invalidaddress = Invalid address. -text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! -text.error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! -text.error.alreadyconnected = Already connected. -text.error.mapnotfound = Map file not found! -text.error.any = Unkown network error. +text.error.unreachable = Server nicht erreichbar. +text.error.invalidaddress = Ungültige Adresse. +text.error.timedout = Zeitüberschreitung!\nStelle sicher, dass die Portweiterleitung auf dem Host richtig eingerichtet ist, und die Adresse stimmt! +text.error.mismatch = Paketfehler:\nClient und Server passen möglicherweise nicht zusammen.\nStelle sicher, dass du und der Host jeweils die neueste Version von Mindustry haben! +text.error.alreadyconnected = Bereits verbunden. +text.error.any = Unbekannter Netzwerkfehler. text.settings.language = Sprache text.settings.reset = Auf Standard zurücksetzen text.settings.rebind = Zuweisen @@ -277,7 +276,7 @@ text.settings.game = Spiel text.settings.sound = Audio text.settings.graphics = Grafiken text.settings.cleardata = Spieldaten zurücksetzen... -text.settings.clear.confirm = Bist du sicher das du die Spieldaten zurücksetzen willst?\n Diese Aktion kann nicht rückgänig gemacht werden! +text.settings.clear.confirm = Bist du sicher, dass du die Spieldaten zurücksetzen willst?\n Diese Aktion kann nicht rückgänig gemacht werden! text.settings.clearall.confirm = [scarlet]Warnung![]\nDas wird jegliche Spieldaten zurücksetzen inklusive Speicherstände, Karten, Freischaltungen und Tastenbelegungen.\n Nachdem du 'OK' drückst wird alles zurückgesetzt und das Spiel schließt sich automatisch. text.settings.clearsectors = Sektoren zurücksetzen text.settings.clearunlocks = Freischaltungen zurücksetzen @@ -289,273 +288,273 @@ text.info.title = [accent]Info text.error.title = [crimson] Ein Fehler ist aufgetreten text.error.crashtitle = Ein Fehler ist aufgetreten! text.blocks.blockinfo = Blockinfo: -text.blocks.powercapacity = Power Kapazität -text.blocks.powershot = Power / Schuss +text.blocks.powercapacity = Kapazität +text.blocks.powershot = Stromverbrauch/Schuss text.blocks.targetsair = Visiert Luft Einheiten an -text.blocks.itemspeed = Units Moved +text.blocks.itemspeed = Beförderte Materialien text.blocks.shootrange = Reichweite -text.blocks.size = Grösse +text.blocks.size = Größe text.blocks.liquidcapacity = Flüssigkeitskapazität -text.blocks.maxitemssecond = Max Gegenstand / Sekunde -text.blocks.powerrange = Power Reichweite -text.blocks.poweruse = Powerbedarf -text.blocks.powerdamage = Power/Schaden -text.blocks.inputitemcapacity = Annahme Kapazität -text.blocks.outputitemcapacity = Ausgabe Kapazität -text.blocks.itemcapacity = Gegenstand Kapazität -text.blocks.basepowergeneration = Base Power Generation -text.blocks.powertransferspeed = Power Transfer -text.blocks.craftspeed = Produktions-Geschwindigkeit -text.blocks.inputliquid = Annahme von Flüssigkeit -text.blocks.inputliquidaux = Aux Flüssigkeit -text.blocks.inputitem = Verwendung von Gegenstand -text.blocks.inputitems = Annahme von Gegenständen -text.blocks.outputitem = Ausgabe von Gegenständen -text.blocks.drilltier = Abbaubar -text.blocks.drillspeed = Grund Abbau Geschwindigkeit -text.blocks.liquidoutput = Flüssigkeits-Ausgabe -text.blocks.liquidoutputspeed = Flüssigkeits-Ausgabe Geschwindigkeit -text.blocks.liquiduse = Flüssigkeits-Verwendung +text.blocks.maxitemssecond = Max Materialien +text.blocks.powerrange = Stromreichweite +text.blocks.poweruse = Stromverbrauch +text.blocks.powerdamage = Stromverbrauch/Schadenspunkt +text.blocks.inputitemcapacity = Annahmekapazität +text.blocks.outputitemcapacity = Ausgabekapazität +text.blocks.itemcapacity = Materialkapazität +text.blocks.basepowergeneration = Basis-Stromerzeugung +text.blocks.powertransferspeed = Stromübertragung +text.blocks.craftspeed = Produktionsgeschwindigkeit +text.blocks.inputliquid = Benötigte Flüssigkeit +text.blocks.inputliquidaux = Optionale Flüssigkeit +text.blocks.inputitem = Akzeptiertes Material +text.blocks.inputitems = Akzeptierte Materialien +text.blocks.outputitem = Erzeugtes Material +text.blocks.drilltier = Abbaubare Erze +text.blocks.drillspeed = Bohrgeschwindigkeit +text.blocks.liquidoutput = Erzeugte Flüssigkeit +text.blocks.liquidoutputspeed = Ausgabegeschwindigkeit +text.blocks.liquiduse = Flüssigkeitsverbrauch text.blocks.coolant = Kühlmittel -text.blocks.coolantuse = Kühlmittel Verwendung -text.blocks.inputliquidfuel = Flüssigkraftstoff -text.blocks.liquidfueluse = Flüssigkraftstoff Benutzung +text.blocks.coolantuse = Kühlmittelverbrauch +text.blocks.inputliquidfuel = Kraftstoff +text.blocks.liquidfueluse = Kraftstoffverbrauch text.blocks.explosive = Hochexplosiv! text.blocks.health = Lebenspunkte text.blocks.inaccuracy = Ungenauigkeit text.blocks.shots = Schüsse -text.blocks.reload = Nachladen +text.blocks.reload = Schüsse/Sekunde text.blocks.inputfuel = Kraftstoff text.blocks.fuelburntime = Kraftstoff Verbrennungs-Zeit text.blocks.inputcapacity = Annahmekapazität text.blocks.outputcapacity = Ausgabekapazität -text.unit.blocks = blocks -text.unit.powersecond = Power Einheit/Sekunde -text.unit.liquidsecond = flüssige Einheit/Sekunde -text.unit.itemssecond = Gegenstand/Sekunde +text.unit.blocks = Blöcke +text.unit.powersecond = Stromeinheiten/Sekunde +text.unit.liquidsecond = Flüssigkeitseinheiten/Sekunde +text.unit.itemssecond = Materialeinheiten/Sekunde text.unit.pixelssecond = Pixel/Sekunde -text.unit.liquidunits = flüssige Einheiten -text.unit.powerunits = Power Einheiten -text.unit.degrees = grad +text.unit.liquidunits = Flüssigkeitseinheiten +text.unit.powerunits = Stromeinheiten +text.unit.degrees = Grad text.unit.seconds = Sekunden -text.unit.items = Gegenstände -text.category.general = General -text.category.power = Power +text.unit.items = Materialeinheiten +text.category.general = Generell +text.category.power = Strom text.category.liquids = Flüssigkeiten -text.category.items = Gegenstände -text.category.crafting = Herstellung +text.category.items = Materialien +text.category.crafting = Erzeugung text.category.shooting = Schießen -setting.autotarget.name = Auto-Target +setting.autotarget.name = Auto-Zielauswahl setting.fpscap.name = Max FPS setting.fpscap.none = kein setting.fpscap.text = {0} FPS -setting.difficulty.training = training +setting.difficulty.training = Training setting.difficulty.easy = Leicht setting.difficulty.normal = Normal setting.difficulty.hard = Schwer setting.difficulty.insane = Unmöglich setting.difficulty.name = Schwierigkeit -setting.screenshake.name = Bildschirm wackeln +setting.screenshake.name = Bildschirmwackeln setting.effects.name = Effekte anzeigen -setting.sensitivity.name = Kontroller Empfindlichkeit +setting.sensitivity.name = Controller-Empfindlichkeit setting.saveinterval.name = Autosave Häufigkeit setting.seconds = {0} Sekunden setting.fullscreen.name = Vollbild setting.multithread.name = Multithreading setting.fps.name = Zeige FPS setting.vsync.name = VSync -setting.lasers.name = Zeige Powerlaser +setting.lasers.name = Zeige Stromlaser setting.minimap.name = Zeige die Minimap setting.musicvol.name = Musiklautstärke setting.mutemusic.name = Musik stummschalten -setting.sfxvol.name = Audioeffekte Lautstärke +setting.sfxvol.name = Audioeffekt-Lautstärke setting.mutesound.name = Audioeffekte stummschalten -text.keybind.title = Tasten Zuweisen +text.keybind.title = Tasten zuweisen category.general.name = Allgemein -category.view.name = View +category.view.name = Ansicht category.multiplayer.name = Mehrspieler command.attack = Angreifen command.retreat = Rückzug command.patrol = Patrouillieren keybind.press = Drücke eine Taste... keybind.press.axis = Drücke eine Taste oder bewege eine Achse... -keybind.move_x.name = bewege_x -keybind.move_y.name = bewege_y -keybind.select.name = wählen -keybind.break.name = Unterbrechung -keybind.deselect.name = Deselektieren -keybind.shoot.name = Schiess -keybind.zoom_hold.name = zoomen_halten -keybind.zoom.name = zoomen +keybind.move_x.name = X-Achse +keybind.move_y.name = Y-Achse +keybind.select.name = Auswählen/Schießen +keybind.break.name = Abreißen +keybind.deselect.name = Auswahl aufheben +keybind.shoot.name = Schießen +keybind.zoom_hold.name = Zoom halten +keybind.zoom.name = Zoomen keybind.menu.name = Menü keybind.pause.name = Pause keybind.dash.name = Bindestrich keybind.chat.name = Chat -keybind.player_list.name = player_list -keybind.console.name = console +keybind.player_list.name = Spielerliste +keybind.console.name = Konsole keybind.rotate.name = Drehen -keybind.toggle_menus.name = Wechsele Menüs +keybind.toggle_menus.name = Menüs umschalten keybind.chat_history_prev.name = Chat Historie zurück keybind.chat_history_next.name = Chat Historie vor -keybind.chat_scroll.name = Chat scroll -keybind.drop_unit.name = drop unit -keybind.zoom_minimap.name = Zoom minimap +keybind.chat_scroll.name = Chat scrollen +keybind.drop_unit.name = Einheit absetzen +keybind.zoom_minimap.name = Minimap-Zoom mode.text.help.title = Beschreibung der Modi mode.waves.name = Wellen -mode.waves.description = Der Normale Modus. Begrenzte Ressourcen und automatische Wellen. +mode.waves.description = Der normale Modus. Begrenzte Ressourcen und automatische Wellen. mode.sandbox.name = Sandkasten -mode.sandbox.description = unendliche Ressourcen und kein Timer für Wellen. -mode.custom.warning = Beachte das Blöcke auch in Eigenen Spielen nicht verwendet werden können, solange sie nicht in den Sektoren freigespielt wurden.\n\n[LIGHT_GRAY]Solange ein Block nicht freigeschaltet wurde, ist er nicht sichtbar. -mode.custom.warning.read = Nur um sicherzugehen das du es gelesen hast:\n[scarlet]FREISCHALTUNGEN in Eigenen Spielen übertragen sich NICHT in Sektoren oder andere Modis!\n\n[LIGHT_GRAY](Ich wünschte der Hinweis wäre nicht notwendig, aber offensichtlich ist es das)[] +mode.sandbox.description = Unendliche Ressourcen und kein Timer für Wellen. +mode.custom.warning = [scarlet]FREISCHALTUNGEN IN BENUTZERDEFINIERTEN SPIELEN ODER SERVERN WERDEN NICHT GESPEICHERT.[]\n\nSpiele in Sektoren, um Dinge freizuschalten. +mode.custom.warning.read = Nur um sicherzugehen, dass du es gelesen hast:\n[scarlet]FREISCHALTUNGEN IN BENUTZERDEFINIERTEN SPIELEN ODER SERVERN WERDEN NICHT GESPEICHERT.[]\n\nSpiele in Sektoren, um Dinge freizuschalten.(Ich wünschte, der Hinweis wäre nicht notwendig, aber anscheinend ist er das)[] mode.freebuild.name = Freier Bau -mode.freebuild.description = begrenzte Ressourcen und kein Timer für Wellen. +mode.freebuild.description = Begrenzte Ressourcen und kein Timer für Wellen. mode.pvp.name = PvP mode.pvp.description = Kämpfe gegen andere Spieler local. -content.item.name = Gegenstand -content.liquid.name = Flüssigkeit +content.item.name = Materialien +content.liquid.name = Flüssigkeiten content.unit.name = Einheiten content.recipe.name = Blöcke content.mech.name = Mechs item.stone.name = Stein -item.stone.description = Ein gängiger Rohstoff der für die Zerteilung und Verfeinerung in andere Gegenstände oder geschmolzen als Lava verwendet wird. +item.stone.description = Ein gängiger Rohstoff ,der für die Zerteilung und Verfeinerung in andere Materialien oder geschmolzen als Lava verwendet wird. item.copper.name = Kupfer item.copper.description = Ein nützliches Material. Wird in allen Arten von Blöcken verwendet. item.lead.name = Blei -item.lead.description = Ein grundliegendes Material. Häufig in Elektronik und Flüssigkeits-Transport Blöcken verwendet. +item.lead.description = Ein grundliegendes Material. Häufig in Elektronik und Flüssigkeits-Transport-Blöcken verwendet. item.coal.name = Kohle item.coal.description = Ein sehr häufiger vorkommender Kraftstoff. item.dense-alloy.name = Dichte Legierung -item.dense-alloy.description = Eine Robuste Legierung aus Blei und Kupfer. Findet Verwendung in fortgeschrittenen Transport Blöcken und höherwertigen Bohrern. +item.dense-alloy.description = Eine robuste Legierung aus Blei und Kupfer. Findet Verwendung in fortgeschrittenen Transport-Blöcken und höherwertigen Bohrern. item.titanium.name = Titan -item.titanium.description = Ein seltenes sehr leichtes Metal. Häufig in Flüssigkeits-Transport Blöcken, Abbauanlagen und Flugzeugen verwendet. +item.titanium.description = Ein seltenes, sehr leichtes Metall. Häufig in Flüssigkeits-Transport-Blöcken, Abbauanlagen und Flugzeugen verwendet. item.thorium.name = Uran -item.thorium.description = Ein dichtes radioaktives Metal, welches als strukturelle Unterstützung und nuklearer Kraftstoff verwendet wird. +item.thorium.description = Ein dichtes radioaktives Metall, welches als strukturelle Unterstützung und nuklearer Kraftstoff verwendet wird. item.silicon.name = Silizium -item.silicon.description = Ein sehr nützlicher Halbleiter. Findet Anwendung in Solar Anlagen und komplexer Elektronik. +item.silicon.description = Ein sehr nützlicher Halbleiter. Findet Anwendung in Solaranlagen und komplexer Elektronik. item.plastanium.name = Plastanium item.plastanium.description = Ein leichtes dehnbares Material welches in Flugzeugen und Splittermunition verwendet wird. -item.phase-fabric.name = Phase Fabric -item.phase-fabric.description = A near-weightless substance used in advanced electronics and self-repairing technology. -item.surge-alloy.name = Gewalzte Legierung -item.surge-alloy.description = An advanced alloy with unique electrical properties. +item.phase-fabric.name = Phasengewebe +item.phase-fabric.description = Eine nahezu gewichtslose Substanz, die in fortgeschrittener Elektronik und in selbstreparierender Technologie verwendet wird. +item.surge-alloy.name = Spannungsstoß-Legierung +item.surge-alloy.description = Eine fortgeschrittene Legierung mit einzigartigen elektrischen Eigenschaften. item.biomatter.name = Biomasse item.biomatter.description = Ein Klumpen organischer Brei. Wird für die Umwandlung in Öl oder als grundliegender Kraftstoff verwendet. item.sand.name = Sand -item.sand.description = Ein gäniges Material welches häufig in geschmolzener Form, flüssig oder als Legierung verwendet wird. +item.sand.description = Ein gängiges Material, welches häufig in geschmolzener Form, flüssig oder als Legierung verwendet wird. item.blast-compound.name = Explosive Mischung -item.blast-compound.description = Eine flüchtige Mischung die in Bomben und Sprengstoffen Verwendung findet. Es besteht die Möglichkeit es als Treibstoff zu verwenden, es wird dringend davon abgeraten. -item.pyratite.name = Pyratite -item.pyratite.description = Eine extrem leicht entflammen Substanz. Verwendet in Brand Waffen. +item.blast-compound.description = Eine flüchtige Mischung, die in Bomben und Sprengstoffen Verwendung findet. Es besteht die Möglichkeit, es als Treibstoff zu verwenden, aber dies ist nicht empfehlenswert. +item.pyratite.name = Pyratit +item.pyratite.description = Eine extrem leicht entflammbare Substanz. Findet Verwendeung in Brandwaffen. liquid.water.name = Wasser liquid.lava.name = Lava liquid.oil.name = Öl -liquid.cryofluid.name = Cryofluid +liquid.cryofluid.name = Kryoflüssigkeit mech.alpha-mech.name = Alpha -mech.alpha-mech.weapon = Heavy Repeater -mech.alpha-mech.ability = Drone Swarm -mech.alpha-mech.description = Der Standart Mech. Ist angemessen Schnell und hat ordentlich Schaden. Kann für erweiterte Offensive Fähigkeiten bis zu 3 Drohnen erzeugen. +mech.alpha-mech.weapon = Schwerer Mehrlader +mech.alpha-mech.ability = Drohnenschwarm +mech.alpha-mech.description = Der Standard-Mech. Ist angemessen schnell und hat ordentlich Schaden. Kann für erweiterte offensive Fähigkeiten bis zu 3 Drohnen erzeugen. mech.delta-mech.name = Delta -mech.delta-mech.weapon = Lichtbogen Generator +mech.delta-mech.weapon = Lichtbogen-Generator mech.delta-mech.ability = Entladen -mech.delta-mech.description = Ein schneller, leicht gepanzerter Mech, der für hit-and-run Attacken gemacht wurde. Verursacht wenig Schaden gegen Gebäude aber tötet Gruppen von Gegnern durch seine Lichtbogen Blitz Waffen. +mech.delta-mech.description = Ein schneller, leicht gepanzerter Mech, der für Überfälle gemacht wurde. Verursacht wenig Schaden gegen Gebäude aber tötet Gruppen von Gegnern durch seine Lichtbogen-Waffen. mech.tau-mech.name = Tau -mech.tau-mech.weapon = Restrukt Laser -mech.tau-mech.ability = Reparier Burst -mech.tau-mech.description = Der Support Mech. Kann Blöcke durch Schüsse heilen. Kann Feuer löschen und verbündete in seinem Aktions Radius heilen. +mech.tau-mech.weapon = Restrukturierlaser +mech.tau-mech.ability = Reparatursalve +mech.tau-mech.description = Der Support Mech. Kann Blöcke durch Schüsse heilen. Kann Feuer löschen und verbündete in seinem Aktionsradius heilen. mech.omega-mech.name = Omega -mech.omega-mech.weapon = Schwarm Raketen -mech.omega-mech.ability = Rüstungs Konfiguration -mech.omega-mech.description = Ein klobiger und gut gepanzerter Mech, der für den Angriff in der Front Line gemacht wurde. Seine Rüstungsfähigkeit ermöglicht es ihm 90% des Schadens abzuwehren. +mech.omega-mech.weapon = Raketenschwarm +mech.omega-mech.ability = Rüstungskonfiguration +mech.omega-mech.description = Ein klobiger und gut gepanzerter Mech, der für den Angriff an der Front entwickelt wurde. Seine Rüstungsfähigkeit ermöglicht es ihm, 90% des Schadens abzuwehren. mech.dart-ship.name = Dart -mech.dart-ship.weapon = Repeater -mech.dart-ship.description = Das standard Schiff. Einigermaßen schnell und leicht. Hat nur wenig offensiv Kraft und geringe Abbaugeschwindigkeit. +mech.dart-ship.weapon = Mehrlader +mech.dart-ship.description = Das Standard-Schiff. Einigermaßen schnell und leicht. Hat nur wenig Offensivkraft und geringe Erzabbaugeschwindigkeit. mech.javelin-ship.name = Javelin -mech.javelin-ship.description = Ein hit-and-run Schiff. Anfänglich träge kann es auf hohe Geschwindigkeiten beschleunigen um an gegnerischen Aussenposten vorbei zu fliegen und dabei mit seinen Blitz Waffen und Raketen große Mengen an Schaden verursachen. -mech.javelin-ship.weapon = Burst Missiles -mech.javelin-ship.ability = Discharge Booster +mech.javelin-ship.description = Ein Schiff für Überfälle. Anfänglich träge, kann es auf hohe Geschwindigkeiten beschleunigen um an gegnerischen Aussenposten vorbei zu fliegen und dabei mit seinen Blitzwaffen und Raketen große Mengen an Schaden verursachen. +mech.javelin-ship.weapon = Raketensalve +mech.javelin-ship.ability = Statische Entladung mech.trident-ship.name = Trident mech.trident-ship.description = Ein schwerer Bomber, solide gepanzert. -mech.trident-ship.weapon = Bomb Bay +mech.trident-ship.weapon = Bombenschacht mech.glaive-ship.name = Glaive -mech.glaive-ship.description = Ein großes gut gepanzertes Gunship. Ausgerüstet mit einer Brand Waffe. Gute Beschleunigung und maximal Geschwindigkeit. -mech.glaive-ship.weapon = Flame Repeater +mech.glaive-ship.description = Ein großes, gut gepanzertes Gunship. Ausgerüstet mit einer Brandwaffe. Gute Beschleunigung und maximale Geschwindigkeit. +mech.glaive-ship.weapon = Flammen-Mehrlader text.item.explosiveness = [LIGHT_GRAY]Explosivität: {0} text.item.flammability = [LIGHT_GRAY]Entflammbarkeit: {0} text.item.radioactivity = [LIGHT_GRAY]Radioaktivität: {0} -text.item.fluxiness = [LIGHT_GRAY]Fluss Power: {0} -text.unit.health = [LIGHT_GRAY]Gesundheit: {0} +text.item.fluxiness = [LIGHT_GRAY]Strömungskraft: {0} +text.unit.health = [LIGHT_GRAY]Lebenskraft: {0} text.unit.speed = [LIGHT_GRAY]Geschwindigkeit: {0} text.mech.weapon = [LIGHT_GRAY]Waffe: {0} text.mech.armor = [LIGHT_GRAY]Rüstung: {0} -text.mech.itemcapacity = [LIGHT_GRAY]Gegenstands Kapazität: {0} -text.mech.minespeed = [LIGHT_GRAY]Mining Geschwindigkeit: {0} -text.mech.minepower = [LIGHT_GRAY]Mining Power: {0} +text.mech.itemcapacity = [LIGHT_GRAY]Materialkapazität: {0} +text.mech.minespeed = [LIGHT_GRAY]Erzabbaugeschwindigkeit: {0} +text.mech.minepower = [LIGHT_GRAY]Erzabbaukraft: {0} text.mech.ability = [LIGHT_GRAY]Fähigkeit: {0} -text.liquid.heatcapacity = [LIGHT_GRAY]Hitze Kapazität: {0} +text.liquid.heatcapacity = [LIGHT_GRAY]Wärmekapazität: {0} text.liquid.viscosity = [LIGHT_GRAY]Viskosität: {0} text.liquid.temperature = [LIGHT_GRAY]Temperatur: {0} -block.spawn.name = Gegner Spawn -block.core.name = Kern -block.metalfloor.name = Metal Boden +block.spawn.name = Gegnerischer Startpunkt +block.core.name = Basis +block.metalfloor.name = Metallboden block.deepwater.name = Tiefes Wasser block.water.name = Wasser block.lava.name = Lava -block.tar.name = Tar +block.tar.name = Teer block.blackstone.name = Schwarzer Stein block.stone.name = Stein block.dirt.name = Dreck block.sand.name = Sand block.ice.name = Eis block.snow.name = Schnee -block.grass.name = Grass +block.grass.name = Gras block.shrub.name = Busch block.rock.name = Fels block.blackrock.name = Schwarzer Fels -block.icerock.name = Eis Fels -block.copper-wall.name = Kupfer Mauer -block.copper-wall-large.name = Grosse Kupfer Mauer -block.dense-alloy-wall.name = Dichte Legierungs Mauer -block.dense-alloy-wall-large.name = Grosse Dichte Legierungs Mauer -block.phase-wall.name = Phase Mauer -block.phase-wall-large.name = Grosse Phase Mauer -block.thorium-wall.name = Thorium Mauer -block.thorium-wall-large.name = Große Thorium Mauer +block.icerock.name = Eisfels +block.copper-wall.name = Kupfermauer +block.copper-wall-large.name = Große Kupfermauer +block.dense-alloy-wall.name = Dichte Legierungsmauer +block.dense-alloy-wall-large.name = Große dichte Legierungsmauer +block.phase-wall.name = Phasenmauer +block.phase-wall-large.name = Große Phasenmauer +block.thorium-wall.name = Thorium-Mauer +block.thorium-wall-large.name = Große Thorium-Mauer block.door.name = Tür -block.door-large.name = grosse Tür +block.door-large.name = Große Tür block.duo.name = Duo block.scorch.name = Scorch block.hail.name = Hail block.lancer.name = Lancer block.conveyor.name = Förderband -block.titanium-conveyor.name = Titanium Transportband +block.titanium-conveyor.name = Titan-Förderband block.junction.name = Kreuzung block.router.name = Verteiler -block.distributor.name = Verteiler +block.distributor.name = Großer Verteiler block.sorter.name = Sortierer -block.sorter.description = Sortiert Gegenstände. Wenn ein Gegenstand der Auswahl entspricht darf er vorbei. Andernfalls wird er links oder rechts ausgegeben. -block.overflow-gate.name = Overflow Gate -block.overflow-gate.description = Eine Kombination aus Splitter und router der nur Gegenstände nach links oder rechts ausgibt falls der Weg gerade aus blockiert ist. +block.sorter.description = Sortiert Materialien. Wenn ein Gegenstand der Auswahl entspricht, darf er vorbei. Andernfalls wird er links oder rechts ausgegeben. +block.overflow-gate.name = Überlauftor +block.overflow-gate.description = Ein Verteiler, der nur Materialien nach links oder rechts ausgibt, falls der Weg gerade aus blockiert ist. block.smelter.name = Schmelzer -block.arc-smelter.name = Lichtbogen Schmelzer -block.silicon-smelter.name = Silizium Schmelzer -block.phase-weaver.name = Phase Weaver +block.arc-smelter.name = Lichtbogen-Schmelzer +block.silicon-smelter.name = Silizium-Schmelzer +block.phase-weaver.name = Phasenweber block.pulverizer.name = Pulverisierer -block.cryofluidmixer.name = Cryofluid Mixer +block.cryofluidmixer.name = Kryoflüssigkeitsmixer block.melter.name = Schmelzer block.incinerator.name = Verbrennungsanlage -block.biomattercompressor.name = Biomassen Verdichter -block.separator.name = Seperierer +block.biomattercompressor.name = Biomassenverdichter +block.separator.name = Separierer block.centrifuge.name = Zentrifuge -block.power-node.name = Power Knoten -block.power-node-large.name = Grosser Power Knoten +block.power-node.name = Stromknoten +block.power-node-large.name = Großer Stromknoten block.battery.name = Batterie -block.battery-large.name = Grosse Batterie -block.combustion-generator.name = Verbrennungs-Generator -block.turbine-generator.name = Turbinen Generator +block.battery-large.name = Große Batterie +block.combustion-generator.name = Verbrennungsgenerator +block.turbine-generator.name = Turbinengenerator block.mechanical-drill.name = Mechanischer Bohrer block.pneumatic-drill.name = Pneumatischer Bohrer -block.laser-drill.name = Laser Bohrer -block.water-extractor.name = Wasser Extraktor +block.laser-drill.name = Laser-Bohrer +block.water-extractor.name = Wasser-Extraktor block.cultivator.name = Kultivierer block.alpha-mech-pad.name = Alpha Mech Pad block.dart-ship-pad.name = Dart Ship Pad @@ -567,57 +566,57 @@ block.omega-mech-pad.name = Omega Mech Pad block.tau-mech-pad.name = Tau Mech Pad block.conduit.name = Leitungsrohr block.mechanical-pump.name = Mechanische Pumpe -block.itemsource.name = Gegenstands Quelle -block.itemvoid.name = Gegenstand Void -block.liquidsource.name = Flüssigkeits-Quelle -block.powervoid.name = Power Void -block.powerinfinite.name = Power Unendlich +block.itemsource.name = Materialquelle +block.itemvoid.name = Materialschlucker +block.liquidsource.name = Flüssigkeitsquelle +block.powervoid.name = Stromsenke +block.powerinfinite.name = Unendliche Stromquelle block.unloader.name = Entlader block.vault.name = Tresor block.wave.name = Welle -block.swarmer.name = Swarmer -block.salvo.name = Salvo -block.ripple.name = Ripple -block.phase-conveyor.name = Phase Transportband -block.bridge-conveyor.name = Brücken Transportband -block.plastanium-compressor.name = Plastanium Verdichter -block.pyratite-mixer.name = Pyratite Mixer -block.blast-mixer.name = Blast Mixer -block.solidifer.name = Solidifer +block.swarmer.name = Schwärmer +block.salvo.name = Salve +block.ripple.name = Riffel +block.phase-conveyor.name = Phasen-Transportband +block.bridge-conveyor.name = Brücken-Transportband +block.plastanium-compressor.name = Plastanium-Verdichter +block.pyratite-mixer.name = Pyratit-Mixer +block.blast-mixer.name = Sprengmixer +block.solidifer.name = Verhärter block.solar-panel.name = Solar Panel -block.solar-panel-large.name = Grosses Solar Panel +block.solar-panel-large.name = Großes Solar Panel block.oil-extractor.name = Oil Extraktor -block.spirit-factory.name = Spirit Drone Fabrik -block.phantom-factory.name = Phantom Drone Fabrik -block.wraith-factory.name = Wraith Fighter Fabrik -block.ghoul-factory.name = Ghoul Bomber Fabrik -block.dagger-factory.name = Dagger Mech Fabrik -block.titan-factory.name = Titan Mech Fabrik -block.fortress-factory.name = Fortress Mech Fabrik -block.revenant-factory.name = Revenant Fighter Fabrik -block.repair-point.name = Reparatur Punkt -block.pulse-conduit.name = Pulse Rohr -block.phase-conduit.name = Phase Rohr -block.liquid-router.name = Liquid Router -block.liquid-tank.name = Liquid Tank -block.liquid-junction.name = Liquid Kreuzung -block.bridge-conduit.name = Brücken Rohr +block.spirit-factory.name = Spirit-Drohnenfabrik +block.phantom-factory.name = Phantom-Drohnenfabrik +block.wraith-factory.name = Wraith Fighter-Fabrik +block.ghoul-factory.name = Ghoul Bomber-Fabrik +block.dagger-factory.name = Dagger Mech-Fabrik +block.titan-factory.name = Titan Mech-Fabrik +block.fortress-factory.name = Fortress Mech-Fabrik +block.revenant-factory.name = Revenant Fighter-Fabrik +block.repair-point.name = Reparaturpunkt +block.pulse-conduit.name = Impulskanal +block.phase-conduit.name = Phasenkanal +block.liquid-router.name = Flüssigkeits-Router +block.liquid-tank.name = Flüssigkeitstank +block.liquid-junction.name = Flüssigkeits-Kreuzung +block.bridge-conduit.name = Kanalbrücke block.rotary-pump.name = Rotierende Pumpe -block.thorium-reactor.name = Thorium Reaktor -block.command-center.name = Kommando Zentrum -block.mass-driver.name = Mass Driver -block.blast-drill.name = Spreng Bohrer +block.thorium-reactor.name = Thorium-Reaktor +block.command-center.name = Kommandozentrum +block.mass-driver.name = Massenbeschleuniger +block.blast-drill.name = Sprengbohrer block.thermal-pump.name = Thermische Pumpe block.thermal-generator.name = Thermischer Generator -block.alloy-smelter.name = Legierungs Schmeltzer -block.mend-projector.name = Mend Projector -block.surge-wall.name = Surge Mauer -block.surge-wall-large.name = Grosse Surge Mauer +block.alloy-smelter.name = Legierungsschmeltzer +block.mend-projector.name = Reparaturprojektor +block.surge-wall.name = Spannungsstoß-Mauer +block.surge-wall-large.name = Große Spannungsstoß-Mauer block.cyclone.name = Cyclone block.fuse.name = Fuse -block.shock-mine.name = Schock Mine -block.overdrive-projector.name = Overdrive Projektor -block.force-projector.name = Force Projektor +block.shock-mine.name = Schock-Mine +block.overdrive-projector.name = Beschleunigungs-Projektor +block.force-projector.name = Kraftfeld-Projektor block.arc.name = Arc block.rtg-generator.name = RTG Generator block.spectre.name = Spectre @@ -630,29 +629,29 @@ team.orange.name = Orange team.none.name = Grau team.green.name = Grün team.purple.name = Lila -unit.alpha-drone.name = Alpha Drone -unit.spirit.name = Spirit Drone -unit.spirit.description = Die anfängliche Drohne. Sie wird gewöhnlich im Kern erzeugt. Baut automatisch Erz ab, sammelt Gegenstände und repariert Blöcke. -unit.phantom.name = Phantom Drone -unit.phantom.description = Eine fortgeschrittene Drohne. Baut automatisch Erz ab, sammelt Gegenstände und repariert Blöcke. Signifikant effizienter als die Drohne. +unit.alpha-drone.name = Alpha Drohne +unit.spirit.name = Spirit Drohne +unit.spirit.description = Die anfängliche Drohne. Sie wird gewöhnlich in der Basis Erz ab, sammelt Materialien und repariert Blöcke. +unit.phantom.name = Phantom Drohne +unit.phantom.description = Eine fortgeschrittene Drohne. Baut automatisch Erz ab, sammelt Materialien und repariert Blöcke. Deutlich effizienter als die Drohne. unit.dagger.name = Dagger -unit.dagger.description = Eine Standard Bodeneinheit. Nützlich in Schwärmen. +unit.dagger.description = Eine Standard-Bodeneinheit. Nützlich in Schwärmen. unit.titan.name = Titan -unit.titan.description = Eine fortgeschrittene gepanzerte Bodeneinheit. Benutzt Carbide als Munition. Kann sowohl Boden als auch Luft Einheiten angreifen. +unit.titan.description = Eine fortgeschrittene gepanzerte Bodeneinheit. Greift sowohl Boden- als auch Luftziele an. unit.ghoul.name = Ghoul Bomber -unit.ghoul.description = Ein schwerer Flächen Bomber. Benutzt Explosives Gemisch und Pyratite als Munition. +unit.ghoul.description = Ein schwerer Flächenbomber. unit.wraith.name = Wraith Fighter -unit.wraith.description = Eine schnelle Abfangjäger Einheit. +unit.wraith.description = Eine schneller Abfangjäger. unit.fortress.name = Fortress -unit.fortress.description = Eine schwere Artillerie Boden-Einheit. +unit.fortress.description = Eine schwere Artillerie-Bodeneinheit. unit.revenant.name = Revenant -unit.revenant.description = Eine schwere Laser Platform. +unit.revenant.description = Eine schwere Laser-Platform. tutorial.begin = Deine Mission ist es den [LIGHT_GRAY]Gegner[] auszurotten.\n\n Beginne damit [accent] Kupfer abzubauen[]. Beginne in dem du auf ein Kupfer Vorkommen nahe deines Kerns klickst. tutorial.drill = Manuelles Abbauen von Ressourcen ist ineffizient.\n[accent]Bohrer[] können automatisch abbauen.\n Platziere einen auf einem Kupfer Vorkommen. -tutorial.conveyor = [accent]Transportbänder[] werden dazu benutzt Gegenstände zum Kern zu transportieren.\n Erstelle eine Reihe von Transportbändern zum Kern. +tutorial.conveyor = [accent]Transportbänder[] werden dazu benutzt Materialien zum Kern zu transportieren.\n Erstelle eine Reihe von Transportbändern zum Kern. tutorial.morecopper = Du brauchst [accent]mehr Kupfer[]!\n\nEntweder du baust es manuell ab, oder du platzierst weitere Bohrer. -tutorial.turret = Wir benötigen Verteidigung gegen den [LIGHT_GRAY] Gegner[].\n Baue einen Duo Turm nahe deiner Basis. -tutorial.drillturret = Der Duo Turm benötigt[accent] Kupfer[] als Munition. Platziere einen Bohrer neben dem Turm, um ihn mit Kupfer zu versorgen. +tutorial.Geschützturm = Wir benötigen Verteidigung gegen den [LIGHT_GRAY] Gegner[].\n Baue einen Duo Turm nahe deiner Basis. +tutorial.drillGeschützturm = Der Duo Turm benötigt[accent] Kupfer[] als Munition. Platziere einen Bohrer neben dem Turm, um ihn mit Kupfer zu versorgen. tutorial.waves = Der [LIGHT_GRAY] Gegner[] greift an.\n\nVerteidige deinen Kern 2 Wellen lang. Bau mehr Türme. tutorial.lead = Mehr Erz ist verfügbar. Finde Blei und bau es ab.\n\n Klicke auf deine Einheit und ziehe die Maus auf den Kern um Ressourcen zu übertragen. tutorial.smelter = Kupfer und Blei sind schwache Metalle.\n Super [accent]dichte Legierung [] kann in einem Schmeltzer erzeugt werden.\n\n Bau einen. @@ -661,120 +660,121 @@ tutorial.siliconsmelter = Der Kern wird nun [accent]spirit drohnen[] erstellen. tutorial.silicondrill = Silizium benötigt [accent]Kohle[] und [accent]Sand[].\n Fange damit an die Bohrer zu platzieren. tutorial.generator = Diese Technologie benötigt power.\n Erstelle einen Verbrennungs-Generator dafür. tutorial.generatordrill = Verbrennungs Generatoren benötigen Kraftstoff.\nBenutze Kohle aus einem Bohrer als Kraftstoff. -tutorial.node = Power muss transportiert werden.\nErstelle einen [accent]Power Knoten[] nahe deinem Verbrennungs Generator um seine Power zu transportieren. -tutorial.nodelink = Power kann über verbundene Power Blocks, Generatoren oder Power Knoten transferierd werden.\n\n Verbinde die Power in dem du auf den Knoten klickst und dann den Generator und den Silizium Schmeltzer auswählst. +tutorial.node = Power muss transportiert werden.\nErstelle einen [accent]Stromknoten[] nahe deinem Verbrennungs Generator um seine Power zu transportieren. +tutorial.nodelink = Power kann über verbundene Power Blocks, Generatoren oder Stromknoten transferierd werden.\n\n Verbinde die Power in dem du auf den Knoten klickst und dann den Generator und den Silizium Schmeltzer auswählst. tutorial.silicon = Silizium wird produziert. Produziere einiges.\n\n Verbesserungen am Produktionssystem werden empfohlen. tutorial.daggerfactory = Konstruiere eine Dagger Mech Fabrik.\n\n Diese wird verwendet um Angreifende Mechs zu erstellen. -tutorial.router = Fabriken benötigen Ressourcen um zu funktionieren.\n Platziere ein Router um Gegenstände auf Transportbändern aufzuteilen. -tutorial.dagger = Verbinde die Fabrik mit einem Power Knoten. Wenn alle Voraussetzungen gegeben sind, beginnt die Fabrik Mechs zu konstruieren.\n\n Platziere mehr Bohrer und Transportbänder um die Versorgung der Fabrik zu sichern. +tutorial.router = Fabriken benötigen Ressourcen um zu funktionieren.\n Platziere ein Router um Materialien auf Transportbändern aufzuteilen. +tutorial.dagger = Verbinde die Fabrik mit einem Stromknoten. Wenn alle Voraussetzungen gegeben sind, beginnt die Fabrik Mechs zu konstruieren.\n\n Platziere mehr Bohrer und Transportbänder um die Versorgung der Fabrik zu sichern. tutorial.battle = Der[LIGHT_GRAY] Gegner[] hat seinen Kern offenbart.\nZerstöre ihn mit deiner Einheit und den 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. +block.core.description = Das wichtigste Gebäude im Spiel +block.copper-wall.description = Ein günstiger Verteidigungsblock.\nNützlich, um die Basis und Türme in den ersten Wellen zu beschützen. +block.copper-wall-large.description = Ein günstiger Verteidigungsblock.\nNützlich, um die Basis und Türme in den ersten Wellen zu beschützen.\nBenötigt mehrere Kacheln. +block.dense-alloy-wall.description = Ein Standard-Verteidigungsblock.\nAngemessener Schutz vor Feinden. +block.dense-alloy-wall-large.description = Ein Standard-Verteidigungsblock.\nAngemessener Schutz vor Feinden.\nBenötigt mehrere Kacheln. +block.thorium-wall.description = Ein starker Verteidigungsblock.\nGuter Schutz vor Feinden. +block.thorium-wall-large.description = Ein starker Verteidigungsblock.\nGuter Schutz vor Feinden.\nBenötigt mehrere Kacheln. +block.phase-wall.description = Nicht so stark wie eine Thorium-Mauer, aber reflektiert Schüsse bis zu einer gewissen Stärke. +block.phase-wall-large.description = Nicht so stark wie eine Thorium-Mauer, aber reflektiert Schüsse bis zu einer gewissen Stärke.\nBenötigt mehrere Kacheln. +block.surge-wall.description = Der stärkste Verteidigungsblock.\nHat eine kleine Chance, bei einem Schuss einen Lichtbogen in Richtung angreifer auszulösen. +block.surge-wall-large.description = Der stärkste Verteidigungsblock.\nHat eine kleine Chance, bei einem Schuss einen Lichtbogen in Richtung angreifer auszulösen.\nBenötigt mehrere Kacheln. +block.door.description = Eine kleine Tür, die durch darauf tippen geöffnet und geschlossen werden kann.\nGegner können durch geöffnete Türen schießen und laufen. +block.door-large.description = Eine kleine Tür, die durch darauf tippen geöffnet und geschlossen werden kann.\nGegner können durch geöffnete Türen schießen und laufen.\nBenötigt mehrere Kacheln. +block.mend-projector.description = Heilt zyklisch Blöcke in seiner Umgebung. +block.overdrive-projector.description = Erhöht die Geschwindigkeit von nahegelegenen Blöcken wie Bohrer und Förderbänder. +block.force-projector.description = Erzeugt ein sechseckiges Kraftfeld um sich selbst, durch das Blöcke und Einheiten vor Schaden beschützt werden. +block.shock-mine.description = Beschädigt Gegner, die auf die Mine laufen. Für Gegener schwer zu sehen. +block.duo.description = Ein kleiner, günstiger Geschützturm. +block.arc.description = Ein kleiner Geschützturm, der Lichtbögen in Richtung des Gegners schießt. +block.hail.description = Ein kleiner Artillerie-Geschützturm. +block.lancer.description = Ein mittelgroßer Geschützturm, der sich auflädt und Elektrizitätsstrahlen verschießt. +block.wave.description = Ein mittelgroßer Geschützturm, der flüssige Kugeln verschießt. +block.salvo.description = Ein mittelgroßer Geschützturm, der Schüsse in Salven abfeuert. +block.swarmer.description = Ein mittelgroßer Geschützturm, der Raketenschwärme abfeuert. +block.ripple.description = Ein großer Artillerie-Geschützturm, der mehrere Schüsse gleichzeitig abfeuert. +block.cyclone.description = Ein großer Schnellfeuer-Geschützturm. +block.fuse.description = Ein großer Geschützturm, der starke Strahlen mit kurzer Reichweite abfeuert. +block.spectre.description = Ein großer Geschützturm, der zwei starke Schüsse gleichzeitig abfeuert. +block.meltdown.description = Ein großer Geschützturm, der starke Strahlen mit großer Reichweite abfeuert. +block.conveyor.description = Basis-Transportblock. Bewegt Materialien vorwärts und lädt sie automatisch in Geschütztürme oder Verarbeitungsanlagen. Rotierbar. +block.titanium-conveyor.description = Verbesserter Transportblock. Bewegt Materialien schneller als Standard-Förderbänder. +block.phase-conveyor.description = Verbesserter Transportblock. Verwendet Strom, um Materialien zu einem verbundenen Phasen-Förderband über mehrere Kacheln zu teleportieren. +block.junction.description = Fungiert als Brücke zwischen zwei kreuzenden Förderbändern. Nützlich, wenn zwei verschiedene Förderbänder sich kreuzen, aber unterschiedliche Materialien verwenden. +block.mass-driver.description = Ultimativer Transportblock. Sammelt mehrere Materialien und schießt sie zu einem verbundenen Massenbeschleuniger über eine große Reichweite. +block.smelter.description = Verbrennt Kohle, um Kupfer und Blei zu einer dichten Legierung zu verschmelzen. +block.arc-smelter.description = Verschmilzt Kupfer und Blei zu einer dichten Legierung, indem es eine externe Stromquelle benutzt. +block.silicon-smelter.description = Reduziert Sand mit hochreinem Kohlenstoff, um Silizium zu produzieren. +block.plastanium-compressor.description = Produziert Plastanium aus Öl und Titan. +block.phase-weaver.description = Produziert Phasengewebe aus radioaktivem Thorium und großen Mengen an Sand. +block.alloy-smelter.description = Verarbeitet Titan, Blei, Silizium und Kupfer zu einer Stromstoßlegierung. +block.pulverizer.description = Zertrümmert Stein zu Sand. Nützlich, wenn kein natürlicher Sand verfügbar ist. +block.pyratite-mixer.description = Vermischt Kohle, Blei und Sand zu hochentzündlichem Pyratit. +block.blast-mixer.description = Verwendet Öl, um Pyratit in eine weniger enzündliche aber explosivee Mischung umzuwandeln. +block.cryofluidmixer.description = Verarbeitet Wasser mit Titan zu einer Kryoflüssigkeit, die viel effizienter kühlt. +block.solidifer.description = Kühlt Lava zu großen Mengen Stein. +block.melter.description = Erhitzt Stein auf extrem hohe Temperaturen, um Lava zu erhalten. +block.incinerator.description = Vernichtet beliebige überschüssige Materialien oder Flüssigkeiten. +block.biomattercompressor.description = Komprimiert Biomasse, um Öl zu erhalten. +block.separator.description = Setzt Stein Wasserdruck aus, um verschiedene Mineralien im Stein freizulegen. +block.centrifuge.description = Effizienter als der Separierer, aber auch teurer zum Bauen und benötigt Strom. +block.power-node.description = Überträgt Strom zu verbundenen Knoten. Bis zu vier Stromquellen, -verbraucher oder -knoten können verbunden werden. Der Knoten erhält Strom von benachbarten Knoten und gibt Strom benachbarte Blöcke weiter. +block.power-node-large.description = Hat einen größeren Radius als der normale Stromknoten und verbindet bis zu sechs Stromquellen, -verbraucher oder -knoten. +block.battery.description = Speichert Strom, solange ein Überschuss besteht, und gibt ihn bei Knappheit ab, solange Kapazität vorhanden ist. +block.battery-large.description = Speichert sehr viel mehr Strom als eine normale Batterie. +block.combustion-generator.description = Generiert Stromg, indem Öl oder entzündliche Materialien verbrannt werden. +block.turbine-generator.description = Effizienter als ein Verbrennungsgenerator, benötigt jedoch zusätzlich Wasser. +block.thermal-generator.description = Erzeugt große Mengen Strom aus Lava. +block.solar-panel.description = Erzeugt kleine Mengen an Strom aus Sonnenenergie. +block.solar-panel-large.description = Erzeugt viel mehr Strom als ein normales Solar Panel, ist aber auch sehr viel teurer in der Anschaffung. +block.thorium-reactor.description = Erzeugt riesige Mengen Strom aus radioaktivem Thorium. Benötigt konstante Kühlung. Explodiert verheerend, wenn unzureichende Mengen an Kühlung vorhanden sind. +block.rtg-generator.description = Ein Radioisotopengenerator, der keine Kühlung benötigt, aber weniger Strom als ein Thorium-Reaktor liefert. +block.unloader.description = Entlädt Materialien aus einem Container, Tresor oder einer Basis auf ein Förderband oder direkt in einen benachbarten Block. Der Typ des auszuladenden Materials kann durch darauf tippen verändert werden. +block.container.description = Speichert eine kleine Menge an Materialien pro Typ. Benachbarte Container, Tresore und Basen werden zu einem Behälter zusammengefasst. Ein[LIGHT_GRAY] Entlader[] kann verwendet werden, um Materialien auszuladen. +block.vault.description = Speichert eine große Menge an Materialien pro Typ. Benachbarte Container, Tresore und Basen werden zu einem Behälter zusammengefasst. Ein[LIGHT_GRAY] Entlader[] kann verwendet werden, um Materialien auszuladen. +block.mechanical-drill.description = Ein günstiger Bohrer. Wenn er auf passende Kacheln gesetzt wird, baut er unbegrenzt Erze des entsprechenden Typs mit geringer Geschwindigkeit ab. +block.pneumatic-drill.description = Ein verbesserter Bohrer, der schneller ist und in der Lage ist, härtere Erze abzubauen, indem er von Luftdruck gebrauch macht. +block.laser-drill.description = Erlaubt es, durch Lasertechnologie noch schneller zu bohren, benötigt aber Strom. Erlaubt zusätzlich das Abbauen von radioaktivem Thorium. +block.blast-drill.description = Der ultimative Bohrer. Benötigt große Mengen an Strom. +block.water-extractor.description = Extrahiert Wasser aus dem Boden. Verwende ihn, wenn es keinen See in der Nähe gibt. +block.cultivator.description = Kultiviert den Boden mit Wasser, um Biomasse zu erzeugen. +block.oil-extractor.description = Verwendet große Mengen an Strom, um Öl aus Sand zu extrahieren. Verwende ihn, wenn es keine direkte Ölquelle gibt. +block.dart-ship-pad.description = Wechsle in einen Standard-Jäger.\nVerwende das Pad, indem du doppelt darauf tippst, während du darauf bist. +block.trident-ship-pad.description = Wechsle in einen massiv gepanzerten schweren Bomber.\nVerwende das Pad, indem du doppelt darauf tippst, während du darauf bist. +block.javelin-ship-pad.description = Wechsle in einen starken und schnellen Abfangjäger mit Blitz-Waffen.\nVerwende das Pad, indem du doppelt darauf tippst, während du darauf bist. +block.glaive-ship-pad.description = Wechsle in ein großes, gut gepanzertes Kampfflugzeug.\nVerwende das Pad, indem du doppelt darauf tippst, während du darauf bist. +block.tau-mech-pad.description = Wechsle in einen Support-Mech, der befreundete Blöcke und Einheiten heilen kann.\nVerwende das Pad, indem du doppelt darauf tippst, während du darauf bist. +block.delta-mech-pad.description = Wechsle in einen schnellen, leicht gepanzerten Mech, der für Überfälle gemacht ist.\nVerwende das Pad, indem du doppelt darauf tippst, während du darauf bist. +block.omega-mech-pad.description = Wechsle in einen klobigen und gut gepanzerten Mech, der für Frontangriffe gemacht ist.\nVerwende das Pad, indem du doppelt darauf tippst, während du darauf bist. +block.spirit-factory.description = Produziert leichte Drohnen, die Erz abbauen und Blöcke reparieren können. +block.phantom-factory.description = Produziert erweiterte Drohnen, die deutlich effizienter sind als Spirit-Drohnen. +block.wraith-factory.description = Produziert schnelle Abfangjäger. +block.ghoul-factory.description = Produziert schwere Flächenbomber. +block.dagger-factory.description = Produziert Standard-Bodeneinheiten. +block.titan-factory.description = Produziert fortgeschrittene, gepanzerte Bodeneinheiten. +block.fortress-factory.description = Produziert schwere Artillerie-Bodeneinheiten. +block.revenant-factory.description = Produziert schwere Laser-Bodeneinheiten. +block.repair-point.description = Heilt durchgehend die nächste befreundete, beschädigte Einheit in der Umgebung. +block.command-center.description = Erlaubt es, die KI der eigenen Einheiten zu ändern. Momentan sind Angriff, Rückzug und Patroulle unterstützt. +block.conduit.description = Standard Flüssigkeits-Transportblock. Funktioniert wie ein Förderband, nur für Flüssigkeiten. Wird am Besten mit Extraktoren, Pumpen oder anderen Kanälen benutzt. +block.pulse-conduit.description = Verbesserter Flüssigkeits-Transportblock. Transportiert Flüssigkeiten schneller und speichert mehr als Standard Kanäle. +block.phase-conduit.description = Verbesserter Flüssigkeits-Transportblock. Verwendet Strom, um Flüssigkeiten zu einem verbundenen Phasenkanal zu teleportieren. +block.liquid-router.description = Akzeptiert Flüssigkeiten aus einer Richtung und verteilt sie an bis zu drei andere Richtungen weiter. Nützlich, um Flüssigkeiten aus einer Quelle an mehrere Empfänger zu verteilen. +block.liquid-tank.description = Speichert eine große Menge an Flüssigkeiten. Verwende es als Puffer, wenn Angebot und Nachfrage an einer Flüssigkeit schwanken. +block.liquid-junction.description = Fungiert als Brücke über zwei kreuzende Kanäle. Nützlich in Situationen, in denen sich zwei Kanäle mit verschiedenen Flüssigkeiten kreuzen. +block.bridge-conduit.description = Verbesserter Flüssigkeits-Transportblock. Erlaubt es, Flüssigkeiten über bis zu 3 Kacheln beliebigen Terrains oder Inhalts zu transportieren. +block.mechanical-pump.description = Eine günstige, langsame Punkte, die keine Strom benötigt. +block.rotary-pump.description = Eine fortgeschrittene Pumpe, die mithilfe von Strom doppelt so schnell pumpt. +block.thermal-pump.description = Die ultimative Pumpe, dreimal so schnell wie eine mechanische Pumpe und die einzige Pumpe, die Lava fördern kann. +block.router.description = Akzeptiert Materialien aus einer Richtung und leitet sie gleichmäßig in bis zu drei andere Richtungen weiter. Nützlich, wenn die Materialien aus einer Richtung an mehrere Empfänger verteilt werden sollen. +block.distributor.description = Ein weiterentwickelter Router, der Materialien in bis zu sieben Richtungen gleichmäßig verteilt. +block.bridge-conveyor.description = Verbesserter Transportblock. Erlaubt es, Materialien über bis zu 3 Kacheln beliebigen Terrains oder Inhalts zu transportieren. +block.alpha-mech-pad.description = Sofern genügend Strom zur Verfügung steht, baut dieses Pad deinen Schiff in einen [accent]Alpha[] mech zurück. +block.itemsource.description = Produziert unendlich items. Nur im Sandkasten verfügbar. +block.liquidsource.description = Produziert unendlich Flüssigkeiten. Nur im Sandkasten verfügbar. +block.itemvoid.description = Zerstört Materialien, die hereingegeben werden, ohne Strom zu verbrauchen. Nur im Sandkasten verfügbar. +block.powerinfinite.description = Erzeugt unendlich viel Strom. Nur im Sandkasten verfügbar. +block.powervoid.description = Verschlingt den kompletten übrigen Strom. Nur im Sandkasten verfügbar. +liquid.water.description = Wird überlicherweise zum Kühlen von Maschinen und zur Müllverarbeitung verwendet. +liquid.lava.description = Kann zu [LIGHT_GRAY] Stein[] verarbeitet werden, zur Stromerzeugung verwendet werden oder als Munition für bestimmte Geschütztürme verwendet werden. +liquid.oil.description = Kann verbrannt, zum explodieren gebracht, oder als Kühlung verwendet werden. +liquid.cryofluid.description = Die effizienteste Flüssigkeit, um Dinge herunter zu kühlen. diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties index 8aa84da7d2..6832c8e1d0 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -7,13 +7,13 @@ text.link.dev-builds.description = Versiones de desarrollo inestable text.link.trello.description = Tablero de Trello oficial para las características planificadas text.link.itch.io.description = itch.io es la página donde podes descargar las versiones para PC y web text.link.google-play.description = Ficha en la Google Play Store -text.link.wiki.description = wiki oficial de Mindustry +text.link.wiki.description = Wiki oficial de Mindustry text.linkfail = ¡Error al abrir el enlace!\nLa URL ha sido copiada a su portapapeles. -text.editor.web = ¡La versión web no es compatible con el editor!\nDescargue el juego para usarlo. +text.editor.web = ¡La versión web no es compatible con el editor!\nDescarga el juego para usarlo. text.web.unsupported = ¡La versión web no soporta esta característica! Descarga el juego para poder usarla. text.gameover = Tu núcleo ha sido destruido. -text.gameover.pvp = El equipo[accent] {0}[] ha ganado! -text.sector.gameover = Este sector ha sido perdido. ¿Re-instaurar? +text.gameover.pvp = ¡El equipo[accent] {0}[] ha ganado! +text.sector.gameover = Este sector ha sido perdido. ¿Re-desplegar? text.sector.retry = Reintentar text.highscore = [accent]¡Nueva mejor puntuación! text.wave.lasted = Duraste hasta la ronda [accent]{0}[]. @@ -22,35 +22,35 @@ text.level.delete.title = Confirmar Eliminación text.map.delete = ¿Estás seguro que quieres borrar el mapa "[accent]{0}[]"? text.level.select = Selección de nivel text.level.mode = Modo de juego: -text.construction.desktop = Los controles de la versión de escritorio han cambiado.\nPara deseleccionar un bloque o dejar de construir, [accent]usa la barra espaciadora[]. +text.construction.desktop = Los controles de la versión de escritorio han cambiado.\nPara deseleccionar un bloque o dejar de construir, [accent]usa la space tab[]. text.construction.title = Guía de Construcción de Bloques text.construction = Acaba de seleccionar el [accent]modo de construcción de bloques[].\n\nPara empezar a colocar, simplemente presione en una localización valida cerca de su nave.\nCuando haya terminado de seleccionar algunos bloques, presiona la casilla para confirmar, y su nave empezara a construirlos.\n\n- [accent]Remueve bloques[] de tu selección presionando en ellos.\n- [accent]Cambia tu selección de lugar[] manteniendo y arrastrando cualquier bloque en la selección.\n- [accent]Coloca bloques en línea[] presionando y manteniendo en un espacio vacío, y arrastrando hacia cualquier dirección.\n- [accent]Cancela la construcción o selección[] presionando la X abajo a la izquierda. text.deconstruction.title = Guía de Deconstrucción de Bloques -text.deconstruction = Acaba de seleccionar el [accent]modo de deconstrucción de bloques[].\n\nPara empezar a destruir, simplemente presione en un bloque cercano a su nave.\nCuando haya terminado de seleccionar algunos bloques, presiona la casilla para confirmar, y su nave empezara a de-construirlos.\n\n- [accent]Remueve bloques[] de tu selección presionando en ellos.\n- [accent]Remueve bloques en un area[] presionando y manteniendo en un espacio vacío, y arrastrando hacia cualquier dirección.\n- [accent]Cancela la deconstrucción o selección[] presionando la X abajo a la izquierda. -text.showagain = No mostrar devuelta en la próxima sesión +text.deconstruction = Acaba de seleccionar el [accent]modo de deconstrucción de blocks[].\n\nPara empezar a destruir, simplemente presione en un bloque cercano a su nave.\nCuando haya terminado de seleccionar algunos bloques, presiona la casilla para confirmar, y su nave empezara a de-construirlos.\n\n- [accent]Remueve bloques[] de tu selección presionando en ellos.\n- [accent]Remueve bloques en un area[] presionando y manteniendo en un espacio vacío, y arrastrando hacia cualquier dirección.\n- [accent]Cancela la deconstrucción o selección[] presionando la X abajo a la izquierda. +text.showagain = No mostrar otra vez en la próxima sesión text.coreattack = < ¡El núcleo está bajo ataque! > text.unlocks = Desbloqueos text.savegame = Guardar Partida text.loadgame = Cargar Partida text.joingame = Unirse a la Partida -text.addplayers = Agregar/Remover Jugadores +text.addplayers = Agregar/Quitar Jugadores text.customgame = Partida personalizada text.sectors = Sectores text.sector = Sector: [LIGHT_GRAY]{0} text.sector.time = Tiempo: [LIGHT_GRAY]{0} text.sector.deploy = Desplegar text.sector.abandon = Abandonar -text.sector.abandon.confirm = ¿Definitivamente quieres abandonar todo el progreso hecho en este sector?\n¡Esto no se puede deshacer! -text.sector.resume = Resumir +text.sector.abandon.confirm = ¿Realmente quieres abandonar todo el progreso hecho en este sector?\n¡Esto no se puede deshacer! +text.sector.resume = Continuar text.sector.locked = [scarlet][[Incompleto] -text.sector.unexplored = [accent][[Inexplorado] -text.missions = Missions:[LIGHT_GRAY] {0} +text.sector.unexplored = [accent][[No explorado] +text.missions = Misiones:[LIGHT_GRAY] {0} text.mission = Misión:[LIGHT_GRAY] {0} text.mission.main = Misión Principal:[LIGHT_GRAY] {0} text.mission.info = Información de la Misión text.mission.complete = ¡Misión completada! text.mission.complete.body = El Sector {0},{1} ha sido conquistado. -text.mission.wave = Sobrevive [accent]{0}[] hordas. +text.mission.wave = Sobrevive [accent]{0}/{1}[] hordas\nHordas en {2} text.mission.wave.enemies = Sobrevive[accent] {0}/{1} []hordas\n{2} Enemigas text.mission.wave.enemy = Sobrevive[accent] {0}/{1} []hordas\n{2} Enemigas text.mission.wave.menu = Sobrevive[accent] {0} []hordas @@ -58,11 +58,11 @@ text.mission.battle = Destruye la base enemiga. text.mission.resource.menu = Obtener {0} x{1} text.mission.resource = Obtén {0} x{1} text.mission.block = Crear {0} -text.mission.unit = Crear {0} Unit -text.mission.command = Enviar Comando {0} A Las Unidades +text.mission.unit = Crear {0} +text.mission.command = Envía Comando {0} a las unidades text.mission.linknode = Conecta nodo de energía text.mission.display = [accent]Misión:\n[LIGHT_GRAY]{0} -text.mission.mech = Cambiar a mech[accent] {0}[] +text.mission.mech = Cambiar a mecanoide[accent] {0}[] text.mission.create = Crear[accent] {0}[] text.none = text.close = Cerrar @@ -82,24 +82,24 @@ text.server.closing = [accent]Cerrando servidor... text.server.kicked.kick = ¡Has sido expulsado del servidor! text.server.kicked.serverClose = El servidor ha cerrado. text.server.kicked.sectorComplete = Sector completado. -text.server.kicked.sectorComplete.text = Tu misión ha sido completada.\nEl servidor ahora continuara con el próximo sector. +text.server.kicked.sectorComplete.text = Tu misión ha sido completada.\nEl servidor ahora continuará con el próximo sector. text.server.kicked.clientOutdated = ¡Cliente desactualizado! ¡Actualiza tu juego! text.server.kicked.serverOutdated = ¡Servidor desactualizado! ¡Pídele al anfitrión que lo actualice! text.server.kicked.banned = Has sido baneado del servidor. text.server.kicked.recentKick = Has sido expulsado recientemente.\nEspera para poder conectarte de nuevo. -text.server.kicked.nameInUse = Ya hay alguien con ese nombre\nen el servidor. +text.server.kicked.nameInUse = Ya hay alguien con ese\nnombre en el servidor. text.server.kicked.nameEmpty = Tu nombre debe por lo menos contener un carácter o número. text.server.kicked.idInUse = ¡Ya estás en el servidor! Conectarse con dos cuentas no está permitido. text.server.kicked.customClient = Este servidor no soporta versiones personalizadas. Descarga una versión oficial. -text.host.info = El botón [accent]hostear[] hostea un servidor en el puerto [scarlet]6567[]. \nCualquier persona en la misma [LIGHT_GRAY]wifi o red local[] debería poder ver tu servidor en la lista de servidores.\n\nSi quieres que cualquier persona se pueda conectar de cualquier lugar por IP, la [accent]asignación de puertos[] es requerida.\n\n[LIGHT_GRAY]Nota: Si alguien experimenta problemas conectándose a tu partida LAN, asegúrate de permitir a Mindustry acceso a tu red local mediante la configuración de tu firewall. -text.join.info = Aquí, puedes escribir la [accent]IP de un servidor[] para conectarte, o descubrir servidores de [accent]red local[] para conectarte.\nLAN y WAN es soportado para jugar en multijugador.\n\n[LIGHT_GRAY]Nota: No hay una lista automática global de servidores; si quieres conectarte por IP, tendrás que preguntarle al anfitrión por la IP. +text.host.info = El botón [accent]host[] hostea un servidor en el puerto [scarlet]6567[]. \nCualquier persona en la misma [LIGHT_GRAY]wifi o red local[] debería poder ver tu servidor en la lista de servidores.\n\nSi quieres que cualquier persona se pueda conectar de cualquier lugar por IP, la [accent]asignación de puertos[] es requerida.\n\n[LIGHT_GRAY]Nota: Si alguien experimenta problemas conectándose a tu partida LAN, asegúrate de permitir a Mindustry acceso a tu red local mediante la configuración de tu firewall. +text.join.info = Aquí, puedes escribir la [accent]IP de un server[] para conectarte, o descubrir servidores de [accent]red local[] para conectarte.\nLAN y WAN es soportado para jugar en multijugador.\n\n[LIGHT_GRAY]Nota: No hay una lista automática global de servidores; si quieres conectarte por IP, tendrás que preguntarle al anfitrión por la IP. text.hostserver = Hostear Servidor text.hostserver.mobile = Hostear\nJuego text.host = Hostear text.hosting = [accent]Abriendo servidor... text.hosts.refresh = Actualizar text.hosts.discovering = Descubrir partidas LAN -text.server.refreshing = Actualizando servidor +text.server.refreshing = Actualizando servidor... text.hosts.none = [lightgray]¡No se han encontrado partidas LAN! text.host.invalid = [scarlet]No se ha podido conectar al anfitrión text.trace = Rastrear Jugador @@ -108,29 +108,29 @@ text.trace.ip = IP: [accent]{0} text.trace.id = ID Única: [accent]{0} text.trace.android = Cliente de Android: [accent]{0} text.trace.modclient = Cliente Personalizado: [accent]{0} -text.trace.totalblocksbroken = Total de bloques removidos: [accent]{0} -text.trace.structureblocksbroken = Bloques de estructura removidos: [accent]{0} -text.trace.lastblockbroken = Último bloque removido: [accent]{0} +text.trace.totalblocksbroken = Total de bloques quitados: [accent]{0} +text.trace.structureblocksbroken = Bloques de estructura quitados: [accent]{0} +text.trace.lastblockbroken = Último bloque quitado: [accent]{0} text.trace.totalblocksplaced = Total de bloques colocados: [accent]{0} text.trace.lastblockplaced = Último bloque colocado: [accent]{0} -text.invalidid = ¡ID de cliente invalida! Envía un informe del error. -text.server.bans = Bans +text.invalidid = ¡ID de cliente inválida! Envía un informe del error. +text.server.bans = Baneos text.server.bans.none = ¡Ningún usuario ha sido baneado! -text.server.admins = Admins -text.server.admins.none = ¡Ningún admin ha sido encontrado! +text.server.admins = Administradores +text.server.admins.none = ¡Ningún administrador ha sido encontrado! text.server.add = Agregar Servidor -text.server.delete = ¿Estás seguro que quieres borrar este servidor? +text.server.delete = ¿Estás seguro de querer borrar este servidor? text.server.hostname = Anfitrión: {0} text.server.edit = Editar Servidor text.server.outdated = [crimson]¡Servidor desactualizado![] text.server.outdated.client = [crimson]¡Cliente desactualizado![] text.server.version = [lightgray]Versión: {0} text.server.custombuild = [yellow]Versión personalizada -text.confirmban = ¿Estás seguro que quieres banear este jugador? -text.confirmkick = ¿Estás seguro que quieres expulsar este jugador? -text.confirmunban = ¿Estás seguro que quieres desbanear este jugador? -text.confirmadmin = ¿Estás seguro que quieres hacer admin a este jugador? -text.confirmunadmin = ¿Estás seguro que quieres quitar los permisos de admin a este jugador? +text.confirmban = ¿Estás seguro de querer banear este jugador? +text.confirmkick = ¿Estás seguro de querer expulsar este jugador? +text.confirmunban = ¿Estás seguro de querer desbanear este jugador? +text.confirmadmin = ¿Estás seguro de querer hacer administrador a este jugador? +text.confirmunadmin = ¿Estás seguro de querer quitar los permisos de administrador a este jugador? text.joingame.title = Unirse a la partida text.joingame.ip = IP: text.disconnect = Desconectado. @@ -138,29 +138,29 @@ text.disconnect.data = ¡Se ha fallado la carga de datos del mundo! text.connecting = [accent]Conectando... text.connecting.data = [accent]Cargando datos del mundo... text.server.port = Puerto: -text.server.addressinuse = ¡La dirección está en uso! +text.server.addressinuse = ¡La dirección ya está en uso! text.server.invalidport = ¡El número de puerto es invalido! -text.server.error = [crimson]Error hosteando el servidor: [accent]{0} -text.save.old = Este punto de guardado es para una versión más antigua de este juego, y ya no puede ser usada.\n\n[LIGHT_GRAY]Guardados con retrocompatibilidad serán completamente implementados en la versión 4.0. +text.server.error = [crimson]Error hosteando el servidor: error [accent]{0} +text.save.old = Este punto de guardado es de una versión más antigua de este juego, y ya no puede ser usada.\n\n[LIGHT_GRAY]La retrocmpatibilidad de los puntos de guardado estará completamente implementada en la versión 4.0. text.save.new = Nuevo Punto de Guardado -text.save.overwrite = ¿Estás seguro que quieres sobrescribir\neste punto de guardado? +text.save.overwrite = ¿Estás seguro de querer sobrescribir\neste punto de guardado? text.overwrite = Sobrescribir text.save.none = ¡No se ha encontrado ningún punto de guardado! text.saveload = [accent]Guardando... text.savefail = ¡No se ha podido guardar la partida! -text.save.delete.confirm = ¿Estás seguro que quieres borrar este punto de guardado? +text.save.delete.confirm = ¿Estás seguro de querer borrar este punto de guardado? text.save.delete = Borrar text.save.export = Exportar Punto de Guardado -text.save.import.invalid = [accent]¡Este punto de guardado es invalido! -text.save.import.fail = [crimson]Se ha fallado la importación del punto de guardado: [accent]{0} -text.save.export.fail = [crimson]Se ha fallado la exportación del punto de guardado: [accent]{0} +text.save.import.invalid = [accent]¡Este punto de guardado es inválido! +text.save.import.fail = [crimson]La importación del punto de guardado ha fallado: error [accent]{0} +text.save.export.fail = [crimson]La exportación del punto de guardado ha fallado: error [accent]{0} text.save.import = Importar Punto de Guardado text.save.newslot = Nombre del Punto de Guardado: text.save.rename = Renombrar text.save.rename.text = Nuevo nombre: text.selectslot = Selecciona un Punto de Guardado. text.slot = [accent]Casilla {0} -text.save.corrupted = [accent]¡El punto de guardado está corrupto o es invalido!\nSi acabas de actualizar el juego, esto debe ser probablemente un cambio en el formato de guardado y [scarlet]no[] un error. +text.save.corrupted = [accent]¡El punto de guardado está corrupto o es inválido!\nSi acabas de actualizar el juego, esto debe ser probablemente un cambio en el formato de guardado y[scarlet] no[] un error. text.sector.corrupted = [accent]El punto de guardado de este sector fue encontrado, pero su carga ha fallado.\nUn nuevo punto ha sido creado. text.empty = text.on = Encendido @@ -169,7 +169,7 @@ text.save.autosave = Autoguardado: {0} text.save.map = Mapa: {0} text.save.wave = Horda {0} text.save.difficulty = Dificultad: {0} -text.save.date = Ultima vez guardado: {0} +text.save.date = Última vez guardado: {0} text.save.playtime = Tiempo de juego: {0} text.confirm = Confirmar text.delete = Borrar @@ -182,9 +182,9 @@ text.back = Atras text.quit.confirm = ¿Estás seguro de querer salir de la partida? text.changelog.title = Registro de Parches text.changelog.loading = Consiguiendo el registro de parches... -text.changelog.error.android = [accent]¡Nota que el registro de parches a veces no funciona en Android 4.4 o inferior!\nEsto es por un error de Android interno. -text.changelog.error.ios = [accent]El registro de parches no es actualmente soportado por iOS. -text.changelog.error = [scarlet]¡Error consiguiendo el registro de parches!\nChequeá tu conexión a Internet. +text.changelog.error.android = [accent]¡Nota: el registro de parches a veces no funciona en Android 4.4 o inferior!\nEsto es por un error interno de Android. +text.changelog.error.ios = [accent]El registro de parches no está actualmente soportado para iOS. +text.changelog.error = [scarlet]¡Error consiguiendo el registro de parches!\Comprueba tu conexión a Internet. text.changelog.current = [yellow][[Versión actual] text.changelog.latest = [accent][[Última version] text.loading = [accent]Cargando... @@ -192,7 +192,7 @@ text.saving = [accent]Guardando... text.wave = [accent]Horda {0} text.wave.waiting = Horda en {0} text.waiting = Esperando... -text.waiting.players = Esperando por jugafores... +text.waiting.players = Esperando jugadores... text.wave.enemies = [LIGHT_GRAY]{0} Enemigos Restantes text.wave.enemy = [LIGHT_GRAY]{0} Enemigo Restante text.loadimage = Cargar Imagen @@ -200,11 +200,11 @@ text.saveimage = Guardar Imagen text.unknown = Desconocido text.custom = Personalizado text.builtin = Incorporado -text.map.delete.confirm = ¿Estás seguro que quieres borrar este mapa? ¡Recuerda que está acción no puede ser descartada! +text.map.delete.confirm = ¿Estás seguro de querer borrar este mapa? ¡Recuerda que está acción no puede sdeshacerse! text.map.random = [accent]Mapa Aleatorio -text.map.nospawn = ¡Este mapa no tiene ningún núcleo en el cual pueda meter al jugador! Agrega un núcleo [ROYAL]azul[] al mapa con el editor. -text.map.nospawn.pvp = ¡Este mapa no tiene ningún núcleo enemigo para que aparezca el jugador! Añade [SCARLET] red[] núcleos a este mapa en el editor. -text.map.invalid = Error cargando el mapa: corrupto o archivo invalido. +text.map.nospawn = ¡Este mapa no tiene ningún núcleo en el cual pueda aparecer el jugador! Agrega un núcleo[ROYAL] blue[] al mapa con el editor. +text.map.nospawn.pvp = ¡Este mapa no tiene ningún núcleo enemigo para que aparezca el jugador! Añade un núcleo[SCARLET] red[] a este mapa en el editor. +text.map.invalid = Error cargando el mapa: archivo corrupto o inválido. text.editor.brush = Pincel text.editor.slope = \\ text.editor.openin = Abrir en el Editor @@ -216,15 +216,15 @@ text.editor.description = Descripción: text.editor.name = Nombre: text.editor.teams = Equipos text.editor.elevation = Elevación -text.editor.errorimageload = Error cargando el archivo:\n[accent]{0} -text.editor.errorimagesave = Error guardando el archivo:\n[accent]{0} +text.editor.errorimageload = Error cargando el archivo:\n[accent] {0} +text.editor.errorimagesave = Error guardando el archivo:\n[accent] {0} text.editor.generate = Generar text.editor.resize = Cambiar Tamaño text.editor.loadmap = Cargar Mapa text.editor.savemap = Guardar Mapa text.editor.saved = ¡Guardado! text.editor.save.noname = ¡Tu mapa no tiene un nombre! Pon uno en el menú 'Info del Mapa'. -text.editor.save.overwrite = ¡Tu mapa sobrescribe uno ya incorporado! Elige un nombre diferente en el menu 'Info del Mapa'. +text.editor.save.overwrite = ¡Tu mapa sobrescribe uno ya incorporado! Elige un nombre diferente en el menú 'Info del Mapa'. text.editor.import.exists = [scarlet]¡No se ha podido importar:[] un mapa incorporado con el nombre '{0}' ya existe! text.editor.import = Importar... text.editor.importmap = Importar Mapa @@ -240,14 +240,14 @@ text.editor.exportimage = Exportar Imagen del Terreno text.editor.exportimage.description = Exportar archivo de imagen del mapa text.editor.loadimage = Importar Terreno text.editor.saveimage = Exportar Terreno -text.editor.unsaved = [scarlet]¡Tienes cambios sin guardar![]\n¿Estás seguro que quieres salir? +text.editor.unsaved = [scarlet]¡Tienes cambios sin guardar![]\n¿Estás seguro de querer salir? text.editor.resizemap = Cambiar Tamaño del Mapa text.editor.mapname = Nombre del Mapa: text.editor.overwrite = [accent]¡Advertencia!\nEsto sobrescribe un mapa ya existente. -text.editor.overwrite.confirm = [scarlet]¡Advertencia![] Un mapa con ese nombre ya existe. ¿Estás seguro que quieres sobrescribirlo? +text.editor.overwrite.confirm = [scarlet]¡Advertencia![] Un mapa con ese nombre ya existe. ¿Estás seguro de querer sobrescribirlo? text.editor.selectmap = Selecciona un mapa para cargar: text.width = Ancho: -text.height = Altura: +text.height = Alto: text.menu = Menu text.play = Jugar text.load = Cargar @@ -264,7 +264,7 @@ text.donate = Donar text.connectfail = [crimson]Ha fallado la conexión con el servidor: [accent]{0} text.error.unreachable = Servidor inaccesible. text.error.invalidaddress = Dirección inválida. -text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! +text.error.timedout = ¡Se acabó el tiempo!\n¡Asegúrate que el host ha hecho el port forwarding, y que la dirección es correcta! text.error.mismatch = Error de paquete:\nposible versión no válida del servidor/cliente.\nAsegúrate de que tú y el host tenéis la última versión de Mindustry. text.error.alreadyconnected = Ya estás conectado. text.error.mapnotfound = ¡Archivo de mapa no encontrado! @@ -277,17 +277,17 @@ text.settings.game = Juego text.settings.sound = Sonido text.settings.graphics = Gráficos text.settings.cleardata = Limpiar Datos del Juego... -text.settings.clear.confirm = ¿Estas seguro de querer limpiar estos datos?\nEsta accion no puede deshacerse! -text.settings.clearall.confirm = [scarlet]ADVERTENCIA![]\nEsto va a eliminar todos tus datos, incluyendo saves, mapas, desbloqueos y keybinds.\nUna vez presiones 'ok' el juego va a borrrar todos tus datos y a salir del juego automáticamente. +text.settings.clear.confirm = ¿Estas seguro de querer limpiar estos datos?\n¡Esta acción no puede deshacerse! +text.settings.clearall.confirm = [scarlet]ADVERTENCIA![]\nEsto va a eliminar todos tus datos, incluyendo guardados, mapas, desbloqueos y keybinds.\nUna vez presiones 'ok', el juego va a borrrar todos tus datos y saldrá del juego automáticamente. text.settings.clearsectors = Limpiar Sectores text.settings.clearunlocks = Limpiar Desbloqueos text.settings.clearall = Limpiar Todo text.paused = Pausado -text.yes = Si +text.yes = Sí text.no = No text.info.title = [accent]Información -text.error.title = [crimson]Un error ha ocurrido -text.error.crashtitle = Un error ha ocurrido +text.error.title = [crimson]Un error ha ocurrido. +text.error.crashtitle = Un error ha ocurrido. text.blocks.blockinfo = Información del Bloque text.blocks.powercapacity = Capacidad de Energía text.blocks.powershot = Energía/Disparo @@ -311,7 +311,7 @@ text.blocks.inputliquidaux = Líquido Auxiliar text.blocks.inputitem = Objeto de Entrada text.blocks.inputitems = Objetos de Entrada text.blocks.outputitem = Objeto de Salida -text.blocks.drilltier = Taladrable +text.blocks.drilltier = Taladrables text.blocks.drillspeed = Velocidad de Base del Taladro text.blocks.liquidoutput = Líquido de Salida text.blocks.liquidoutputspeed = Velocidad de Salida del Líquido @@ -326,7 +326,7 @@ text.blocks.inaccuracy = Imprecisión text.blocks.shots = Disparos text.blocks.reload = Recarga text.blocks.inputfuel = Combustible -text.blocks.fuelburntime = Tiempo de Quema del Combustible +text.blocks.fuelburntime = Tiempo de Quemado del Combustible text.blocks.inputcapacity = Capacidad de entrada text.blocks.outputcapacity = Capacidad de salida text.unit.blocks = bloques @@ -346,7 +346,7 @@ text.category.items = Objetos text.category.crafting = Fabricación text.category.shooting = Disparo setting.autotarget.name = Auto apuntado -setting.fpscap.name = Max FPS +setting.fpscap.name = Máx FPS setting.fpscap.none = Nada setting.fpscap.text = {0} FPS setting.difficulty.training = entrenamiento @@ -361,28 +361,28 @@ setting.sensitivity.name = Sensibilidad del Control setting.saveinterval.name = Intervalo del Auto-guardado setting.seconds = {0} Segundos setting.fullscreen.name = Pantalla Completa -setting.multithread.name = Multihilo +setting.multithread.name = Multiproceso setting.fps.name = Mostrar FPS setting.vsync.name = VSync -setting.lasers.name = Mostrar Energía de los Lasers +setting.lasers.name = Mostrar Energía de los Láseres setting.minimap.name = Mostrar Minimapa -setting.musicvol.name = Volumen de la Musica -setting.mutemusic.name = Mutear Musica +setting.musicvol.name = Volumen de la Música +setting.mutemusic.name = Silenciar Musica setting.sfxvol.name = Volumen de los efectos de sonido -setting.mutesound.name = Mutear Sonido +setting.mutesound.name = Silenciar Sonido text.keybind.title = Reasignar Teclas category.general.name = General category.view.name = Visión category.multiplayer.name = Multijugador command.attack = Atacar -command.retreat = Retirada +command.retreat = Retirarse command.patrol = Patrullar keybind.press = Presiona una tecla... keybind.press.axis = Pulsa un eje o botón... keybind.move_x.name = Mover x keybind.move_y.name = Mover y keybind.select.name = Seleccionar -keybind.break.name = Remover +keybind.break.name = Romper keybind.deselect.name = Deseleccionar keybind.shoot.name = Disparar keybind.zoom_hold.name = Mantener Zoom @@ -402,9 +402,9 @@ keybind.drop_unit.name = drop unit keybind.zoom_minimap.name = Zoom minimapa mode.text.help.title = Descripción de modos mode.waves.name = hordas -mode.waves.description = el modo normal. con recursos limitados y entrada de hordas automática. +mode.waves.description = El modo normal. con recursos limitados y entrada de hordas automática. mode.sandbox.name = sandbox -mode.sandbox.description = recursos ilimitados y no hay temporizador para las hordas. +mode.sandbox.description = Recursos ilimitados y sin temporizador para las hordas. mode.custom.warning = Ten en cuenta que los bloques no pueden usarse en partidas personalizadas hasta que se desbloqueen en sectores.\n\n[LIGHT_GRAY]Si no desbloqueaste ningún bloque, ningno aparecerá. mode.custom.warning.read = Solo para asegurar que lo has leído:\n[scarlet]¡LOS DESBLOQUEOS EN PARTIDAS PERSONALIZADAS NO ESTÁN DISPONIBLES EN LOS SECTORES U OTROS MODOS DE JUEGO!\n\n[LIGHT_GRAY](Ojalá esto no fuera necesario, pero parece que lo es) mode.freebuild.name = construcción libre @@ -451,33 +451,33 @@ liquid.lava.name = Lava liquid.oil.name = Petróleo liquid.cryofluid.name = Criogénico mech.alpha-mech.name = Alpha -mech.alpha-mech.weapon = Heavy Repeater +mech.alpha-mech.weapon = Repetidor Pesado mech.alpha-mech.ability = Drone Swarm -mech.alpha-mech.description = The standard mech. Has decent speed and damage output; can create up to 3 drones for increased offensive capability. +mech.alpha-mech.description = El mecanoide estándar. Tiene velocidad y daño decentes, puede crear hasta 3 drones para poder ofensivo incremenado. mech.delta-mech.name = Delta -mech.delta-mech.weapon = Arc Generator -mech.delta-mech.ability = Discharge -mech.delta-mech.description = A fast, lightly-armored mech made for hit-and-run attacks. Does little damage against structures, but can kill large groups of enemy units very quickly with its arc lightning weapons. +mech.delta-mech.weapon = Generador de arco +mech.delta-mech.ability = Descarga +mech.delta-mech.description = Un mecanoide rápido y ligeramente armado para ataques de ataque y retirada. Hace poco daño a estructuras, pero puede eliminar rápidamente a grandes grupos de unidades con sus armas de arco eléctrico. mech.tau-mech.name = Tau -mech.tau-mech.weapon = Restruct Laser +mech.tau-mech.weapon = Láser de reestructuración mech.tau-mech.ability = Repair Burst -mech.tau-mech.description = The support mech. Heals allied blocks by shooting at them. Can extinguish fires and heal allies in a radius with its repair ability. +mech.tau-mech.description = El mecanoide de soporte. Repara bloques aliados disparándolos. Puede extinguir el fuego y reparar aliados en un rango con su habilidad de reparación. mech.omega-mech.name = Omega mech.omega-mech.weapon = Swarm Missiles mech.omega-mech.ability = Armored Configuration -mech.omega-mech.description = A bulky and well-armored mech, made for front-line assaults. Its armor ability can block up to 90% of incoming damage. -mech.dart-ship.name = Dart -mech.dart-ship.weapon = Repeater +mech.omega-mech.description = Un mecanoide grande y bien armado, hecho para asaltos en primera línea. Su habilidad de armadura puede bloquear hasta el 90% del daño que recibe. +mech.dart-ship.name = Dardo +mech.dart-ship.weapon = Repetidor mech.dart-ship.description = La nave normal. Bastante ligera y rápida, pero tiene poca capacidad ofensiva y baja velocidad minado. mech.javelin-ship.name = Jabalina -mech.javelin-ship.description = A hit-and-run strike ship. While initially slow, it can accelerate to great speeds and fly by enemy outposts, dealing large amounts of damage with its lightning ability and missiles. +mech.javelin-ship.description = Una nave de ataque y retirada. Aunque inicialmente lento, puede acelerar a altas velocidades y volar sobre puestos enemigos, causando gran daño con su habilidad de rayos y misiles. mech.javelin-ship.weapon = Burst Missiles mech.javelin-ship.ability = Discharge Booster mech.trident-ship.name = Tridente -mech.trident-ship.description = A heavy bomber. Reasonably well armored. +mech.trident-ship.description = Un bombardero pesado. Razonablemente bien equipado. mech.trident-ship.weapon = Bomb Bay mech.glaive-ship.name = Glaive -mech.glaive-ship.description = A large, well-armored gunship. Equipped with an incendiary repeater. Good acceleration and maximum speed. +mech.glaive-ship.description = Una nave pistolera grande y bien armada. Equipada con un repetidor incendiario. Buena aceleración y velocidad máxima. mech.glaive-ship.weapon = Flame Repeater text.item.explosiveness = [LIGHT_GRAY]Explosividad: {0} text.item.flammability = [LIGHT_GRAY]Inflamabilidad: {0} @@ -557,14 +557,14 @@ block.pneumatic-drill.name = Taladro neumático block.laser-drill.name = Taladro Laser block.water-extractor.name = Extractor de Agua block.cultivator.name = Cultivador -block.alpha-mech-pad.name = Alpha Mech Pad -block.dart-ship-pad.name = Dart Ship Pad -block.delta-mech-pad.name = Delta Mech Pad -block.javelin-ship-pad.name = Javelin Ship Pad -block.trident-ship-pad.name = Trident Ship Pad +block.alpha-mech-pad.name = Pad de mecanoide Alpha +block.dart-ship-pad.name = Pad de nave de dardos +block.delta-mech-pad.name = Pad de mecanoide Delta +block.javelin-ship-pad.name = Pad de nave Jabalina +block.trident-ship-pad.name = Pad de nave Tridente block.glaive-ship-pad.name = Glaive Ship Pad -block.omega-mech-pad.name = Omega Mech Pad -block.tau-mech-pad.name = Tau Mech Pad +block.omega-mech-pad.name = Pad de mecanoide Omega +block.tau-mech-pad.name = Pad de mecanoide Tau block.conduit.name = Conducto block.mechanical-pump.name = Bomba Mecánica block.itemsource.name = Objeto Fuente @@ -587,12 +587,12 @@ block.solidifer.name = Solidificador block.solar-panel.name = Panel Solar block.solar-panel-large.name = Panel Solar Grande block.oil-extractor.name = Extractor de Petróleo -block.spirit-factory.name = Spirit Drone Factory -block.phantom-factory.name = Phantom Drone Factory +block.spirit-factory.name = Fábrica de Drones Espíritu +block.phantom-factory.name = Fábrica de Drones Fantasmales 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.dagger-factory.name = Fábrica de Dagas +block.titan-factory.name = Fábrica de Titanes block.fortress-factory.name = Fortress Mech Factory block.revenant-factory.name = Revenant Fighter Factory block.repair-point.name = Punto de Reparación @@ -610,7 +610,7 @@ block.blast-drill.name = Taladro Gigante block.thermal-pump.name = Bomba Térmica block.thermal-generator.name = Generador Térmico block.alloy-smelter.name = Alloy Smtler -block.mend-projector.name = Mend Projector +block.mend-projector.name = Proyector de reparación block.surge-wall.name = Surge Wall block.surge-wall-large.name = Large Surge Wall block.cyclone.name = Ciclón @@ -622,30 +622,30 @@ block.arc.name = Arc block.rtg-generator.name = Generador RTG block.spectre.name = Spectre block.meltdown.name = Meltdown -block.container.name = Container +block.container.name = Contenedor team.blue.name = azul team.red.name = rojo team.orange.name = naranja team.none.name = gris team.green.name = verde team.purple.name = púrpura -unit.alpha-drone.name = Alpha Drone -unit.spirit.name = Spirit Drone +unit.alpha-drone.name = Dron Alpha +unit.spirit.name = Dron Espíritu unit.spirit.description = El dron del comienzo. Aparece en el núcleo por defecto. Mina automáticamente minerales, recoge objetos y repara bloques. -unit.phantom.name = Phantom Drone +unit.phantom.name = Dron Fantasmal unit.phantom.description = Un dron avanzado. Mina automáticamente minerales, recoge objetos y repra bloques. Bastante más efectivo que un dron normal. unit.dagger.name = Daga unit.dagger.description = Una unidad de terreno. Útil con enjambres. unit.titan.name = Titán unit.titan.description = Una unidad blindada de terreno, avanzada. Ataca blancos de aire y de terreno. unit.ghoul.name = Ghoul Bomber -unit.ghoul.description = A heavy carpet bomber. Uses blast compound or pyratite as ammo. +unit.ghoul.description = Una unidad bombardera pesada. Usa compuesto explosivo o pirotita como munición. unit.wraith.name = Wraith Fighter -unit.wraith.description = A fast, hit-and-run interceptor unit. +unit.wraith.description = Una unidad interceptora rápida. unit.fortress.name = Fortress -unit.fortress.description = A heavy artillery ground unit. +unit.fortress.description = Una unidad terrestre pesada de artillería. unit.revenant.name = Revenant -unit.revenant.description = A heavy laser platform. +unit.revenant.description = Una plataforma láser pesada. tutorial.begin = Tu objetivo aquí es erradicar el[LIGHT_GRAY] enemy[].\n\nComienza[accent]minando copper[]. Toca una veta de cobre cerca de tu núcleo para hacer esto. tutorial.drill = Minar manualmente es ineficiente.\nLos [accent]taladros pueden minar automáticamente.\nColoca uno en una veta de cobre. tutorial.conveyor = Los [accent]Conveyors[] se usan para transportar objetos al núcleo.\nConstruye una línea de transportadores del taladro al núcleo. @@ -667,53 +667,53 @@ tutorial.daggerfactory = Construye una[accent] dagger mech factory[].\n\nEsto se tutorial.router = Las fábricas necesitan recursos para funcionar.\nCrea un enrutador para separar recursos del transportador. tutorial.dagger = Conecta nodos de energía a la fábrica.\nUna vez las necesidades se cumplan, una unidad será creada.\n\nCrea taladros, generadores y transportadores según necesites. tutorial.battle = El[LIGHT_GRAY] enemy[] ha revelado su núcleo.\nDestrúyelo con tu nave y tus unidades de combate. -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.copper-wall.description = Un bloque defensivo barato.\nÚtil para defneder e núcleo y las torres en las primeras hordas. +block.copper-wall-large.description = Un bloque defensivo barato.\nÚtil para defneder e núcleo y las torres en las primeras hordas.\nOcupa múltiples casillas. +block.dense-alloy-wall.description = Un bloque de defensa estándar.\nProtección adecuada contra enemigos. +block.dense-alloy-wall-large.description = Un bloque de defensa estándar.\nProtección adecuada contra enemigos.\nOcupa múltiples casillas. +block.thorium-wall.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos. +block.thorium-wall-large.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos.\nOcupa múltiples casillas. +block.phase-wall.description = No es tan fuerte como un muro de torio pero rebota balas al enemigo si no son demasiado fuertes. +block.phase-wall-large.description = No es tan fuerte como un muro de torio pero rebota balas al enemigo si no son demasiado fuertes.\nOcupa múltiples casillas. +block.surge-wall.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante. +block.surge-wall-large.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante.\nOcupa múltiplies casillas. +block.door.description = Una puerta pequeña que puede ser abierta y cerrada tocándola.\nSi está abirta, los enemigos pueden moverse y disparar a través de ella.\nOcupa múltiples casillas. +block.door-large.description = Una puerta grande que puede ser abierta y cerrada tocándola.\nSi está abirta, los enemigos pueden moverse y disparar a través de ella.\nOcupa múltiples casillas. +block.mend-projector.description = Regenera edificios cercanos periódcamente. +block.overdrive-projector.description = Aumenta la velocidad de edificios cercanos como taladros y transportadores. +block.force-projector.description = Crea un área de fuerza hexagonal alrededor de él, protegiendo edificios y unidades dentro de él del daño de las balas. +block.shock-mine.description = Daña enemigos que pisan a mina. Casi invisible al enemigo. +block.duo.description = Una torre pequeña y barata. +block.arc.description = Una torre pequeña que disapra electricidad en un arco aleatorio al enemigo. +block.hail.description = Una torre de artillería pequeña. +block.lancer.description = Una torre de tamaño mediano que dispara rayos cargados eléctricamente. +block.wave.description = Una torre de tamaño mediano que dispara burbujas de líquido. +block.salvo.description = Una torre de tramaño mediano que dispara balas en salvos. +block.swarmer.description = Una torre de tamaño mediano que dispara misiles en grupo. +block.ripple.description = Una torre de artillería grande que dispara varios disparos simultáneamente. +block.cyclone.description = Una torre de disparo rápido grande. +block.fuse.description = Una torre grande que dispara rayos poderosos de corto alcance. +block.spectre.description = Una torre grande que dispara dos balas poderosas de una vez. +block.meltdown.description = Una torre grande que dispara rayos poderosos de largo alcance. +block.conveyor.description = Bloque de transporte básico. Mueve objetos hacia adelante y los deposita automáticamente en torres o fábricas. Rotable. +block.titanium-conveyor.description = Bloque de transporte avanzado. Mueve objetos más rápido que los transportadores estándar. +block.phase-conveyor.description = Bloque de transporte avanzado. Usa energía para transportar objetos a otro transportador de fase conectado por varias casillas. +block.junction.description = Actúa como puente para dos transportadores que se cruzan. Útil en situaciones con dos diferentes transportadores transportando diferentes materiales a diferentes lugares. +block.mass-driver.description = El mejor bloque de transorte. Recoge varios objetos y los dispara a otro conductor de masa en un largo rango. +block.smelter.description = Quema carbón para fundir cobre y plomo, produciendo así aleación densa. +block.arc-smelter.description = Funde cobre y plomo en aleación densa usando una fuented de energía externa. 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.plastanium-compressor.description = Produce plastanio con aceite y titanio. 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.alloy-smelter.description = Produce "surge alloy" con titanio, plomo, silicona y cobre. +block.pulverizer.description = Despedaza la piedra en arena. Útil cuando no hay arena natural. +block.pyratite-mixer.description = Mezcla carbón, plomo y arena en pirotita altamente inflamable. +block.blast-mixer.description = Usa aceite para transformar pirotita en un objeto menos inflamable pero más explosivo: compuesto explosivo. +block.cryofluidmixer.description = Combina agua y titanio en líquido criogénico que es mucho más eficiente para enfriar. +block.solidifer.description = Enfría la lava a piedra a una gran velocidad. +block.melter.description = Calienta piedra a temperaturas muy altas para obtener lava. +block.incinerator.description = Se deshace de cualquier líquido u objeto excesivo. +block.biomattercompressor.description = Comprime biomateria para extraer aceite. block.separator.description = Expone piedra a la presión del agua para obtener diversos minerales contenidos en la piedra. block.centrifuge.description = Más eficiente que un separador, pero es más caro de construir y requiere energía. block.power-node.description = Transmite energía a nodos conectados, conecta hasta cuatro fuentes de energía, edificios que usan energía o nodos. El nodo obtendrá o transmitirá energía de cualquier bloque adyacente. @@ -733,47 +733,48 @@ block.vault.description = Almacena una gran cantidad de objetos. Úsalo para cre block.mechanical-drill.description = Un taladro barato. Cuando es colocado en casillas apropiadas, extrae objetos lentamente de forma indefinida. block.pneumatic-drill.description = Un taladro mejorado que es más rápido y puede obtener minerales más duros usando la presión. block.laser-drill.description = Permite obtener minerales incluso más rápido con la tecnología láser, pero requiere energía. Además, se puede obtener torio radioactivo con este taladro. -block.blast-drill.description = The ultimate drill. Requires large amounts of power. +block.blast-drill.description = El mejor taladro. Requiere grandes cantidades de energía. block.water-extractor.description = Extrae agua de la tierra. Úsalo cuando no haya lagos cercanos. block.cultivator.description = Cultiva la tierra para obtener biomateria. block.oil-extractor.description = Usa grandes cantidades de energía para extraer aceite de la arena. Úsalo cuando no hay fuentes directas de aceite cerca. -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.dart-ship-pad.description = Deja tu nave actual y transfórmate en una unidad aérea básica.\nUsa el pad tocándolo dos veces mientras estás en él. +block.trident-ship-pad.description = Deja tu nave actual y transfórmate en una unidad aérea bombardera pesada.\nUsa el pad tocándolo dos veces mientras estás en él. +block.javelin-ship-pad.description = Deja tu nave actual y transfórmate en una unidad aérea fuerte y rápida interceptora con arma eléctrica.\nUsa el pad tocándolo dos veces mientras estás en él. +block.glaive-ship-pad.description = Deja tu nave actual y transfórmate en una unidad aérea grande y bien armada nave pistolera.\nUsa el pad tocándolo dos veces mientras estás en él. +block.tau-mech-pad.description = Deja tu nave actual y transfórmate en un mecanoide de soporte que puede reparar construcciones y tropas aliadas.\nUsa el pad tocándolo dos veces mientras estás en él. 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. +Deja tu nave actual y transfórmate en un mecanoide rápido, con armas ligeras hecho para ataques de ataque y retirada.\nUsa el pad tocándolo dos veces mientras estás en él. +block.omega-mech-pad.description = Deja tu nave actual y transfórmate en un mecanoide pesado y bien armado, hecho para asaltos en primera línea.\nUsa el pad tocándolo dos veces mientras estás en él. block.spirit-factory.description = Produce drones ligeros que obtienen minerales y reparan bloques. -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.phantom-factory.description = Produce drones avanzados que son significativamente más eficientes que un dron espíritu. +block.wraith-factory.description = Produce unidades aéreas rápidas e interceptoras. +block.ghoul-factory.description = Produce unidadess bombarderas pesadas. block.dagger-factory.description = Produce unidades terrestres básicas. -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.titan-factory.description = Produce unidades terrestres avanzadas. +block.fortress-factory.description = Produce unidades terrestres de artillería pesada. +block.revenant-factory.description = Produce unidades terrestres láser pesadas. block.repair-point.description = Repara la unidad dañada más cercana a su alrededor. -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. +block.command-center.description = Permite cambiar el comportamiento de la IA aliada. Actualmente, atacar, retirarse y patrullar son los comandos soportados. +block.conduit.description = Bloque de transporte de líquidos básico. Funciona como un transportador, pero con líquidos. Usado con bombas, extractores u otros conductos. +block.pulse-conduit.description = Bloque de transporte de líquidos avanzado. Transporta líquidos más rápidamente y almacena más que los conductos estándar. +block.phase-conduit.description = Bloque de transporte de líquidos avanzado. Usa energía para transportar líquidos a otro conducto de fase conectado por varias casillas. +block.liquid-router.description = Acepta líquidos de una dirección y los deja en hasta 3 direcciones equitativamente. También puede amacenar cierta capacidad de líquido. Útil para dividir los líquidos de una fuente a varios objetivos. +block.liquid-tank.description = Almacena una gran cantidad de líquidos. Úsalo para crear almacenes cuando no hay una demanda constante de materiales o para asegurarse de enfriar bloques vitales. +block.liquid-junction.description = Actúa como un puente para dos condusctos que se cruzan. Útil en situaciones en las que hay dos conductos con líquidos diferentes a diferentes lugares. +block.bridge-conduit.description = Bloque avanzado de transporte de líquidos. Permite transportar líquidos por encima hasta 3 casillas de cualquier terreno o construcción. +block.mechanical-pump.description = Una bomba barata con extracción lenta, pero sin uso de energía. +block.rotary-pump.description = Una bomba avanzada que duplica la velocidad usando energía. +block.thermal-pump.description = La mejor bomba. Tres veces más rápido que la bomba mecánica, y la única bomba que puede extraer lava. +block.router.description = Acepta objetos de una dirección y deja objetos equitativamente en hasta 3 direcciones diferentes. Útil para dividir los materiales de una fuente de recursos a múltiples objetivos. +block.distributor.description = Un enrutador avanzado que distribuye objetos equitativamente en hasta otras 7 direcciones. +block.bridge-conveyor.description = Bloque avanado de transporte. Puede transportar objetos por encima hasta 3 casillas de cualquier terreno o construcción. +block.alpha-mech-pad.description = Cuando se le da suficiente energía, reconstruye tu nave en el mecanoide[accent] Alpha[]. +block.itemsource.description = Da objetos infinitos. Solo en sandbox. +block.liquidsource.description = Da líquido infinito. Solo en sandbox. +block.itemvoid.description = Destruye cuanquier objeto que va a él sin necesitar energía. Solo en sandbox. +block.powerinfinite.description = Da energía infinita. Solo en sandbox. +block.powervoid.description = Elimina toda la energía que se le da. Solo en sandbox. +liquid.water.description = Usado comúnmente para enfriar máquinas y para procesar residuos. +liquid.lava.description = Puede usarse para ser transformado en[LIGHT_GRAY] stone[], para generar energía o para munición de ciertas torres. +liquid.oil.description = Puede ser quemado, explotado o como un enfriador. +liquid.cryofluid.description = El líquido más eficiente pra enfriar las cosas. diff --git a/core/assets/bundles/bundle_in_ID.properties b/core/assets/bundles/bundle_in_ID.properties index 7abcfa5a02..838876490c 100644 --- a/core/assets/bundles/bundle_in_ID.properties +++ b/core/assets/bundles/bundle_in_ID.properties @@ -50,7 +50,7 @@ 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}[] waves. +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 diff --git a/core/assets/bundles/bundle_ita.properties b/core/assets/bundles/bundle_it.properties similarity index 99% rename from core/assets/bundles/bundle_ita.properties rename to core/assets/bundles/bundle_it.properties index a61ccb7072..bfcd087d53 100644 --- a/core/assets/bundles/bundle_ita.properties +++ b/core/assets/bundles/bundle_it.properties @@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0} text.mission.info = Mission Info text.mission.complete = Missione completata! text.mission.complete.body = Il settore {0},{1} è stato conquistato. -text.mission.wave = Sopravvivi a [accent]{0}[] onda/e. +text.mission.wave = Sopravvivi a [accent]{0}/{1][] onda/e.Onda 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 diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 2c64fc3e65..2f4d1c04ec 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -13,22 +13,22 @@ text.editor.web = HTML5 버전은 에디터 기능을 지원하지 않습니다! text.web.unsupported = HTML5 버전은 이 기능을 지원하지 않습니다! 게임을 다운로드 한 뒤에 사용 해 주세요. text.gameover = 코어가 터졌습니다. 게임 오버! text.gameover.pvp = [accent]{0}[] 팀이 승리했습니다! -text.sector.gameover = 이 구역을 공략하는데 실패했습니다. 다시 배치하시겠습니까? -text.sector.retry = 다시할꺼임 +text.sector.gameover = 이 구역을 공략하는데 실패했습니다. 포기 하시겠습니까? +text.sector.retry = 아니오 text.highscore = [YELLOW]최고점수 달성! text.wave.lasted = [accent]{0}[] 까지 버티셨습니다. text.level.highscore = 최고 점수 : [accent]{0} text.level.delete.title = 삭제 확인 -text.map.delete = 정말로 "[accent]{0}[]" 맵을 삭제하시겠습니까? +text.map.delete = 정말로 "[orange]{0}[]" 맵을 삭제하시겠습니까? text.level.select = 맵 선택 text.level.mode = 게임모드 : text.construction.desktop = PC 에서의 조작 방법이 변경되었습니다.\n블록 선택을 해제하거나 건설을 중지하려면 [accent]스페이스 바[]를 누르세요. text.construction.title = 블록 배치 안내서 text.construction = [accent]블록 배치 모드[]를 선택하셨습니다.\n\n블록을 설치하고 싶으면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 배치 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요. \n- [accent]블록을 넓게 배치[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\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.coreattack = < 코어가 공격받고 있습니다! > text.unlocks = 아이템들 text.savegame = 게임 저장 text.loadgame = 게임 불러오기 @@ -50,20 +50,20 @@ text.mission.main = 주요 목표 : [LIGHT_GRAY]{0} text.mission.info = 미션 정보 text.mission.complete = 미션 성공! text.mission.complete.body = 구역 {0},{1} 클리어. -text.mission.wave = [accent]{0}[]단계가 될때까지 생존하세요. -text.mission.wave.enemies = [accent] {0}/{1} []단계동안 생존하세요.\n{2}마리 남음 -text.mission.wave.enemy = [accent] {0}/{1} []단계동안 생존하세요.\n{2}마리 남음 +text.mission.wave = [accent]{0}/{1}[] 단계동안 생존하세요.남은 시간 {2}\n +text.mission.wave.enemies = [accent] {0}/{1} []단계를 생존하세요.\n{2}마리 남음 +text.mission.wave.enemy = [accent] {0}/{1} []단계를 생존하세요.\n{2}마리 남음 text.mission.wave.menu = [accent]{0}[] 단계 -text.mission.battle = 적 본부를 파괴하세요. +text.mission.battle = 적 코어를 파괴하세요. text.mission.resource.menu = {0} {1}개 수집 text.mission.resource = {0} 자원을 수집하세요 :\n[accent]{1}/{2}[] -text.mission.block = 이것을 만드세요 :\n{0} -text.mission.unit = 이 유닛을 만드세요 :\n{0} -text.mission.command = 유닛에게 이 명령을 보내세요 :\n{0} +text.mission.block = {0} 를 만드세요 +text.mission.unit = {0} 유닛을 만드세요 +text.mission.command = 유닛에게 {0} 명령을 보내세요 text.mission.linknode = 전력 노드를 연결하세요. -text.mission.display = [accent]미션 : \n[LIGHT_GRAY]{0} -text.mission.mech = 이 기체로 바꾸세요 :\n[accent]{0} -text.mission.create = 이 자원을 만드세요 :\n[accent]{0} +text.mission.display = [accent]미션 :\n[LIGHT_GRAY]{0} +text.mission.mech = [accent]{0}[] 기체로 바꾸세요 +text.mission.create = [accent]{0}[] 자원을 만드세요 text.none = <없음> text.close = 닫기 text.quit = 나가기 @@ -91,12 +91,12 @@ text.server.kicked.nameInUse = 이 닉네임이 이미 서버에서 사용중입 text.server.kicked.nameEmpty = 닉네임에는 반드시 영어 또는 숫자가 있어야 합니다. text.server.kicked.idInUse = 이미 서버에 접속중입니다! 다중 계정은 허용되지 않습니다. text.server.kicked.customClient = 이 서버는 직접 빌드한 버전을 지원하지 않습니다. 공식 버전을 사용하세요. -text.host.info = [accent]호스트[] 버튼은 현재 네트워크의 [scarlet]6567[] 과 [scarlet]6568[] 포트를 사용합니다.\n[LIGHY_GRAY]같은 Wi-Fi 또는 로컬 네트워크[] 에서 서버 목록을 볼 수 있습니다.\n\n만약 플레이어들이 이 IP를 통해 어디에서나 연결할 수 있게 하고 싶다면, 공유기 설정에서 [accent]포트 포워딩[]을 해야 합니다.\n\n[LIGHT_GRAY]참고 : LAN 게임 연결에 문제가 있는 사람이 있다면, 방화벽 설정에서 Mindustry 가 로컬 네트워크에 액세스하도록 허용했는지 확인 해 주세요. +text.host.info = [accent]호스트[] 버튼은 현재 네트워크의 [scarlet]6567[] 포트를 사용합니다.\n[LIGHY_GRAY]같은 Wi-Fi 또는 로컬 네트워크[] 에서 서버 목록을 볼 수 있습니다.\n\n만약 플레이어들이 이 IP를 통해 어디에서나 연결할 수 있게 하고 싶다면, 공유기 설정에서 [accent]포트 포워딩[]을 해야 합니다.\n\n[LIGHT_GRAY]참고 : LAN 게임 연결에 문제가 있는 사람이 있다면, 방화벽 설정에서 Mindustry 가 로컬 네트워크에 액세스하도록 허용했는지 확인 해 주세요. text.join.info = 여기서 [accent]서버 IP[]를 입력하여 다른 서버에 접속할 수 있습니다.\n또는 [accent]로컬 네트워크(LAN)[] 서버를 검색하여 접속할 수 있습니다.\nLAN 및 WAN 멀티 플레이어 모두 지원됩니다.\n\n[LIGHT_GRAY]참고:여기에서는 자동으로 글로벌 서버를 추가하지 않습니다. IP로 다른 사람의 서버에 접속할려면 서버장에게 IP를 요청해야 합니다. text.hostserver = 서버 열기 -text.hostserver.mobile = 게임\n호스트 -text.host = 호스트 -text.hosting = [accent]서버 여는중.. +text.hostserver.mobile = 서버\n열기 +text.host = 서버 열기 +text.hosting = [accent]서버 여는중... text.hosts.refresh = 새로고침 text.hosts.discovering = LAN 게임 찾기 text.server.refreshing = 서버 목록 새로고치는중... @@ -129,7 +129,7 @@ text.server.custombuild = [yellow]커스텀 서버 text.confirmban = 이 플레이어를 차단하시겠습니까? text.confirmkick = 정말로 이 플레이어를 추방시키겠습니까? text.confirmunban = 이 플레이어를 차단해제 하시겠습니까? -text.confirmadmin = 이 플레이어를 영자로 만들겠습니까? +text.confirmadmin = 이 플레이어를 관리자로 만들겠습니까? text.confirmunadmin = 이 플레이어를 일반 유저로 만들겠습니까? text.joingame.title = 게임 참가 text.joingame.ip = IP : @@ -140,7 +140,7 @@ text.connecting.data = [accent]맵 데이터 다운로드중... text.server.port = 포트 : text.server.addressinuse = 이 주소는 이미 사용중입니다! text.server.invalidport = 포트 번호가 잘못되었습니다. -text.server.error = [crimson]{0}[accent]서버를 여는데 오류가 발생했습니다.[] +text.server.error = [crimson]{0}[orange]서버를 여는데 오류가 발생했습니다.[] text.save.old = 이 저장파일은 이전 버전의 게임용이며, 지금은 사용할 수 없습니다. \n\n[LIGHT_GRAY]4.0 정식때 이전 게임버전에서 만든 저장파일과 호환됩니다. text.save.new = 새로 저장 text.save.overwrite = 이 저장 슬롯을 덮어씌우겠습니까? @@ -151,17 +151,17 @@ text.savefail = 게임을 저장하지 못했습니다! text.save.delete.confirm = 이 저장파일을 삭제 하시겠습니까? text.save.delete = 삭제 text.save.export = 저장파일 내보내기 -text.save.import.invalid = [accent]파일이 잘못되었습니다! -text.save.import.fail = [crimson]저장파일을 불러오지 못함 : [accent]{0} -text.save.export.fail = [crimson]저장파일을 내보내지 못함 : [accent]{0} +text.save.import.invalid = [orange]파일이 잘못되었습니다! +text.save.import.fail = [crimson]저장파일을 불러오지 못함 : [orange]{0} +text.save.export.fail = [crimson]저장파일을 내보내지 못함 : [orange]{0} text.save.import = 저장파일 불러오기 text.save.newslot = 저장 파일이름 : text.save.rename = 이름 변경 text.save.rename.text = 새 이름 : text.selectslot = 저장슬롯을 선택하십시오. text.slot = [accent]{0}번째 슬롯 -text.save.corrupted = [accent]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[]. -text.sector.corrupted = [accent]저장 파일에서 구역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다. +text.save.corrupted = [orange]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[]. +text.sector.corrupted = [orange]저장 파일에서 구역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다. text.empty = <비어있음> text.on = 켜기 text.off = 끄기 @@ -182,14 +182,14 @@ text.back = 뒤로가기 text.quit.confirm = 정말로 종료하시겠습니까? text.changelog.title = 변경사항 text.changelog.loading = 변경사항 가져오는중... -text.changelog.error.android = [accent]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다.이것은 내부 Android 버그 때문입니다. -text.changelog.error.ios = [accent]현재 iOS에서는 변경 사항을 지원하지 않습니다. +text.changelog.error.android = [orange]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다. 이것은 내부 Android 버그 때문입니다. +text.changelog.error.ios = [orange]현재 iOS에서는 변경 사항을 지원하지 않습니다. text.changelog.error = [scarlet]게임 변경사항을 가져오는 중 오류가 발생했습니다![]\n인터넷 연결을 확인하십시오. -text.changelog.current = [accent][[현재 버전] -text.changelog.latest = [accent][[최신 버전] +text.changelog.current = [orange][[현재 버전] +text.changelog.latest = [orange][[최신 버전] text.loading = [accent]불러오는중... text.saving = [accent]저장중... -text.wave = [accent]{0}단계 +text.wave = [orange]{0}단계 text.wave.waiting = 다음 단계 시작까지 {0}초 text.waiting = [LIGHT_GRAY]대기중... text.waiting.players = 다른 플레이어를 기다리는 중.. @@ -216,14 +216,14 @@ text.editor.description = 설명 : text.editor.name = 이름 : text.editor.teams = 팀 text.editor.elevation = 지형 높이 -text.editor.errorimageload = [accent]{0}[] 파일을 불러오는데 오류가 발생했습니다. -text.editor.errorimagesave = [accent]{0}[] 파일 저장중 오류가 발생했습니다. +text.editor.errorimageload = [orange]{0}[] 파일을 불러오는데 오류가 발생했습니다. +text.editor.errorimagesave = [orange]{0}[] 파일 저장중 오류가 발생했습니다. text.editor.generate = 생성 text.editor.resize = 맵 크기조정 text.editor.loadmap = 맵 불러오기 text.editor.savemap = 맵 저장 text.editor.saved = 저장됨! -text.editor.save.noname = 지도에 이름이 없습니다! '맵 정보' 메뉴에서 설정하세요. +text.editor.save.noname = 지도에 이름이 없습니다! 메뉴 -> '맵 정보' 에서 설정하세요. text.editor.save.overwrite = 이 맵의 이름은 기존에 있던 맵을 덮어씁니다! '맵 정보' 메뉴에서 다른 이름을 선택하세요. text.editor.import.exists = [scarlet]맵을 불러올 수 없음 : [] 기존에 있던 '{0}' 맵이 이미 존재합니다! text.editor.import = 가져오기 @@ -261,7 +261,7 @@ text.tutorial = 게임 방법 text.editor = 편집기 text.mapeditor = 맵 편집기 text.donate = 기부 -text.connectfail = [crimson]{0}[accent] 서버에 연결하지 못했습니다.[] +text.connectfail = [crimson]{0}[orange] 서버에 연결하지 못했습니다.[] text.error.unreachable = 서버에 연결하지 못했습니다. text.error.invalidaddress = 잘못된 주소입니다. text.error.timedout = 시간 초과!\n서버에 포트 포워딩이 설정되어 있고 주소가 올바른지 확인하십시오. @@ -285,50 +285,50 @@ text.settings.clearall = 모두 초기화 text.paused = 일시 정지 text.yes = 예 text.no = 아니오 -text.info.title = 정보 +text.info.title = [accent]정보 text.error.title = [crimson]오류가 발생했습니다. text.error.crashtitle = 오류가 발생했습니다. text.blocks.blockinfo = 블록 정보 -text.blocks.powercapacity = 최대 전력 용량 -text.blocks.powershot = 1발당 전력 소모량 -text.blocks.targetsair = 공중공격 가능 -text.blocks.itemspeed = 유닛 이동 속도 -text.blocks.shootrange = 사거리 -text.blocks.size = 블록 크기 -text.blocks.liquidcapacity = 최대 액체 용량 -text.blocks.maxitemssecond = 최대 아이템 보관량 -text.blocks.powerrange = 전력 범위 -text.blocks.poweruse = 전력 사용 -text.blocks.powerdamage = 전력/데미지 -text.blocks.inputitemcapacity = 입력 아이템 용량 -text.blocks.outputitemcapacity = 출력 아이템 용량 -text.blocks.itemcapacity = 저장 용량 -text.blocks.basepowergeneration = 기지 전력 생성기 -text.blocks.powertransferspeed = 전력 전송량 -text.blocks.craftspeed = 생산 속도 -text.blocks.inputliquid = 사용되는 액체 -text.blocks.inputliquidaux = 보조 액체 -text.blocks.inputitem = 사용되는 아이템 -text.blocks.inputitems = 사용되는 아이템들 -text.blocks.outputitem = 출력 아이템 -text.blocks.drilltier = 드릴 -text.blocks.drillspeed = 기본 드릴 속도 -text.blocks.liquidoutput = 액체 출력 -text.blocks.liquidoutputspeed = 액체 출력속도 -text.blocks.liquiduse = 액체 사용량 -text.blocks.coolant = 냉각제 -text.blocks.coolantuse = 냉각수 사용 -text.blocks.inputliquidfuel = 연료 액 -text.blocks.liquidfueluse = 액체 연료 사용 -text.blocks.explosive = 이게 터지면 펑 터지면서 주변 블록에게 피해를 입힙니다! -text.blocks.health = 체력 -text.blocks.inaccuracy = 오차각 -text.blocks.shots = 발포 횟수 -text.blocks.reload = 재장전 -text.blocks.inputfuel = 연료 -text.blocks.fuelburntime = 연료 연소 시간 -text.blocks.inputcapacity = 입력 용량 -text.blocks.outputcapacity = 출력 용량 +text.blocks.powercapacity = 최대 전력 용량 +text.blocks.powershot = 1발당 전력 소모량 +text.blocks.targetsair = 공중공격 가능 +text.blocks.itemspeed = 유닛 이동 속도 +text.blocks.shootrange = 사거리 +text.blocks.size = 블록 크기 +text.blocks.liquidcapacity = 최대 액체 용량 +text.blocks.maxitemssecond = 최대 아이템 보관량 +text.blocks.powerrange = 전력 범위 +text.blocks.poweruse = 전력 사용 +text.blocks.powerdamage = 전력/데미지 +text.blocks.inputitemcapacity = 입력 아이템 용량 +text.blocks.outputitemcapacity = 출력 아이템 용량 +text.blocks.itemcapacity = 저장 용량 +text.blocks.basepowergeneration = 기지 전력 생성기 +text.blocks.powertransferspeed = 전력 전송량 +text.blocks.craftspeed = 생산 속도 +text.blocks.inputliquid = 사용되는 액체 +text.blocks.inputliquidaux = 보조 액체 +text.blocks.inputitem = 사용되는 아이템 +text.blocks.inputitems = 사용되는 아이템들 +text.blocks.outputitem = 출력 아이템 +text.blocks.drilltier = 드릴 +text.blocks.drillspeed = 기본 드릴 속도 +text.blocks.liquidoutput = 액체 출력 +text.blocks.liquidoutputspeed = 액체 출력속도 +text.blocks.liquiduse = 액체 사용량 +text.blocks.coolant = 냉각제 +text.blocks.coolantuse = 냉각수 사용 +text.blocks.inputliquidfuel = 연료 액 +text.blocks.liquidfueluse = 액체 연료 사용 +text.blocks.explosive = 이 블록이 터지면 주변 블록과 같이 자폭을 합니다!! +text.blocks.health = 체력 +text.blocks.inaccuracy = 오차각 +text.blocks.shots = 발포 횟수 +text.blocks.reload = 재장전 +text.blocks.inputfuel = 연료 +text.blocks.fuelburntime = 연료 연소 시간 +text.blocks.inputcapacity = 입력 용량 +text.blocks.outputcapacity = 출력 용량 text.unit.blocks = 블록 text.unit.powersecond = 전력/초 text.unit.liquidsecond = 액체/초 @@ -370,6 +370,7 @@ setting.musicvol.name = 음악 크기 setting.mutemusic.name = 음소거 setting.sfxvol.name = 효과음 크기 setting.mutesound.name = 소리 끄기 +setting.crashreport.name = 오류 보고서 보내기 text.keybind.title = 키 바인딩 category.general.name = 일반 category.view.name = 보기 @@ -417,11 +418,11 @@ content.unit.name = 유닛 content.recipe.name = 블록 content.mech.name = 기체 item.stone.name = 돌 -item.stone.description = 주로 용암을 사용하여 얻을 수 있습니다. +item.stone.description = 주로 용암을 사용하여 얻을 수 있는 자원입니다. item.copper.name = 구리 item.copper.description = 모든 유형의 블록에서 광범위하게 사용되는 자원입니다. item.lead.name = 납 -item.lead.description = 쉽게 구할 수 있는 자원.\n전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다. +item.lead.description = 쉽게 구할 수 있으며, 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다. item.coal.name = 석탄 item.coal.description = 쉽게 구할 수 있으며, 주로 제련소 등에서 연료로 사용됩니다. item.dense-alloy.name = 합금 @@ -439,9 +440,9 @@ item.phase-fabric.description = 최첨단 전자 제품과 자기수리 기술 item.surge-alloy.name = 설금 item.surge-alloy.description = 주로 건물의 재료로 사용되는 자원입니다 item.biomatter.name = 바이오메터 -item.biomatter.description = 이것은 유기농 덤불입니다!\n석유로 전환하거나 연료로 사용됩니다. +item.biomatter.description = 이것은 유기농 덤불입니다!\n압축기에 넣어 석유로 바꿀 수 있습니다. item.sand.name = 모래 -item.sand.description = 합금이나 플렉스 등에서 제련시 광범위하게 사용되는 일반적인 재료입니다. +item.sand.description = 합금이나 플럭스 등에서 제련시 광범위하게 사용되는 일반적인 재료입니다. item.blast-compound.name = 화합물 item.blast-compound.description = 포탑 및 건설의 재료로 사용되는 휘발성 화합물.\n연료로도 사용할 수 있지만, 별로 추천하지는 않습니다. item.pyratite.name = 피라테 @@ -482,7 +483,7 @@ mech.glaive-ship.weapon = 방화총 text.item.explosiveness = [LIGHT_GRAY]폭발력 : {0} text.item.flammability = [LIGHT_GRAY]인화성 : {0} text.item.radioactivity = [LIGHT_GRAY]방사능 : {0} -text.item.fluxiness = [LIGHT_GRAY]플렉스 파워 : {0} +text.item.fluxiness = [LIGHT_GRAY]플럭스 파워 : {0} text.unit.health = [LIGHT_GRAY]체력 : {0} text.unit.speed = [LIGHT_GRAY]속도 : {0} text.mech.weapon = [LIGHT_GRAY]무기 : {0} @@ -496,7 +497,7 @@ text.liquid.viscosity = [LIGHT_GRAY]점도 : {0} text.liquid.temperature = [LIGHT_GRAY]온도 : {0} block.spawn.name = 적 스폰지점 block.core.name = 코어 -block.metalfloor.name = 메탈 바닥 +block.metalfloor.name = 철판 block.deepwater.name = 깊은물 block.water.name = 물 block.lava.name = 용암 @@ -517,7 +518,7 @@ block.copper-wall-large.name = 큰 구리벽 block.dense-alloy-wall.name = 합금 벽 block.dense-alloy-wall-large.name = 큰 합금 벽 block.phase-wall.name = 메타벽 -block.phase-wall-large.name = 메타벽 +block.phase-wall-large.name = 큰 메타벽 block.thorium-wall.name = 토륨벽 block.thorium-wall-large.name = 대형 토륨벽 block.door.name = 문 @@ -534,7 +535,7 @@ block.distributor.name = 대형 분배기 block.sorter.name = 필터 block.sorter.description = 아이템을 넣어서 필터에 설정된 아이템일 경우 바로 앞으로 통과하며, 그렇지 않을 경우 옆으로 통과합니다. block.overflow-gate.name = 오버플로 게이트 -block.overflow-gate.description = 정면 경로가 차단된 경우 왼쪽과 오른쪽으로만 출력하는 복합 분배기입니다. +block.overflow-gate.description = 정면으로 가는 자원이 막히면 옆으로 출력하고, 그렇지 않으면 계속 정면으로 출력합니다. block.smelter.name = 제련소 block.arc-smelter.name = 대형 제련소 block.silicon-smelter.name = 실리콘 제련소 @@ -623,7 +624,6 @@ block.rtg-generator.name = 토륨 발전소 block.spectre.name = 스펙터 block.meltdown.name = 멜트다운 block.container.name = 컨테이너 -block.core.description = 게임에서 가장 중요한 건물.\n파괴되면 게임이 끝납니다. team.blue.name = 블루팀 team.red.name = 레드팀 team.orange.name = 오렌지팀 @@ -637,6 +637,7 @@ unit.phantom.name = 팬텀 드론 unit.phantom.description = 첨단 드론 유닛. 광석을 자동으로 채광하며, 아이템을 수집하고 블록을 수리합니다. 일반 드론보다 훨씬 효과적입니다. unit.dagger.name = 귀여운 디거 unit.dagger.description = 밈의 대상으로 지정되어 이름이 바뀐 기본 지상 유닛입니다. +## unit.dagger.description = 기본 지상 유닛입니다. 스웜과 같이 쓰면 유용합니다. unit.titan.name = 타이탄 unit.titan.description = 고급 지상 유닛입니다. 합금을 탄약으로 사용하며 지상과 공중 둘다 공격할 수 있습니다. unit.ghoul.name = 구울 폭격기 @@ -668,6 +669,7 @@ tutorial.daggerfactory = 이[accent] 귀여운 디거 기체 공장[]은\n\n공 tutorial.router = 공장을 작동시키기 위해 자원이 필요합니다.\n컨베이어에 운반되고 있는 자원을 분할할 분배기를 만드세요. tutorial.dagger = 전력 노드를 공장에 연결하세요.\n일단 요구 사항이 충족되면 기체 생산을 시작합니다.\n\n필요에 따라 드릴 및 발전기, 컨베이어를 더 많이 만들 수 있습니다. tutorial.battle = [LIGHT_GRAY]적[]의 코어가 드러났습니다.\n당신의 부대와 귀여운 디거를 사용하여 파괴하세요. +block.core.description = 게임에서 가장 중요한 건물.\n파괴되면 게임이 끝납니다. block.copper-wall.description = 구리로 만든 벽. block.copper-wall-large.description = 구리로 만든 큰 벽. block.dense-alloy-wall.description = 합금으로 만든 벽. 구리벽보다 체력이 높습니다. @@ -680,17 +682,17 @@ block.surge-wall.description = 데미지를 입으면 번개를 일으켜 대상 block.surge-wall-large.description = 설금을 재료로 한 큰 벽.\n데미지를 입으면 번개를 일으켜 대상에게 피해를 입힙니다. block.door.description = 유닛이 지나갈 수 있도록 만든 문. 클릭하면 열고 닫습니다. block.door-large.description = 유닛이 자나갈 수 있도록 만든 큰 문. 클릭하면 열고 닫습니다. -block.mend-projector.description = 주위 건물을 치료하는 건물. -block.overdrive-projector.description = 범위 내 모든 행동의 속도를 높여주는 보조형 방어 건물. +block.mend-projector.description = 주위 건물을 치료하는 건물입니다. +block.overdrive-projector.description = 범위 내 모든 행동의 속도를 높여주는 보조형 방어 건물입니다. block.force-projector.description = 보호막을 생성하는 건물.\n기본적으로 전기만 있으면 작동하지만, 메타를 넣어 보호막의 범위를 크게 확장시킬 수 있습니다. -block.shock-mine.description = 적이 이 블록을 지나가면 전격 공격을 하는 함정형 방어 건물. +block.shock-mine.description = 적이 이 블록을 지나가면 전격 공격을 하는 함정형 방어 건물입니다. block.duo.description = 범용성을 가진 터렛.\n지상 및 공중공격을 하며, 초중반에 유용합니다. block.arc.description = 목표 방향으로 전격 공격을 하는 포탑입니다. block.hail.description = 장거리 지상 공격을 하는 터렛입니다.\n적이 오기 전에 쓸어버릴 수 있습니다. block.lancer.description = 중거리 레이져 포탑입니다.\n적을 관통하기 때문에 뭉쳐있는 적들에게 매우 효과적입니다. block.wave.description = 적이 있는 자리에 액체를 뿌립니다.\n이 포탑을 활용하여 액체를 뿌린 곳에 불을 붙이거나 적을 느리게 할 수 있습니다. block.salvo.description = 명중률이 높고, 3발씩 끊어 발사하는 포탑입니다. -block.swarmer.description = 4발씩 끊어 발사하고, 유도 미사일을 가진 포탑입니다. +block.swarmer.description = 4발씩 끊어서 유도체를 발사하는 포탑입니다 block.ripple.description = 4개의 탄약으로 나눠 발사하여 명중률이 낮지만, 사거리가 매우 긴 포탑입니다. block.cyclone.description = 낮은 명중률과 높은 RPM 을 가진 포탑입니다.\n탄약이 남아있는 한 멈추지 않고 계속 연사합니다. block.fuse.description = 단거리에서 범위형 레이저를 발사하는 포탑입니다. @@ -701,21 +703,21 @@ block.titanium-conveyor.description = 빠른 속도로 자원을 수송할 수 block.phase-conveyor.description = 자원을 순간이동 시켜 주는 컨베이어 입니다. block.junction.description = 컨베이어를 교차시켜 자원을 수송할 때 사용할 수 있는 블록입니다. block.mass-driver.description = 자원을 받아서 다른 물질 이동기로 전달할 수 있는 블록입니다.\n엄청난 사거리를 가지고 있으며, 주로 컨베이어가 접근할 수 없는 곳에 유용하게 사용됩니다. -block.smelter.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.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 = 생성된 전기를 다른 건물로 전달하기 위한 건물이며, 일반 노드보다 더 많은 전력을 이동시킬 수 있습니다. @@ -729,31 +731,31 @@ block.solar-panel-large.description = 태양열을 받아 자기 스스로 전 block.thorium-reactor.description = 토륨을 원료로 하는 토륨 원자로 입니다.\n많은 전력을 생산하지만 엄청난 열을 발생시키기 때문에, 많은 량의 물 또는 냉각수가 있어야 터지지 않고 작동합니다. block.rtg-generator.description = 냉각은 필요 없지만 토륨 원자로보다 적은량의 전력을 생산하는 방사선 동위원소 열전자 발전기. block.unloader.description = 해당 창고 및 코어에서 자원을 빼내는데 사용됩니다. -block.container.description = 자원을 운반하기 위한 수송 블록입니다. -block.vault.description = 아이템을 임시로 저장할 수 있는 대형 창고 +block.container.description = 아이템을 임시로 저장할 수 있는 소형 창고입니다. +block.vault.description = 아이템을 임시로 저장할 수 있는 대형 창고입니다. block.mechanical-drill.description = 구리로 제작할 수 있는 기본 드릴입니다. block.pneumatic-drill.description = 돌, 티타늄을 채광할 수 있는 고급 드릴입니다. block.laser-drill.description = 토륨을 채광할 수 있는 최고급 드릴입니다.\n전력과 물을 공급하여 빠른 속도로 채광할 수 있습니다. block.blast-drill.description = 최상위 드릴입니다. 엄청난 양의 전력과 물을 소모하는 대신, 매우 빠른 속도로 채광합니다. -block.water-extractor.description = 바닥에서 물을 추출하여 건물에 공급할 수 있는 건물. -block.cultivator.description = 잔디에서 바이오메터를 추출할 수 있는 건물. -block.oil-extractor.description = 기름을 추출 해 주는 건물. -block.dart-ship-pad.description = 다트 비행선으로 바꿀 수 있는 패드. -block.trident-ship-pad.description = 삼지창 비행선으로 바꿀 수 있는 패드. -block.javelin-ship-pad.description = 자비린 비행선으로 바꿀 수 있는 패드. -block.glaive-ship-pad.description = 글레브 비행선으로 바꿀 수 있는 패드. +block.water-extractor.description = 바닥에서 물을 추출하여 건물에 공급할 수 있는 건물입니다. +block.cultivator.description = 잔디에서 바이오메터를 추출할 수 있는 건물입니다. +block.oil-extractor.description = 기름(타르)을 추출 해 주는 건물입니다. +block.dart-ship-pad.description = 다트 비행선으로 바꿀 수 있는 패드입니다. +block.trident-ship-pad.description = 삼지창 비행선으로 바꿀 수 있는 패드입니다. +block.javelin-ship-pad.description = 자비린 비행선으로 바꿀 수 있는 패드입니다. +block.glaive-ship-pad.description = 글레브 비행선으로 바꿀 수 있는 패드입니다. block.tau-mech-pad.description = 타우 기체로 바꿀 수 있는 패드 -block.delta-mech-pad.description = 델타 기체로 바꿀 수 있는 패드. +block.delta-mech-pad.description = 델타 기체로 바꿀 수 있는 패드입니다. block.omega-mech-pad.description = 오메가 기체로 바꿀 수 있는 패드 -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.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 = 생산된 유닛들을 제어할 수 있는 건물.\n첫번째 버튼은 적 기지로 공격하며, 두번째는 대기 상태, 세번째는 기지 근처를 돌며 정찰합니다. block.conduit.description = 일반 파이프. 액체가 지나갈 수 있도록 해 줍니다. block.pulse-conduit.description = 티타늄으로 만들어 졌으며, 일반 파이프보다 액체 수용량이 높습니다. @@ -768,13 +770,13 @@ block.thermal-pump.description = 용암 위에서 사용할 수 있는 펌프입 block.router.description = 한 방향에서 아이템을 받은 후 최대 3개의 다른 방향으로 동일하게 출력합니다.\n재료를 한곳에서 여러 대상으로 분할하여 운반하는데 유용합니다. block.distributor.description = 아이템을 최대 7개의 다른 방향으로 똑같이 분할하는 고급 분배기. block.bridge-conveyor.description = 고급 자원 수송 블록.\n지형이나 건물을 넘어 최대 3개 타일을 건너뛰고 자원을 운송할 수 있습니다. -block.alpha-mech-pad.description = 알파 기체로 바꿀 수 있는 패드. -block.itemsource.description = 자원을 선택하면 그 자원이 무한하게 튀어나오는 블록입니다. +block.alpha-mech-pad.description = 알파 기체로 바꿀 수 있는 패드입니다. +block.itemsource.description = 자원을 선택하면 그 자원이 무한하게 생성되는 블록입니다. block.liquidsource.description = 무한한 액체를 출력해냅니다. block.itemvoid.description = 아이템을 시공으로 빠트려 사라지게 만듭니다. -block.powerinfinite.description = 무한한 전력을 출력해냅니다. -block.powervoid.description = 무한한 아이템을 출력해냅니다. -liquid.water.description = 유닛이 이 위를 지나가면 이동속도가 느려지고, 깊은 물에 빠지면 죽습니다. -liquid.lava.description = 유닛이 이 위를 지나가면 이동속도가 매우 느려지고, 지속적으로 데미지를 입습니다. +block.powerinfinite.description = 무한한 전력을 공급해주는 블록입니다. +block.powervoid.description = 설정된 아이템을 계속해서 출력하는 블록입니다. +liquid.water.description = 지상 유닛이 이 위를 지나가면 이동속도가 느려지고, 깊은 물에 빠지면 죽습니다. +liquid.lava.description = 지상 유닛이 이 위를 지나가면 이동속도가 매우 느려지고, 지속적으로 데미지를 입습니다. liquid.oil.description = 일부 조합 블록에서 사용되는 자원입니다. liquid.cryofluid.description = 포탑 및 토륨 원자로에서 사용되는 자원입니다. 누출시 폭발 및 방화의 위험성이 있습니다. diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index 5c3d76a869..850ad3327e 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -50,7 +50,7 @@ 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}[] waves. +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 diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index 61e267fdab..e36c930dce 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -50,7 +50,7 @@ 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 = Sobrevive [accent]{0}[] Onda. +text.mission.wave = Sobrevive [accent]{0}/{1}[] Onda\nOnda em {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 diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index ec1c960dad..9c4d361ef3 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -50,7 +50,7 @@ text.mission.main = Главная мисия:[LIGHT_GRAY] {0} text.mission.info = Информация о миссии text.mission.complete = Миссия выполнена! text.mission.complete.body = Сектор {0},{1} был завоёван. -text.mission.wave = Пережить следующее количество волн: [accent]{0}[]. +text.mission.wave = Пережить следующее количество волн: [accent]{0}/{1}[]\nВолна в {2} text.mission.wave.enemies = Осталось волн:[accent] {0}/{1}[]\n{2} враг. text.mission.wave.enemy = Осталось волн:[accent] {0}/{1}[]\n{2} враг text.mission.wave.menu = Пережить[accent] {0} []волн @@ -407,7 +407,7 @@ mode.sandbox.name = Песочница mode.sandbox.description = Бесконечные ресурсы и нет таймера для волн, но можно самим вызвать волну. mode.custom.warning = [scarlet]РАЗБЛОКИРОВАННОЕ В ПОЛЬЗОВАТЕЛЬСКИХ ИГРАХ ИЛИ НА СЕРВЕРАХ НЕ СОХРАНЯЕТСЯ[]\n\nИграйте в секторах для разблокировки чего-либо mode.custom.warning.read = Внимательно прочитайте это!:\n[scarlet]РАЗБЛОКИРОВАННОЕ В ПОЛЬЗОВАТЕЛЬСКИХ ИГРАХ ИЛИ ДРУГИХ РЕЖИМАХ ИГРЫ НЕ РАСПРОСТРАНЯЕТСЯ НА СЕКТОРА ИЛИ ДРУГИЕ РЕЖИМЫ ИГРЫ!\n\n[LIGHT_GRAY](Я бы хотел, чтобы это не было необходимо, но, по-видимому, это так) -mode.freebuild.name = Cвободная\nстройка +mode.freebuild.name = Свободная\nстройка mode.freebuild.description = ограниченные ресурсы и нет таймера для волн. mode.pvp.name = Противо-\nстояние mode.pvp.description = боритесь против других игроков. diff --git a/core/assets/bundles/bundle_tk.properties b/core/assets/bundles/bundle_tk.properties index 1301e74969..ece71c0b5d 100644 --- a/core/assets/bundles/bundle_tk.properties +++ b/core/assets/bundles/bundle_tk.properties @@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0} text.mission.info = Mission Info 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 = [accent]{0}/{1}[] Dalga hayatta kal\n{2} Dalga 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 diff --git a/core/assets/bundles/bundle_tr.properties b/core/assets/bundles/bundle_tr.properties index 560453c021..68df10afd4 100644 --- a/core/assets/bundles/bundle_tr.properties +++ b/core/assets/bundles/bundle_tr.properties @@ -50,7 +50,7 @@ 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}[] waves. +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 diff --git a/core/assets/bundles/bundle_uk_UA.properties b/core/assets/bundles/bundle_uk_UA.properties index a01322f8e6..95630c8669 100644 --- a/core/assets/bundles/bundle_uk_UA.properties +++ b/core/assets/bundles/bundle_uk_UA.properties @@ -50,7 +50,7 @@ text.mission.main = Головна місія:[LIGHT_GRAY] {0} text.mission.info = Інформація про місії text.mission.complete = Місія завершена! text.mission.complete.body = Сектор {0},{1} був завойований. -text.mission.wave = Пережити наступну кількість хвиль:[accent]{0}[] . +text.mission.wave = Пережити наступну кількість хвиль:[accent]{0}/{1}[]\nХвиля в {2} text.mission.wave.enemies = Пережити [accent] {0}/{1} []хвиль\n{2} Ворог. text.mission.wave.enemy = Пережити[accent] {0}/{1} []хвиль\n{2} Ворог text.mission.wave.menu = Пережити[accent] {0} []хвиль diff --git a/core/assets/bundles/bundle_zh_CN.properties b/core/assets/bundles/bundle_zh_CN.properties index 6e0006c6d5..2e6526dd68 100644 --- a/core/assets/bundles/bundle_zh_CN.properties +++ b/core/assets/bundles/bundle_zh_CN.properties @@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0} text.mission.info = Mission Info text.mission.complete = 任务完成! text.mission.complete.body = 区域 {0},攻占了 {1} 个 -text.mission.wave = 存活了 [accent]{0}[] 波。 +text.mission.wave = 存活了 [accent]{0}/{1}[] 波。\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 diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 220b24c6b6..3d18289129 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -50,7 +50,7 @@ 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}[] waves. +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 diff --git a/core/assets/maps/sandbox.mmap b/core/assets/maps/sandbox.mmap index 3a448b7c1d..14e89ed3b7 100644 Binary files a/core/assets/maps/sandbox.mmap and b/core/assets/maps/sandbox.mmap differ diff --git a/core/assets/shaders/shield.fragment b/core/assets/shaders/shield.fragment index cfef064bb2..e71cb95f37 100644 --- a/core/assets/shaders/shield.fragment +++ b/core/assets/shaders/shield.fragment @@ -6,17 +6,15 @@ precision highp int; #define MAX_HITS 64 #define HIT_RADIUS 12.0 #define ALPHA 0.18 +#define thickness 1.0 +#define step 2.0 uniform sampler2D u_texture; - -uniform vec4 u_color; uniform vec2 u_texsize; uniform float u_time; uniform float u_scaling; uniform float u_dp; uniform vec2 u_offset; -uniform int u_hitamount; -uniform vec3 u_hits[MAX_HITS]; varying vec4 v_color; varying vec2 v_texCoord; @@ -28,29 +26,19 @@ float round(float f){ void main() { vec2 T = v_texCoord.xy; - vec2 coords = (T * u_texsize) + u_offset; T += vec2(sin(coords.y / 3.0 + u_time / 20.0) / 240.0, sin(coords.x / 3.0 + u_time / 20.0) / 240.0) * u_scaling; float si = sin(u_time / 20.0) / 8.0; - vec4 color = texture2D(u_texture, T); - vec2 v = vec2(1.0/u_texsize.x, 1.0/u_texsize.y); - bool any = false; + if(texture2D(u_texture, T).a < 0.1 && + (texture2D(u_texture, T + vec2(0, step) * v).a > 0.1 || texture2D(u_texture, T + vec2(0, -step) * v).a > 0.1 || + texture2D(u_texture, T + vec2(step, 0) * v).a > 0.1 || texture2D(u_texture, T + vec2(-step, 0) * v).a > 0.1)){ - float thickness = 1.0; - float step = 2.0; - - if(texture2D(u_texture, T).a < 0.1 && - (texture2D(u_texture, T + vec2(0, step) * v).a > 0.1 || texture2D(u_texture, T + vec2(0, -step) * v).a > 0.1 || - texture2D(u_texture, T + vec2(step, 0) * v).a > 0.1 || texture2D(u_texture, T + vec2(-step, 0) * v).a > 0.1)) - any = true; - - if(any){ - gl_FragColor = mix(u_color, vec4(1.0), si); + gl_FragColor = mix(v_color, vec4(1.0), si); }else{ if(color.a > 0.1){ @@ -59,18 +47,6 @@ void main() { } color.a = ALPHA; - - for(int i = 0; i < MAX_HITS; i ++){ - if(i >= u_hitamount) break; - vec3 hit = u_hits[i]; - float rad = hit.z * HIT_RADIUS; - float fin = 1.0 - hit.z; - - if(abs(distance(vec2(hit.x, hit.y), coords - u_texsize/2.0) - rad) < 1.0){ - color = mix(color, mix(u_color, vec4(1.0), si), (1.0 * fin)); - color.a = ALPHA + 0.82 *fin; - } - } } gl_FragColor = color; diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index b17d0e8649..53901c92d1 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/src/Mindustry.gwt.xml b/core/src/Mindustry.gwt.xml deleted file mode 100644 index 828369ac80..0000000000 --- a/core/src/Mindustry.gwt.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 038a48ee7e..a11a7dbdcb 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -94,6 +94,7 @@ public class Vars{ public static float controllerMin = 0.25f; public static float baseControllerSpeed = 11f; public static boolean snapCamera = true; + public static ContentLoader content; public static GameState state; public static ThreadHandler threads; @@ -162,6 +163,7 @@ public class Vars{ }); } + state = new GameState(); threads = new ThreadHandler(); mobile = Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS || testMobile; diff --git a/core/src/io/anuke/mindustry/ai/BlockIndexer.java b/core/src/io/anuke/mindustry/ai/BlockIndexer.java index c533186978..112a5a1219 100644 --- a/core/src/io/anuke/mindustry/ai/BlockIndexer.java +++ b/core/src/io/anuke/mindustry/ai/BlockIndexer.java @@ -71,6 +71,7 @@ public class BlockIndexer{ flagMap[i][j] = new ObjectSet<>(); } } + typeMap.clear(); ores = null; @@ -246,7 +247,7 @@ public class BlockIndexer{ for(int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++){ for(int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){ Tile result = world.tile(x, y); - if(result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue; + if( result == null || result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue; itemSet.add(result.block().drops.item); } diff --git a/core/src/io/anuke/mindustry/content/Mechs.java b/core/src/io/anuke/mindustry/content/Mechs.java index e8898e9a84..88fb7b6a9e 100644 --- a/core/src/io/anuke/mindustry/content/Mechs.java +++ b/core/src/io/anuke/mindustry/content/Mechs.java @@ -37,7 +37,7 @@ public class Mechs implements ContentList{ alpha = new Mech("alpha-mech", false){ int maxDrones = 3; - float buildTime = 200f; + float buildTime = 20f; { drillPower = 1; @@ -53,14 +53,19 @@ public class Mechs implements ContentList{ @Override public void updateAlt(Player player){ - if(getDrones(player) < maxDrones && !TutorialSector.supressDrone() && player.timer.get(Player.timerAbility, buildTime)){ - if(!Net.client()) { - AlphaDrone drone = (AlphaDrone) UnitTypes.alphaDrone.create(player.getTeam()); - drone.leader = player; - drone.set(player.x, player.y); - drone.add(); + if(player.isShooting && getDrones(player) < maxDrones && !TutorialSector.supressDrone()){ + player.timer.get(Player.timerAbility, buildTime); + + if(player.timer.getTime(Player.timerAbility) > buildTime/2f){ + if(!Net.client()){ + AlphaDrone drone = (AlphaDrone) UnitTypes.alphaDrone.create(player.getTeam()); + drone.leader = player; + drone.set(player.x, player.y); + drone.add(); + + Effects.effect(UnitFx.unitLand, player); + } } - Effects.effect(UnitFx.unitLand, player); } } diff --git a/core/src/io/anuke/mindustry/content/blocks/Blocks.java b/core/src/io/anuke/mindustry/content/blocks/Blocks.java index da606c6851..67e031d4a6 100644 --- a/core/src/io/anuke/mindustry/content/blocks/Blocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/Blocks.java @@ -139,7 +139,7 @@ public class Blocks extends BlockList implements ContentList{ }}; ice = new Floor("ice"){{ - dragMultiplier = 0.3f; + dragMultiplier = 0.2f; speedMultiplier = 0.4f; minimapColor = Color.valueOf("b8eef8"); hasOres = true; diff --git a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java index 4333317e7a..a9e9f97155 100644 --- a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java @@ -30,7 +30,7 @@ public class LiquidBlocks extends BlockList implements ContentList{ thermalPump = new Pump("thermal-pump"){{ shadow = "shadow-rounded-2"; - pumpAmount = 0.3f; + pumpAmount = 0.275f; consumes.power(0.03f); liquidCapacity = 40f; hasPower = true; diff --git a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java index fb43623e58..1420f0c838 100644 --- a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java @@ -20,9 +20,9 @@ public class PowerBlocks extends BlockList implements ContentList{ }}; thermalGenerator = new LiquidHeatGenerator("thermal-generator"){{ - maxLiquidGenerate = 0.5f; + maxLiquidGenerate = 4f; powerCapacity = 40f; - powerPerLiquid = 1f; + powerPerLiquid = 0.1f; generateEffect = BlockFx.redgeneratespark; size = 2; }}; diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 44833a7406..8950f37594 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -179,12 +179,6 @@ public class Control extends Module{ }); Events.on(WorldLoadEvent.class, event -> threads.runGraphics(() -> Events.fire(new WorldLoadGraphicsEvent()))); - - Events.on(TileChangeEvent.class, event -> { - if(event.tile.getTeam() == players[0].getTeam() && Recipe.getByResult(event.tile.block()) != null){ - unlocks.handleContentUsed(Recipe.getByResult(event.tile.block())); - } - }); } public void addPlayer(int index){ @@ -278,7 +272,7 @@ public class Control extends Module{ outer: for(int i = 0; i < content.recipes().size; i ++){ Recipe recipe = content.recipes().get(i); - if(!recipe.hidden && recipe.requirements != null){ + if(!recipe.isHidden() && recipe.requirements != null){ for(ItemStack stack : recipe.requirements){ if(!entity.items.has(stack.item, Math.min((int) (stack.amount * unlockResourceScaling), 2000))) continue outer; } diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index fb1feb196d..471eba010e 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -10,9 +10,11 @@ import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Teams; +import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Events; import io.anuke.ucore.core.Timers; @@ -35,13 +37,31 @@ public class Logic extends Module{ public boolean doUpdate = true; public Logic(){ - state = new GameState(); + Events.on(TileChangeEvent.class, event -> { + if(event.tile.getTeam() == defaultTeam && Recipe.getByResult(event.tile.block()) != null){ + handleContent(Recipe.getByResult(event.tile.block())); + } + }); } @Override public void init(){ EntityQuery.init(); - EntityQuery.collisions().setCollider(tilesize, world::solid); + EntityQuery.collisions().setCollider(tilesize, (x, y) -> { + Tile tile = world.tile(x, y); + return tile != null && tile.solid(); + }); + } + + /**Handles the event of content being used by either the player or some block.*/ + public void handleContent(UnlockableContent content){ + if(world.getSector() != null){ + world.getSector().currentMission().onContentUsed(content); + } + + if(!headless){ + control.unlocks.unlockContent(content); + } } public void play(){ @@ -142,7 +162,8 @@ public class Logic extends Module{ world.sectors.completeSector(world.getSector().x, world.getSector().y); world.sectors.save(); - if(!headless){ + + if(!headless && !Net.client()){ ui.missions.show(world.getSector()); } @@ -151,7 +172,6 @@ public class Logic extends Module{ @Override public void update(){ - if(threads.isEnabled() && !threads.isOnThread()) return; if(Vars.control != null){ control.runUpdateLogic(); @@ -159,15 +179,10 @@ public class Logic extends Module{ if(!state.is(State.menu)){ - if(!Net.client() && !world.isInvalidMap()){ - updateSectors(); - checkGameOver(); - } - if(!state.isPaused()){ Timers.update(); - if(!state.mode.disableWaveTimer && !state.mode.disableWaves){ + if(!state.mode.disableWaveTimer && !state.mode.disableWaves && !state.gameOver){ state.wavetime -= Timers.delta(); } @@ -216,10 +231,11 @@ public class Logic extends Module{ world.pathfinder.update(); } - } - if(threads.isEnabled()){ - netServer.update(); + if(!Net.client() && !world.isInvalidMap()){ + updateSectors(); + checkGameOver(); + } } } } diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index baebe42cc8..12a644687d 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -165,14 +165,17 @@ public class NetClient extends Module{ public static void onKick(KickReason reason){ netClient.disconnectQuietly(); state.set(State.menu); - if(!reason.quiet){ - if(reason.extraText() != null){ - ui.showText(reason.toString(), reason.extraText()); - }else{ - ui.showText("$text.disconnect", reason.toString()); + + threads.runGraphics(() -> { + if(!reason.quiet){ + if(reason.extraText() != null){ + ui.showText(reason.toString(), reason.extraText()); + }else{ + ui.showText("$text.disconnect", reason.toString()); + } } - } - ui.loadfrag.hide(); + ui.loadfrag.hide(); + }); } @Remote(variants = Variant.both) @@ -396,11 +399,11 @@ public class NetClient extends Module{ quiet = true; } - public synchronized void addRemovedEntity(int id){ + public void addRemovedEntity(int id){ removed.add(id); } - public synchronized boolean isEntityUsed(int id){ + public boolean isEntityUsed(int id){ return removed.contains(id); } @@ -411,11 +414,9 @@ public class NetClient extends Module{ BuildRequest[] requests; - synchronized(player.getPlaceQueue()){ - requests = new BuildRequest[player.getPlaceQueue().size]; - for(int i = 0; i < requests.length; i++){ - requests[i] = player.getPlaceQueue().get(i); - } + requests = new BuildRequest[player.getPlaceQueue().size]; + for(int i = 0; i < requests.length; i++){ + requests[i] = player.getPlaceQueue().get(i); } Call.onClientShapshot(lastSent++, TimeUtils.millis(), player.x, player.y, diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 2a9103f14d..063c074ad4 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -416,7 +416,6 @@ public class NetServer extends Module{ } public void update(){ - if(threads.isEnabled() && !threads.isOnThread()) return; if(!headless && !closing && Net.server() && state.is(State.menu)){ closing = true; diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 7931a10827..95c202051f 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -248,11 +248,12 @@ public class Renderer extends RendererModule{ overlays.drawBottom(); drawAndInterpolate(playerGroup, p -> true, Player::drawBuildRequests); - Shaders.shield.color.set(Palette.accent); Graphics.beginShaders(Shaders.shield); EntityDraw.draw(shieldGroup); EntityDraw.drawWith(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawOver()); + Draw.color(Palette.accent); Graphics.endShaders(); + Draw.color(); overlays.drawTop(); diff --git a/core/src/io/anuke/mindustry/core/ThreadHandler.java b/core/src/io/anuke/mindustry/core/ThreadHandler.java index f439a6670e..6531acc2ac 100644 --- a/core/src/io/anuke/mindustry/core/ThreadHandler.java +++ b/core/src/io/anuke/mindustry/core/ThreadHandler.java @@ -1,80 +1,35 @@ package io.anuke.mindustry.core; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.utils.Queue; import com.badlogic.gdx.utils.TimeUtils; import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Timers; -import io.anuke.ucore.util.Log; -import io.anuke.ucore.util.Threads; import io.anuke.ucore.util.Threads.ThreadInfoProvider; -import static io.anuke.mindustry.Vars.control; -import static io.anuke.mindustry.Vars.logic; - public class ThreadHandler implements ThreadInfoProvider{ - private final Queue toRun = new Queue<>(); - private Thread thread, graphicsThread; - private final Object updateLock = new Object(); - private float delta = 1f; - private float smoothDelta = 1f; - private long frame = 0, lastDeltaUpdate; - private float framesSinceUpdate; - private boolean enabled; - private boolean rendered = true; private long lastFrameTime; public ThreadHandler(){ - Threads.setThreadInfoProvider(this); - graphicsThread = Thread.currentThread(); - Timers.setDeltaProvider(() -> { - float result = isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f; - return Math.min(Float.isNaN(result) ? 1f : result, 15f); + float result = Gdx.graphics.getDeltaTime() * 60f; + return Math.min(Float.isNaN(result) || Float.isInfinite(result) ? 1f : result, 15f); }); } public void run(Runnable r){ - if(enabled){ - synchronized(toRun){ - toRun.addLast(r); - } - }else{ - r.run(); - } + r.run(); } public void runGraphics(Runnable r){ - if(enabled){ - Gdx.app.postRunnable(r); - }else{ - r.run(); - } + r.run(); } public void runDelay(Runnable r){ - if(enabled){ - synchronized(toRun){ - toRun.addLast(r); - } - }else{ - Gdx.app.postRunnable(r); - } - } - - public int getTPS(){ - if(smoothDelta == 0f){ - return 60; - } - return (int) (60 / smoothDelta); + Gdx.app.postRunnable(r); } public long getFrameID(){ - return enabled ? frame : Gdx.graphics.getFrameId(); - } - - public float getFramesSinceUpdate(){ - return framesSinceUpdate; + return Gdx.graphics.getFrameId(); } public void handleBeginRender(){ @@ -95,119 +50,16 @@ public class ThreadHandler implements ThreadInfoProvider{ } } } - - if(!enabled) return; - - framesSinceUpdate += Timers.delta(); - - synchronized(updateLock){ - rendered = true; - updateLock.notify(); - } - } - - public boolean isEnabled(){ - return enabled; - } - - public void setEnabled(boolean enabled){ - if(enabled){ - logic.doUpdate = false; - Timers.runTask(2f, () -> { - if(thread != null){ - thread.interrupt(); - thread = null; - } - - thread = new Thread(this::runLogic); - thread.setDaemon(true); - thread.setName("Update Thread"); - thread.start(); - Log.info("Starting logic thread."); - - this.enabled = true; - }); - }else{ - this.enabled = false; - if(thread != null){ - thread.interrupt(); - thread = null; - } - Timers.runTask(2f, () -> { - logic.doUpdate = true; - }); - } - } - - public boolean doInterpolate(){ - return enabled && Gdx.graphics.getFramesPerSecond() - getTPS() > 20 && getTPS() < 30; - } - - public boolean isOnThread(){ - return Thread.currentThread() == thread; } @Override public boolean isOnLogicThread() { - return !enabled || Thread.currentThread() == thread; + return true; } @Override public boolean isOnGraphicsThread() { - return !enabled || Thread.currentThread() == graphicsThread; + return true; } - private void runLogic(){ - try{ - while(true){ - long time = TimeUtils.nanoTime(); - - while(true){ - Runnable r; - synchronized(toRun){ - if(toRun.size > 0){ - r = toRun.removeFirst(); - }else{ - break; - } - } - - r.run(); - } - - logic.doUpdate = true; - logic.update(); - logic.doUpdate = false; - - long elapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time)); - long target = (long) ((1000) / 60f); - - if(elapsed < target){ - Thread.sleep(target - elapsed); - } - - synchronized(updateLock){ - while(!rendered){ - updateLock.wait(); - } - rendered = false; - } - - long actuallyElapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time)); - delta = Math.max(actuallyElapsed, target) / 1000f * 60f; - - if(TimeUtils.timeSinceMillis(lastDeltaUpdate) > 1000){ - lastDeltaUpdate = TimeUtils.millis(); - smoothDelta = delta; - } - - frame++; - framesSinceUpdate = 0; - } - }catch(InterruptedException ex){ - Log.info("Stopping logic thread."); - }catch(Throwable ex){ - control.setError(ex); - } - } } diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index d8158b84fe..1fb684cdb2 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -28,6 +28,7 @@ import io.anuke.ucore.scene.ui.TextField.TextFieldFilter; import io.anuke.ucore.scene.ui.TooltipManager; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Unit; +import io.anuke.ucore.util.Threads; import static io.anuke.mindustry.Vars.*; import static io.anuke.ucore.scene.actions.Actions.*; @@ -154,6 +155,7 @@ public class UI extends SceneModule{ load = new LoadDialog(); levels = new CustomGameDialog(); language = new LanguageDialog(); + unlocks = new UnlocksDialog(); settings = new SettingsMenuDialog(); host = new HostDialog(); paused = new PausedDialog(); @@ -164,7 +166,6 @@ public class UI extends SceneModule{ traces = new TraceDialog(); maps = new MapsDialog(); localplayers = new LocalPlayerDialog(); - unlocks = new UnlocksDialog(); content = new ContentInfoDialog(); sectors = new SectorsDialog(); missions = new MissionDialog(); @@ -239,6 +240,8 @@ public class UI extends SceneModule{ } public void showInfoFade(String info){ + Threads.assertGraphics(); + Table table = new Table(); table.setFillParent(true); table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor()); @@ -247,6 +250,8 @@ public class UI extends SceneModule{ } public void showInfo(String info){ + Threads.assertGraphics(); + new Dialog("$text.info.title", "dialog"){{ getCell(content()).growX(); content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center); @@ -255,6 +260,8 @@ public class UI extends SceneModule{ } public void showInfo(String info, Runnable clicked){ + Threads.assertGraphics(); + new Dialog("$text.info.title", "dialog"){{ getCell(content()).growX(); content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center); diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 38d4724446..4c67c5e679 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -70,7 +70,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra public TargetTrait moveTarget; private float walktime; - private Queue placeQueue = new ThreadQueue<>(); + private Queue placeQueue = new Queue<>(); private Tile mining; private CarriableTrait carrying; private Trail trail = new Trail(12); @@ -323,7 +323,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra } if(floor.isLiquid){ - Draw.tint(Color.WHITE, floor.liquidColor, Mathf.clamp(drownTime)); + Draw.tint(Color.WHITE, floor.liquidColor, drownTime); }else{ Draw.tint(Color.WHITE); } @@ -421,55 +421,53 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra /**Draw all current build requests. Does not draw the beam effect, only the positions.*/ public void drawBuildRequests(){ - synchronized(getPlaceQueue()){ - for(BuildRequest request : getPlaceQueue()){ - if(getCurrentRequest() == request) continue; + for(BuildRequest request : getPlaceQueue()){ + if(getCurrentRequest() == request) continue; - if(request.breaking){ - Block block = world.tile(request.x, request.y).target().block(); + if(request.breaking){ + Block block = world.tile(request.x, request.y).target().block(); - //draw removal request - Lines.stroke(2f); + //draw removal request + Lines.stroke(2f); - Draw.color(Palette.removeBack); + Draw.color(Palette.removeBack); - float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1; + 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); + Lines.square( + request.x * tilesize + block.offset(), + request.y * tilesize + block.offset() - 1, + rad); - Draw.color(Palette.remove); + Draw.color(Palette.remove); - Lines.square( - request.x * tilesize + block.offset(), - request.y * tilesize + block.offset(), - rad); - }else{ - //draw place request - Lines.stroke(2f); + Lines.square( + request.x * tilesize + block.offset(), + request.y * tilesize + block.offset(), + rad); + }else{ + //draw place request + Lines.stroke(2f); - Draw.color(Palette.accentBack); + Draw.color(Palette.accentBack); - float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f; + 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); + Lines.square( + request.x * tilesize + request.recipe.result.offset(), + request.y * tilesize + request.recipe.result.offset() - 1, + rad); - Draw.color(Palette.accent); + Draw.color(Palette.accent); - Lines.square( - request.x * tilesize + request.recipe.result.offset(), - request.y * tilesize + request.recipe.result.offset(), - rad); - } + Lines.square( + request.x * tilesize + request.recipe.result.offset(), + request.y * tilesize + request.recipe.result.offset(), + rad); } - - Draw.reset(); } + + Draw.reset(); } //endregion @@ -512,14 +510,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra achievedFlight = true; } - if(boostHeat <= liftoffBoost + 0.05f && achievedFlight){ + if(boostHeat <= liftoffBoost + 0.05f && achievedFlight && !mech.flying){ if(tile != null){ if(mech.shake > 1f){ Effects.shake(mech.shake, mech.shake, this); } Effects.effect(UnitFx.unitLand, tile.floor().minimapColor, x, y, tile.floor().isLiquid ? 1f : 0.5f); } - if(!mech.flying) mech.onLand(this); + mech.onLand(this); achievedFlight = false; } diff --git a/core/src/io/anuke/mindustry/entities/TileEntity.java b/core/src/io/anuke/mindustry/entities/TileEntity.java index 910d36d10f..10aec5f47b 100644 --- a/core/src/io/anuke/mindustry/entities/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/TileEntity.java @@ -259,27 +259,25 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ @Override public void update(){ - synchronized(Tile.tileSetLock){ - //TODO better smoke effect, this one is awful - if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) && - Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){ + //TODO better smoke effect, this one is awful + if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) && + Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){ - Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4)); - } + Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4)); + } - timeScaleDuration -= Timers.delta(); - if(timeScaleDuration <= 0f || !tile.block().canOverdrive){ - timeScale = 1f; - } + timeScaleDuration -= Timers.delta(); + if(timeScaleDuration <= 0f || !tile.block().canOverdrive){ + timeScale = 1f; + } - if(health <= 0){ - onDeath(); - } - Block previous = tile.block(); - tile.block().update(tile); - if(tile.block() == previous && cons != null){ - cons.update(this); - } + if(health <= 0){ + onDeath(); + } + Block previous = tile.block(); + tile.block().update(tile); + if(tile.block() == previous && cons != null){ + cons.update(this); } } diff --git a/core/src/io/anuke/mindustry/entities/Unit.java b/core/src/io/anuke/mindustry/entities/Unit.java index 9508693e30..239bedb687 100644 --- a/core/src/io/anuke/mindustry/entities/Unit.java +++ b/core/src/io/anuke/mindustry/entities/Unit.java @@ -278,7 +278,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ drownTime = Mathf.clamp(drownTime); - if(drownTime >= 0.999f){ + if(drownTime >= 0.999f && !Net.client()){ damage(health + 1); } diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index 82b551103d..2d4808cc6a 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -88,14 +88,13 @@ public interface BuilderTrait extends Entity{ } default void readBuilding(DataInput input, boolean applyChanges) throws IOException{ - synchronized(getPlaceQueue()){ - if(applyChanges) getPlaceQueue().clear(); + if(applyChanges) getPlaceQueue().clear(); - byte type = input.readByte(); - if(type != -1){ - int position = input.readInt(); - float progress = input.readFloat(); - BuildRequest request; + byte type = input.readByte(); + if(type != -1){ + int position = input.readInt(); + float progress = input.readFloat(); + BuildRequest request; if(type == 1){ //remove request = new BuildRequest(Pos.x(position), Pos.y(position)); @@ -105,13 +104,12 @@ public interface BuilderTrait extends Entity{ request = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.recipe(recipe)); } - request.progress = progress; + request.progress = progress; - if(applyChanges){ - getPlaceQueue().addLast(request); - }else if(isBuilding()){ - getCurrentRequest().progress = progress; - } + if(applyChanges){ + getPlaceQueue().addLast(request); + }else if(isBuilding()){ + getCurrentRequest().progress = progress; } } } @@ -126,13 +124,11 @@ public interface BuilderTrait extends Entity{ * Otherwise, a new place request is added to the queue. */ default void replaceBuilding(int x, int y, int rotation, Recipe recipe){ - synchronized(getPlaceQueue()){ - for(BuildRequest request : getPlaceQueue()){ - if(request.x == x && request.y == y){ - clearBuilding(); - addBuildRequest(request); - return; - } + for(BuildRequest request : getPlaceQueue()){ + if(request.x == x && request.y == y){ + clearBuilding(); + addBuildRequest(request); + return; } } @@ -146,18 +142,16 @@ public interface BuilderTrait extends Entity{ /**Add another build requests to the tail of the queue, if it doesn't exist there yet.*/ default void addBuildRequest(BuildRequest place){ - synchronized(getPlaceQueue()){ - for(BuildRequest request : getPlaceQueue()){ - if(request.x == place.x && request.y == place.y){ - return; - } + for(BuildRequest request : getPlaceQueue()){ + if(request.x == place.x && request.y == place.y){ + return; } - Tile tile = world.tile(place.x, place.y); - if(tile != null && tile.entity instanceof BuildEntity){ - place.progress = tile.entity().progress; - } - getPlaceQueue().addLast(place); } + Tile tile = world.tile(place.x, place.y); + if(tile != null && tile.entity instanceof BuildEntity){ + place.progress = tile.entity().progress; + } + getPlaceQueue().addLast(place); } /** @@ -165,9 +159,7 @@ public interface BuilderTrait extends Entity{ * May return null. */ default BuildRequest getCurrentRequest(){ - synchronized(getPlaceQueue()){ - return getPlaceQueue().size == 0 ? null : getPlaceQueue().first(); - } + return getPlaceQueue().size == 0 ? null : getPlaceQueue().first(); } /** @@ -279,18 +271,15 @@ public interface BuilderTrait extends Entity{ /**Draw placement effects for an entity. This includes mining*/ default void drawBuilding(Unit unit){ BuildRequest request; - - synchronized(getPlaceQueue()){ - if(!isBuilding()){ - if(getMineTile() != null){ - drawMining(unit); - } - return; + if(!isBuilding()){ + if(getMineTile() != null){ + drawMining(unit); } - - request = getCurrentRequest(); + return; } + request = getCurrentRequest(); + Tile tile = world.tile(request.x, request.y); if(unit.distanceTo(tile) > placeDistance){ diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java index 74472c764a..c608928a0e 100644 --- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java @@ -28,10 +28,7 @@ import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.util.Angles; -import io.anuke.ucore.util.Geometry; -import io.anuke.ucore.util.Mathf; -import io.anuke.ucore.util.Timer; +import io.anuke.ucore.util.*; import java.io.DataInput; import java.io.DataOutput; @@ -316,8 +313,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ if(target != null) behavior(); if(!isWave && !isFlying()){ - x = Mathf.clamp(x, 0, world.width() * tilesize); - y = Mathf.clamp(y, 0, world.height() * tilesize); + x = Mathf.clamp(x, tilesize/2f, world.width() * tilesize - tilesize/2f); + y = Mathf.clamp(y, tilesize/2f, world.height() * tilesize - tilesize/2f); } } diff --git a/core/src/io/anuke/mindustry/entities/units/types/AlphaDrone.java b/core/src/io/anuke/mindustry/entities/units/types/AlphaDrone.java index 7f4f017e92..6f80b842c0 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/AlphaDrone.java +++ b/core/src/io/anuke/mindustry/entities/units/types/AlphaDrone.java @@ -1,15 +1,21 @@ package io.anuke.mindustry.entities.units.types; import com.badlogic.gdx.math.Vector2; +import io.anuke.annotations.Annotations.Loc; +import io.anuke.annotations.Annotations.Remote; import io.anuke.mindustry.Vars; +import io.anuke.mindustry.content.fx.UnitFx; +import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Predict; -import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.traits.TargetTrait; +import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.entities.units.FlyingUnit; import io.anuke.mindustry.entities.units.UnitCommand; import io.anuke.mindustry.entities.units.UnitState; +import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.AmmoType; +import io.anuke.ucore.core.Effects; import io.anuke.ucore.util.Mathf; import java.io.DataInput; @@ -22,7 +28,8 @@ import static io.anuke.mindustry.Vars.players; public class AlphaDrone extends FlyingUnit { static final float followDistance = 80f; - public Unit leader; + public Player leader; + public final UnitState attack = new UnitState() { @Override public void update() { @@ -32,15 +39,18 @@ public class AlphaDrone extends FlyingUnit { } TargetTrait last = target; target = leader; + if(last == null){ - circle(50f); + circle(leader.isShooting ? 60f : 0f); } + target = last; if(distanceTo(leader) < followDistance){ targetClosest(); }else{ target = null; } + if(target != null){ attack(50f); @@ -51,9 +61,20 @@ public class AlphaDrone extends FlyingUnit { getWeapon().update(AlphaDrone.this, to.x, to.y); } } + + if(!leader.isShooting && distanceTo(leader) < 8f){ + Call.onAlphaDroneFade(AlphaDrone.this); + } } }; + @Remote(called = Loc.server) + public static void onAlphaDroneFade(BaseUnit drone){ + if(drone == null) return; + drone.remove(); + Effects.effect(UnitFx.pickup, drone); + } + @Override public void onCommand(UnitCommand command){ //nuh diff --git a/core/src/io/anuke/mindustry/entities/units/types/Drone.java b/core/src/io/anuke/mindustry/entities/units/types/Drone.java index 319879254a..e909449a38 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Drone.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Drone.java @@ -40,12 +40,11 @@ import static io.anuke.mindustry.Vars.unitGroups; import static io.anuke.mindustry.Vars.world; public class Drone extends FlyingUnit implements BuilderTrait{ - protected static float discoverRange = 120f; protected static int timerRepairEffect = timerIndex++; protected Item targetItem; protected Tile mineTile; - protected Queue placeQueue = new ThreadQueue<>(); + protected Queue placeQueue = new Queue<>(); protected boolean isBreaking; public final UnitState @@ -250,14 +249,12 @@ public class Drone extends FlyingUnit implements BuilderTrait{ for(BaseUnit unit : group.all()){ if(unit instanceof Drone){ Drone drone = (Drone)unit; - synchronized(drone.getPlaceQueue()){ - if(drone.isBuilding()){ - //stop building if opposite building begins. - BuildRequest req = drone.getCurrentRequest(); - if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){ - drone.clearBuilding(); - drone.setState(drone.repair); - } + if(drone.isBuilding()){ + //stop building if opposite building begins. + BuildRequest req = drone.getCurrentRequest(); + if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){ + drone.clearBuilding(); + drone.setState(drone.repair); } } @@ -319,6 +316,10 @@ public class Drone extends FlyingUnit implements BuilderTrait{ TileEntity entity = (TileEntity) target; entity.health += type.healSpeed * Timers.delta(); entity.health = Mathf.clamp(entity.health, 0, entity.tile.block().health); + + if(timer.get(timerRepairEffect, 30)){ + Effects.effect(BlockFx.healBlockFull, Palette.heal, entity.x, entity.y, entity.tile.block().size); + } } updateBuilding(this); diff --git a/core/src/io/anuke/mindustry/game/Unlocks.java b/core/src/io/anuke/mindustry/game/Unlocks.java index 0730c4af64..e2bbd5984b 100644 --- a/core/src/io/anuke/mindustry/game/Unlocks.java +++ b/core/src/io/anuke/mindustry/game/Unlocks.java @@ -19,14 +19,6 @@ public class Unlocks{ Settings.setSerializer(ContentType.class, (stream, t) -> stream.writeInt(t.ordinal()), stream -> ContentType.values()[stream.readInt()]); } - /**Handles the event of content being used by either the player or some block.*/ - public void handleContentUsed(UnlockableContent content){ - if(world.getSector() != null){ - world.getSector().currentMission().onContentUsed(content); - } - unlockContent(content); - } - /** Returns whether or not this piece of content is unlocked yet.*/ public boolean isUnlocked(UnlockableContent content){ return rootSet().isUnlocked(content) || currentSet().isUnlocked(content); diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 33ac40ce03..2b34127e2a 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -106,32 +106,29 @@ public class BlockRenderer{ for(int x = minx; x <= maxx; x++){ for(int y = miny; y <= maxy; y++){ boolean expanded = (Math.abs(x - avgx) > rangex || Math.abs(y - avgy) > rangey); + Tile tile = world.rawTile(x, y); - synchronized(Tile.tileSetLock){ - Tile tile = world.rawTile(x, y); + if(tile != null){ + Block block = tile.block(); + Team team = tile.getTeam(); - if(tile != null){ - Block block = tile.block(); - Team team = tile.getTeam(); + if(!expanded && block != Blocks.air && world.isAccessible(x, y)){ + tile.block().drawShadow(tile); + } - if(!expanded && block != Blocks.air && world.isAccessible(x, y)){ - tile.block().drawShadow(tile); + if(block != Blocks.air){ + if(!expanded){ + addRequest(tile, Layer.block); + teamChecks.add(team.ordinal()); } - if(block != Blocks.air){ - if(!expanded){ - addRequest(tile, Layer.block); - teamChecks.add(team.ordinal()); + if(block.expanded || !expanded){ + if(block.layer != null && block.isLayer(tile)){ + addRequest(tile, block.layer); } - if(block.expanded || !expanded){ - if(block.layer != null && block.isLayer(tile)){ - addRequest(tile, block.layer); - } - - if(block.layer2 != null && block.isLayer2(tile)){ - addRequest(tile, block.layer2); - } + if(block.layer2 != null && block.isLayer2(tile)){ + addRequest(tile, block.layer2); } } } @@ -171,16 +168,14 @@ public class BlockRenderer{ layerBegins(req.layer); } - synchronized(Tile.tileSetLock){ - Block block = req.tile.block(); + Block block = req.tile.block(); - if(req.layer == Layer.block){ - block.draw(req.tile); - }else if(req.layer == block.layer){ - block.drawLayer(req.tile); - }else if(req.layer == block.layer2){ - block.drawLayer2(req.tile); - } + if(req.layer == Layer.block){ + block.draw(req.tile); + }else if(req.layer == block.layer){ + block.drawLayer(req.tile); + }else if(req.layer == block.layer2){ + block.drawLayer2(req.tile); } lastLayer = req.layer; @@ -199,17 +194,16 @@ public class BlockRenderer{ BlockRequest req = requests.get(index); if(req.tile.getTeam() != team) continue; - synchronized(Tile.tileSetLock){ - Block block = req.tile.block(); + Block block = req.tile.block(); - if(req.layer == Layer.block){ - block.draw(req.tile); - }else if(req.layer == block.layer){ - block.drawLayer(req.tile); - }else if(req.layer == block.layer2){ - block.drawLayer2(req.tile); - } + if(req.layer == Layer.block){ + block.draw(req.tile); + }else if(req.layer == block.layer){ + block.drawLayer(req.tile); + }else if(req.layer == block.layer2){ + block.drawLayer2(req.tile); } + } } diff --git a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java index dab7016c99..917bf12365 100644 --- a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java @@ -74,20 +74,18 @@ public class MinimapRenderer implements Disposable{ dx = Mathf.clamp(dx, sz, world.width() - sz); dy = Mathf.clamp(dy, sz, world.height() - sz); - synchronized(units){ - rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); - Graphics.beginClip(x, y, w, h); + rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); + Graphics.beginClip(x, y, w, h); - for(Unit unit : units){ - float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h; - Draw.color(unit.getTeam().color); - Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2)); - } - - Draw.color(); - - Graphics.endClip(); + for(Unit unit : units){ + float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h; + Draw.color(unit.getTeam().color); + Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2)); } + + Draw.color(); + + Graphics.endClip(); } public TextureRegion getRegion(){ @@ -128,11 +126,9 @@ public class MinimapRenderer implements Disposable{ dx = Mathf.clamp(dx, sz, world.width() - sz); dy = Mathf.clamp(dy, sz, world.height() - sz); - synchronized(units){ - rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); - units.clear(); - Units.getNearby(rect, units::add); - } + rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); + units.clear(); + Units.getNearby(rect, units::add); } private int colorFor(Tile tile){ diff --git a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java index f9863fa670..51d65dfbb8 100644 --- a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java @@ -53,10 +53,7 @@ public class OverlayRenderer{ //draw config selected block if(input.frag.config.isShown()){ Tile tile = input.frag.config.getSelectedTile(); - - synchronized(Tile.tileSetLock){ - tile.block().drawConfigure(tile); - } + tile.block().drawConfigure(tile); } input.drawTop(); @@ -113,53 +110,52 @@ public class OverlayRenderer{ Draw.reset(); } - synchronized(Tile.tileSetLock){ - Block block = target.block(); - TileEntity entity = target.entity; + Block block = target.block(); + TileEntity entity = target.entity; - if(entity != null){ - int[] values = {0, 0}; - boolean[] doDraw = {false}; + if(entity != null){ + int[] values = {0, 0}; + boolean[] doDraw = {false}; - Runnable drawbars = () -> { - for(BlockBar bar : block.bars.list()){ - float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1])); + Runnable drawbars = () -> { + for(BlockBar bar : block.bars.list()){ + float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1])); - float value = bar.value.get(target); + float value = bar.value.get(target); - if(MathUtils.isEqual(value, -1f)) continue; + if(MathUtils.isEqual(value, -1f)) continue; - if(doDraw[0]){ - drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value); - } - - if(bar.top) - values[0]++; - else - values[1]++; + if(doDraw[0]){ + drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value); } - }; - drawbars.run(); - - if(values[0] > 0){ - drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]); + if(bar.top) + values[0]++; + else + values[1]++; } + }; - if(values[1] > 0){ - drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]); - } + drawbars.run(); - doDraw[0] = true; - values[0] = 0; - values[1] = 1; - - drawbars.run(); + if(values[0] > 0){ + drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]); } + if(values[1] > 0){ + drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]); + } - target.block().drawSelect(target); + doDraw[0] = true; + values[0] = 0; + values[1] = 1; + + drawbars.run(); } + + + target.block().drawSelect(target); + } } diff --git a/core/src/io/anuke/mindustry/graphics/Shaders.java b/core/src/io/anuke/mindustry/graphics/Shaders.java index 69be1a9008..e3c3a5a656 100644 --- a/core/src/io/anuke/mindustry/graphics/Shaders.java +++ b/core/src/io/anuke/mindustry/graphics/Shaders.java @@ -3,7 +3,6 @@ package io.anuke.mindustry.graphics; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.utils.FloatArray; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; @@ -168,9 +167,7 @@ public class Shaders{ } public static class Shield extends Shader{ - public static final int MAX_HITS = 3 * 64; - public Color color = new Color(); - public FloatArray hits = new FloatArray(); + //public Color color = new Color(); public Shield(){ super("shield", "default"); @@ -179,12 +176,9 @@ public class Shaders{ @Override public void apply(){ float scaling = Core.cameraScale / 4f / Core.camera.zoom; - if(hits.size > 0){ - shader.setUniform3fv("u_hits[0]", hits.items, 0, Math.min(hits.size, MAX_HITS)); - shader.setUniformi("u_hitamount", Math.min(hits.size, MAX_HITS) / 3); - } + shader.setUniformf("u_dp", Unit.dp.scl(1f)); - shader.setUniformf("u_color", color); + //shader.setUniformf("u_color", color); shader.setUniformf("u_time", Timers.time() / Unit.dp.scl(1f)); shader.setUniformf("u_scaling", scaling); shader.setUniformf("u_offset", diff --git a/core/src/io/anuke/mindustry/graphics/Trail.java b/core/src/io/anuke/mindustry/graphics/Trail.java index 1d5f3fade1..bd34dc7002 100644 --- a/core/src/io/anuke/mindustry/graphics/Trail.java +++ b/core/src/io/anuke/mindustry/graphics/Trail.java @@ -22,7 +22,7 @@ public class Trail{ this.length = length; } - public synchronized void update(float curx, float cury){ + public void update(float curx, float cury){ if(Vector2.dst(curx, cury, lastX, lastY) >= maxJump){ points.clear(); } @@ -39,11 +39,11 @@ public class Trail{ lastY = cury; } - public synchronized void clear(){ + public void clear(){ points.clear(); } - public synchronized void draw(Color color, float stroke){ + public void draw(Color color, float stroke){ Draw.color(color); for(int i = 0; i < points.size - 2; i += 2){ diff --git a/core/src/io/anuke/mindustry/input/MobileInput.java b/core/src/io/anuke/mindustry/input/MobileInput.java index 97ad3d4a43..0197d323e0 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -430,7 +430,7 @@ public class MobileInput extends InputHandler implements GestureListener{ @Override public boolean touchDown(int screenX, int screenY, int pointer, int button){ - if(state.is(State.menu)) return false; + if(state.is(State.menu) || player.isDead()) return false; //get tile on cursor Tile cursor = tileAt(screenX, screenY); @@ -519,7 +519,7 @@ public class MobileInput extends InputHandler implements GestureListener{ @Override public boolean longPress(float x, float y){ - if(state.is(State.menu) || mode == none) return false; + if(state.is(State.menu) || mode == none || player.isDead()) return false; //get tile on cursor Tile cursor = tileAt(x, y); @@ -535,7 +535,7 @@ public class MobileInput extends InputHandler implements GestureListener{ if(mode == breaking){ Effects.effect(Fx.tapBlock, cursor.worldx(), cursor.worldy(), 1f); - }else{ + }else if(recipe != null){ Effects.effect(Fx.tapBlock, cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe.result.size); } @@ -595,7 +595,7 @@ public class MobileInput extends InputHandler implements GestureListener{ @Override public void update(){ - if(state.is(State.menu)){ + if(state.is(State.menu) || player.isDead()){ selection.clear(); removals.clear(); mode = none; diff --git a/core/src/io/anuke/mindustry/io/MapIO.java b/core/src/io/anuke/mindustry/io/MapIO.java index 4e07de02e3..7dea904ef3 100644 --- a/core/src/io/anuke/mindustry/io/MapIO.java +++ b/core/src/io/anuke/mindustry/io/MapIO.java @@ -47,23 +47,15 @@ public class MapIO{ data.position(0, 0); TileDataMarker marker = data.newDataMarker(); - Color color = new Color(); for(int y = 0; y < data.height(); y++){ for(int x = 0; x < data.width(); x++){ data.read(marker); + byte elev = y >= data.height() - 1 ? 0 : data.read(x, y + 1, DataPosition.elevation); Block floor = content.block(marker.floor); Block wall = content.block(marker.wall); - int wallc = ColorMapper.getBlockColor(wall); - if(wallc == 0 && (wall.update || wall.solid || wall.breakable)) wallc = Team.all[marker.team].intColor; - wallc = wallc == 0 ? ColorMapper.getBlockColor(floor) : wallc; - if(marker.elevation > 0){ - float scaling = 1f + marker.elevation / 8f; - color.set(wallc); - color.mul(scaling, scaling, scaling, 1f); - wallc = Color.rgba8888(color); - } - pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, wallc); + int color = ColorMapper.colorFor(floor, wall, Team.all[marker.team], marker.elevation + 1, elev > marker.elevation ? (byte)(1 << 6) : (byte)0); + pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, color); } } diff --git a/core/src/io/anuke/mindustry/maps/MapMeta.java b/core/src/io/anuke/mindustry/maps/MapMeta.java index c731941297..148ad5a099 100644 --- a/core/src/io/anuke/mindustry/maps/MapMeta.java +++ b/core/src/io/anuke/mindustry/maps/MapMeta.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.maps; import com.badlogic.gdx.utils.IntIntMap; import com.badlogic.gdx.utils.ObjectMap; +import io.anuke.ucore.util.Bundles; public class MapMeta{ public final int version; @@ -18,15 +19,19 @@ public class MapMeta{ } public String author(){ - return tags.get("author", "unknown"); + return tag("author"); } public String description(){ - return tags.get("description", "unknown"); + return tag("description"); } public String name(){ - return tags.get("name", "unknown"); + return tag("name"); + } + + public String tag(String name){ + return tags.containsKey(name) && !tags.get(name).trim().isEmpty() ? tags.get(name): Bundles.get("text.unknown"); } public boolean hasOreGen(){ diff --git a/core/src/io/anuke/mindustry/maps/SectorPresets.java b/core/src/io/anuke/mindustry/maps/SectorPresets.java index 24368e333c..08fa7f1b19 100644 --- a/core/src/io/anuke/mindustry/maps/SectorPresets.java +++ b/core/src/io/anuke/mindustry/maps/SectorPresets.java @@ -23,10 +23,10 @@ public class SectorPresets{ public SectorPresets(){ - //base tutorial mission (disabled) - /*add(new SectorPreset(0, 0, + //base tutorial mission + add(new SectorPreset(0, 0, TutorialSector.getMissions(), - Array.with(Items.copper, Items.coal, Items.lead)));*/ + Array.with(Items.copper, Items.coal, Items.lead))); //command center mission add(new SectorPreset(0, 1, @@ -56,7 +56,8 @@ public class SectorPresets{ Missions.blockRecipe(ProductionBlocks.waterExtractor), new ContentMission(Items.biomatter), Missions.blockRecipe(CraftingBlocks.biomatterCompressor), - new ContentMission(Liquids.oil) + new ContentMission(Liquids.oil), + new BattleMission() ), Array.with(Items.copper, Items.lead, Items.coal, Items.titanium))); } @@ -69,6 +70,8 @@ public class SectorPresets{ return presets.get(x, y); } + public GridMap getPresets() { return presets; } + private void add(SectorPreset preset){ presets.put(preset.x, preset.y, preset); orePresets.put(preset.x, preset.y, preset.ores); diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 1854b14bf7..0d94ff6d6b 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -41,7 +41,7 @@ public class Sectors{ private final AsyncExecutor executor = new AsyncExecutor(6); public void playSector(Sector sector){ - if(sector.hasSave() && SaveIO.breakingVersions.contains(sector.getSave().getBuild())){ + if(!headless && sector.hasSave() && SaveIO.breakingVersions.contains(sector.getSave().getBuild())){ sector.getSave().delete(); ui.showInfo("$text.save.old"); } @@ -88,8 +88,6 @@ public class Sectors{ public Difficulty getDifficulty(Sector sector){ if(sector.difficulty == 0){ - //yes, this means hard tutorial difficulty - //(((have fun))) return Difficulty.hard; }else if(sector.difficulty < 4){ return Difficulty.normal; @@ -158,7 +156,7 @@ public class Sectors{ } grid.clear(); - Array out = Settings.getObject("sectors", Array.class, Array::new); + Array out = Settings.getObject("sector-data-2", Array.class, Array::new); for(Sector sector : out){ @@ -187,7 +185,7 @@ public class Sectors{ } } - Settings.putObject("sectors", out); + Settings.putObject("sector-data-2", out); Settings.save(); } @@ -229,7 +227,7 @@ public class Sectors{ private void generate(Sector sector){ //50% chance to get a wave mission - if(Mathf.randomSeed(sector.getSeed() + 6) < 0.5){ + if(Mathf.randomSeed(sector.getSeed() + 7) < 0.5){ //recipe mission (maybe) addRecipeMission(sector, 3); sector.missions.add(new WaveMission(sector.difficulty*5 + Mathf.randomSeed(sector.getSeed(), 1, 4)*5)); diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index 3d6a486e72..f88dbbabc9 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -2,12 +2,15 @@ package io.anuke.mindustry.maps; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.content.UnitTypes; -import io.anuke.mindustry.content.blocks.*; -import io.anuke.mindustry.maps.generation.Generation; -import io.anuke.mindustry.maps.missions.*; +import io.anuke.mindustry.content.blocks.CraftingBlocks; +import io.anuke.mindustry.content.blocks.ProductionBlocks; +import io.anuke.mindustry.content.blocks.StorageBlocks; +import io.anuke.mindustry.content.blocks.UnitBlocks; +import io.anuke.mindustry.maps.missions.BlockMission; +import io.anuke.mindustry.maps.missions.ItemMission; +import io.anuke.mindustry.maps.missions.Mission; +import io.anuke.mindustry.maps.missions.WaveMission; import io.anuke.mindustry.world.Block; -import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.*; @@ -16,7 +19,7 @@ public class TutorialSector{ private static int droneIndex; public static Array getMissions(){ - +/* Array missions = Array.with( new ItemMission(Items.copper, 60).setMessage("$tutorial.begin"), @@ -30,7 +33,8 @@ public class TutorialSector{ //TODO fill turret with items mission //new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drillturret"), - new WaveMission(2).setMessage("$tutorial.waves"), + // Create a wave mission which spawns the core at 60, 60 rather than in the center of the map + new WaveMission(2, 60, 60).setMessage("$tutorial.waves"), new ItemMission(Items.lead, 150).setMessage("$tutorial.lead"), new ItemMission(Items.copper, 250).setMessage("$tutorial.morecopper"), @@ -82,9 +86,21 @@ public class TutorialSector{ droneIndex = i; break; } - } + }*/ - return missions; + return Array.with( + //intentionally unlocalized + new ItemMission(Items.copper, 50).setMessage("An updated tutorial will return next build.\nFor now, you'll have to deal with... this."), + + new BlockMission(ProductionBlocks.mechanicalDrill), + + new ItemMission(Items.copper, 100), + new ItemMission(Items.lead, 50), + + new BlockMission(CraftingBlocks.smelter), + new ItemMission(Items.densealloy, 10), + new WaveMission(5) + ); } public static boolean supressDrone(){ diff --git a/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java b/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java index ef58381653..def5cf1e0c 100644 --- a/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java @@ -57,6 +57,7 @@ public class FortressGenerator{ void gen(){ gen.setBlock(enemyX, enemyY, StorageBlocks.core, team); + gen.random.nextBoolean(); float difficultyScl = Mathf.clamp(gen.sector.difficulty / 20f + gen.random.range(0.25f), 0f, 0.9999f); float dscl2 = Mathf.clamp(0.5f + gen.sector.difficulty / 20f + gen.random.range(0.1f), 0f, 1.5f); diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index f83c03b84c..cb9371eea8 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -312,7 +312,7 @@ public class WorldGenerator{ + sim3.octaveNoise2D(detailed ? 12 : 9, 0.6, 1f / 1100f, x - 120, y); double lake = sim2.octaveNoise2D(1, 1, 1f / 110f, x, y); - elevation -= lake/3f; + elevation -= Math.pow(lake + 0.15, 5); int lerpDst = 20; lerpDst *= lerpDst; @@ -330,9 +330,9 @@ public class WorldGenerator{ } } - if(elevation < 0.7 || lake > 0.96){ + if(elevation < 0.7){ floor = Blocks.deepwater; - }else if(elevation < 0.79 || lake > 0.948){ + }else if(elevation < 0.79){ floor = Blocks.water; }else if(elevation < 0.85){ floor = Blocks.sand; diff --git a/core/src/io/anuke/mindustry/maps/missions/BattleMission.java b/core/src/io/anuke/mindustry/maps/missions/BattleMission.java index 4ea34022c6..bd2e8e26a9 100644 --- a/core/src/io/anuke/mindustry/maps/missions/BattleMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/BattleMission.java @@ -12,8 +12,24 @@ import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.*; -public class BattleMission extends Mission{ +public class BattleMission extends MissionWithStartingCore{ final int spacing = 30; + public static final int defaultXCorePos = 50; + public static final int defaultYCorePos = 50; + + /** Creates a battle mission with the player core being at (@defaultXCorePos, @defaultYCorePos) */ + public BattleMission(){ + this(defaultXCorePos, defaultYCorePos); + } + + /** + * Creates a wave survival with the player core being at a custom location. + * @param xCorePos The X coordinate of the custom core position. + * @param yCorePos The Y coordinate of the custom core position. + */ + public BattleMission(int xCorePos, int yCorePos){ + super(xCorePos, yCorePos); + } @Override public String getIcon(){ @@ -37,7 +53,7 @@ public class BattleMission extends Mission{ @Override public void generate(Generation gen){ - generateCoreAt(gen, 50, 50, defaultTeam); + generateCoreAtFirstSpawnPoint(gen, defaultTeam); if(state.teams.get(defaultTeam).cores.size == 0){ return; diff --git a/core/src/io/anuke/mindustry/maps/missions/MessageMission.java b/core/src/io/anuke/mindustry/maps/missions/MessageMission.java deleted file mode 100644 index 920f2cc111..0000000000 --- a/core/src/io/anuke/mindustry/maps/missions/MessageMission.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.anuke.mindustry.maps.missions; - -import io.anuke.mindustry.Vars; - -/**A mission that just displays some text.*/ -public class MessageMission extends ActionMission{ - - public MessageMission(String text){ - super(() -> { - if(!Vars.headless){ - Vars.ui.showInfo(text); - } - }); - } -} diff --git a/core/src/io/anuke/mindustry/maps/missions/Mission.java b/core/src/io/anuke/mindustry/maps/missions/Mission.java index 7544ee5861..25c9c5574e 100644 --- a/core/src/io/anuke/mindustry/maps/missions/Mission.java +++ b/core/src/io/anuke/mindustry/maps/missions/Mission.java @@ -100,10 +100,4 @@ public abstract class Mission{ } public void generate(Generation gen){} - - public void generateCoreAt(Generation gen, int coreX, int coreY, Team team){ - gen.tiles[coreX][coreY].setBlock(StorageBlocks.core); - gen.tiles[coreX][coreY].setTeam(team); - state.teams.get(team).cores.add(gen.tiles[coreX][coreY]); - } } diff --git a/core/src/io/anuke/mindustry/maps/missions/MissionWithStartingCore.java b/core/src/io/anuke/mindustry/maps/missions/MissionWithStartingCore.java new file mode 100644 index 0000000000..1dbb2b81a3 --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/MissionWithStartingCore.java @@ -0,0 +1,61 @@ +package io.anuke.mindustry.maps.missions; + +import com.badlogic.gdx.math.GridPoint2; +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.content.blocks.StorageBlocks; +import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.maps.generation.Generation; +import io.anuke.mindustry.world.Tile; + +import static io.anuke.mindustry.Vars.state; + +public abstract class MissionWithStartingCore extends Mission{ + /** Stores a custom starting location for the core, or null if the default calculation (map center) shall be used. */ + private final GridPoint2 customStartingPoint; + + /** Default constructor. Missions created this way will have a player starting core in the center of the map. */ + MissionWithStartingCore(){ + this.customStartingPoint = null; + } + + /** + * Creates a mission with a core on a non-default location. + * @param xCorePos The x coordinate of the custom core position. + * @param yCorePos The y coordinate of the custom core position. + */ + MissionWithStartingCore(int xCorePos, int yCorePos){ + this.customStartingPoint = new GridPoint2(xCorePos, yCorePos); + } + + /** + * Generates a player core based on generation parameters. + * @param gen The generation parameters which provide the map size. + * @param team The team to generate the core for. + */ + public void generateCoreAtFirstSpawnPoint(Generation gen, Team team){ + Array spawnPoints = getSpawnPoints(gen); + if(spawnPoints == null || spawnPoints.size == 0){ + throw new IllegalArgumentException("A MissionWithStartingCore subclass did not provide a spawn point in getSpawnPoints(). However, at least one point must always be provided."); + } + + Tile startingCoreTile = gen.tiles[spawnPoints.first().x][spawnPoints.first().y]; + startingCoreTile.setBlock(StorageBlocks.core); + startingCoreTile.setTeam(team); + state.teams.get(team).cores.add(startingCoreTile); + } + + /** + * Retrieves the spawn point in the center of the map or at a custom location which was provided through the constructor. + * @param gen The generation parameters which provide the map size. + * @return The center of the map or a custom location. + * @implNote Must return an array with at least one entry. + */ + @Override + public Array getSpawnPoints(Generation gen){ + if(this.customStartingPoint == null){ + return Array.with(new GridPoint2(gen.width / 2, gen.height / 2)); + }else{ + return Array.with(this.customStartingPoint); + } + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java index 7a002d85b7..5a257192a4 100644 --- a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java @@ -1,6 +1,5 @@ package io.anuke.mindustry.maps.missions; -import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; import io.anuke.mindustry.game.GameMode; @@ -9,16 +8,31 @@ import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Waves; import io.anuke.mindustry.maps.Sector; import io.anuke.mindustry.maps.generation.Generation; +import io.anuke.mindustry.net.Net; import io.anuke.ucore.util.Bundles; -import static io.anuke.mindustry.Vars.state; -import static io.anuke.mindustry.Vars.waveTeam; -import static io.anuke.mindustry.Vars.world; +import static io.anuke.mindustry.Vars.*; -public class WaveMission extends Mission{ +public class WaveMission extends MissionWithStartingCore{ private final int target; + /** + * Creates a wave survival mission with the player core being in the center of the map. + * @param target The number of waves to be survived. + */ public WaveMission(int target){ + super(); + this.target = target; + } + + /** + * Creates a wave survival with the player core being at a custom location. + * @param target The number of waves to be survived. + * @param xCorePos The X coordinate of the custom core position. + * @param yCorePos The Y coordinate of the custom core position. + */ + public WaveMission(int target, int xCorePos, int yCorePos){ + super(xCorePos, yCorePos); this.target = target; } @@ -29,8 +43,7 @@ public class WaveMission extends Mission{ @Override public void generate(Generation gen){ - int coreX = gen.width/2, coreY = gen.height/2; - generateCoreAt(gen, coreX, coreY, Team.blue); + generateCoreAtFirstSpawnPoint(gen, Team.blue); } @Override @@ -49,7 +62,7 @@ public class WaveMission extends Mission{ public String displayString(){ return state.wave > target ? Bundles.format( - Vars.unitGroups[Vars.waveTeam.ordinal()].size() > 1 ? + Vars.unitGroups[Vars.waveTeam.ordinal()].size() > 1 && !Net.client() ? "text.mission.wave.enemies" : "text.mission.wave.enemy", target, target, Vars.unitGroups[Vars.waveTeam.ordinal()].size()) : Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60)); @@ -71,9 +84,4 @@ public class WaveMission extends Mission{ public boolean isComplete(){ return state.wave > target && Vars.unitGroups[Vars.waveTeam.ordinal()].size() == 0; } - - @Override - public Array getSpawnPoints(Generation gen){ - return Array.with(new GridPoint2(gen.width/2, gen.height/2)); - } } diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index 78941f012f..4bd10f57fd 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -59,7 +59,7 @@ public class Net{ } String error = t.getMessage() == null ? "" : t.getMessage().toLowerCase(); - String type = error.getClass().toString().toLowerCase(); + String type = t.getClass().toString().toLowerCase(); if(error.equals("mismatch")){ error = Bundles.get("text.error.mismatch"); diff --git a/core/src/io/anuke/mindustry/ui/Minimap.java b/core/src/io/anuke/mindustry/ui/Minimap.java index 0adc2145a4..3ee65de5e3 100644 --- a/core/src/io/anuke/mindustry/ui/Minimap.java +++ b/core/src/io/anuke/mindustry/ui/Minimap.java @@ -1,21 +1,17 @@ package io.anuke.mindustry.ui; import com.badlogic.gdx.graphics.Texture.TextureFilter; -import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import io.anuke.mindustry.graphics.Shaders; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Graphics; +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.style.TextureRegionDrawable; -import io.anuke.ucore.scene.ui.Image; import io.anuke.ucore.scene.ui.layout.Table; -import static io.anuke.mindustry.Vars.renderer; -import static io.anuke.mindustry.Vars.showFog; -import static io.anuke.mindustry.Vars.world; +import static io.anuke.mindustry.Vars.*; public class Minimap extends Table{ @@ -25,14 +21,15 @@ public class Minimap extends Table{ margin(5); marginBottom(10); - Image image = new Image(new TextureRegionDrawable(new TextureRegion())){ + TextureRegion r = new TextureRegion(); + + Element elem = new Element(){ @Override - public void draw(Batch batch, float parentAlpha){ + public void draw(){ if(renderer.minimap.getRegion() == null) return; - TextureRegionDrawable draw = (TextureRegionDrawable) getDrawable(); - draw.getRegion().setRegion(renderer.minimap.getRegion()); - super.draw(batch, parentAlpha); + Draw.crect(renderer.minimap.getRegion(), x, y, width, height); + if(renderer.minimap.getTexture() != null){ renderer.minimap.drawEntities(x, y, width, height); } @@ -40,7 +37,7 @@ public class Minimap extends Table{ if(showFog){ renderer.fog.getTexture().setFilter(TextureFilter.Nearest, TextureFilter.Nearest); - TextureRegion r = draw.getRegion(); + r.setRegion(renderer.minimap.getRegion()); float pad = renderer.fog.getPadding(); float px = r.getU() * world.width() + pad; @@ -55,7 +52,7 @@ public class Minimap extends Table{ r.setV2(1f - py2 / (world.height() + pad*2f)); Graphics.shader(Shaders.fog); - super.draw(batch, parentAlpha); + Draw.crect(r, x, y, width, height); Graphics.shader(); renderer.fog.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear); @@ -70,7 +67,7 @@ public class Minimap extends Table{ } }); - image.update(() -> { + elem.update(() -> { Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true); if(e != null && e.isDescendantOf(this)){ @@ -79,6 +76,7 @@ public class Minimap extends Table{ Core.scene.setScrollFocus(null); } }); - add(image).size(140f, 140f); + + add(elem).size(140f, 140f); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java index 26a90e46bc..728e94bae1 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java @@ -57,6 +57,9 @@ public class PausedDialog extends FloatingDialog{ hide(); }); + content().row(); + content().addButton("$text.unlocks", ui.unlocks::show); + content().row(); content().addButton("$text.settings", ui.settings::show); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index 90a466e023..1ea6ed5d04 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -60,7 +60,7 @@ public class SectorsDialog extends FloatingDialog{ margin(0); getTitleTable().clear(); clear(); - stack(content(), buttons(), container).grow(); + stack(content(), container, buttons()).grow(); shown(this::setup); } @@ -128,7 +128,7 @@ public class SectorsDialog extends FloatingDialog{ class SectorView extends Element{ float lastX, lastY; boolean clicked = false; - float panX = 0, panY = -sectorSize/2f; + float panX = sectorSize/2f, panY = sectorSize/2f; SectorView(){ addListener(new InputListener(){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index 79faa1a780..a8931f70a7 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -130,13 +130,16 @@ public class SettingsMenuDialog extends SettingsDialog{ sound.volumePrefs(); game.screenshakePref(); - //game.checkPref("smoothcam", true); game.checkPref("effects", true); if(mobile){ game.checkPref("autotarget", true); } - //game.sliderPref("sensitivity", 100, 10, 300, i -> i + "%"); - game.sliderPref("saveinterval", 60, 10, 5 * 120, i -> Bundles.format("setting.seconds", i)); + game.sliderPref("saveinterval", 120, 10, 5 * 120, i -> Bundles.format("setting.seconds", i)); + + if(!mobile){ + game.checkPref("crashreport", true); + } + game.pref(new Setting(){ @Override public void add(SettingsTable table){ @@ -187,12 +190,6 @@ public class SettingsMenuDialog extends SettingsDialog{ }); graphics.sliderPref("fpscap", 125, 5, 125, 5, s -> (s > 120 ? Bundles.get("setting.fpscap.none") : Bundles.format("setting.fpscap.text", s))); - graphics.checkPref("multithread", mobile, threads::setEnabled); - - if(Settings.getBool("multithread")){ - threads.setEnabled(true); - } - if(!mobile){ graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b)); diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 0341a51de1..b2deb85ce9 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -107,7 +107,7 @@ public class HudFragment extends Fragment{ Stack stack = new Stack(); TextButton waves = new TextButton(""); - Table btable = new Table().margin(14); + Table btable = new Table().margin(0); stack.add(waves); stack.add(btable); @@ -126,7 +126,6 @@ public class HudFragment extends Fragment{ IntFormat tps = new IntFormat("text.tps"); IntFormat ping = new IntFormat("text.ping"); t.label(() -> fps.get(Gdx.graphics.getFramesPerSecond())).padRight(10); - t.label(() -> tps.get(threads.getTPS())).visible(() -> threads.isEnabled()); t.row(); if(Net.hasClient()){ t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2); @@ -375,7 +374,7 @@ public class HudFragment extends Fragment{ (!state.mode.disableWaveTimer ? Bundles.format("text.wave.waiting", (int)(state.wavetime/60)) : Bundles.get("text.waiting"))) : - Bundles.format("text.mission.display", world.getSector().currentMission().displayString())).growX(); + Bundles.format("text.mission.display", world.getSector().currentMission().displayString())).growX().pad(8f); table.clicked(() -> { if(world.getSector() != null && world.getSector().currentMission().hasMessage()){ diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 979b48f3d6..7f3c0a1f26 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -230,7 +230,7 @@ public class Block extends BaseBlock { /**Call when some content is produced. This unlocks the content if it is applicable.*/ public void useContent(Tile tile, UnlockableContent content){ if(!headless && tile.getTeam() == players[0].getTeam()){ - control.unlocks.handleContentUsed(content); + logic.handleContent(content); } } diff --git a/core/src/io/anuke/mindustry/world/ColorMapper.java b/core/src/io/anuke/mindustry/world/ColorMapper.java index e8a5205267..6d3bdea310 100644 --- a/core/src/io/anuke/mindustry/world/ColorMapper.java +++ b/core/src/io/anuke/mindustry/world/ColorMapper.java @@ -14,11 +14,7 @@ public class ColorMapper implements ContentList{ private static ObjectIntMap colorMap = new ObjectIntMap<>(); private static ThreadLocal tmpColors = new ThreadLocal<>(); - public static Block getByColor(int color){ - return blockMap.get(color); - } - - public static int getBlockColor(Block block){ + private static int getBlockColor(Block block){ return colorMap.get(block, 0); } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index 6089fe0218..5861ccd819 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -22,7 +22,6 @@ import static io.anuke.mindustry.Vars.*; public class Tile implements PosTrait, TargetTrait{ - public static final Object tileSetLock = new Object(); /** * The coordinates of the core tile this is linked to, in the form of two bytes packed into one. * This is relative to the block it is linked to; negate coords to find the link. @@ -130,8 +129,9 @@ public class Tile implements PosTrait, TargetTrait{ return wall; } + @Override public Team getTeam(){ - return Team.all[team]; + return Team.all[target().team]; } public void setTeam(Team team){ @@ -143,33 +143,27 @@ public class Tile implements PosTrait, TargetTrait{ } public void setBlock(Block type, int rotation){ - synchronized(tileSetLock){ - preChanged(); - if(rotation < 0) rotation = (-rotation + 2); - this.wall = type; - this.link = 0; - setRotation((byte) (rotation % 4)); - changed(); - } + preChanged(); + if(rotation < 0) rotation = (-rotation + 2); + this.wall = type; + this.link = 0; + setRotation((byte) (rotation % 4)); + changed(); } public void setBlock(Block type, Team team){ - synchronized(tileSetLock){ - preChanged(); - this.wall = type; - this.team = (byte)team.ordinal(); - this.link = 0; - changed(); - } + preChanged(); + this.wall = type; + this.team = (byte)team.ordinal(); + this.link = 0; + changed(); } public void setBlock(Block type){ - synchronized(tileSetLock){ - preChanged(); - this.wall = type; - this.link = 0; - changed(); - } + preChanged(); + this.wall = type; + this.link = 0; + changed(); } public void setFloor(Floor type){ @@ -266,7 +260,7 @@ public class Tile implements PosTrait, TargetTrait{ * Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock. * This array contains all linked tiles, including this tile itself. */ - public synchronized Array getLinkedTiles(Array tmpArray){ + public Array getLinkedTiles(Array tmpArray){ Block block = block(); tmpArray.clear(); if(block.isMultiblock()){ @@ -288,7 +282,7 @@ public class Tile implements PosTrait, TargetTrait{ * Returns the list of all tiles linked to this multiblock if it were this block, or an empty array if it's not a multiblock. * This array contains all linked tiles, including this tile itself. */ - public synchronized Array getLinkedTilesAs(Block block, Array tmpArray){ + public Array getLinkedTilesAs(Block block, Array tmpArray){ tmpArray.clear(); if(block.isMultiblock()){ int offsetx = -(block.size - 1) / 2; @@ -390,52 +384,47 @@ public class Tile implements PosTrait, TargetTrait{ } private void preChanged(){ - synchronized(tileSetLock){ - block().removed(this); - if(entity != null){ - entity.removeFromProximity(); - } - team = 0; + block().removed(this); + if(entity != null){ + entity.removeFromProximity(); } + team = 0; } private void changed(){ - - synchronized(tileSetLock){ - if(entity != null){ - entity.remove(); - entity = null; - } - - Block block = block(); - - if(block.hasEntity()){ - entity = block.newEntity().init(this, block.update); - entity.cons = new ConsumeModule(); - if(block.hasItems) entity.items = new ItemModule(); - if(block.hasLiquids) entity.liquids = new LiquidModule(); - if(block.hasPower){ - entity.power = new PowerModule(); - entity.power.graph.add(this); - } - - if(!world.isGenerating()){ - entity.updateProximity(); - } - }else if(!(block instanceof BlockPart) && !world.isGenerating()){ - //since the entity won't update proximity for us, update proximity for all nearby tiles manually - for(GridPoint2 p : Geometry.d4){ - Tile tile = world.tile(x + p.x, y + p.y); - if(tile != null){ - tile = tile.target(); - tile.block().onProximityUpdate(tile); - } - } - } - - updateOcclusion(); + if(entity != null){ + entity.remove(); + entity = null; } + Block block = block(); + + if(block.hasEntity()){ + entity = block.newEntity().init(this, block.update); + entity.cons = new ConsumeModule(); + if(block.hasItems) entity.items = new ItemModule(); + if(block.hasLiquids) entity.liquids = new LiquidModule(); + if(block.hasPower){ + entity.power = new PowerModule(); + entity.power.graph.add(this); + } + + if(!world.isGenerating()){ + entity.updateProximity(); + } + }else if(!(block instanceof BlockPart) && !world.isGenerating()){ + //since the entity won't update proximity for us, update proximity for all nearby tiles manually + for(GridPoint2 p : Geometry.d4){ + Tile tile = world.tile(x + p.x, y + p.y); + if(tile != null){ + tile = tile.target(); + tile.block().onProximityUpdate(tile); + } + } + } + + updateOcclusion(); + world.notifyChanged(this); } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java index 8f71d61531..fa1a44c5cf 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -5,6 +5,7 @@ import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter; +import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.ucore.core.Effects; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; @@ -15,9 +16,7 @@ import static io.anuke.mindustry.Vars.tilesize; public abstract class ItemLiquidGenerator extends ItemGenerator{ protected float minLiquidEfficiency = 0.2f; protected float powerPerLiquid = 0.13f; - /** - * Maximum liquid used per frame. - */ + /**Maximum liquid used per frame.*/ protected float maxLiquidGenerate = 0.4f; public ItemLiquidGenerator(String name){ @@ -28,6 +27,12 @@ public abstract class ItemLiquidGenerator extends ItemGenerator{ consumes.add(new ConsumeLiquidFilter(liquid -> getLiquidEfficiency(liquid) >= minLiquidEfficiency, 0.001f, true)).update(false).optional(true); } + @Override + public void init(){ + super.init(); + stats.remove(BlockStat.liquidFuelUse); + } + @Override public void update(Tile tile){ ItemGeneratorEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java index 2be20f985e..8a8ed8ca25 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java @@ -13,19 +13,21 @@ import io.anuke.ucore.util.Mathf; public abstract class LiquidGenerator extends PowerGenerator{ protected float minEfficiency = 0.2f; - protected float powerPerLiquid = 0.13f; - /** - * Maximum liquid used per frame. - */ - protected float maxLiquidGenerate = 0.4f; + protected float powerPerLiquid; + /**Maximum liquid used per frame.*/ + protected float maxLiquidGenerate; protected Effect generateEffect = BlockFx.generatespark; public LiquidGenerator(String name){ super(name); liquidCapacity = 30f; hasLiquids = true; + } - consumes.add(new ConsumeLiquidFilter(liquid -> getEfficiency(liquid) >= minEfficiency, 0.001f)).update(false); + @Override + public void setStats(){ + consumes.add(new ConsumeLiquidFilter(liquid -> getEfficiency(liquid) >= minEfficiency, maxLiquidGenerate)).update(false); + super.setStats(); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java index 4c19816a8e..67a5bed015 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java @@ -14,7 +14,7 @@ public class LiquidHeatGenerator extends LiquidGenerator{ public void setStats(){ super.setStats(); - stats.add(BlockStat.basePowerGeneration, maxLiquidGenerate * powerPerLiquid * 60f * 0.4f, StatUnit.powerSecond); + stats.add(BlockStat.basePowerGeneration, maxLiquidGenerate * powerPerLiquid * 60f, StatUnit.powerSecond); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java index 7dfdfa57d2..a66721afa4 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.utils.IntSet; import com.badlogic.gdx.utils.ObjectSet; import com.badlogic.gdx.utils.Queue; import io.anuke.mindustry.world.Tile; +import io.anuke.ucore.core.Timers; import static io.anuke.mindustry.Vars.threads; @@ -37,63 +38,38 @@ public class PowerGraph{ lastFrameUpdated = threads.getFrameID(); - boolean charge = false; - float totalInput = 0f; - float bufferInput = 0f; + for(Tile producer : producers){ - if (producer.block().consumesPower) { - bufferInput += producer.entity.power.amount; - } else { - totalInput += producer.entity.power.amount; - } + totalInput += producer.entity.power.amount; } - float maxOutput = 0f; - float bufferOutput = 0f; - for(Tile consumer : consumers){ - if (consumer.block().outputsPower) { - bufferOutput += consumer.block().powerCapacity - consumer.entity.power.amount; - } else { - maxOutput += consumer.block().powerCapacity - consumer.entity.power.amount; - } - } - - if (maxOutput < totalInput) { - charge = true; - } - - if (totalInput + bufferInput <= 0.0001f || maxOutput + bufferOutput <= 0.0001f) { - return; - } - - float bufferUsed = 0; - if (charge) { - bufferUsed = Math.min((totalInput - maxOutput) / bufferOutput, 1f); - } else { - bufferUsed = Math.min((maxOutput - totalInput) / bufferInput, 1f); - } - - float inputUsed = charge ? Math.min((maxOutput + bufferOutput) / totalInput, 1f) : 1f; for(Tile producer : producers){ - if (producer.block().consumesPower) { - if (!charge) { - producer.entity.power.amount -= producer.entity.power.amount * bufferUsed; - } + float accumulator = producer.entity.power.amount; + + if(accumulator <= 0.0001f) continue; + + float toEach = accumulator / consumers.size; + float outputs = 0f; + + for(Tile tile : consumers){ + outputs += Math.min(tile.block().powerCapacity - tile.entity.power.amount, toEach) / toEach; + } + + float finalEach = toEach / outputs * Timers.delta(); + float buffer = 0f; + + if(Float.isNaN(finalEach) || Float.isInfinite(finalEach)){ continue; } - producer.entity.power.amount -= producer.entity.power.amount * inputUsed; - } - float outputSatisfied = charge ? 1f : Math.min((totalInput + bufferInput) / maxOutput, 1f); - for(Tile consumer : consumers){ - if (consumer.block().outputsPower) { - if (charge) { - consumer.entity.power.amount += (consumer.block().powerCapacity - consumer.entity.power.amount) * bufferUsed; - } - continue; + for(Tile tile : consumers){ + float used = Math.min(tile.block().powerCapacity - tile.entity.power.amount, finalEach) * accumulator / totalInput; + buffer += used; + tile.entity.power.amount += used; } - consumer.entity.power.amount += (consumer.block().powerCapacity - consumer.entity.power.amount) * outputSatisfied; + + producer.entity.power.amount -= buffer; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java b/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java index 38cec398f8..e2c226a348 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java @@ -127,7 +127,7 @@ public class MechPad extends Block{ if(checkValidTap(tile, player)){ Call.onMechFactoryTap(player, tile); - }else if(player.isLocal && mobile){ + }else if(player.isLocal && mobile && !player.isDead()){ player.moveTarget = tile.entity; } } diff --git a/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java b/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java index 54bfa7e1dd..1f29c1a906 100644 --- a/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java +++ b/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java @@ -23,6 +23,16 @@ public class CrashHandler{ public static void handle(Throwable e){ e.printStackTrace(); + try{ + //check crash report setting + if(!Settings.getBool("crashreport")){ + return; + } + }catch(Throwable ignored){ + //don't send since we don't know if the user has the setting set + return; + } + if(!OS.isMac){ try{ javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName()); diff --git a/ios/Info.plist.xml b/ios/Info.plist.xml index bc072235db..abd81b462c 100644 --- a/ios/Info.plist.xml +++ b/ios/Info.plist.xml @@ -34,6 +34,8 @@ UIRequiresFullScreen + LSSupportsOpeningDocumentsInPlace + NSPhotoLibraryAddUsageDescription Mindustry UIDeviceFamily diff --git a/ios/robovm.properties b/ios/robovm.properties index 24b6483340..694b9dfa68 100644 --- a/ios/robovm.properties +++ b/ios/robovm.properties @@ -2,5 +2,5 @@ app.version=4.0 app.id=io.anuke.mindustry app.mainclass=io.anuke.mindustry.IOSLauncher app.executable=IOSLauncher -app.build=23 +app.build=27 app.name=Mindustry diff --git a/ios/robovm.xml b/ios/robovm.xml index 851c59da6f..efa0df89f0 100644 --- a/ios/robovm.xml +++ b/ios/robovm.xml @@ -18,6 +18,7 @@ + net.jpountz.lz4.** io.anuke.ucore.scene.** io.anuke.mindustry.gen.Call io.anuke.mindustry.net.** diff --git a/kryonet/src/io/anuke/kryonet/KryoServer.java b/kryonet/src/io/anuke/kryonet/KryoServer.java index fc8882da9c..45269e42fb 100644 --- a/kryonet/src/io/anuke/kryonet/KryoServer.java +++ b/kryonet/src/io/anuke/kryonet/KryoServer.java @@ -30,7 +30,6 @@ import java.util.concurrent.CopyOnWriteArraySet; import static io.anuke.mindustry.Vars.threads; public class KryoServer implements ServerProvider { - final boolean tcpOnly = System.getProperty("java.version") == null; final Server server; final CopyOnWriteArrayList connections = new CopyOnWriteArrayList<>(); final CopyOnWriteArraySet missing = new CopyOnWriteArraySet<>(); @@ -150,11 +149,7 @@ public class KryoServer implements ServerProvider { lastconnection = 0; connections.clear(); missing.clear(); - if(tcpOnly){ - server.bind(port); - }else{ - server.bind(port, port); - } + server.bind(port, port); serverThread = new Thread(() -> { try{ @@ -172,7 +167,7 @@ public class KryoServer implements ServerProvider { connections.clear(); lastconnection = 0; - async(server::close); + async(server::stop); } @Override diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index 18260e3315..c0a43aae57 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -68,7 +68,7 @@ public class ServerControl extends Module{ ); Log.setLogger(new LogHandler(){ - DateTimeFormatter dateTime = DateTimeFormatter.ofPattern("MM-dd-yyyy | HH:mm:ss"); + DateTimeFormatter dateTime = DateTimeFormatter.ofPattern("MM-dd-yyyy | HH:mm:ss"); @Override public void info(String text, Object... args){ diff --git a/tests/src/test/java/SectorTests.java b/tests/src/test/java/SectorTests.java new file mode 100644 index 0000000000..3aae6cb305 --- /dev/null +++ b/tests/src/test/java/SectorTests.java @@ -0,0 +1,54 @@ +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.core.ContentLoader; +import io.anuke.mindustry.maps.SectorPresets; +import io.anuke.mindustry.maps.generation.Generation; +import io.anuke.mindustry.maps.missions.Mission; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** This class is responsible for testing predefined sectors. */ +public class SectorTests{ + + private SectorPresets presets; + private Generation fakeGen; + + @BeforeAll + static void initializeDependencies(){ + Vars.content = new ContentLoader(); + Vars.content.load(); + } + + @BeforeEach + void initTest(){ + this.presets = new SectorPresets(); + + // Fake away the Generation dependency + this.fakeGen = new Generation(null, null, 250, 250, null); + } + + /** Returns true if at least one mission provides a spawn point. */ + private boolean spawnPointIsDefined(Array missions){ + for(Mission mission : missions){ + if(mission.getSpawnPoints(this.fakeGen).size > 0){ + return true; + } + } + // No spawn point provided + return false; + } + + /** + * Makes sure that every predefined sector has a position for the player core defined. + * This is achieved by adding at least one mission which defines a spawn point. + */ + @Test + void test_sectorHasACore(){ + for(SectorPresets.SectorPreset preset : this.presets.getPresets().values()){ + assertTrue(spawnPointIsDefined(preset.missions), "Sector at (" + preset.x + "|" + preset.y + ") contains no missions which define a spawn point. Add a battle or wave mission."); + } + } +}