diff --git a/android/res/layout/gdxdialogs_inputtext.xml b/android/res/layout/gdxdialogs_inputtext.xml
deleted file mode 100755
index 0341a7d385..0000000000
--- a/android/res/layout/gdxdialogs_inputtext.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java
index ff729c7227..c75b6af249 100644
--- a/android/src/io/anuke/mindustry/AndroidLauncher.java
+++ b/android/src/io/anuke/mindustry/AndroidLauncher.java
@@ -27,7 +27,6 @@ import io.anuke.mindustry.io.SaveIO;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.ui.dialogs.FileChooser;
import io.anuke.ucore.function.Consumer;
-import io.anuke.ucore.scene.ui.TextField;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Strings;
@@ -52,11 +51,6 @@ public class AndroidLauncher extends PatchedAndroidApplication{
config.useImmersiveMode = true;
Platform.instance = new Platform(){
- @Override
- public void addDialog(TextField field, int length){
- TextFieldDialogListener.add(field, 0, length);
- }
-
@Override
public void openDonations(){
showDonations();
diff --git a/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java b/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java
deleted file mode 100644
index 381bd7573f..0000000000
--- a/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package io.anuke.mindustry;
-
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.text.InputFilter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager.LayoutParams;
-import android.widget.EditText;
-import com.badlogic.gdx.Gdx;
-
-public class AndroidTextFieldDialog{
- private Activity activity;
- private EditText userInput;
- private AlertDialog.Builder builder;
- private TextPromptListener listener;
- private boolean isBuild;
-
- public AndroidTextFieldDialog(){
- this.activity = (Activity) Gdx.app;
- load();
- }
-
- public AndroidTextFieldDialog show(){
-
- activity.runOnUiThread(() -> {
- AlertDialog dialog = builder.create();
-
- dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
-
- dialog.show();
-
- });
-
- return this;
- }
-
- private AndroidTextFieldDialog load(){
-
- activity.runOnUiThread(() -> {
-
- AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
- LayoutInflater li = LayoutInflater.from(activity);
-
- View promptsView = li.inflate(getResourceId("gdxdialogs_inputtext", "layout"), null);
-
- alertDialogBuilder.setView(promptsView);
-
- userInput = promptsView.findViewById(getResourceId("gdxDialogsEditTextInput", "id"));
-
- alertDialogBuilder.setCancelable(false);
- builder = alertDialogBuilder;
-
- isBuild = true;
- });
-
- // Wait till TextPrompt is built.
- while(!isBuild){
- try{
- Thread.sleep(10);
- }catch(InterruptedException ignored){
- }
- }
-
- return this;
- }
-
- public int getResourceId(String pVariableName, String pVariableType){
- try{
- return activity.getResources().getIdentifier(pVariableName, pVariableType, activity.getPackageName());
- }catch(Exception e){
- Gdx.app.error("Android Dialogs", "Cannot find resouce with name: " + pVariableName
- + " Did you copy the layouts to /res/layouts and /res/layouts_v14 ?");
- e.printStackTrace();
- return -1;
- }
- }
-
- public AndroidTextFieldDialog setText(CharSequence value){
- userInput.append(value);
- return this;
- }
-
- public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label){
- builder.setNegativeButton(label, (dialog, id) -> dialog.cancel());
- return this;
- }
-
- public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label){
- builder.setPositiveButton(label, (dialog, id) -> {
- if(listener != null && !userInput.getText().toString().isEmpty()){
- listener.confirm(userInput.getText().toString());
- }
-
- });
- return this;
- }
-
- public AndroidTextFieldDialog setTextPromptListener(TextPromptListener listener){
- this.listener = listener;
- return this;
- }
-
- public AndroidTextFieldDialog setInputType(int type){
- userInput.setInputType(type);
- return this;
- }
-
- public AndroidTextFieldDialog setMaxLength(int length){
- userInput.setFilters(new InputFilter[]{new InputFilter.LengthFilter(length)});
- return this;
- }
-
- public interface TextPromptListener{
- void confirm(String text);
- }
-
-}
diff --git a/android/src/io/anuke/mindustry/TextFieldDialogListener.java b/android/src/io/anuke/mindustry/TextFieldDialogListener.java
deleted file mode 100644
index c603fbff05..0000000000
--- a/android/src/io/anuke/mindustry/TextFieldDialogListener.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package io.anuke.mindustry;
-
-
-import android.text.InputType;
-import com.badlogic.gdx.Application.ApplicationType;
-import com.badlogic.gdx.Gdx;
-import io.anuke.ucore.scene.event.ChangeListener;
-import io.anuke.ucore.scene.event.ClickListener;
-import io.anuke.ucore.scene.event.InputEvent;
-import io.anuke.ucore.scene.event.InputListener;
-import io.anuke.ucore.scene.ui.TextField;
-
-public class TextFieldDialogListener extends ClickListener{
- private TextField field;
- private int type;
- private int max;
-
- //type - 0 is text, 1 is numbers, 2 is decimals
- public TextFieldDialogListener(TextField field, int type, int max){
- this.field = field;
- this.type = type;
- this.max = max;
- }
-
- public static void add(TextField field, int type, int max){
- field.addListener(new TextFieldDialogListener(field, type, max));
- field.addListener(new InputListener(){
- public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
- Gdx.input.setOnscreenKeyboardVisible(false);
- return false;
- }
- });
- }
-
- public static void add(TextField field){
- add(field, 0, 16);
- }
-
- public void clicked(final InputEvent event, float x, float y){
-
- if(Gdx.app.getType() == ApplicationType.Desktop) return;
-
- AndroidTextFieldDialog dialog = new AndroidTextFieldDialog();
-
- 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);
- }else if(type == 1){
- dialog.setInputType(InputType.TYPE_CLASS_NUMBER);
- }else if(type == 2){
- dialog.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
- }
-
- dialog.setConfirmButtonLabel("OK").setText(field.getText());
- dialog.setCancelButtonLabel("Cancel");
- dialog.setMaxLength(max);
- dialog.show();
- event.cancel();
-
- }
-}
diff --git a/build.gradle b/build.gradle
index 8bc3fca889..92579ba541 100644
--- a/build.gradle
+++ b/build.gradle
@@ -23,9 +23,9 @@ allprojects {
versionModifier = 'alpha'
versionType = 'official'
appName = 'Mindustry'
- gdxVersion = '1.9.8'
+ gdxVersion = '1.9.9'
roboVMVersion = '2.3.0'
- uCoreVersion = '8919cb7b6881d040fb720149779fcf58c1927893'
+ uCoreVersion = 'c93c55179ec05b44926d59c5878534a3177d804f'
getVersionString = {
String buildVersion = getBuildVersion()
diff --git a/core/assets-raw/sprites/blocks/production/alloy-fuser.png b/core/assets-raw/sprites/blocks/production/alloy-fuser.png
deleted file mode 100644
index 19815de0ff..0000000000
Binary files a/core/assets-raw/sprites/blocks/production/alloy-fuser.png and /dev/null differ
diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties
index d4d20529e8..0dc46e60d8 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!
@@ -497,6 +497,7 @@ text.mech.ability = [LIGHT_GRAY]Ability\: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Heat Capacity\: {0}
text.liquid.viscosity = [LIGHT_GRAY]Viscosity\: {0}
text.liquid.temperature = [LIGHT_GRAY]Temperature\: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Enemy Spawn
block.core.name = Core
block.metalfloor.name = Metal Floor
@@ -504,16 +505,16 @@ block.deepwater.name = deepwater
block.water.name = water
block.lava.name = lava
block.tar.name = Tar
-block.blackstone.name = blackstone
-block.stone.name = stone
-block.dirt.name = dirt
-block.sand.name = sand
-block.ice.name = ice
-block.snow.name = snow
-block.grass.name = grass
-block.shrub.name = shrub
-block.rock.name = rock
-block.blackrock.name = blackrock
+block.blackstone.name = Black Stone
+block.stone.name = Stone
+block.dirt.name = Dirt
+block.sand.name = Sand
+block.ice.name = Ice
+block.snow.name = Snow
+block.grass.name = Grass
+block.shrub.name = Shrub
+block.rock.name = Rock
+block.blackrock.name = Black Rock
block.icerock.name = icerock
block.copper-wall.name = Copper Wall
block.copper-wall-large.name = Large Copper Wall
@@ -755,7 +756,7 @@ 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.revenant-factory.description = Produces heavy laser air 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.
diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties
index 5e5df2b1e3..9c853977a2 100644
--- a/core/assets/bundles/bundle_de.properties
+++ b/core/assets/bundles/bundle_de.properties
@@ -267,6 +267,7 @@ 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.mapnotfound = Map file not found!
text.error.any = Unbekannter Netzwerkfehler.
text.settings.language = Sprache
text.settings.reset = Auf Standard zurücksetzen
@@ -369,6 +370,7 @@ setting.musicvol.name = Musiklautstärke
setting.mutemusic.name = Musik stummschalten
setting.sfxvol.name = Audioeffekt-Lautstärke
setting.mutesound.name = Audioeffekte stummschalten
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Tasten zuweisen
category.general.name = Allgemein
category.view.name = Ansicht
@@ -493,6 +495,7 @@ text.mech.ability = [LIGHT_GRAY]Fähigkeit: {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.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Gegnerischer Startpunkt
block.core.name = Basis
block.metalfloor.name = Metallboden
@@ -622,7 +625,7 @@ block.rtg-generator.name = RTG Generator
block.spectre.name = Spectre
block.meltdown.name = Meltdown
block.container.name = Container
-block.core.description = The most important building in the game.
+block.core.description = Das wichtigste Gebäude im Spiel
team.blue.name = Blau
team.red.name = Rot
team.orange.name = Orange
@@ -650,8 +653,8 @@ tutorial.begin = Deine Mission ist es den [LIGHT_GRAY]Gegner[] auszurotten.\n\n
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 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.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.turret = Defensive structures must be built to repel the[LIGHT_GRAY] enemy[].\nBuild a duo turret near your base.
+tutorial.drillturret = Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill next to the turret to supply it with mined copper.
tutorial.waves = 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.
@@ -667,7 +670,6 @@ tutorial.daggerfactory = Konstruiere eine Dagger Mech Fabrik.\n\n Diese wird ver
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.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.
diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties
index 6832c8e1d0..d668090bdf 100644
--- a/core/assets/bundles/bundle_es.properties
+++ b/core/assets/bundles/bundle_es.properties
@@ -184,7 +184,7 @@ text.changelog.title = Registro de Parches
text.changelog.loading = Consiguiendo el registro de parches...
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.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...
@@ -370,6 +370,7 @@ 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 = Silenciar Sonido
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Reasignar Teclas
category.general.name = General
category.view.name = Visión
@@ -452,7 +453,7 @@ liquid.oil.name = Petróleo
liquid.cryofluid.name = Criogénico
mech.alpha-mech.name = Alpha
mech.alpha-mech.weapon = Repetidor Pesado
-mech.alpha-mech.ability = Drone Swarm
+mech.alpha-mech.ability = Enjambre de Drones
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 = Generador de arco
@@ -463,7 +464,7 @@ mech.tau-mech.weapon = Láser de reestructuración
mech.tau-mech.ability = Repair Burst
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.weapon = Enjambre de misiles
mech.omega-mech.ability = Armored Configuration
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
@@ -471,7 +472,7 @@ 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 = 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.weapon = Ráfaga de misiles
mech.javelin-ship.ability = Discharge Booster
mech.trident-ship.name = Tridente
mech.trident-ship.description = Un bombardero pesado. Razonablemente bien equipado.
@@ -494,24 +495,25 @@ text.mech.ability = [LIGHT_GRAY]Hablidad: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Capacidad Térmica: {0}
text.liquid.viscosity = [LIGHT_GRAY]Viscosidad: {0}
text.liquid.temperature = [LIGHT_GRAY]Temperatura: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Punto de generación
-block.core.name = núcleo
+block.core.name = Núcleo
block.metalfloor.name = Suelo de Metal
-block.deepwater.name = aguas profundas
-block.water.name = agua
-block.lava.name = lava
+block.deepwater.name = Aguas profundas
+block.water.name = Agua
+block.lava.name = Lava
block.tar.name = Tar
-block.blackstone.name = piedra negra
-block.stone.name = piedra
-block.dirt.name = tierra
-block.sand.name = arena
-block.ice.name = hielo
-block.snow.name = nieve
-block.grass.name = pasto
-block.shrub.name = arbusto
-block.rock.name = roca
-block.blackrock.name = roca negra
-block.icerock.name = roca de hielo
+block.blackstone.name = Piedra negra
+block.stone.name = Piedra
+block.dirt.name = Tierra
+block.sand.name = Arena
+block.ice.name = Hielo
+block.snow.name = Nieve
+block.grass.name = Pasto
+block.shrub.name = Arbusto
+block.rock.name = Roca
+block.blackrock.name = Roca negra
+block.icerock.name = Roca de hielo
block.copper-wall.name = Muro de cobre
block.copper-wall-large.name = Muro de cobre grande
block.dense-alloy-wall.name = Muro de aleación densa
@@ -567,10 +569,10 @@ 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
-block.itemvoid.name = Objeto Vacío
-block.liquidsource.name = Líquido Fuente
-block.powervoid.name = Energía Vacía
+block.itemsource.name = Fuente de objetos
+block.itemvoid.name = Vacío de objetos
+block.liquidsource.name = Fuente de líquidos
+block.powervoid.name = Vacío de energía
block.powerinfinite.name = Energía Infinita
block.unloader.name = Descargador
block.vault.name = Bóveda
@@ -599,7 +601,7 @@ block.repair-point.name = Punto de Reparación
block.pulse-conduit.name = Conducto de Pulso
block.phase-conduit.name = Conducto de Fase
block.liquid-router.name = Enrutador de Líquidos
-block.liquid-tank.name = Tanque de Líquido
+block.liquid-tank.name = Tanque de Líquidos
block.liquid-junction.name = Cruce de Líquidos
block.bridge-conduit.name = Conducto Puente
block.rotary-pump.name = Bomba Rotatoria
@@ -620,15 +622,16 @@ block.overdrive-projector.name = Overdrive Projector
block.force-projector.name = Force Projector
block.arc.name = Arc
block.rtg-generator.name = Generador RTG
-block.spectre.name = Spectre
+block.spectre.name = Espectro
block.meltdown.name = Meltdown
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
+block.core.description = The most important building in the game.
+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 = 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.
@@ -743,7 +746,6 @@ block.javelin-ship-pad.description = Deja tu nave actual y transfórmate en una
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.
-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 = Produce drones avanzados que son significativamente más eficientes que un dron espíritu.
diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties
index 4706b387dc..855775dccb 100644
--- a/core/assets/bundles/bundle_fr.properties
+++ b/core/assets/bundles/bundle_fr.properties
@@ -8,8 +8,8 @@ text.link.trello.description = Trello officiel pour les futurs ajouts .
text.link.itch.io.description = page itch.io avec le lien du téléchargement pour PC et la version web .
text.link.google-play.description = listing par le store google play
text.link.wiki.description = wiki officiel de mindustry .
-text.linkfail = Failed to open link!\nThe URL has been copied to your cliboard.
-text.editor.web = The web version does not support the editor!\nDownload the game to use it.
+text.linkfail = Erreur lors de l'ouverture du lien !\nL'URL a été copié avec succès.
+text.editor.web = La version web ne possède pas l'éditeur !\nTéléchargez le jeu pour l'avoir.
text.web.unsupported = La version web ne supporte pas cette fonction ! Téléchargez le jeu pour l'utiliser.
text.gameover = Partie terminée.
text.gameover.pvp = L'équipe [accent] {0}[] a gagnée !
@@ -64,7 +64,7 @@ text.mission.linknode = Reliez un transmetteur
text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0}
text.mission.mech = Équiper ce mécha[accent] {0}[]
text.mission.create = Créez[accent] {0}[]
-text.none =
+text.none =
text.close = Fermer
text.quit = Quitter
text.maps = Cartes
@@ -262,13 +262,13 @@ text.editor = Éditeur
text.mapeditor = Éditeur de carte
text.donate = Faire un\ndon
text.connectfail = [crimson]Échec de la connexion au serveur : [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 injoignable.
+text.error.invalidaddress = Adresse invalide.
+text.error.timedout = Délai de connexion dépassé!\nAssurez-vous que l'hôte a autorisé l'accès au port, et que l'adresse soit correcte!
+text.error.mismatch = Erreur de paquet:\nPossible différence de verison entre le client et le serveur .\nVérifiez que vous et l'hôte avez la plus récente version de Mindustry !
+text.error.alreadyconnected = Déjà connecté.
+text.error.mapnotfound = Fichier de la carte introuvable!
+text.error.any = Erreur réseau inconnue.
text.settings.language = Langage
text.settings.reset = Valeur par défaut.
text.settings.rebind = Réatttribuer
@@ -370,6 +370,7 @@ setting.musicvol.name = volume de la musique
setting.mutemusic.name = Couper la musique
setting.sfxvol.name = Volume des SFX
setting.mutesound.name = Couper les SFX
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Paramétrer les touches
category.general.name = General
category.view.name = Voir
@@ -417,7 +418,7 @@ content.unit.name = Unités
content.recipe.name = Blocs
content.mech.name = Méchas
item.stone.name = Pierre
-item.stone.description = Un matériau brut commun. Peut-être séparé et raffiné en d'autres matériaux, ou fondus en lave.
+item.stone.description = Un matériau brut commun. Peut être séparé et raffiné en d'autres matériaux, ou fondu en lave.
item.copper.name = Cuivre
item.copper.description = Un matériau de construction utile.Utilisé intensivement dans tout les blocs.
item.lead.name = Plomb
@@ -434,10 +435,10 @@ item.silicon.name = Silicone
item.silicon.description = Un matériau semi-conducteur extrêmement utile, avec des utilisations dans les panneaux solaires et beaucoup d'autre composants électroniques complexes.
item.plastanium.name = Plastanium
item.plastanium.description = Un matériau léger et docile utilisé dans l'aviation avancée et dans les munitions à fragmentation.
-item.phase-fabric.name = Phase Fabric
-item.phase-fabric.description = A near-weightless substance used in advanced electronics and self-repairing technology.
+item.phase-fabric.name = Tissu phasé
+item.phase-fabric.description = Une substance au poids quasiment inexistant utilisé pour l'électronique avancé et la technologie auto-réparatrice.
item.surge-alloy.name = alliage superchargé
-item.surge-alloy.description = An advanced alloy with unique electrical properties.
+item.surge-alloy.description = Un alliage avancé avec des propriétés électriques avancées.
item.biomatter.name = Biomasse
item.biomatter.description = Un mélange de matières organiques; utilisé pour la transformation en huile ou en tant que carburant de base.
item.sand.name = Sable
@@ -494,13 +495,14 @@ text.mech.ability = [LIGHT_GRAY]Compétence: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Capacité Thermique: {0}
text.liquid.viscosity = [LIGHT_GRAY]Viscosité: {0}
text.liquid.temperature = [LIGHT_GRAY]Température: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Générateur d'ennemi
block.core.name = Base
block.metalfloor.name = Sol en métal
block.deepwater.name = eau profonde
block.water.name = eau
block.lava.name = lave
-block.tar.name = Tar
+block.tar.name = pétrole
block.blackstone.name = roche sombre
block.stone.name = roche
block.dirt.name = terre
@@ -623,7 +625,7 @@ block.rtg-generator.name = G.T.R.
block.spectre.name = Spectre
block.meltdown.name = Meltdown
block.container.name = Conteneur
-block.core.description = The most important building in the game.
+block.core.description = Le batiment le plus important du jeu .
team.blue.name = bleu
team.red.name = rouge
team.orange.name = orange
@@ -668,113 +670,113 @@ tutorial.daggerfactory = Construire [accent]une usine de "Poignards" []est recom
tutorial.router = Les usines ont besoin de ressources pour fonctionner.\nCréez un routeur pour séparer les objets.
tutorial.dagger = Reliez des transmetteurs énergétiques à l'usine.\nUne fois que les conditions seront remplies , un mécha sera créé.\nConstruisez autant de foreuses, de générateurs et de tapis roulants que nécessaire.
tutorial.battle = [LIGHT_GRAY]L'Ennemi[] a révélé sa base .\nDétruisez la avec votre unité et des méchas "Poignard".
-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.copper-wall.description = Un bloc défensif à faible coût.\nUtile pour protéger la base et les tourelles dans les premières lors des premières vagues.
+block.copper-wall-large.description = Un bloc défensif à faible coût.\nUtile pour protéger la base et les tourelles dans les premières lors des premières vagues.\nFait du 2 sur 2.
+block.dense-alloy-wall.description = Un bloc défensif standard .\nProcure une bonne protection contre les ennemis.
+block.dense-alloy-wall-large.description = Un bloc défensif standard .\nProcure une bonne protection contre les ennemis.\nFait du 2 sur 2.
+block.thorium-wall.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les ennemis.
+block.thorium-wall-large.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les ennemis.\nFait du 2 sur 2.
+block.phase-wall.description = Moins puissant qu'un mur en Thorium mais déviera les balles sauf si elles sont trop puissantes.
+block.phase-wall-large.description = Moins puissant qu'un mur en Thorium mais déviera les balles sauf si elles sont trop puissantes.\nFait du 2 sur 2.
+block.surge-wall.description = Le plus puissant bloc défensif .\nA une faible chance de créer des éclairs vers les ennemis .
+block.surge-wall-large.description = Le plus puissant bloc défensif .\nA une faible chance de créer des éclairs vers les ennemis .\nFait du 2 sur 2.
+block.door.description = Une petite porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte les ennemis peuvent tirer et passer à travers.
+block.door-large.description = Une large porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte les ennemis peuvent tirer et passer à travers.\nFait du 2 sur 2.
+block.mend-projector.description = Soigne périodiquement les batiments autour de lui.
+block.overdrive-projector.description = Accélère les batiments autour de lui, notamment les foreuses et les convoyeurs.
+block.force-projector.description = Crée un champ de force hexagonal autour de lui qui protège les batiments et les unités à l'intérieur de prendre des dégâts à cause des balles.
+block.shock-mine.description = Blesse les ennemis qui marchent dessus. Quasiment invisble pour l'ennemi.
+block.duo.description = une petite tourelle avec un coût faible .
+block.arc.description = une petite tourelle tirant des arcs électrques vers les ennemis.
+block.hail.description = une petite tourelle d'artillerie.
+block.lancer.description = une tourelle de taille moyenne tirant des rayons chargés en électricité.
+block.wave.description = une tourelle de taille moyenne tirant rapidement des bulles de liquide .
+block.salvo.description = une tourelle de taille moyenne qui tire par salves.
+block.swarmer.description = une tourelle de taille moyenne qui tire des missiles qui se dispersent.
+block.ripple.description = Une grande tourelle d'artillerie qui tire plusieurs tirs simultanément.
+block.cyclone.description = Une grande tourelle tirant rapidement ... très rapidement .
+block.fuse.description = Une grande tourelle qui tire de puissants rayons lasers avec une faible portée.
+block.spectre.description = Une grande tourelle qui tire deux puissantes balles simultanément.
+block.meltdown.description = Une grande tourelle tirant de puissants rayons lasers avec une grande portée.
+block.conveyor.description = Convoyeur basique servant à transporter des objets. Les objets déplacés en avant sont automatiquement déposés dans les tourelles ou les batiments. Peut être tourné.
+block.titanium-conveyor.description = Convoyeur avancé . Déplace les objets plus rapidement que les convoyeurs standards.
+block.phase-conveyor.description = convoyeur très avancé . Utilise de l'énergie pour téléporter des objets à un convoyeur phasé connecté jusqu'à une longue distance .
+block.junction.description = Agit comme un pont pour deux ligne de convoyeurs se croisant. Utile lorsque deux différents convoyeurs déplacent différents matériaux à différents endroits.
+block.mass-driver.description = Batiment de transport d'objet [accent]ultime[]. Collecte un grand nombre d'objets puis les tire à un autre transporteur de masse sur une très longue distance.
+block.smelter.description = Brûle du charbon pour fondre du cuivre et du plomb en un alliage lourd.
+block.arc-smelter.description = Fait fondre du cuivre et du plomb en un alliage lourd en utilisant une source d'énergie extérieure .
+block.silicon-smelter.description = Utilise du sable, du charbon et de l'énergie afin de produire du silicone.
+block.plastanium-compressor.description = Produit du plastanium à partir de pétrole et de titane.
+block.phase-weaver.description = Produit du tissu phasé à partir de thorium et de grandes quantités de sable.
+block.alloy-smelter.description = Produit un alliage superchargé à l'aide de titane de plomb de silicone et de cuivre.
+block.pulverizer.description = Écrase la pierre pour en faire du sable. Utile quand il y a un manque de sable naturel.
+block.pyratite-mixer.description = Mélange charbon, plomb et sable en l'hautement inflammable pyratite.
+block.blast-mixer.description = Utilise du pétrole pour transformer la pyratite en un mélange explosif moins inflammable mais plus explosif que la pyratite.
+block.cryofluidmixer.description = Combine de l'eau et du titane en un liquide cryogénique bien plus efficace pour refroidir.
+block.solidifer.description = Refroidit de la lave en pierre très rapidement.
+block.melter.description = chauffe de la pierre à de très hautes températures pour obtenir de la lave.
+block.incinerator.description = Permet de se débarasser de n'importe quel objet ou liquide en exces .
+block.biomattercompressor.description = Compresse de la biomasse pour en récupérer le pétrole.
+block.separator.description = Expose la pierre à de l'eau sous pression afin d'obtenir différents minéraux contenus dansla pierre.
+block.centrifuge.description = Plus efficace qu'un séparateur mais aussi plus cher à construire et demande plus d'énergie.
+block.power-node.description = Transmet l'énergie aux transmetteurs énergétiques connectés . Jusqu'à quatre sources d'énergie, consommateurs ou transmetteurs peuvent être connectés. Le transmetteur recevra de l'énergie ou le transmettra à n'importe quel batiment adjacent.
+block.power-node-large.description = A un plus grand rayon que le transmetteur énergétique standard et jusqu'à six sources d'énergie, consommateurs ou transmetteurs peuvent être connectés.
+block.battery.description = Stocke l'énergie quand elle est en abondance et le distribue si il y a trop peu d'énergie tant qu'il lui reste de l'énergie.
+block.battery-large.description = Stocke bien plus d'énergie qu'une batterie normale.
+block.combustion-generator.description = Génère de l'énergie en brûlant du pétrole ou des matériaux inflammables.
+block.turbine-generator.description = Plus efficace qu'un générateur à combustion, mais requiert de l'eau .
+block.thermal-generator.description = Génère une grande quantité d'énergie à partir de lave .
+block.solar-panel.description = Génère une faible quantité d'énergie .
+block.solar-panel-large.description = Génère bien plus d'énergie qu'un panneau solaire standard, Mais est aussi bien plus cher à construire.
+block.thorium-reactor.description = Génère énormément d'énergie à l'aide de la radioactivité du thorium. Requiert néanmoins un refroidissement constant. Explosera violemment en cas de surchauffe.
+block.rtg-generator.description = Un générateur thermo-électrique à radioisotope qui ne demande pas de refroidissement mais produit moins d'énergie qu'un réacteur à Thorium.
+block.unloader.description = Décharge des objets depuis des conteneurs, coffres-forts ou de la base sur un convoyeur ou directement dans un bloc adjacent . Le type d'objet peut être changé en appuyant sur le déchargeur.
+block.container.description = Stocke un petit nombre d'objet . Utile pour réguler le flux d'objet quand la demande de matériaux est inconstante.un [LIGHT_GRAY] déchargeur[] peut être utilisé pour récupérer des objets depuis le conteneur.
+block.vault.description = Stocke un grand nombre d'objets. Utile pour réguler le flux d'objet quand la demande de matériaux est inconstante.un [LIGHT_GRAY] déchargeur[] peut être utilisé pour récupérer des objets depuis le coffre-fort.
+block.mechanical-drill.description = Une foreuse de faible coût. Si elle est placée sur à un endroit approprié, produit des matériaux lentement à l'infini.
+block.pneumatic-drill.description = Une foreuse amélioré plus rapide et capable de forer des matériaux plus dur grâce à l'usage de vérins à air comprimé.
+block.laser-drill.description = Permet de forer bien plus vite grâce à la technologie laser, cela demande néanmoins de l'énergie . Additionnellement, le thorium, un matériau radioactif, peut-être récupéré avec cette foreuse.
+block.blast-drill.description = La Foreuse ultime . Demande une grande quantité d'énergie .
+block.water-extractor.description = Extrait l'eau des nappes phréatiques. Utile quand il n'y a pas d'eau à proximité.
+block.cultivator.description = Cultive le sol avec de l'eau afin d'obtenir de la biomasse.
+block.oil-extractor.description = Utilise une grande quantité d'énergie afin d'extraire du pétrole du sable . Utile quand il n'y a pas de lacs de pétrole à proximité.
+block.dart-ship-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un avion de combat basique .\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
+block.trident-ship-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un bombardier lourd raisonnablement cuirassé .\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
+block.javelin-ship-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un intercepteur rapide et puissant avec des armes électriques.\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
+block.glaive-ship-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un large vaisseau cuirassé .\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
+block.tau-mech-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un mécha de support qui peut soigner les batiments et unités alliées.\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
+block.delta-mech-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un mécha rapide mais peu résistant fait pour les stratégies de harcèlement.\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
+block.omega-mech-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un mécha cuirassé et large, fait pour les assauts frontaux .\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
+block.spirit-factory.description = Produit des petits drones qui réparent les batiments et minent des matériaux.
+block.phantom-factory.description = Produit des drones avancés qui sont bien plus efficaces que les drones spirituels.
+block.wraith-factory.description = Produit des intercepteurs rapides qui harcèlent l'ennemi.
+block.ghoul-factory.description = Produit des bombardiers lourds.
+block.dagger-factory.description = Produit des unités terrestres basiques.
+block.titan-factory.description = Produit des unités terrestres avancées et cuirassées.
+block.fortress-factory.description = Produit des unités terrestres d'artillerie lourde .
+block.revenant-factory.description = Produit des unités terrestres lourdes avec des lasers.
+block.repair-point.description = Soigne en continu l'unité blessée la plus proche tant qu'elle est à sa portée.
+block.command-center.description = Permet de changer le comportement des IA alliées. Pour le moment, l'attaque, la retraite et les patrouilles sont supportées.
+block.conduit.description = tuyau basique permettant le transport de liquide . Marche comme un convoyeur mais avec les liquides. Utile si utilisé avec des extracteurs, des pompes ou d'autres conduits.
+block.pulse-conduit.description = tuyau avancé permettant le transport de liquide . Transporte les liquides plus rapidement et en stocke plus que les tuyaux standards.
+block.phase-conduit.description = tuyau très avancé permettant le transport de liquide. Utilise de l'énergie pour téléporter les liquides à un autre tuyau phasé sur une longue distance.
+block.liquid-router.description = Accepte les liquide en une direction et les rejete de tout les côtés équitablement. Peut aussi stocker une certaine quantité de liquide. Utile pour envoyer un liquide à plusieurs endroits.
+block.liquid-tank.description = Stocke une grande quantité de liquides . Utile pour réguler la sortie quand la demande est inconstante ou comme sécurité pour refroidir des batiments important.
+block.liquid-junction.description = Agit comme une intersection pour deux conduits se croisant.Utile si deux conduits amènent différents liquides à différents endroits.
+block.bridge-conduit.description = bloc de transport de liquide avancé . Permet le transport de liquides jusqu'à 3 blocs de n'importe quel terrain ou batiment .
+block.mechanical-pump.description = Une pompe de faible prix pompant lentement, mais ne consomme pas d'énergie.
+block.rotary-pump.description = Une pompe avancée qui double sa vitesse en utilisant de l'énergie.
+block.thermal-pump.description = La pompe ultime . Trois fois plus rapide qu'une pompe mécanique et la seule pompe capable de récupérer de la lave.
+block.router.description = Accepte les objets depuis une ou plus directions et le renvoie dans n'importe quelle direction. Utile pour séparer une chaîne de convoyeurs en plusieurs.[accent]Le seul et l'Unique[]
+block.distributor.description = Un routeur avancé qui sépare les objets jusqu'à 7 autres directions équitablement.
+block.bridge-conveyor.description = bloc de transport avancé permettant de traverser jusqu'à 3 blocs de n'importe quel terrain ou batiment.
+block.alpha-mech-pad.description = Avec assez d'énergie, reconstruit votre vaisseau en un mécha [accent] Alpha[].
+block.itemsource.description = Produit des objets à l'infini. Bac à sable uniquement .
+block.liquidsource.description = Source de liquide infinie . Bac à sable uniquement.
+block.itemvoid.description = Désintègre n'importe quel objet qui va à l'intérieur sans utiliser d'énergie. Bac à sable uniquement.
+block.powerinfinite.description = Produit de l'énergie à l'infini. Bac à sable uniquement.
+block.powervoid.description = Supprime toute l'énergie allant à l'intérieur.Bac à sable uniquement
+liquid.water.description = Couramment utilisé pour le refroidissement et le traitement des déchets.
+liquid.lava.description = Peut être transformé en [LIGHT_GRAY]pierre[], utilisé pour produire de l'énergie ou utilisé comme munition par certaines tourelles.
+liquid.oil.description = Peut être brûlé, utilisé comme explosif ou comme liquide de refroidissement.
+liquid.cryofluid.description = Le liquide de refroidissement le plus efficace.
diff --git a/core/assets/bundles/bundle_fr_BE.properties b/core/assets/bundles/bundle_fr_BE.properties
index e178e665f9..538b3aefe4 100644
--- a/core/assets/bundles/bundle_fr_BE.properties
+++ b/core/assets/bundles/bundle_fr_BE.properties
@@ -73,7 +73,7 @@ text.nextmission = Prochaine Mission
text.maps.none = [LIGHT_GRAY]Aucune carte trouvée!
text.about.button = À propos
text.name = Nom:
-text.filename = File Name:
+text.filename = Nom du fichier:
text.unlocked = Nouveau bloc debloqué!
text.unlocked.plural = Nouveaux blocs débloqués!
text.players = {0} joueurs en ligne
@@ -262,13 +262,13 @@ text.editor = Éditeur
text.mapeditor = Éditeur de carte
text.donate = Faire un\ndon
text.connectfail = [crimson]Échec de la connexion au serveur: [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 = Serveur inaccessible.
+text.error.invalidaddress = Adresse invalide.
+text.error.timedout = Expiration du délai !\nAssurez-vous que la redirection de port est configurée sur l'hôte et que l'adresse est correcte !
+text.error.mismatch = Erreur de paquet:\nPossible d'incompatibilité de version client/serveur.\nAssurez-vous que l'hôte et vous disposez de la dernière version de Mindustry !
+text.error.alreadyconnected = Déjà connecté.
+text.error.mapnotfound = Fichier de carte introuvable !
+text.error.any = Erreur réseau inconnue.
text.settings.language = Langage
text.settings.reset = Valeur par défaut.
text.settings.rebind = Réatttribuer
@@ -370,6 +370,7 @@ setting.musicvol.name = Volume de la musique
setting.mutemusic.name = Couper la musique
setting.sfxvol.name = Volume des SFX
setting.mutesound.name = Couper les SFX
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Paramétrer les touches
category.general.name = Général
category.view.name = Voir
@@ -419,9 +420,9 @@ content.mech.name = Mécha
item.stone.name = Pierre
item.stone.description = Un matériau brut commun. Peut-être séparé et raffiné en d'autres matériaux, ou fondus en lave.
item.copper.name = Cuivre
-item.copper.description = Un matériau de construction utile.Utilisé intensivement dans tout les blocs.
+item.copper.description = Un matériau de construction utile. Utilisé intensivement dans tout les blocs.
item.lead.name = Plomb
-item.lead.description = Un matériau de départ . Utilisé intensivement en électronique et pour le transport de blocs.
+item.lead.description = Un matériau de départ. Utilisé intensivement en électronique et pour le transport de blocs.
item.coal.name = Charbon
item.coal.description = Un carburant commun et facile à obtenir.
item.dense-alloy.name = Alliage lourd
@@ -494,13 +495,14 @@ text.mech.ability = [LIGHT_GRAY]Compétence: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Capacité Thermique {0}
text.liquid.viscosity = [LIGHT_GRAY]Viscosité: {0}
text.liquid.temperature = [LIGHT_GRAY]Température: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Générateur d'ennemi
block.core.name = Base
block.metalfloor.name = Sol en métal
block.deepwater.name = Eau profonde
block.water.name = Eau
block.lava.name = Lave
-block.tar.name = Tar
+block.tar.name = Pétrole
block.blackstone.name = Roche sombre
block.stone.name = Roche
block.dirt.name = Terre
@@ -623,7 +625,7 @@ block.rtg-generator.name = G.T.R.
block.spectre.name = Spectre
block.meltdown.name = Meltdown
block.container.name = Conteneur
-block.core.description = The most important building in the game.
+block.core.description = Sert de point de base pour le/les joueur(s). Ce bâtiment est le plus [scarlet]important[] du jeu !
team.blue.name = Bleu
team.red.name = Rouge
team.orange.name = Orange
@@ -632,7 +634,7 @@ team.green.name = Vert
team.purple.name = Violet
unit.alpha-drone.name = Drone alpha
unit.spirit.name = Drone spirituel
-unit.spirit.description = TL'unité de soutien de départ. Apparaît dans la base par défaut. Mine automatiquement les minerais, récupère les objets au sol et répare les blocs.
+unit.spirit.description = L'unité de soutien de départ. Apparaît dans la base par défaut. Mine automatiquement les minerais, récupère les objets au sol et répare les blocs.
unit.phantom.name = Drone Fantôme
unit.phantom.description = Une unité de soutien avancée. Mine automatiquement les minerais, récupère les objets au sol et répare les blocs. Bien plus efficace qu'un drone spirituel.
unit.dagger.name = Poignard
@@ -667,114 +669,114 @@ tutorial.silicon = Du silicone est maintenant produit. Obtenez-en.\n\nAugmenter
tutorial.daggerfactory = Construire [accent]une usine de "Poignards" []est recommandé .\n\nElle sera utilisée pour produire des unités d'attaque.
tutorial.router = Les usines ont besoin de ressources pour fonctionner.\nCréez un routeur pour séparer les objets.
tutorial.dagger = Reliez des transmetteurs énergétiques à l'usine.\nUne fois que les conditions seront remplies , un mécha sera créé.\nConstruisez autant de foreuses, de générateurs et de tapis roulants que nécessaire.
-tutorial.battle = [LIGHT_GRAY]L'Ennemi[] a révélé sa base .\nDétruisez la avec votre unité et des méchas "Poignard".
-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.
+tutorial.battle = [LIGHT_GRAY]L'Ennemi[] a révélé sa base.\nDétruisez la avec votre unité et des méchas "Poignard".
+block.copper-wall.description = Un bloc défensif bon marché.\nUtile pour protéger le noyau et les tourelles lors des premières vagues.
+block.copper-wall-large.description = Un bloc défensif bon marché.\nUtile pour protéger le noyau et les tourelles lors des premières vagues.\nS'étend sur plusieurs tuiles.
+block.dense-alloy-wall.description = Un bloc défensif standard.\nUne protection adéquate contre les ennemis.
+block.dense-alloy-wall-large.description = Un bloc défensif standard.\nUne protection adéquate contre les ennemis.\nS'étend sur plusieurs tuiles.
+block.thorium-wall.description = Un puissant bloc défensif.\nBonne protection contre les ennemis.
+block.thorium-wall-large.description = Un puissant bloc défensif.\nBonne protection contre les ennemis.\nS'étend sur plusieurs tuiles.
+block.phase-wall.description = Pas aussi fort qu'un mur de thorium, mais détournera les balles à moins qu'elles ne soient trop puissantes.
+block.phase-wall-large.description = Pas aussi fort qu'un mur de thorium, mais détournera les balles à moins qu'elles ne soient trop puissantes.\nS'étend sur plusieurs tuiles.
+block.surge-wall.description = Le bloc défensif le plus puissant.\nPeu de chances de déclencher des éclairs en direction de l'attaquant.
+block.surge-wall-large.description = Le bloc défensif le plus puissant.\nPeu de chances de déclencher des éclairs en direction de l'attaquant.\nS'étend sur plusieurs tuiles.
+block.door.description = Une petite porte qui peut être ouverte et fermée en tapotant dessus.\nSi elle est ouverte, les ennemis peuvent tirer et se déplacer.
+block.door-large.description = Une grande porte qui peut être ouverte et fermée en tapotant dessus.\nSi elle est ouverte, les ennemis peuvent tirer et se déplacer.\nS'étend sur plusieurs tuiles.
+block.mend-projector.description = Guérit périodiquement les bâtiments situés à proximité.
+block.overdrive-projector.description = Augmente la vitesse des bâtiments à proximité, comme les foreuses et les convoyeurs.
+block.force-projector.description = Crée un champ de force hexagonal autour de lui-même, protégeant les bâtiments et les unités internes des dommages causés par les balles.
+block.shock-mine.description = Endommage les ennemis qui marchent sur la mine. Presque invisible à l'ennemi.
+block.duo.description = Une petite tourelle pas chère.
+block.arc.description = Une petite tourelle qui tire de l'électricité dans un arc au hasard vers l'ennemi.
+block.hail.description = Une petite tourelle d'artillerie.
+block.lancer.description = Une tourelle de taille moyenne qui tire des faisceaux d’électricité chargés.
+block.wave.description = Une tourelle de taille moyenne à tir rapide qui tire des bulles de liquide.
+block.salvo.description = Une tourelle de taille moyenne qui tire des coups de salves.
+block.swarmer.description = Une tourelle de taille moyenne qui tire des missiles éclatés.
+block.ripple.description = Une grande tourelle d'artillerie qui tire plusieurs coups simultanément.
+block.cyclone.description = Une grande tourelle à tir rapide.
+block.fuse.description = Une grande tourelle qui tire de puissants faisceaux à courte portée.
+block.spectre.description = Une grande tourelle qui tire deux balles puissantes à la fois.
+block.meltdown.description = Une grande tourelle qui tire de puissants faisceaux à longue portée.
+block.conveyor.description = Bloc de transport d'articles standard.\nDéplace les objets et les déposes automatiquement dans des tourelles ou des usines. Rotatif.
+block.titanium-conveyor.description = Bloc de transport d'articles avancé.\nDéplace les articles plus rapidement que les convoyeurs standard.
+block.phase-conveyor.description = Bloc de transport d'articles avancé.\nUtilise le pouvoir de téléporter des articles vers un convoyeur de phase connecté sur plusieurs carreaux.
+block.junction.description = Agit comme un pont pour deux bandes transporteuses qui se croisent.\nUtile dans les situations avec deux convoyeurs différents transportant des matériaux différents à des endroits différents.
+block.mass-driver.description = Bloc de transport d'articles ultime.\nRecueille plusieurs objets et les envoie ensuite à un autre pilote de masse sur une longue distance.
+block.smelter.description = Brûle le charbon pour fondre le cuivre et le plomb en un alliage dense.
+block.arc-smelter.description = Fait fondre le cuivre et le plomb en un alliage dense en utilisant une source d'alimentation externe.
+block.silicon-smelter.description = Réduit le sable avec du coke* très pur afin de produire du silicium. (*Coke produit à partir de charbon:REF)
+block.plastanium-compressor.description = Produit du plastanium à partir de pétrole et de titane.
+block.phase-weaver.description = Produit un tissu de phase à partir de thorium radioactif et de grandes quantités de sable.
+block.alloy-smelter.description = Produit un alliage de surtension à partir de titane, plomb, silicium et cuivre.
+block.pulverizer.description = Brise la pierre en sable. Utile en cas de manque de sable naturel.
+block.pyratite-mixer.description = Mélange le charbon, le plomb et le sable en pyratite hautement inflammable.
+block.blast-mixer.description = Utilise du pétrole pour transformer la pyratite en un composé explosif moins inflammable mais plus explosif.
+block.cryofluidmixer.description = L'eau et le titane combinés forment un fluide cryo beaucoup plus efficace pour le refroidissement.
+block.solidifer.description = Refroidit la lave en pierre à un rythme rapide.
+block.melter.description = Chauffe la pierre à des températures très élevées pour obtenir de la lave.
+block.incinerator.description = Se débarrasse de tout article ou liquide en excès.
+block.biomattercompressor.description = Compresse biomatter afin de récupérer du pétrole.
+block.separator.description = Exposer la pierre à la pression de l'eau afin d'obtenir différents minéraux contenus dans la pierre.
+block.centrifuge.description = Plus efficace que le séparateur, mais aussi plus coûteux à construire et à alimenter.
+block.power-node.description = Transmet la puissance à des noeuds connectés. Il est possible de connecter jusqu'à quatre sources d'alimentation, puits ou nœuds.\nLe nœud recevra de l’alimentation ou fournira l’alimentation à tous les blocs adjacents.
+block.power-node-large.description = Son rayon d'action est supérieur à celui du nœud d'alimentation et peut être connecté à six sources d'alimentation, puits ou nœuds au maximum.
+block.battery.description = Stocke l’énergie chaque fois qu’il ya abondance et en cas de pénurie, tant qu’il reste de la capacité.
+block.battery-large.description = Stocke beaucoup plus d'énergie qu'une batterie ordinaire.
+block.combustion-generator.description = Génère de l'énergie en brûlant du pétrole ou des matériaux inflammables.
+block.turbine-generator.description = Plus efficace qu'un générateur de combustion, mais nécessite de l'eau supplémentaire.
+block.thermal-generator.description = Génère une grande quantité d'énergie grâce à la lave.
+block.solar-panel.description = Fournit une petite quantité d'énergie grâce au soleil.
+block.solar-panel-large.description = Fournit une bien meilleure alimentation qu'un panneau solaire standard, mais coûte également beaucoup plus cher à construire.
+block.thorium-reactor.description = Génère d'énormes quantités d'énergie à partir de thorium hautement radioactif. Nécessite un refroidissement constant.\nExplose violemment si des quantités insuffisantes de liquide de refroidissement ne sont pas fournies.
+block.rtg-generator.description = Générateur thermoélectrique à radio-isotopes ne nécessitant pas de refroidissement mais fournissant moins d'énergie qu'un réacteur à thorium.
+block.unloader.description = Décharge des articles d'un conteneur, d'une chambre forte ou d'un noyau sur un convoyeur ou directement dans un bloc adjacent.\nLe type d'élément à décharger peut être modifié en tapotant sur le déchargeur.
+block.container.description = Stocke une petite quantité d'objets. Utilisez-le pour créer des tampons lorsqu'il existe une demande non constante de matériaux. [LIGHT_GRAY]Un déchargeur[] peut être utilisé pour récupérer des éléments du conteneur.
+block.vault.description = Stocke une grande quantité d'objets. Utilisez-le pour créer des tampons lorsqu'il existe une demande non constante de matériaux. [LIGHT_GRAY]Un déchargeur[] peut être utilisé pour récupérer des éléments du coffre-fort.
+block.mechanical-drill.description = Un extracteur bon marché. Lorsqu'il est placé sur des carreaux appropriés, les objets sortent à un rythme lent et indéfiniment.
+block.pneumatic-drill.description = Un extracteur améliorée, plus rapide et capable de traiter des matériaux plus durs en utilisant la pression atmosphérique.
+block.laser-drill.description = Permet de forer encore plus rapidement grâce à la technologie laser, mais nécessite de l'énergie. De plus, le thorium radioactif peut être récupéré avec cet extracteur.
+block.blast-drill.description = L'extracteur ultime. Nécessite de grandes quantités d'énergie.
+block.water-extractor.description = Extrait l'eau du sol. Utilisez-le quand il n'y a pas de lac à proximité.
+block.cultivator.description = Cultiver le sol avec de l'eau afin d'obtenir du biomatter.
+block.oil-extractor.description = Utilise de grandes quantités d'énergie pour extraire le pétrole du sable. Utilisez-le lorsqu'il n'y a pas de source directe de pétrole à proximité.
+block.dart-ship-pad.description = Quittez votre vaisseau actuel et changez-vous en avion de combat de base.\nUtilisez la plate-forme en tapotant deux fois dessus.
+block.trident-ship-pad.description = Quittez votre vaisseau actuel et changez-vous en un bombardier lourd raisonnablement bien blindé.\nUtilisez la plate-forme en tapotant deux fois dessus.
+block.javelin-ship-pad.description = Quittez votre vaisseau actuel et changez-vous en un intercepteur puissant et rapide doté d’armes légères.\nUtilisez la plate-forme en tapotant deux fois dessus.
+block.glaive-ship-pad.description = Quittez votre vaisseau actuel et changez-vous en un grand vaisseau de combat bien blindé.\nUtilisez la plate-forme en tapotant deux fois dessus.
+block.tau-mech-pad.description = Quittez votre vaisseau actuel et changez-vous en un centre de support capable de soigner les bâtiments et unités amis.\nUtilisez la plate-forme en tapotant deux fois dessus.
+block.delta-mech-pad.description = Quittez votre vaisseau actuel et changez-vous en un méchant rapide, légèrement blindé, conçu pour les attaques à la volée.\nUtilisez la plate-forme en tapotant deux fois dessus.
+block.omega-mech-pad.description = Quittez votre vaisseau actuel et changez-vous en un mech encombrant et bien blindé, conçu pour les assauts de première ligne.\nUtilisez la plate-forme en tapotant deux fois dessus.
+block.spirit-factory.description = Produit des drones légers qui extraient du minerai et réparent des blocs.
+block.phantom-factory.description = Produit des unités de drones avancées qui sont nettement plus efficaces qu'un drone spirituel.
+block.wraith-factory.description = Produit des intercepteurs rapides qui harcèlent l'ennemi.
+block.ghoul-factory.description = Produit des tapis de bombardiers lourds.
+block.dagger-factory.description = Produit des unités terrestres de base.
+block.titan-factory.description = Produit des unités terrestres avancées et blindées.
+block.fortress-factory.description = Produit des unités terrestres d'artillerie lourde.
+block.revenant-factory.description = Produit des unités terrestres laser lourdes.
+block.repair-point.description = Soigne en permanence l'unité endommagée la plus proche à proximité.
+block.command-center.description = Permet de changer le comportement amical de l'IA. Actuellement, les commandes d'attaque, de retraite et de patrouille sont prises en charge.
+block.conduit.description = Bloc de transport liquide de base. Fonctionne comme un convoyeur, mais avec des liquides. Utilisation optimale avec des extracteurs, des pompes ou d’autres conduits.
+block.pulse-conduit.description = Bloc de transport de liquide avancé. Transporte les liquides plus rapidement et stocke plus que des conduits standard.
+block.phase-conduit.description = Bloc de transport de liquide avancé. Utilise le pouvoir de téléporter des liquides vers un conduit de phase connecté sur plusieurs carreaux.
+block.liquid-router.description = Accepte les liquides d'une direction et les envoie dans 3 autres directions de manière égale. Peut également stocker une certaine quantité de liquide. Utile pour séparer les liquides d'une source à plusieurs cibles.
+block.liquid-tank.description = Stocke une grande quantité de liquides. Utilisez-le pour créer des tampons en cas de demande non constante de matériaux ou comme protection pour le refroidissement des blocs vitaux.
+block.liquid-junction.description = Agit comme un pont pour deux conduits de croisement. Utile dans les situations avec deux conduits différents transportant des liquides différents à des endroits différents.
+block.bridge-conduit.description = Bloc de transport de liquide avancé. Permet de transporter des liquides jusqu'à 3 tuiles de n'importe quel terrain ou bâtiment.
+block.mechanical-pump.description = Une pompe bon marché avec un débit lent, mais aucune consommation d'énergie.
+block.rotary-pump.description = Une pompe avancée qui double la vitesse en utilisant l’énergie.
+block.thermal-pump.description = La pompe ultime. Trois fois plus rapide qu'une pompe mécanique et la seule pompe capable de récupérer de la lave.
+block.router.description = Accepte les éléments d'une direction et les envoie dans 3 autres directions de manière égale. Utile pour séparer les matériaux d'une source en plusieurs cibles.
+block.distributor.description = Un routeur avancé qui divise les articles en 7 autres directions de manière égale. [scarlet]Seule et unique ![]
+block.bridge-conveyor.description = Bloc de transport d'articles avancé. Permet de transporter des objets sur plus de 3 tuiles de n'importe quel terrain ou bâtiment.
+block.alpha-mech-pad.description = Lorsque vous avez assez de puissance, reconstruisez votre vaisseau dans le [accent]Alpha[] mech.
+block.itemsource.description = Sort infiniment les articles. Bac à sable seulement.
+block.liquidsource.description = Débit infini de liquides. Bac à sable seulement.
+block.itemvoid.description = Détruit tous les objets qui y entrent sans utiliser d'énergie. Bac à sable seulement.
+block.powerinfinite.description = Débit infini d'énergie. Bac à sable seulement.
+block.powervoid.description = Annule toute l'énergie qui y est introduite. Bac à sable seulement.
+liquid.water.description = Couramment utilisé pour les machines de refroidissement et le traitement des déchets.
+liquid.lava.description = Peut être transformé en [LIGHT_GRAY]pierre[], utilisé pour générer de l'énergie ou utilisé comme munition pour certaines tourelles.
+liquid.oil.description = Peut être brûlé, explosé ou utilisé comme liquide de refroidissement.
+liquid.cryofluid.description = Le liquide de refroidissement le plus efficace.
diff --git a/core/assets/bundles/bundle_in_ID.properties b/core/assets/bundles/bundle_in_ID.properties
index 838876490c..f62937a494 100644
--- a/core/assets/bundles/bundle_in_ID.properties
+++ b/core/assets/bundles/bundle_in_ID.properties
@@ -370,6 +370,7 @@ setting.musicvol.name = Volume Musik
setting.mutemusic.name = Bisukan Musik
setting.sfxvol.name = Volume Suara
setting.mutesound.name = Bisukan Suara
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Rebind Keys
category.general.name = General
category.view.name = View
@@ -494,6 +495,7 @@ text.mech.ability = [LIGHT_GRAY]Ability: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Heat Capacity: {0}
text.liquid.viscosity = [LIGHT_GRAY]Viscosity: {0}
text.liquid.temperature = [LIGHT_GRAY]Temperature: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Enemy Spawn
block.core.name = Core
block.metalfloor.name = Metal Floor
diff --git a/core/assets/bundles/bundle_it.properties b/core/assets/bundles/bundle_it.properties
index bfcd087d53..b91fe81ef4 100644
--- a/core/assets/bundles/bundle_it.properties
+++ b/core/assets/bundles/bundle_it.properties
@@ -370,6 +370,7 @@ setting.musicvol.name = Volume Musica
setting.mutemusic.name = Silenzia musica
setting.sfxvol.name = Volume SFX
setting.mutesound.name = Togli suoni
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Configurazione Tasti
category.general.name = Generale
category.view.name = Visualizzazione
@@ -494,6 +495,7 @@ text.mech.ability = [LIGHT_GRAY]Abilità: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Capacità calorifica: {0}
text.liquid.viscosity = [LIGHT_GRAY]Viscosità: {0}
text.liquid.temperature = [LIGHT_GRAY]Temperatura: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Enemy Spawn
block.core.name = Nucleo
block.metalfloor.name = Pavimento di ferro
diff --git a/core/assets/bundles/bundle_ja.properties b/core/assets/bundles/bundle_ja.properties
new file mode 100644
index 0000000000..0af4f3b0f6
--- /dev/null
+++ b/core/assets/bundles/bundle_ja.properties
@@ -0,0 +1,782 @@
+text.credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!)
+text.credits = クレジット
+text.discord = DiscordのMindustryに参加!
+text.link.discord.description = Mindustryの公式Discordグループ
+text.link.github.description = ゲームのソースコード
+text.link.dev-builds.description = 不安定な開発ビルド
+text.link.trello.description = 公式 Trelloボード の実装予定の機能をチェック
+text.link.itch.io.description = itch.ioでPC版のダウンロードやweb版をプレイ
+text.link.google-play.description = Google Playのストアページ
+text.link.wiki.description = 公式 Mindustry Wiki
+text.linkfail = リンクを開くのに失敗しました!\nURLをクリップボードにコピーしました。
+text.editor.web = Web版はエディターをサポートしていません!\nゲームをダウンロードして、使用してください。
+text.web.unsupported = Web版はこの機能をサポートしてません! ゲームをダウンロードして、使用してください。
+text.gameover = ゲームオーバー
+text.gameover.pvp = [accent] {0}[] チームの勝利!
+text.sector.gameover = この区域は敗北しました。 再配備しますか?
+text.sector.retry = リトライ
+text.highscore = [accent]ハイスコアを記録!
+text.wave.lasted = あなたはウェーブ[accent]{0}[]まで続きました。
+text.level.highscore = ハイスコア: [accent]{0}
+text.level.delete.title = 削除の確認
+text.map.delete = マップ "[accent]{0}[]" を削除してもよろしいですか?
+text.level.select = レベル選択
+text.level.mode = ゲームモード:
+text.construction.desktop = ブロックの選択や建設を止めるには、[accent]スペースを使用してください[]。
+text.construction.title = ブロック建設ガイド
+text.construction = [accent]ブロック建設モード[]になりました。\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.showagain = 次回以降表示しない
+text.coreattack = < コアが攻撃を受けています! >
+text.unlocks = アンロック
+text.savegame = ゲームを保存
+text.loadgame = ゲームを読み込む
+text.joingame = ゲームに参加
+text.addplayers = プレイヤーを追加/削除
+text.customgame = カスタムゲーム
+text.sectors = 区域
+text.sector = 区域: [LIGHT_GRAY]{0}
+text.sector.time = 時間: [LIGHT_GRAY]{0}
+text.sector.deploy = 配備
+text.sector.abandon = 撤退
+text.sector.abandon.confirm = 区域のすべての進行を撤退します。\nこれは元に戻すことはできません!
+text.sector.resume = 再開
+text.sector.locked = [scarlet][[不完全]
+text.sector.unexplored = [accent][[未調査]
+text.missions = ミッション:[LIGHT_GRAY] {0}
+text.mission = ミッション:[LIGHT_GRAY] {0}
+text.mission.main = メインミッション:[LIGHT_GRAY] {0}
+text.mission.info = ミッション情報
+text.mission.complete = ミッション完了!
+text.mission.complete.body = 区域 {0},{1} を征服しました。
+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}[] ウェーブ
+text.mission.battle = 敵のコアを破壊する
+text.mission.resource.menu = {0} を{1}個を入手する
+text.mission.resource = {0} を入手する :\n[accent]{1}/{2}[]
+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 = 機体を[accent]{0}[]に乗り換える
+text.mission.create = [accent]{0}[] を作る
+text.none = <なし>
+text.close = 閉じる
+text.quit = 終了
+text.maps = マップ
+text.continue = 続ける
+text.nextmission = 次のミッションへ
+text.maps.none = [LIGHT_GRAY]マップが存在しません!
+text.about.button = About
+text.name = 名前:
+text.filename = ファイル名:
+text.unlocked = 新しいブロックをアンロック!
+text.unlocked.plural = 新しいブロックをアンロック!
+text.players = {0} 人がオンライン
+text.players.single = {0} 人がオンライン
+text.server.closing = [accent]サーバーを閉じています...
+text.server.kicked.kick = サーバからキックされました!
+text.server.kicked.serverClose = サーバーが閉じました。
+text.server.kicked.sectorComplete = 区域を制覇しました。
+text.server.kicked.sectorComplete.text = ミッションが完了しました。\nサーバーは次の区域に移ります。
+text.server.kicked.clientOutdated = 古いクライアントです! ゲームをアップデートしてください!
+text.server.kicked.serverOutdated = 古いサーバーです! ホストに更新してもらってください!
+text.server.kicked.banned = サーバーからBanされています。
+text.server.kicked.recentKick = 直前にキックされています。\nもう一度接続できるまでお待ちください。
+text.server.kicked.nameInUse = このサーバーでは、\nその名前はすでに使用されています。
+text.server.kicked.nameEmpty = 無効な名前です。
+text.server.kicked.idInUse = すでにサーバーに参加しています。! 二つのアカウントでの接続は許可されていません。
+text.server.kicked.customClient = このサーバーはカスタムビルドをサポートしていません。公式版をダウンロードしてください。
+text.host.info = [accent]ホスト[]ボタンを押すと、ポート[scarlet]6567[]でサーバーが開かれます。同じ[LIGHT_GRAY]Wifi や ローカルネットワーク[]からはサーバーリストで見ることができます。\n\nIPアドレスからどこからでもアクセスできるようにするには、[accent]ポート開放[]する必要があります。\n\n[LIGHT_GRAY]注意:: LAN上のゲームで接続できない場合、Mindustryがファイアウォールの設定でローカルネットワークに接続が許可されているか確認してください。
+text.join.info = ここでは、[accent]サーバーのIPアドレス[]から接続したり、[accent]ローカルネットワーク[]のサーバーを探すことができます。\nLANとWANの両方のマルチプレイに対応しています。\n\n[LIGHT_GRAY]注意:グローバルサーバーリストはありません。誰かのサーバーにIPで接続したい場合、ホストにIPをお尋ねください。
+text.hostserver = ゲームをホスト
+text.hostserver.mobile = ホスト
+text.host = ホスト
+text.hosting = [accent]サーバーを開いています...
+text.hosts.refresh = リフレッシュ
+text.hosts.discovering = LAN上のサーバーを探しています
+text.server.refreshing = サーバーをリフレッシュ
+text.hosts.none = [lightgray]ローカルゲームが見つかりません!
+text.host.invalid = [scarlet]ホストに接続できません。
+text.trace = プレイヤーの記録
+text.trace.playername = プレイヤー名: [accent]{0}
+text.trace.ip = IP: [accent]{0}
+text.trace.id = ユニークID: [accent]{0}
+text.trace.android = Androidクライアント: [accent]{0}
+text.trace.modclient = カスタムクライアント: [accent]{0}
+text.trace.totalblocksbroken = 総ブロック破壊数: [accent]{0}
+text.trace.structureblocksbroken = 総建設物破壊数: [accent]{0}
+text.trace.lastblockbroken = 最後に破壊したブロック: [accent]{0}
+text.trace.totalblocksplaced = 総ブロック設置数: [accent]{0}
+text.trace.lastblockplaced = 最後に設置したブロック: [accent]{0}
+text.invalidid = 無効なクライアントIDです! バグ報告してください。
+text.server.bans = Ban
+text.server.bans.none = Banされたプレイヤーはいません!
+text.server.admins = 管理者
+text.server.admins.none = 管理者はいません!
+text.server.add = サーバーを追加
+text.server.delete = サーバーを削除しますか?
+text.server.hostname = ホスト: {0}
+text.server.edit = サーバーを編集
+text.server.outdated = [crimson]古いサーバー![]
+text.server.outdated.client = [crimson]古いクライアント![]
+text.server.version = [lightgray]バージョン: {0} {1}
+text.server.custombuild = [yellow]カスタムビルド
+text.confirmban = このプレイヤーを Ban しますか?
+text.confirmkick = このプレイヤーをキックしますか?
+text.confirmunban = このプレイヤーの Ban を解除しますか?
+text.confirmadmin = このプレイヤーを管理者にしますか?
+text.confirmunadmin = このプレイヤーを管理者から削除しますか?
+text.joingame.title = サーバーに参加
+text.joingame.ip = IP:
+text.disconnect = 接続が切断されました。
+text.disconnect.data = ワールドデータの読み込みに失敗しました!
+text.connecting = [accent]接続中...
+text.connecting.data = [accent]ワールドデータを読み込んでいます...
+text.server.port = ポート:
+text.server.addressinuse = アドレスがすでに使用されています。!
+text.server.invalidport = 無効なポート番号です。!
+text.server.error = [crimson]サーバーエラー: [accent]{0}
+text.save.old = これは古いバージョンのセーブデータで、使用することができません。\n\n[LIGHT_GRAY]下位互換性の実装は正式版の4.0行われます。
+text.save.new = 新しく保存
+text.save.overwrite = このスロットに上書きしてよろしいですか?
+text.overwrite = 上書き
+text.save.none = セーブデータがありません!
+text.saveload = [accent]セーブしています...
+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 = セーブデータを読み込む
+text.save.newslot = セーブデータ名:
+text.save.rename = リネーム
+text.save.rename.text = 新しい名前:
+text.selectslot = セーブデータを選択
+text.slot = [accent]スロット {0}
+text.save.corrupted = [accent]セーブファイルが無効、または破損しました!\nゲームのアップデート直後の場合、恐らくセーブデータのフォーマットの変更によるもので、バグではありません。
+text.sector.corrupted = [accent]区域のセーブファイルが見つかりましたが、読み込みに失敗しました。\n新しく区域がが作成されます。
+text.empty = <空>
+text.on = オン
+text.off = オフ
+text.save.autosave = 自動保存: {0}
+text.save.map = マップ: {0}
+text.save.wave = ウェーブ {0}
+text.save.difficulty = 難易度: {0}
+text.save.date = 最終保存: {0}
+text.save.playtime = プレイ時間: {0}
+text.confirm = 確認
+text.delete = 削除
+text.ok = OK
+text.open = 開く
+text.cancel = キャンセル
+text.openlink = リンクを開く
+text.copylink = リンクをコピー
+text.back = 戻る
+text.quit.confirm = 終了してもよろしいですか?
+text.changelog.title = 変更履歴
+text.changelog.loading = 変更履歴を取得しています...
+text.changelog.error.android = [accent]Android4.4または、それ以下では変更履歴が動作しない場合があります。!\nこれはAndroidの内部バグによるものです。
+text.changelog.error.ios = [accent]iOSは変更履歴に対応していません。
+text.changelog.error = [scarlet]変更履歴の取得エラー!\nインターネット接続を確認してください。
+text.changelog.current = [yellow][[現在のバージョン]
+text.changelog.latest = [accent][[最新バージョン]
+text.loading = [accent]読み込み中...
+text.saving = [accent]保存中...
+text.wave = [accent]ウェーブ {0}
+text.wave.waiting = [LIGHT_GRAY]次のウェーブまで {0} 秒
+text.waiting = [LIGHT_GRAY]待機中...
+text.waiting.players = プレイヤーを待っています...
+text.wave.enemies = [LIGHT_GRAY]残り {0} 体
+text.wave.enemy = [LIGHT_GRAY]残り {0} 体
+text.loadimage = イメージを読み込む
+text.saveimage = イメージを保存
+text.unknown = 不明
+text.custom = カスタム
+text.builtin = 組み込み
+text.map.delete.confirm = マップを削除してもよろしいですか? これは戻すことができません!
+text.map.random = [accent]ランダムマップ
+text.map.nospawn = このマップにはスポーンするためのプレイヤーのコアがありません! [ROYAL]青い[]コアをエディターでマップに追加してください。
+text.map.nospawn.pvp = このマップには敵がスポーンするためのプレイヤーのコアがありません! [SCARLET]赤い[]コアをエディターでマップに追加してください。
+text.map.invalid = マップの読み込みエラー: ファイルが無効、または破損しています。
+text.editor.brush = ブラシ
+text.editor.slope = \\
+text.editor.openin = エディターで開く
+text.editor.oregen = 鉱石の生成
+text.editor.oregen.info = 鉱石の生成:
+text.editor.mapinfo = マップ情報
+text.editor.author = 作者:
+text.editor.description = 説明:
+text.editor.name = 名前:
+text.editor.teams = チーム
+text.editor.elevation = 標高
+text.editor.errorimageload = ファイルの読み込みエラー:\n[accent]{0}
+text.editor.errorimagesave = ファイルの保存エラー:\n[accent]{0}
+text.editor.generate = 生成
+text.editor.resize = リサイズ
+text.editor.loadmap = マップを読み込む
+text.editor.savemap = マップを保存
+text.editor.saved = 保存しました!
+text.editor.save.noname = マップに名前がありません! メニューの 'マップ情報' から設定してください。
+text.editor.save.overwrite = マップが組み込みマップを上書きしようとしています。! メニューの 'マップ情報' から異なる名前に設定してください。
+text.editor.import.exists = [scarlet]インポートできません:[] '{0}' はすでに組み込みマップの名前として存在します!
+text.editor.import = インポート...
+text.editor.importmap = マップをインポート
+text.editor.importmap.description = すでに存在しているマップをインポート
+text.editor.importfile = ファイルをインポート
+text.editor.importfile.description = 外部マップファイルをインポート
+text.editor.importimage = 古いイメージをインポート
+text.editor.importimage.description = 外部イメージファイルをインポート
+text.editor.export = エクスポート...
+text.editor.exportfile = ファイルをエクスポート
+text.editor.exportfile.description = マップファイルをエクスポート
+text.editor.exportimage = 地形イメージをエクスポート
+text.editor.exportimage.description = イメージファイルをエクスポート
+text.editor.loadimage = 地形をインポート
+text.editor.saveimage = 地形をエクスポート
+text.editor.unsaved = [scarlet]保存されていない変更があります![]\n終了してもよろしいですか?
+text.editor.resizemap = マップをリサイズ
+text.editor.mapname = マップ名:
+text.editor.overwrite = [accent]警告!\n存在するマップを上書きします。
+text.editor.overwrite.confirm = [scarlet]警告![] この名前のマップがすでに存在します。上書きしてもよろしいですか?
+text.editor.selectmap = 読み込むマップを選択:
+text.width = 幅:
+text.height = 高さ:
+text.menu = メニュー
+text.play = プレイ
+text.load = 読み込む
+text.save = 保存
+text.fps = FPS: {0}
+text.tps = TPS: {0}
+text.ping = Ping: {0}ms
+text.language.restart = 言語設定を有効にするにはゲームを再起動してください。
+text.settings = 設定
+text.tutorial = チュートリアル
+text.editor = エディター
+text.mapeditor = マップエディター
+text.donate = 寄附
+text.connectfail = [crimson]サーバーへの接続できませんでした:\n\n[accent]{0}
+text.error.unreachable = サーバーに到達できません。\nアドレスは正しいですか?
+text.error.invalidaddress = 無効なアドレスです。
+text.error.timedout = タイムアウトしました!\nホストがポート開放されているか確認してください。アドレスは正しいです!
+text.error.mismatch = パケットエラー:\nクライアント/サーバーのバージョンが一致しません。\nゲームとホストが最新のMindustryか確認してください!
+text.error.alreadyconnected = すでに接続されています。
+text.error.mapnotfound = マップファイルが見つかりません!
+text.error.any = 不明なネットワークエラーです。
+text.settings.language = 言語
+text.settings.reset = デフォルトにリセット
+text.settings.rebind = 再設定
+text.settings.controls = コントロール
+text.settings.game = ゲーム
+text.settings.sound = サウンド
+text.settings.graphics = グラフィック
+text.settings.cleardata = データを削除...
+text.settings.clear.confirm = データを削除してもよろしいですか?\n元に戻すことはできません!
+text.settings.clearall.confirm = [scarlet]警告![]\nこれはすべてのデータが削除されます。これにはセーブデータ、マップ、アンロック、キーバインドが含まれます。\n「ok」 を押すと、すべてのデータが削除され、自動的に終了します。
+text.settings.clearsectors = 区域を削除
+text.settings.clearunlocks = アンロックを削除
+text.settings.clearall = すべてを削除
+text.paused = [accent]< ポーズ >
+text.yes = はい
+text.no = いいえ
+text.info.title = 情報
+text.error.title = [crimson]エラーが発生しました
+text.error.crashtitle = エラーが発生しました
+text.blocks.blockinfo = ブロック情報
+text.blocks.powercapacity = 電力容量
+text.blocks.powershot = 電力/ショット
+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 = 液体/秒
+text.unit.itemssecond = アイテム/秒
+text.unit.pixelssecond = ピクセル/秒
+text.unit.liquidunits = 液体
+text.unit.powerunits = 電力
+text.unit.degrees = 度
+text.unit.seconds = 秒
+text.unit.items = アイテム
+text.category.general = 一般
+text.category.power = 電力
+text.category.liquids = 液体
+text.category.items = アイテム
+text.category.crafting = 製作速度
+text.category.shooting = 攻撃速度
+setting.autotarget.name = 自動ターゲット
+setting.fpscap.name = 最大FPS
+setting.fpscap.none = なし
+setting.fpscap.text = {0} FPS
+setting.difficulty.training = トレーニング
+setting.difficulty.easy = イージー
+setting.difficulty.normal = ノーマル
+setting.difficulty.hard = ハード
+setting.difficulty.insane = クレイジー
+setting.difficulty.name = 難易度:
+setting.screenshake.name = 画面を振る
+setting.effects.name = 画面効果
+setting.sensitivity.name = 操作感度
+setting.saveinterval.name = 自動保存間隔
+setting.seconds = {0} 秒
+setting.fullscreen.name = フルスクリーン
+setting.multithread.name = マルチスレッド
+setting.fps.name = FPSを表示
+setting.vsync.name = VSync
+setting.lasers.name = 電力レーザーを表示
+setting.minimap.name = ミニマップを表示
+setting.musicvol.name = 音楽 音量
+setting.mutemusic.name = 音楽をミュート
+setting.sfxvol.name = 効果音 音量
+setting.mutesound.name = 効果音をミュート
+setting.crashreport.name = 匿名でクラッシュレポートを送信する
+text.keybind.title = キーバインド
+category.general.name = 一般
+category.view.name = 表示
+category.multiplayer.name = マルチプレイ
+command.attack = 攻撃
+command.retreat = 退却
+command.patrol = 警戒
+keybind.press = キーを押してください...
+keybind.press.axis = 軸またはキーを押してください...
+keybind.move_x.name = 左右移動
+keybind.move_y.name = 上下移動
+keybind.select.name = 選択/ショット
+keybind.break.name = 破壊
+keybind.deselect.name = 選択解除
+keybind.shoot.name = ショット
+keybind.zoom_hold.name = ズーム長押し
+keybind.zoom.name = ズーム
+keybind.menu.name = メニュー
+keybind.pause.name = ポーズ
+keybind.dash.name = ダッシュ
+keybind.chat.name = チャット
+keybind.player_list.name = プレイヤーリスト
+keybind.console.name = コンソール
+keybind.rotate.name = 回転
+keybind.toggle_menus.name = メニュー切り替え
+keybind.chat_history_prev.name = 前のチャット履歴
+keybind.chat_history_next.name = 次のチャット履歴
+keybind.chat_scroll.name = チャットスクロール
+keybind.drop_unit.name = ドロップユニット
+keybind.zoom_minimap.name = ミニマップのズーム
+mode.text.help.title = モードの説明
+mode.waves.name = ウェーブ
+mode.waves.description = ノーマルモードです。限られた資源でウェーブが自動的に始まります。
+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 = フリービルド
+mode.freebuild.description = 限られた資源でウェーブを自由に始められます。
+mode.pvp.name = PvP
+mode.pvp.description = ローカルで他のプレイヤー戦います。
+content.item.name = アイテム
+content.liquid.name = 液体
+content.unit.name = ユニット
+content.recipe.name = ブロック
+content.mech.name = 機体
+item.stone.name = 石
+item.stone.description = 基本的な原材料です。他の材料を分離したり、精製や溶岩を溶かしたりするのに使用します。
+item.copper.name = 銅
+item.copper.description = 便利な鉱石です。様々なブロックの材料として幅広く使われています。
+item.lead.name = 鉛
+item.lead.description = 一般的で手軽な鉱石です。機械や液体輸送ブロックなどに使われます。
+item.coal.name = 石炭
+item.coal.description = 一般的で有用な燃料です。
+item.dense-alloy.name = 高密度合金
+item.dense-alloy.description = 銅と鉛でできた丈夫な合金です。高性能な戦争ブロックやドリルに使われます。
+item.titanium.name = チタン
+item.titanium.description = 希少で超軽量な金属です。液体輸送やドリル、航空機などで使われます。
+item.thorium.name = トリウム
+item.thorium.description = 高密度で放射性の金属です。構造的な支援や核燃料に使われます。
+item.silicon.name = シリコン
+item.silicon.description = 非常に有用な半導体でソーラーパネルや多くの複雑な機械に応用できます。
+item.plastanium.name = プラスタニウム
+item.plastanium.description = 軽量で伸縮性のある材料です。飛行機や弾薬に使用されます。
+item.phase-fabric.name = フェーズファイバー
+item.phase-fabric.description = 軽くない物質です。高度な機械や自己修復技術に使用されます。
+item.surge-alloy.name = サージ合金
+item.surge-alloy.description = 独特な電気的特性を持った特殊合金です。
+item.biomatter.name = バイオメター
+item.biomatter.description = 有機物の混ざったの塊です。石油への転換や燃料として使われます。
+item.sand.name = 砂
+item.sand.description = 合金や融剤など広く使用されている一般的な材料です。
+item.blast-compound.name = 爆発性化合物
+item.blast-compound.description = 爆弾や爆発物に使われる揮発性化合物です。燃料として燃やすこともできますが、推奨されません。
+item.pyratite.name = ピラタイト
+item.pyratite.description = 兵器に使われる非常に燃えやすい物質です。
+liquid.water.name = 水
+liquid.lava.name = 溶岩
+liquid.oil.name = 石油
+liquid.cryofluid.name = 冷却水
+mech.alpha-mech.name = アルファ
+mech.alpha-mech.weapon = 重武装機関砲
+mech.alpha-mech.ability = ドローン部隊
+mech.alpha-mech.description = 一般的な機体です。標準的な速度と攻撃力を持っています。攻撃力を高めるために最大3体のドローンを作成することができます。
+mech.delta-mech.name = デルタ
+mech.delta-mech.weapon = 電撃砲
+mech.delta-mech.ability = 電撃チャージ
+mech.delta-mech.description = 高速に移動する敵のために素早く軽装化された機体です。建造物にはほとんどダメージを与えませんが、電撃を使って、たくさんの敵を素早く倒すことができます。
+mech.tau-mech.name = タウ
+mech.tau-mech.weapon = 修復レーザー
+mech.tau-mech.ability = リペアバースト
+mech.tau-mech.description = 支援型機体です。ダメージを受けたブロックを修復や火災の消火、半径内の味方を治療を行います。
+mech.omega-mech.name = オメガ
+mech.omega-mech.weapon = ロケット弾
+mech.omega-mech.ability = 重装備
+mech.omega-mech.description = 最前線での攻撃向けに作られた大型機体です。重装備によってダメージの90%を防ぐことができます。
+mech.dart-ship.name = ダート
+mech.dart-ship.weapon = 機関砲
+mech.dart-ship.description = 一般的な機体です。高速で軽く使いやすいですが、攻撃能力はほとんどなく採掘速度が遅いのが欠点です。
+mech.javelin-ship.name = ジャベリン
+mech.javelin-ship.description = 最初は遅いですが、敵の基地では速度と飛行能力が飛躍的に高まり、電撃やミサイルで多量のダメージを与えることができます。
+mech.javelin-ship.weapon = バーストミサイル
+mech.javelin-ship.ability = 放電ブースター
+mech.trident-ship.name = トライデント
+mech.trident-ship.description = 強力な爆撃機です。頑丈な装甲です。
+mech.trident-ship.weapon = 爆弾
+mech.glaive-ship.name = グライブ
+mech.glaive-ship.description = 大きく、重武装された攻撃機です。焼夷弾が装備され、優れた加速と最高速度を保有しています。
+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.unit.health = [LIGHT_GRAY]耐久値: {0}
+text.unit.speed = [LIGHT_GRAY]速度: {0}
+text.mech.weapon = [LIGHT_GRAY]武器: {0}
+text.mech.armor = [LIGHT_GRAY]装備: {0}
+text.mech.itemcapacity = [LIGHT_GRAY]アイテム容量: {0}
+text.mech.minespeed = [LIGHT_GRAY]採掘速度: {0}
+text.mech.minepower = [LIGHT_GRAY]採掘力: {0}
+text.mech.ability = [LIGHT_GRAY]能力: {0}
+text.liquid.heatcapacity = [LIGHT_GRAY]熱容量: {0}
+text.liquid.viscosity = [LIGHT_GRAY]粘度: {0}
+text.liquid.temperature = [LIGHT_GRAY]温度: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
+block.spawn.name = エネミースポーン
+block.core.name = コア
+block.metalfloor.name = 金属製の床
+block.deepwater.name = 深層水
+block.water.name = 水
+block.lava.name = 溶岩
+block.tar.name = タール
+block.blackstone.name = 黒い石
+block.stone.name = 石
+block.dirt.name = 土
+block.sand.name = 砂
+block.ice.name = 氷
+block.snow.name = 雪
+block.grass.name = 草
+block.shrub.name = 低木
+block.rock.name = 岩
+block.blackrock.name = 黒い岩
+block.icerock.name = 氷岩
+block.copper-wall.name = 銅の壁
+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.thorium-wall.name = トリウムの壁
+block.thorium-wall-large.name = 大きなトリウムの壁
+block.door.name = ドア
+block.door-large.name = 大きなドア
+block.duo.name = デュオ
+block.scorch.name = スコッチ
+block.hail.name = ヘイル
+block.lancer.name = ランサー
+block.conveyor.name = コンベアー
+block.titanium-conveyor.name = チタンコンベアー
+block.junction.name = ジャンクション
+block.router.name = ルーター
+block.distributor.name = ディストリビューター
+block.sorter.name = ソーター
+block.sorter.description = アイテムを分別します。設定されたアイテムを通します。異なるアイテムの場合、左右に搬出します。
+block.overflow-gate.name = オーバーフローゲート
+block.overflow-gate.description = 搬出先がいっぱいの場合に左右にアイテムを搬出します。
+block.smelter.name = 溶鉱炉
+block.arc-smelter.name = 電気式溶鉱炉
+block.silicon-smelter.name = シリコン溶鉱炉
+block.phase-weaver.name = フェーズ織機
+block.pulverizer.name = 粉砕機
+block.cryofluidmixer.name = 冷却ミキサー
+block.melter.name = 融合機
+block.incinerator.name = 焼却炉
+block.biomattercompressor.name = バイオメター圧縮機
+block.separator.name = 分離機
+block.centrifuge.name = 遠心分離機
+block.power-node.name = 電源ノード
+block.power-node-large.name = 大型電源ノード
+block.battery.name = バッテリー
+block.battery-large.name = 大型バッテリー
+block.combustion-generator.name = 火力発電機
+block.turbine-generator.name = タービン発電機
+block.mechanical-drill.name = 機械ドリル
+block.pneumatic-drill.name = 空気圧ドリル
+block.laser-drill.name = レーザードリル
+block.water-extractor.name = ウォーターポンプ
+block.cultivator.name = 耕作機
+block.alpha-mech-pad.name = アルファパッド
+block.dart-ship-pad.name = ダートパッド
+block.delta-mech-pad.name = デルタパッド
+block.javelin-ship-pad.name = ジャベリンパッド
+block.trident-ship-pad.name = トライデントパッド
+block.glaive-ship-pad.name = グライブパッド
+block.omega-mech-pad.name = オメガパッド
+block.tau-mech-pad.name = タウパッド
+block.conduit.name = パイプ
+block.mechanical-pump.name = 機械ポンプ
+block.itemsource.name = アイテムソース
+block.itemvoid.name = アイテムボイド
+block.liquidsource.name = 液体ソース
+block.powervoid.name = 電力ボイド
+block.powerinfinite.name = 無限電源
+block.unloader.name = アンローダー
+block.vault.name = ボールト
+block.wave.name = ウェーブ
+block.swarmer.name = スウォーマー
+block.salvo.name = サルボー
+block.ripple.name = リップル
+block.phase-conveyor.name = フェーズコンベアー
+block.bridge-conveyor.name = ブリッジコンベアー
+block.plastanium-compressor.name = プラスタニウムコンプレッサー
+block.pyratite-mixer.name = ピラタイトミキサー
+block.blast-mixer.name = 化合物ミキサー
+block.solidifer.name = 冷却機
+block.solar-panel.name = ソーラーパネル
+block.solar-panel-large.name = 大型ソーラーパネル
+block.oil-extractor.name = 石油抽出機
+block.spirit-factory.name = スピリットドローン製造機
+block.phantom-factory.name = ファントムドローン製造機
+block.wraith-factory.name = レースファイター製造機
+block.ghoul-factory.name = グールボンバー製造機
+block.dagger-factory.name = ダガーユニット製造機
+block.titan-factory.name = タイタンユニット製造機
+block.fortress-factory.name = フォートレスユニット製造機
+block.revenant-factory.name = レベナントファイター製造機
+block.repair-point.name = 修理ポイント
+block.pulse-conduit.name = パルスパイプ
+block.phase-conduit.name = フェーズパイプ
+block.liquid-router.name = 液体ルーター
+block.liquid-tank.name = 液体タンク
+block.liquid-junction.name = 液体ジャンクション
+block.bridge-conduit.name = ブリッジパイプ
+block.rotary-pump.name = ロータリーポンプ
+block.thorium-reactor.name = トリウムリアクター
+block.command-center.name = コマンドセンター
+block.mass-driver.name = マスドライバー
+block.blast-drill.name = エアブラシドリル
+block.thermal-pump.name = サーマルポンプ
+block.thermal-generator.name = サーマル発電機
+block.alloy-smelter.name = 合金溶鉱炉
+block.mend-projector.name = 修復プロジェクター
+block.surge-wall.name = サージの壁
+block.surge-wall-large.name = 大きなサージの壁
+block.cyclone.name = サイクロン
+block.fuse.name = ヒューズ
+block.shock-mine.name = 地雷
+block.overdrive-projector.name = 加速プロジェクター
+block.force-projector.name = 力場プロジェクター
+block.arc.name = アーク
+block.rtg-generator.name = RTG発電機
+block.spectre.name = スペクター
+block.meltdown.name = メルトダウン
+block.container.name = コンテナー
+block.core.description = ゲームで最も重要な建物です。
+team.blue.name = ブルー
+team.red.name = レッド
+team.orange.name = オレンジ
+team.none.name = グレー
+team.green.name = グリーン
+team.purple.name = パープル
+unit.alpha-drone.name = アルファドローン
+unit.spirit.name = スピリットドローン
+unit.spirit.description = 初期のユニットです。デフォルトでコアからスポーンします。自動で鉱石の採掘やブロックの修理をします。
+unit.phantom.name = ファントムドローン
+unit.phantom.description = 強化されたユニットです。自動で鉱石の採掘やブロックの修理をします。スピリットドローンよりも効率的に行います。
+unit.dagger.name = ダガー
+unit.dagger.description = 一般的な地上ユニットです。集団になると便利です。
+unit.titan.name = タイタン
+unit.titan.description = 強化された地上戦闘ユニットです。地上と空の敵の両方に攻撃します。
+unit.ghoul.name = グール爆撃機
+unit.ghoul.description = 地上爆撃機です。
+unit.wraith.name = レースファイター
+unit.wraith.description = 高速な攻撃機ユニットです。
+unit.fortress.name = フォートレス
+unit.fortress.description = 砲撃地上ユニットです。
+unit.revenant.name = レベナント
+unit.revenant.description = レーザープラットフォームです。
+tutorial.begin = ここでのミッションは[LIGHT_GRAY]敵[]を倒すことです。\n\nまずは、[accent]銅の採掘[]から始めましょう。コアの近くの銅鉱石の鉱脈をタップしましょう。
+tutorial.drill = 手動で採掘するのは非効率的です。\n[accent]ドリル[]を使えば自動で採掘できます。\n銅鉱石の鉱脈の上に1つ置いてみましょう。
+tutorial.conveyor = [accent]コンベアー[]はコアにアイテムを輸送することができます。\nドリルからコアまでコンベアー作りましょう。
+tutorial.morecopper = まだまだ銅が必要です。\n\n手動で採掘するか、ドリルをもっと設置しましょう。
+tutorial.turret = [LIGHT_GRAY]敵[]を撃退するために防衛体制を作らなければなりません。\n基地の近くにターレットのデュオを設置しましょう。
+tutorial.drillturret = デュオには弾として[accent]銅の弾薬[]が必要です。\nデュオの横にドリルを置き、採掘した銅を供給しましょう。
+tutorial.waves = [LIGHT_GRAY]敵[]が近づいてきます。\n\n2ウェーブの間、コアを守ってください。ターレットをもっと設置しましょう。
+tutorial.lead = 他の鉱石も使ってみましょう。[accent]鉛[]を見つけて、採掘しましょう。\n\nユニットからコアにドラッグして、資源を転送できます。
+tutorial.smelter = 銅を鉛はやわらかい金属です。\nより硬い[accent]高密度合金[]を溶鉱炉で作りましょう。
+tutorial.densealloy = 溶鉱炉で作った合金を回収しましょう。\n\nまた、必要に応じて効率化しましょう。
+tutorial.siliconsmelter = コアは、採掘やブロックの修復のために[accent]スピリットドローン[]を作成しています。\n\n他のユニットを作るには[accent]シリコン[]が必要です。\nシリコン溶鉱炉を作りましょう。
+tutorial.silicondrill = シリコンには[accent]石炭[]と[accent]砂[]が必要です。\nまず、ドリルを作りましょう。
+tutorial.generator = この技術には電力が必要です。\n[accent]火力発電機[]を作りましょう。
+tutorial.generatordrill = 火力発電機には燃料が必要です。\nドリルから石炭を補給しましょう。
+tutorial.node = 電力を送電する必要があります。\n火力発電機の隣に[accent]電源ノード[]を作って、電力を供給しましょう。
+tutorial.nodelink = 電力は隣接している電力ブロックや発電機、接続された状態の電源ノードを使って送電することができます。\n\nノードをタップしてから、発電機とシリコン溶鉱炉を選択して電力を繋げましょう。
+tutorial.silicon = シリコン溶鉱炉で製造したシリコンを回収しましょう。\n\nまた、効率化をすることをお勧めします。
+tutorial.daggerfactory = [accent]ダガーユニット製造機[]を作りましょう。\n\nこれを使うと攻撃ユニットを作ってくれます。
+tutorial.router = 生産機には電力が必要です。\nコンベアーから資源を分けるためにルーターを作りましょう。
+tutorial.dagger = 電源ノードを生産機に接続しましょう。\n要件が揃うと、ユニットを作り始めます。\n\n必要に応じて、ドリルや発電機、コンベアーを増やしましょう。
+tutorial.battle = [LIGHT_GRAY]敵[]のコアが見つかりました。\nユニットやダガーで破壊しましょう。
+block.copper-wall.description = 安価な防壁ブロックです。\n最初のウェーブでコアやターレットを保護するのに便利です。
+block.copper-wall-large.description = 安価な大型防壁ブロックです。\n最初のウェーブでコアやターレットを保護するのに便利です。
+block.dense-alloy-wall.description = 標準的な防壁ブロックです。\n敵からの保護に最適です。
+block.dense-alloy-wall-large.description = 標準的な大型防壁ブロックです。\n敵からの保護に最適です。
+block.thorium-wall.description = 強化された防壁ブロックです。\n敵からの保護により強固です。
+block.thorium-wall-large.description = 強化された大型防壁ブロックです。\n敵からの保護により強固です。
+block.phase-wall.description = トリウムの壁ほど強固ではないが、強力な弾でなければ弾き返すことができます。
+block.phase-wall-large.description = トリウムの壁ほど強固ではないが、強力な弾でなければ弾き返すことができます。
+block.surge-wall.description = 最も硬い防壁ブロックです。\n偶に攻撃されると敵に電撃を与えます。
+block.surge-wall-large.description = 最も硬い大型防壁ブロックです。\n偶に攻撃されると敵に電撃を与えます。
+block.door.description = 小さなドアです。タップすることで開閉することができます。\nただし、ドアが開いている場合、弾や敵も通過できます。
+block.door-large.description = 大きなドアです。タップすることで開閉することができます。\nただし、ドアが開いている場合、弾や敵も通過できます。
+block.mend-projector.description = 周辺のブロックを修復します。
+block.overdrive-projector.description = ドリルやコンベアなどの近くの施設の速度を向上させます。
+block.force-projector.description = 六角形の力場を作り出し、内部の建造物やユニットなどを守ります。
+block.shock-mine.description = 敵が踏むと、ダメージを与えます。敵には見えません。
+block.duo.description = 小さく安価なターレットです。
+block.arc.description = 小さな電撃ターレットです。敵に向かってランダムな半円状に電撃を放ちます。
+block.hail.description = 小さな砲撃ターレットです。
+block.lancer.description = チャージビームを放つ中型ターレットです。
+block.wave.description = バブルの連射攻撃をする中型ターレットです。
+block.salvo.description = 一斉に攻撃を行う中型のターレットです。
+block.swarmer.description = バーストミサイルで攻撃する中型ターレットです。
+block.ripple.description = 同時に複数ショットを発射する大型ターレットです。
+block.cyclone.description = 大型連射ターレットです。
+block.fuse.description = 短距離攻撃をする大型ターレットです。
+block.spectre.description = 一度に2発の強力な弾を撃つ大型ターレットです。
+block.meltdown.description = 強力な長距離攻撃をする大型ターレットです。
+block.conveyor.description = 一般的なアイテム輸送ブロックです。アイテムを前方に移動し、自動的にターレットや製造機などに入れます。回転できます。
+block.titanium-conveyor.description = 強化されたアイテム輸送ブロックです。通常のコンベアーよりも速くアイテムを移動します。
+block.phase-conveyor.description = 強化されたアイテム転送ブロックです。電力を使用して、離れた場所にあるフェーズコンベアーにアイテムを転送することができます。
+block.junction.description = 交差している2つのコンベアーをブリッジします。2つの異なるコンベアーが異なる場所に異なる材料を運んでいるときに便利です。
+block.mass-driver.description = 長距離の輸送が可能なアイテム輸送ブロックです。離れた別のマスドライバーにアイテムを発射します。
+block.smelter.description = 石炭を燃やして、銅と鉛から高密度合金を製錬します。
+block.arc-smelter.description = 電力を使用して銅と鉛から高密度合金を製錬します。
+block.silicon-smelter.description = 石炭と砂からシリコンを製造します。
+block.plastanium-compressor.description = オイルとチタンからプラスチナニウムを製造します。
+block.phase-weaver.description = 放射性トリウムと多量の砂からフェーズファイバーを作り出します。
+block.alloy-smelter.description = チタンや鉛、シリコン、銅からサージ合金を製造します。
+block.pulverizer.description = 石を砕いて砂にします。自然の砂がない時に便利です。
+block.pyratite-mixer.description = 石炭、鉛、砂から燃えやすいピラタイトを作成します。
+block.blast-mixer.description = 可燃性のピラタイトを石油を使用してさらに爆発性化合物にします。
+block.cryofluidmixer.description = 水とチタンから冷却に効率的な冷却水を生成します。
+block.solidifer.description = 溶岩から急速に冷やして石を生成します。
+block.melter.description = 石を高温にして溶岩を生成します。
+block.incinerator.description = 不要なアイテムや液体を焼却します。
+block.biomattercompressor.description = バイオメターを圧縮し、石油を回収します。
+block.separator.description = 石に水圧をかけて、石に含まれる様々な鉱石を回収します。
+block.centrifuge.description = 分離機よりも効率的ですが、建設費が高価で電力が必要です。
+block.power-node.description = 他のノードに接続して電気を送ります。最大で4つの電力源やノードなどに接続できます。隣接するブロックから電力を受け取ったり、電力の供給を行います。
+block.power-node-large.description = 電源ノードよりも大きく、最大で6つの電力源やノードなどに接続できます。
+block.battery.description = 電源ノード間で電力が余っていれば充電し、不足していれば供給します。
+block.battery-large.description = 通常のバッテリーより多くの電力を貯めて置くことができます。
+block.combustion-generator.description = 石油や可燃性の物質を燃やして発電します。
+block.turbine-generator.description = 火力発電機より効率的ですが、水が必要です。
+block.thermal-generator.description = 溶岩から大量の電力を発電します。
+block.solar-panel.description = 太陽光から少量の電力を発電します。
+block.solar-panel-large.description = 通常のソーラーパネルより大量の電力を発電できますが、建設費が高価です。
+block.thorium-reactor.description = 高放射性のトリウムから大量の電力を発電します。これには一定の冷却が必要です。冷却が不十分な場合大きな爆発が発生します。
+block.rtg-generator.description = トリウムリアクターよりも発電量は少ないですが、冷却を必要としない放射性同位体熱発電機(RTG)です。
+block.unloader.description = コンテナやボールト、コアからアイテムをコンベアーか隣接するブロックに搬出します。アンローダーをタップすると搬出するアイテムを変更することができます。
+block.container.description = 各種類のアイテムを少量ずつ保管します。隣接するコンテナーやボール卜、コアは一つのストレージユニットとして扱われます。 [LIGHT_GRAY]アンローダー[]を使って、コンテナーからアイテムを搬出できます。
+block.vault.description = 各種類のアイテムを大量に保管します。隣接するコンテナーやボール卜、コアは一つのストレージユニットとして扱われます。[LIGHT_GRAY]アンローダー[]を使って、ボールトからアイテムを搬出できます。
+block.mechanical-drill.description = 安価なドリルです。採掘可能な鉱脈に設置すると、アイテムを採掘して搬出します。
+block.pneumatic-drill.description = 速く採掘できるように改善されたドリルです。また、より硬い鉱石も採掘することができます。
+block.laser-drill.description = 電力を使用して、レーザー技術でより速く採掘することができます。また、このドリルで放射性トリウムを回収することができます。
+block.blast-drill.description = 高級ドリルです。大量の電力が必要です。
+block.water-extractor.description = 地面から水を汲み上げます。近くに湖がない場合に便利です。
+block.cultivator.description = 水で土壌を耕して、バイオメターを回収します。
+block.oil-extractor.description = 大量の電力を使用して、砂から石油を回収します。近くに油田がない場合に便利です。
+block.dart-ship-pad.description = 今使っている機体から一般的な戦闘機に乗り換えます。\nパッドに乗って、パッドをダブルタップすることで使用できます。
+block.trident-ship-pad.description = 今使っている機体から武装した爆撃機に乗り換えます。\nパッドに乗って、パッドをダブルタップすることで使用できます。
+block.javelin-ship-pad.description = 今使っている機体から速くて強い電撃を放つ要撃機に乗り換えます。\nパッドに乗って、パッドをダブルタップすることで使用できます。
+block.glaive-ship-pad.description = 今使っている機体から大きく、重武装された攻撃機に乗り換えます。\nパッドに乗って、パッドをダブルタップすることで使用できます。
+block.tau-mech-pad.description = 今使っている機体から仲間の建物やユニットを修復する支援型機体に乗り換えます。\nパッドに乗って、パッドをダブルタップすることで使用できます。
+block.delta-mech-pad.description = 今使っている機体から速く突撃攻撃に向いた軽装備の戦闘機に乗り換えます。\nパッドに乗って、パッドをダブルタップすることで使用できます。
+block.omega-mech-pad.description = 今使っている機体から最前線での戦いに向けた重装備の大型機体に乗り換えます。\nパッドに乗って、パッドをダブルタップすることで使用できます。
+block.spirit-factory.description = 鉱石の採掘やブロックの修復を行う軽いドローンを製造します。
+block.phantom-factory.description = スピリットドローンより効率的な強化されたドローンユニットを製造します。
+block.wraith-factory.description = 素速く、突撃攻撃が得意な戦闘ユニットを製造します。
+block.ghoul-factory.description = 重爆撃機を製造します。
+block.dagger-factory.description = 一般的な地上ユニットを製造します。
+block.titan-factory.description = 強化され武装した地上ユニットを製造します。
+block.fortress-factory.description = 地上砲撃ユニットを製造します。
+block.revenant-factory.description = 航空レーザーユニットを製造します。
+block.repair-point.description = 近くの負傷したユニットを修復します。
+block.command-center.description = 仲間のAIの動作を変更できるようにします。現在は攻撃、撤退、警戒に対応しています。
+block.conduit.description = 一般的な液体輸送ブロックです。液体版のコンベアーです。ポンプや他のパイプに使うことができます。
+block.pulse-conduit.description = 強化された液体輸送ブロックです。通常のパイプより速く多くのアイテムを輸送することができます。
+block.phase-conduit.description = 強化された液体転送ブロックです。電力を使用して、液体を他の離れたフューズコンベアーに転送することができます。
+block.liquid-router.description = 一つの方向から受け取った液体を他の3方向に搬出します。一定の量の液体を貯めておくこともできます。一つの資源から複数に分ける際に便利です。
+block.liquid-tank.description = たくさんの量の水を保管できます。需要が安定しない素材の製造時や重要な施設の冷却水の予備として使えます。
+block.liquid-junction.description = 交差している2つのコンベアーをブリッジします。2つの異なるパイプが異なる場所に異なる材料を運んでいるときに便利です。
+block.bridge-conduit.description = 高度な液体輸送ブロックです。地形や建物を超えて、3ブロック離れた場所に輸送することができます。
+block.mechanical-pump.description = 安価で性能の低いポンプです。電力が必要ありません。
+block.rotary-pump.description = 強化されたポンプです。電力を使用して2倍速く搬出します。
+block.thermal-pump.description = 高級ポンプです。機械ポンプより3倍速く、唯一溶岩を採取できるポンプです。
+block.router.description = 一つの方向から受け取ったアイテムを他の3方向に搬出します。一つの資源から複数に分ける際に便利です。
+block.distributor.description = 高度なルーターです。アイテムを7方向に均等に分けて搬出します。
+block.bridge-conveyor.description = 高度な輸送ブロックです。地形や建物を超えて、3ブロック離れた場所に輸送することができます。
+block.alpha-mech-pad.description = 電力を使用して、機体を[accent]アルファ[]機体に作り直します。
+block.itemsource.description = アイテムを無限に搬出します。サンドボックスのみ。
+block.liquidsource.description = 液体を無限に搬出します。サンドボックスのみ。
+block.itemvoid.description = 電力なしでアイテムを廃棄します。サンドボックスのみ。
+block.powerinfinite.description = 無限に電力を搬出します。サンドボックスのみ。
+block.powervoid.description = 入力されたすべての電力を破棄します。サンドボックスのみ。
+liquid.water.description = 機械の冷却や廃棄物の処理に一般的に使用されます。
+liquid.lava.description = 冷却して石にしたり、発電や一部ターレットの弾薬として使用することができます。
+liquid.oil.description = 燃焼させたり、爆発させたり、冷却水しても使えます。
+liquid.cryofluid.description = 冷却させるのに最も効率的な液体です。
diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties
index 2f4d1c04ec..54e56c5368 100644
--- a/core/assets/bundles/bundle_ko.properties
+++ b/core/assets/bundles/bundle_ko.properties
@@ -495,6 +495,7 @@ text.mech.ability = [LIGHT_GRAY]능력 : {0}
text.liquid.heatcapacity = [LIGHT_GRAY]발열량 : {0}
text.liquid.viscosity = [LIGHT_GRAY]점도 : {0}
text.liquid.temperature = [LIGHT_GRAY]온도 : {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = 적 스폰지점
block.core.name = 코어
block.metalfloor.name = 철판
@@ -624,6 +625,7 @@ 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,7 +639,6 @@ unit.phantom.name = 팬텀 드론
unit.phantom.description = 첨단 드론 유닛. 광석을 자동으로 채광하며, 아이템을 수집하고 블록을 수리합니다. 일반 드론보다 훨씬 효과적입니다.
unit.dagger.name = 귀여운 디거
unit.dagger.description = 밈의 대상으로 지정되어 이름이 바뀐 기본 지상 유닛입니다.
-## unit.dagger.description = 기본 지상 유닛입니다. 스웜과 같이 쓰면 유용합니다.
unit.titan.name = 타이탄
unit.titan.description = 고급 지상 유닛입니다. 합금을 탄약으로 사용하며 지상과 공중 둘다 공격할 수 있습니다.
unit.ghoul.name = 구울 폭격기
@@ -669,7 +670,6 @@ 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 = 합금으로 만든 벽. 구리벽보다 체력이 높습니다.
diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties
index 850ad3327e..251d4b4f07 100644
--- a/core/assets/bundles/bundle_pl.properties
+++ b/core/assets/bundles/bundle_pl.properties
@@ -370,6 +370,7 @@ setting.musicvol.name = Głośność muzyki
setting.mutemusic.name = Wycisz muzykę
setting.sfxvol.name = Głośność dźwięków
setting.mutesound.name = Wycisz dźwięki
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Zmień ustawienia przycisków
category.general.name = General
category.view.name = View
@@ -494,6 +495,7 @@ text.mech.ability = [LIGHT_GRAY]Ability: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Wytrzymałość na przegrzewanie: {0}
text.liquid.viscosity = [LIGHT_GRAY]Lepkość: {0}
text.liquid.temperature = [LIGHT_GRAY]Temperatura: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Enemy Spawn
block.core.name = Core
block.metalfloor.name = Metal Floor
diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties
index e36c930dce..b1be2af279 100644
--- a/core/assets/bundles/bundle_pt_BR.properties
+++ b/core/assets/bundles/bundle_pt_BR.properties
@@ -370,6 +370,7 @@ setting.musicvol.name = Volume da Música
setting.mutemusic.name = Desligar Música
setting.sfxvol.name = Volume de Efeitos
setting.mutesound.name = Desligar Som
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Refazer teclas
category.general.name = General
category.view.name = View
@@ -494,6 +495,7 @@ text.mech.ability = [LIGHT_GRAY]Ability: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Capacidade de aquecimento: {0}
text.liquid.viscosity = [LIGHT_GRAY]Viscosidade: {0}
text.liquid.temperature = [LIGHT_GRAY]Temperatura: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Enemy Spawn
block.core.name = Core
block.metalfloor.name = Metal Floor
diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties
index 9c4d361ef3..ebe7bf00c3 100644
--- a/core/assets/bundles/bundle_ru.properties
+++ b/core/assets/bundles/bundle_ru.properties
@@ -50,9 +50,9 @@ text.mission.main = Главная мисия:[LIGHT_GRAY] {0}
text.mission.info = Информация о миссии
text.mission.complete = Миссия выполнена!
text.mission.complete.body = Сектор {0},{1} был завоёван.
-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 = Осталось[accent] {0}[] волн из[accent] {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} []волн
text.mission.battle = Уничтожьте ядро противника.
text.mission.resource.menu = Добыть {0} х{1}
@@ -262,13 +262,12 @@ text.editor = Редактор
text.mapeditor = Редактор карт
text.donate = Донат
text.connectfail = [crimson]Не удалось подключиться к серверу: [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 = Сервер недоступен.
+text.error.invalidaddress = Некорректный адрес.
+text.error.timedout = Время ожидания истекло!\nУбедитесь, что хост настроен для перенаправления портов и адрес корректный!
+text.error.mismatch = Ошибка пакета:\nвозможное несоответствие версии клиента/сервера. \nУбедитесь, что у вас и у создателя сервера установлена последняя версия Mindustry\\!
+text.error.alreadyconnected = Вы уже подключены.
+text.error.any = Неизвестная сетевая ошибка.
text.settings.language = Язык
text.settings.reset = Сбросить по умолчанию
text.settings.rebind = Смена
@@ -370,6 +369,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 = Просмотр
@@ -434,10 +434,10 @@ item.silicon.name = Кремень
item.silicon.description = Очень полезный полупроводник с применениями в солнечных батареях и множестве сложной электроники.
item.plastanium.name = Пластиний
item.plastanium.description = Легкий, пластичный материал, используемый в современных самолетах и боеприпасах для фрагментации.
-item.phase-fabric.name = Phase Fabric
-item.phase-fabric.description = A near-weightless substance used in advanced electronics and self-repairing technology.
+item.phase-fabric.name = Фазовая ткань
+item.phase-fabric.description = Невесомое вещество, используемое в современной электронике и технологии самовосстановления.
item.surge-alloy.name = Высокопрочный сплав
-item.surge-alloy.description = An advanced alloy with unique electrical properties.
+item.surge-alloy.description = Передовой сплав с уникальными электрическими свойствами.
item.biomatter.name = Биоматерия
item.biomatter.description = Скопление органической кашки; используется для переработки в нефть или в качестве топлива.
item.sand.name = Песок
@@ -494,13 +494,14 @@ text.mech.ability = [LIGHT_GRAY]Способность: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Теплоёмкость: {0}
text.liquid.viscosity = [LIGHT_GRAY]Вязкость: {0}
text.liquid.temperature = [LIGHT_GRAY]Температура: {0}
+block.constructing = {0}\n[LIGHT_GRAY](В процессе)
block.spawn.name = Спаун врагов
block.core.name = Ядро
block.metalfloor.name = Мeталичeский пoл
block.deepwater.name = Глубоководье
block.water.name = Вода
block.lava.name = Лава
-block.tar.name = Tar
+block.tar.name = Дёготь
block.blackstone.name = Чёрный камень
block.stone.name = Камень
block.dirt.name = Земля
@@ -557,9 +558,9 @@ block.pneumatic-drill.name = Пневматический бур
block.laser-drill.name = Лазерный бур
block.water-extractor.name = Экстрактор воды
block.cultivator.name = Культиватор
-block.alpha-mech-pad.name = Завод мехов "Альфа"
-block.dart-ship-pad.name = Реконструктор дротиковых самолётов
-block.delta-mech-pad.name = Завод мехов "Дельта"
+block.alpha-mech-pad.name = Реконструктор мехов "Альфа"
+block.dart-ship-pad.name = Реконструктор кораблей "Дротик"
+block.delta-mech-pad.name = Реконструктор мехов "Дельта"
block.javelin-ship-pad.name = Реконструктор кораблей "Джавелин"
block.trident-ship-pad.name = Реконструктор кораблей "Трезубeц"
block.glaive-ship-pad.name = Реконструктор кораблей "Копьё"
@@ -623,7 +624,6 @@ block.rtg-generator.name = Радиоизотопный термоэлектри
block.spectre.name = Призрак
block.meltdown.name = Катастрофа
block.container.name = Склад
-block.core.description = Самое главное здание в игре.
team.blue.name = Синяя
team.red.name = Красная
team.orange.name = Оранжевая
@@ -668,7 +668,8 @@ tutorial.daggerfactory = Постройте[accent] завод по произв
tutorial.router = Заводы нуждаются в ресурсах для работы.\nСоздайте маршрутизатор для разделения ресурсов конвейера.
tutorial.dagger = Соедините силовой узел с заводом.\nПосле выполнения требований будет создан мех. \n\nПри необходимости создайте дополнительные буры, генераторы и конвейеры.
tutorial.battle = [LIGHT_GRAY] Враг[] показал своё ядро.\nУничтожьте его своим мехом и вашой новой боевой единицой.
-block.copper-wall.description = Стена с самым маленьким запасом прочности.\n Хороша в начале игры для защиты.
+block.core.description = Самое главное здание в игре.
+block.copper-wall.description = Дешевый оборонительный блок.\nПолезно для защиты ядра и турелей во время первых волн.
block.copper-wall-large.description = Большая стена самым маленьким запасом прочности.\n Хороша в начале игры.
block.dense-alloy-wall.description = Стена с показателем прочности "ниже среднего".
block.dense-alloy-wall-large.description = Большая стена с показателем прочности "ниже среднего".
@@ -684,7 +685,7 @@ block.mend-projector.description = Ремонтирует строения в н
block.overdrive-projector.description = Ускоряет в небольшом радиусе все ваши действия.
block.force-projector.description = Создаёт в небольшом радиусе силовое поле, которое защищает от атак противника.
block.shock-mine.description = Поставьте её на землю. Она бьётся ЭЛЕКТРИЧЕСТВОМ О_О
-block.duo.description = Хорошая турель начальная турель. Используйте стены для её зашиты.\n\nИспользует в качестве снарядов медь, плотный сплав, кремний и пиротит.\n\nМожно подвести воду и криогенную жидкость для ускорения стрельбы.
+block.duo.description = Маленькая и дешёвая турель.
block.arc.description = Турель с малым радиусом атаки. В качестве патронов требует воду или криогенную жидкость. Также нужна энергия.
block.hail.description = Дальнобойная начальная турель.\nИспользует в качестве снарядов плотный сплав, кремний и пиротит.\nДля ускорения стрельбы можно подвести воду и криогенную жидкость.
block.lancer.description = Турель, которая стреляет лазером на среднее расстояние.\nИспользует в качестве снарядов энергию.\nДля ускорения стрельбы можно подвести воду, нефть и криогенную жидкость.
@@ -727,54 +728,54 @@ block.thermal-generator.description = [accent]Горячее восприним
block.solar-panel.description = Зелёная энергия. Бесконечный источник энергии.
block.solar-panel-large.description = Зелёная энергия. Большой и бесконечный источник энергии.
block.thorium-reactor.description = Производит энергию в большом количестве. Может взорваться. Требуется торий и жидкость для охлаждения (вода или криогенная).
-block.rtg-generator.description = A radioisotope thermoelectric generator which does not require cooling but provides less power than a thorium reactor.
+block.rtg-generator.description = Радиоизотопный термоэлектрический генератор, который не требует охлаждения, но обеспечивает меньшую мощность, чем ториевый реактор.
block.unloader.description = Выгружает из ядра или хранилища верхний левый предмет.
-block.container.description = Может хранить 500 ед. ресурсов. С помощью разгрузчика можно достать ресурсы из него.
-block.vault.description = Хранит предметы в количестве до 2 000.
-block.mechanical-drill.description = Самый первый доступный бур. Добывает медь, свинец, уголь, песок. Можно подвести к нему [BLUE] воду[] для увеличения скорости сверления.
+block.container.description = Хранит небольшое количество предметов(250). Используйте его для создания буферов, когда существует непостоянная потребность в материалах. [LIGHT_GRAY] Разгрузчик[] можно использовать для извлечения элементов из хранилища.
+block.vault.description = Хранит большое количество предметов(1000). Используйте его для создания буферов, когда существует непостоянная потребность в материалах.[LIGHT_GRAY] Разгрузчик[] можно использовать для извлечения элементов из хранилища.
+block.mechanical-drill.description = Самый первый доступный бур. \n\nДобывает медь, свинец, уголь, песок. \n\nМожно подвести к нему [BLUE] воду[] для увеличения скорости сверления.
block.pneumatic-drill.description = Улучшенная версия механического бура.\n\nДобывает тоже самое, что и механический бур. Также может добывать титан и камень.\n\nМожно подвести к нему[BLUE] воду[] для увеличения скорости сверления.
block.laser-drill.description = Улучшенная версия пневматического бура.\n\nДобывает тоже самое, что и пневматический бур. Также может добывать торий.\n\nМожно подвести к нему[BLUE] воду[] для увеличения скорости сверления.
-block.blast-drill.description = Самый мощный бур.\n\n Добывает тоже самое, что и лазерный бур. Сверлит быстрей всех буров, но требует ещё больше энергии.\n\n Можно подвести к нему [BLUE]воду[] для увеличения скорости сверления.
-block.water-extractor.description = Добывает воду из земли. Требует Энергию.
-block.cultivator.description = Производит биоматерию из травы и воды. Требует энергии.
-block.oil-extractor.description = Производит нефть из динозавров(зачёркнуто), воды и песка. Требует энергии.
-block.dart-ship-pad.description = Превращает вас в дротиковый самолёт. Реконструктор требует энергию.\nПодробности про дротиковых самолётов в "разблокированное".
-block.trident-ship-pad.description = Превращает вас в Трезубeц. Реконструктор требует энергию.\nПодробности про Трезубeц в "разблокированное".
-block.javelin-ship-pad.description = Превращает вас в Джавелин. Реконструктор требует энергию.\nПодробности про Джавелин в "разблокированное".
+block.blast-drill.description = Самый мощный бур.\n\nДобывает тоже самое, что и лазерный бур. Сверлит быстрей всех буров, но требует ещё больше энергии.\n\nМожно подвести к нему [BLUE]воду[] для увеличения скорости сверления.
+block.water-extractor.description = Извлекает воду из земли. Используйте его, когда поблизости нет озера.
+block.cultivator.description = Культирует почву водой для получения биоматерии.
+block.oil-extractor.description = Использует большое количество энергии для добычи нефти из песка, динозавров(зачёркнуто). Используйте его, когда поблизости нет прямого источника нефти.
+block.dart-ship-pad.description = Оставьте свое текущее судно и перейдите на основной истребитель.\nИспользуйте двойное нажатие, стоя на реконструкторе, чтобы превратиться в этот мех.
+block.trident-ship-pad.description = Оставьте свой текущий корабль и перейдите в достаточно хорошо бронированный тяжёлый бомбардировщик.\nИспользуйте двойное нажатие, стоя на реконструкторе, чтобы превратиться в этот мех.
+block.javelin-ship-pad.description = Оставьте свой текущий корабль и перейдите в сильный и быстрый перехватчик с молниеносным оружием.\nИспользуйте двойное нажатие, стоя на реконструкторе, чтобы превратиться в этот мех.
block.glaive-ship-pad.description = Превращает вас в Копьё. Реконструктор требует энергию.\nПодробности про Копьё в "разблокированное".
-block.tau-mech-pad.description = Превращает вас в Тау. Реконструктор требует энергию.\nПодробности про Тау в "разблокированное".
-block.delta-mech-pad.description = Превращает вас в "Дельта". Реконструктор требует энергию.\nПодробности про "Дельта" в "разблокированное".
-block.omega-mech-pad.description = Превращает вас в Омега. Реконструктор требует энергию.\nПодробности про Омега в "разблокированное".
-block.spirit-factory.description = Производит дронов типа "призрак"
-block.phantom-factory.description = Производит дронов типа "фантом"\nПодробности в "разблокированное"
-block.wraith-factory.description = Производит призрачных истребителей\nПодробности в "разблокированное"
-block.ghoul-factory.description = Производит гулевых бомбардировщиков\nПодробности в "разблокированное"
-block.dagger-factory.description = Производит\nПодробности в "разблокированное"
-block.titan-factory.description = Производит мехов типа "Титан".\nПодробности в "разблокированное"
-block.fortress-factory.description = Огромный медленный мех обладающий такой-же огромной пушкой.
-block.revenant-factory.description = Производит бомбардировщиков типа "Потусторонний убийца"\nПодробности в "разблокированное"
+block.tau-mech-pad.description = Покиньте свой текущий корабль и превратитесь в мех поддержки, который может исцелять дружественные здания и юниты.\nИспользуйте двойное нажатие, стоя на реконструкторе, чтобы превратиться в этот мех.
+block.delta-mech-pad.description = Оставьте свой текущий корабль и перейдите в большой, хорошо бронированный боевой корабль.\nИспользуйте двойное нажатие, стоя на реконструкторе, чтобы превратиться в этот мех.
+block.omega-mech-pad.description = Оставьте свой текущий корабль и превратите его в громоздкий и хорошо бронированный мех, сделанный для фронтовых нападений. \nИспользуйте двойное нажатие, стоя на реконструкторе, чтобы превратиться в этот мех.
+block.spirit-factory.description = Производит легкие дроны, которые добывают руду(медную и свинцовую) и ремонтирует блоки.
+block.phantom-factory.description = Производит усовершенствованные единицы, которые значительно эффективнее, чем дрон-привидение.
+block.wraith-factory.description = Производит быстрые и летающие боевые единицы.
+block.ghoul-factory.description = Производит тяжёлых ковровых бомбардировщиков.
+block.dagger-factory.description = Производит основных наземных боевых единиц.
+block.titan-factory.description = Производит продвинутые защищённые боевые единицы.
+block.fortress-factory.description = Производит тяжелые артиллерийские боевые единицы.
+block.revenant-factory.description = Производит тяжелые наземные боевые единицы.
block.repair-point.description = Может ремонтировать вас и ваши боевые единицы
-block.command-center.description = Позволяет управлять боевыми единицами.\nСтрелочка - атаковать\nЩит - отступать.
-block.conduit.description = Конвейер для жидкостей первого поколения. Медленная скорость передачи жидкости.
-block.pulse-conduit.description = Конвейер для жидкостей второго поколения.
-block.phase-conduit.description = Лучший трубопровод, требует энергию. Похоже, он из будущего.
-block.liquid-router.description = Распределяет жидкость на 4 стороны.
-block.liquid-tank.description = Хранит жидкость.
-block.liquid-junction.description = Название говорит само за себя. С помощью него можно сделать две трубы, которые проходят через друг-друга и не смешиваются.
-block.bridge-conduit.description = Позволяет проходить над возвышенностями(блоками). Лучше всего подключать последовательно и в линию.
-block.mechanical-pump.description = Качает только воду.
-block.rotary-pump.description = Качает воду и нефть. Требует энергии.
-block.thermal-pump.description = Позволяет качать лаву, воду и нефть.
-block.router.description = Принимает предметы из одного направления и равномерно выводит их до трех других направлений. Полезно для разделения материалов из одного источника на несколько целей.
-block.distributor.description = Продвинутый маршрутизатор, который равномерно разбивает элементы до 7 направлений.
-block.bridge-conveyor.description = Продвинутый транспортный блок элемента. Позволяет транспортировать предметы до 3-х плиток любого ландшафта или здания.
-block.alpha-mech-pad.description = Превращает вас в "Альфа". Требует энергию.\n Подробности про "Альфа" в "разблокированное".
-block.itemsource.description = Из этого блока можно получить любой предмет.
-block.liquidsource.description = Из этого блока можно получить любую жидкость.
-block.itemvoid.description = Предметы просто уходят в пустоту
-block.powerinfinite.description = Бесконечность — не предел.
-block.powervoid.description = Жидкости просто уходят в пустоту
+block.command-center.description = Позволяет изменять дружественное поведение ИИ. В настоящее время поддерживаются команды атаки, отступления и патрулирования.
+block.conduit.description = Основной блок транспортировки жидкости. Работает как конвейер, но с жидкостями. Лучше всего использовать экстракторы, насосы или т.п..
+block.pulse-conduit.description = Улучшенный блок транспортировки жидкости. Транспортирует жидкости быстрее и хранит больше, чем стандартные.
+block.phase-conduit.description = Улучшенный блок транспортировки жидкости. Использует энергию для передачи жидкостей на подключенный фазовый канал на несколько плиток.
+block.liquid-router.description = Принимает жидкости с одного направления и равномерно выводит их до трех других направлений. Может также хранить определенное количество жидкости. Полезно для разделения жидкостей из одного источника на несколько целей.
+block.liquid-tank.description = Хранит большое количество жидкостей. Используйте его для создания буферов, когда существует непостоянная потребность в материалах или в качестве защиты для охлаждения жизненно важных блоков.
+block.liquid-junction.description = Действует как мост для двух пересекающихся каналов. Полезно в ситуациях с двумя различными каналами, перевозящими различные жидкости в разные места.
+block.bridge-conduit.description = Расширенный блок транспортировки жидкости. Позволяет транспортировать жидкости до 3 блоков любого ландшафта или здания. Лучше всего подключать последовательно и в линию.
+block.mechanical-pump.description = Дешевый насос с медленным выкачиванием, но без потребления энергии. Качает только воду.
+block.rotary-pump.description = Передовой насос, который удваивает скорость, используя энергию.
+block.thermal-pump.description = Конечный насос. В три раза быстрее, чем механический насос и единственный насос, который способен извлекать лаву.
+block.router.description = Принимает предметы из одного направления и равномерно выводит их до трёх других направлений. Полезно для разделения материалов из одного источника на несколько целей.
+block.distributor.description = Передовой маршрутизатор, который равномерно разбивает элементы до 7 других направлений.
+block.bridge-conveyor.description = Улучшенный транспортный блок элементов. Позволяет транспортировать предметы до 3-х блоков над любым ландшафтом или зданием.
+block.alpha-mech-pad.description = Превращает вас в мех [accent] Альфа[]. Требует энергию.
+block.itemsource.description = Бесконечно выводит предметы. Работает только в песочнице.
+block.liquidsource.description = Бесконечно выводит жидкости. Работает только в песочнице.
+block.itemvoid.description = Уничтожает любые предметы, которые входят в него, без использования энергии. Работает только в песочнице.
+block.powerinfinite.description = Бесконечность — не предел. Бесконечно выводит энергию. Доступен только в песочнице.
+block.powervoid.description = Энергия просто уходит в пустоту. Присутствует только в песочнице.
liquid.water.description = Намного лучше чем [BLUE]монооксид дигидрогена[].\n\n Для получения воды используйте помпу(насос) на источнике(блоке) или экстрактор воды.\n\n Эту жидкость можно подвести к бурам для ускорения скорости добычи или к турелям для ускорения стрельбы.
liquid.lava.description = [accent]Горячо...\nВещество расплавленное из горно-каменных пород.\nСлужит как топливо для термального генератора.
-liquid.oil.description = Кто-то писал о добавлении золота в игру. Его добавили, правда оно какое-то чёрное...\nСмесь жидких углеводородов, выделяющаяся из природного газа в результате снижения температуры и пластового давления.\nСлужит для пластиенивого компрессора и т.д..
+liquid.oil.description = Кто-то писал о добавлении золота в игру. Его добавили, правда оно какое-то чёрное...\nСмесь жидких углеводородов, выделяющаяся из природного газа в результате снижения температуры и пластового давления.\nСлужит для пластиниевого компрессора и т.д..
liquid.cryofluid.description = Жидкость с температурой ниже чем -273 градусов по цельсию. Может быть использована для ускорения стрельбы турелей или для охлаждения чего-то.
diff --git a/core/assets/bundles/bundle_tk.properties b/core/assets/bundles/bundle_tk.properties
index ece71c0b5d..9bee717114 100644
--- a/core/assets/bundles/bundle_tk.properties
+++ b/core/assets/bundles/bundle_tk.properties
@@ -370,6 +370,7 @@ setting.musicvol.name = Ses yuksekligi
setting.mutemusic.name = Sesi kapat
setting.sfxvol.name = Ses seviyesi
setting.mutesound.name = Sesi kapat
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Tuslari ayarla
category.general.name = General
category.view.name = Goster
@@ -494,6 +495,7 @@ text.mech.ability = [LIGHT_GRAY]yetenek gucu: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]isinma kapasitesi: {0}
text.liquid.viscosity = [LIGHT_GRAY]Yari sivilik: {0}
text.liquid.temperature = [LIGHT_GRAY]isi: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Enemy Spawn
block.core.name = cekirdek
block.metalfloor.name = metal zemin
diff --git a/core/assets/bundles/bundle_tr.properties b/core/assets/bundles/bundle_tr.properties
index 68df10afd4..0a26b33e6d 100644
--- a/core/assets/bundles/bundle_tr.properties
+++ b/core/assets/bundles/bundle_tr.properties
@@ -370,6 +370,7 @@ setting.musicvol.name = Müzik sesi
setting.mutemusic.name = Müziği Kapat
setting.sfxvol.name = SFX Hacmi
setting.mutesound.name = Sesi kapat
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Tuşları yeniden ayarla
category.general.name = General
category.view.name = View
@@ -494,6 +495,7 @@ text.mech.ability = [LIGHT_GRAY]Ability: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Heat Capacity: {0}
text.liquid.viscosity = [LIGHT_GRAY]Viscosity: {0}
text.liquid.temperature = [LIGHT_GRAY]Temperature: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Enemy Spawn
block.core.name = Core
block.metalfloor.name = Metal Floor
diff --git a/core/assets/bundles/bundle_uk_UA.properties b/core/assets/bundles/bundle_uk_UA.properties
index 95630c8669..b119182495 100644
--- a/core/assets/bundles/bundle_uk_UA.properties
+++ b/core/assets/bundles/bundle_uk_UA.properties
@@ -370,6 +370,7 @@ setting.musicvol.name = Гучність музики
setting.mutemusic.name = Заглушити музику
setting.sfxvol.name = Гучність звукових ефектів
setting.mutesound.name = Заглушити звук
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = Налаштування управління
category.general.name = Основне
category.view.name = Перегляд
@@ -494,6 +495,7 @@ text.mech.ability = [LIGHT_GRAY]Здібність: {0}
text.liquid.heatcapacity = [LIGHT_GRAY]Теплоємність: {0}
text.liquid.viscosity = [LIGHT_GRAY]В'язкість: {0}
text.liquid.temperature = [LIGHT_GRAY]Температура: {0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
block.spawn.name = Спавн ворога
block.core.name = Ядро
block.metalfloor.name = Металічна підлога
diff --git a/core/assets/bundles/bundle_zh_CN.properties b/core/assets/bundles/bundle_zh_CN.properties
index 2e6526dd68..1a539ca3fc 100644
--- a/core/assets/bundles/bundle_zh_CN.properties
+++ b/core/assets/bundles/bundle_zh_CN.properties
@@ -12,7 +12,7 @@ text.linkfail = 打开链接失败!\nURL 已经复制到剪贴板。
text.editor.web = 网页版不支持地图编辑器!\n下载以使用编辑器。
text.web.unsupported = 网页版不支持此功能,请下载以使用此功能。
text.gameover = 你的核心被摧毁了!
-text.gameover.pvp = The[accent] {0}[] team is victorious!
+text.gameover.pvp = accent] {0}[] 队获胜!
text.sector.gameover = 这个区域失守了,要重新部署吗?
text.sector.retry = 重试
text.highscore = [accent]新纪录!
@@ -39,32 +39,32 @@ text.sectors = 区域
text.sector = 区域: [LIGHT_GRAY]{0}
text.sector.time = 时间: [LIGHT_GRAY]{0}
text.sector.deploy = 部署
-text.sector.abandon = Abandon
-text.sector.abandon.confirm = Are you sure you want to abandon all progress at this sector?\nThis cannot be undone!
+text.sector.abandon = 放弃
+text.sector.abandon.confirm = 你确定要放弃这个区域的所有进展吗?\n此操作不可撤销!
text.sector.resume = 继续
text.sector.locked = [scarlet][[Incomplete]
text.sector.unexplored = [accent][[Unexplored]
-text.missions = Missions:[LIGHT_GRAY] {0}
+text.missions = 任务:[LIGHT_GRAY] {0}
text.mission = 任务[LIGHT_GRAY] {0}
-text.mission.main = Main Mission:[LIGHT_GRAY] {0}
-text.mission.info = Mission Info
+text.mission.main = 主要任务:[LIGHT_GRAY] {0}
+text.mission.info = 任务信息
text.mission.complete = 任务完成!
text.mission.complete.body = 区域 {0},攻占了 {1} 个
-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
+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} []波
text.mission.battle = 摧毁敌方基地。
-text.mission.resource.menu = Obtain {0} x{1}
-text.mission.resource = 获得 {0}:\n[accent]{1}/{2}[]
-text.mission.block = Create {0}
-text.mission.unit = Create {0} Unit
-text.mission.command = Send Command {0} To Units
-text.mission.linknode = Link Power Node
-text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0}
-text.mission.mech = Switch to mech[accent] {0}[]
-text.mission.create = Create[accent] {0}[]
-text.none =
+text.mission.resource.menu = 获取{0}x{1}
+text.mission.resource = 获取{0}︰\n[accent]{1}/{2}[]
+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 = 转换至[accent]{0}[]机甲
+text.mission.create = 制造[accent] {0}[]
+text.none = <无>
text.close = 关闭
text.quit = 退出
text.maps = 地图
@@ -73,30 +73,30 @@ text.nextmission = 下一个任务
text.maps.none = [LIGHT_GRAY]未发现地图!
text.about.button = 关于
text.name = 名字:
-text.filename = File Name:
-text.unlocked = 新方块解锁!
-text.unlocked.plural = 新方块解锁!
+text.filename = 文件名:
+text.unlocked = 新方块已解锁!
+text.unlocked.plural = 新方块已解锁!
text.players = {0} 玩家在线
text.players.single = {0} 玩家在线
-text.server.closing = [accent]正在关闭服务器...
-text.server.kicked.kick = 你被踢出服务器了!
-text.server.kicked.serverClose = 服务器已关闭
-text.server.kicked.sectorComplete = 区域已完成
+text.server.closing = [accent]正在关闭服务器……
+text.server.kicked.kick = 你被踢出服务器了!
+text.server.kicked.serverClose = 服务器已关闭。
+text.server.kicked.sectorComplete = 区域已完成。
text.server.kicked.sectorComplete.text = 任务已完成。\n服务器将在下一个区域继续。
text.server.kicked.clientOutdated = 客户端版本过旧!请升级!
text.server.kicked.serverOutdated = 服务器版本过旧!请联系房主升级!
text.server.kicked.banned = 你被这个服务器拉黑了。
-text.server.kicked.recentKick = 你刚刚被踢出服务器\n请稍后再重新连接!
-text.server.kicked.nameInUse = 服务器中已经\n有相同的名字了。
+text.server.kicked.recentKick = 你刚刚被踢出服务器。\n请稍后重新连接!
+text.server.kicked.nameInUse = 服务器中已经\n有人有相同的名字了。
text.server.kicked.nameEmpty = 你的名字必须至少包含一个字母或数字。
-text.server.kicked.idInUse = 你已经在服务器中了!不允许用两个账号。
-text.server.kicked.customClient = 这个服务器不支持修改版连接,请下载官方版本。
-text.host.info = [accent]创建局域网游戏[] 按钮会在 [scarlet]6567[] 端口运行一个服务器并且 [scarlet]6568.[]\n任何在同一个 [LIGHT_GRAY]wifi或本地网络[] 下的人都将在服务器列表中看到你的服务器。\n\n如果你想让别人在任何地方都能通过ip地址连接, 那么需要[accent]端口转发[]。\n\n[LIGHT_GRAY]请注意:如果某人无法连接到你的局域网游戏,请确保你在防火墙设置里允许了 Mindustry 连接本地网络。
-text.join.info = 你可以在这里输入[accent]服务器的IP地址[]以连接,或寻找[accent]本地网络[]中的服务器以连接。\n支持局域网或广域网多人游戏。\n\n[LIGHT_GRAY]请注意:没有全球服务器列表;如果你想通过IP地址连接某个服务器,你需要向房主询问IP地址。
-text.hostserver = 服务器
-text.hostserver.mobile = Host\nGame
-text.host = 创建服务器
-text.hosting = [accent]正在打开服务器...
+text.server.kicked.idInUse = 你已经在服务器中!不允许用两个账号。
+text.server.kicked.customClient = 这个服务器不支持修改版客户端,请下载官方版本。
+text.host.info = [accent]创建局域网游戏[]按钮会在[scarlet]6567[]端口运行一个服务器。[]\n任何在同一个[LIGHT_GRAY]网络或本地网络[]下的人都将在服务器列表中看到你的服务器。\n\n如果你想让别人在任何地方都能通过IP地址连接,你需要设定[accent]端口转发[]。\n\n[LIGHT_GRAY]请注意:如果某人无法连接到你的局域网游戏,请确保你在防火墙设置里允许了Mindustry连接本地网络。
+text.join.info = 你可以在这里输入[accent]服务器的IP地址[]以连接,或寻找[accent]本地网络[]中的服务器以连接。\n目前支持局域网或广域网多人游戏。\n\n[LIGHT_GRAY]请注意:没有全球服务器列表;如果你想通过IP地址连接某个服务器,你需要向房主询问IP地址。
+text.hostserver = 创建服务器
+text.hostserver.mobile = 创建\n服务器
+text.host = 创建
+text.hosting = [accent]正在打开服务器……
text.hosts.refresh = 刷新
text.hosts.discovering = 正在搜索局域网服务器
text.server.refreshing = 正在刷新服务器
@@ -105,64 +105,64 @@ text.host.invalid = [scarlet]无法连接服务器。
text.trace = 跟踪玩家
text.trace.playername = 玩家名字: [accent]{0}
text.trace.ip = IP地址: [accent]{0}
-text.trace.id = ID: [accent]{0}
+text.trace.id = ID︰[accent]{0}
text.trace.android = 安卓客户端: [accent]{0}
text.trace.modclient = 修改版客户端: [accent]{0}
text.trace.totalblocksbroken = 总共破坏了 [accent]{0} 个方块。
-text.trace.structureblocksbroken = 总共破坏了 [accent]{0} 个结构。
+text.trace.structureblocksbroken = 总共破坏了[accent]{0}个方块。
text.trace.lastblockbroken = 最后破坏的方块: [accent]{0}
text.trace.totalblocksplaced = 总共放置了 [accent]{0} 个方块。
text.trace.lastblockplaced = 最后放置的方块: [accent]{0}
-text.invalidid = 无效的客户端ID!请提交 bug 报告。
+text.invalidid = 无效的客户端ID!请提交错误报告。
text.server.bans = 黑名单
text.server.bans.none = 没有被拉黑的玩家!
text.server.admins = 管理员
text.server.admins.none = 没有管理员!
text.server.add = 添加服务器
text.server.delete = 确定要删除这个服务器吗?
-text.server.hostname = 主机: {0}
+text.server.hostname = 主机︰{0}
text.server.edit = 编辑服务器
text.server.outdated = [crimson]服务器过旧![]
text.server.outdated.client = [crimson]客户端过旧![]
text.server.version = [lightgray]版本: {0}
text.server.custombuild = [yellow]修改版
-text.confirmban = 确认拉黑这个玩家?
-text.confirmkick = 您确定要删除此播放器吗?
+text.confirmban = 确认拉黑这个玩家吗?
+text.confirmkick = 您确定要踢出这个玩家吗?
text.confirmunban = 确认要取消拉黑这个玩家吗?
text.confirmadmin = 确认要添加这个玩家为管理员吗?
text.confirmunadmin = 确认要取消这个玩家的管理员身份吗?
text.joingame.title = 加入游戏
-text.joingame.ip = IP:
+text.joingame.ip = IP:
text.disconnect = 已断开
text.disconnect.data = 载入世界失败!
-text.connecting = [accent]连接中...
-text.connecting.data = [accent]加载世界中...
-text.server.port = 端口:
+text.connecting = [accent]连接中……
+text.connecting.data = [accent]加载世界中……
+text.server.port = 端口︰
text.server.addressinuse = 地址已经使用!
text.server.invalidport = 无效的端口!
text.server.error = [crimson]创建服务器错误:[accent]{0}
text.save.old = 这个存档属于旧版本游戏,无法继续使用了。\n\n[LIGHT_GRAY]存档向下兼容将在 4.0 版本中实现。
text.save.new = 新存档
-text.save.overwrite = 确认要\n覆盖这个存档吗?
+text.save.overwrite = 确认要覆盖这个存档吗?
text.overwrite = 覆盖
text.save.none = 没有存档!
-text.saveload = [accent]保存中...
+text.saveload = [accent]保存中……
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.fail = [crimson]导入存档失败:[accent]{0}
+text.save.export.fail = [crimson]导出存档失败:[accent]{0}
text.save.import = 导入存档
text.save.newslot = 保存游戏:
text.save.rename = 重命名
text.save.rename.text = 新名字:
-text.selectslot = 选择一个存档
+text.selectslot = 选择一个存档。
text.slot = [accent]存档 {0}
text.save.corrupted = [accent]存档损坏或无效!\n如果你刚刚升级了游戏,那么这可能是因为存档格式改变了而[scarlet]不是[] bug 。
text.sector.corrupted = [accent]发现了一个此区域的保存文件,但是加载失败。\n已经创建了一个新的。
-text.empty =
+text.empty = <空>
text.on = 开
text.off = 关
text.save.autosave = 自动保存:{0}
@@ -187,14 +187,14 @@ text.changelog.error.ios = [accent]iOS还不支持更新日志。
text.changelog.error = [scarlet]获取更新日志失败!\n请检查你的网络。
text.changelog.current = [yellow][[Current version]
text.changelog.latest = [accent][[Latest version]
-text.loading = [accent]加载中...
-text.saving = [accent]保存中...
+text.loading = [accent]加载中……
+text.saving = [accent]保存中……
text.wave = [accent]第 {0} 波
text.wave.waiting = 下一波将在 {0} 秒后到来
-text.waiting = 等待中...
-text.waiting.players = Waiting for players...
-text.wave.enemies = [LIGHT_GRAY]{0} Enemies Remaining
-text.wave.enemy = [LIGHT_GRAY]{0} Enemy Remaining
+text.waiting = 等待中……
+text.waiting.players = 等待玩家中……
+text.wave.enemies = 剩下 [LIGHT_GRAY]{0} 敌人
+text.wave.enemy = 剩下 [LIGHT_GRAY]{0} 敌人
text.loadimage = 加载图片
text.saveimage = 保存图片
text.unknown = 未知
@@ -203,7 +203,7 @@ text.builtin = 内建的
text.map.delete.confirm = 确认要删除地图吗?这个操作无法撤销!
text.map.random = [accent]随机地图
text.map.nospawn = 这个地图没有核心!请在编辑器中添加一个[ROYAL]蓝色[]的核心。
-text.map.nospawn.pvp = This map does not have any enemy cores for player to spawn into! Add[SCARLET] red[] cores to this map in the editor.
+text.map.nospawn.pvp = 这个地图没有敌人的核心!请在编辑器中添加一个[ROYAL]红色[]的核心。
text.map.invalid = 地图载入错误:地图文件可能已经损坏。
text.editor.brush = 笔刷
text.editor.slope = \\
@@ -226,14 +226,14 @@ text.editor.saved = 已保存!
text.editor.save.noname = 你的地图还没有名字!在“地图信息”菜单里设置一个名字。
text.editor.save.overwrite = 你的地图覆盖了一个内建的地图!在“地图信息”菜单里重新设置一个。
text.editor.import.exists = [scarlet]无法导入:[] 一个叫 '{0}' 的内建地图已经存在。
-text.editor.import = 导入...
+text.editor.import = 导入……
text.editor.importmap = 导入地图
text.editor.importmap.description = 导入一个已经存在的地图
text.editor.importfile = 导入文件
text.editor.importfile.description = 导入一个外置的地图文件
text.editor.importimage = 导入地形图像
text.editor.importimage.description = 导入外置地图图像文件
-text.editor.export = 导出...
+text.editor.export = 导出……
text.editor.exportfile = 导出文件
text.editor.exportfile.description = 导出一个地图文件
text.editor.exportimage = 导出一个地形文件
@@ -262,13 +262,13 @@ text.editor = 编辑器
text.mapeditor = 地图编辑器
text.donate = 捐赠
text.connectfail = [crimson]服务器连接失败: [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 = 服务器无法访问。
+text.error.invalidaddress = 地址无效。
+text.error.timedout = 连接超时!\n确保服务器设置了端口转发,并且地址正确!
+text.error.mismatch = 包错误:\n可能是客户端/服务器版本不匹配.\n请确保客户端和服务器都是最新的版本!
+text.error.alreadyconnected = 已连接。
+text.error.mapnotfound = 找不到地图文件!
+text.error.any = 未知网络错误.
text.settings.language = 语言
text.settings.reset = 恢复默认
text.settings.rebind = 重新绑定
@@ -276,11 +276,11 @@ text.settings.controls = 控制
text.settings.game = 游戏
text.settings.sound = 声音
text.settings.graphics = 图像
-text.settings.cleardata = 清除游戏数据...
-text.settings.clear.confirm = 您确定要清除此数据吗?\n你无法撤销这个!
-text.settings.clearall.confirm = [scarlet]报警![]\n这将清除所有数据,包括已保存,解锁和见帮定.\n按“OK”后,游戏将删除所有并自动推出.
-text.settings.clearsectors = 清楚任务
-text.settings.clearunlocks = 清除未锁定的快
+text.settings.cleardata = 清除游戏数据……
+text.settings.clear.confirm = 您确定要清除数据吗?\n这个操作无法撤销!
+text.settings.clearall.confirm = [scarlet]警告![]\n这将清除所有数据,包括存档、地图、解锁和键绑定。\n按「是」后,游戏将删除所有数据并自动退出。
+text.settings.clearsectors = 清除区域
+text.settings.clearunlocks = 清除解锁
text.settings.clearall = 清除所有
text.paused = 暂停
text.yes = 是
@@ -303,27 +303,27 @@ text.blocks.powerdamage = 功率/损伤
text.blocks.inputitemcapacity = 最大输入
text.blocks.outputitemcapacity = 最大输出
text.blocks.itemcapacity = 物品容量
-text.blocks.basepowergeneration = Base Power Generation
+text.blocks.basepowergeneration = 基础能源输出
text.blocks.powertransferspeed = 能量传输
text.blocks.craftspeed = 生产速度
-text.blocks.inputliquid = 输入液体
-text.blocks.inputliquidaux = Aux 液体
-text.blocks.inputitem = 输入物品
-text.blocks.inputitems = 输入物品
-text.blocks.outputitem = 输出物品
+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.liquiduse = 液体使用速度
text.blocks.coolant = 冷却剂
-text.blocks.coolantuse = 使用冷却剂
-text.blocks.inputliquidfuel = 使用燃料
-text.blocks.liquidfueluse = 使用液体燃料
-text.blocks.explosive = 高度易燃易爆!
+text.blocks.coolantuse = 冷却剂使用速度
+text.blocks.inputliquidfuel = 液体燃料输入
+text.blocks.liquidfueluse = 液体燃料使用速度
+text.blocks.explosive = 易爆炸!
text.blocks.health = 生命值
text.blocks.inaccuracy = 误差
-text.blocks.shots = 发射
+text.blocks.shots = 发射数
text.blocks.reload = 重新装弹
text.blocks.inputfuel = 燃料
text.blocks.fuelburntime = 燃料燃烧时间
@@ -343,18 +343,18 @@ text.category.general = 普通
text.category.power = 能量
text.category.liquids = 液体
text.category.items = 物品
-text.category.crafting = 制造速度
-text.category.shooting = 射速
-setting.autotarget.name = Auto-Target
+text.category.crafting = 制造
+text.category.shooting = 发射
+setting.autotarget.name = 自动发射
setting.fpscap.name = 最高 FPS
-setting.fpscap.none = None
+setting.fpscap.none = 无
setting.fpscap.text = {0} FPS
-setting.difficulty.training = training
+setting.difficulty.training = 训练
setting.difficulty.easy = 简单
setting.difficulty.normal = 普通
setting.difficulty.hard = 困难
setting.difficulty.insane = 疯狂
-setting.difficulty.name = 难度:
+setting.difficulty.name = 难度:
setting.screenshake.name = 屏幕抖动
setting.effects.name = 显示效果
setting.sensitivity.name = 控制器灵敏度
@@ -370,17 +370,18 @@ setting.musicvol.name = 音乐音量
setting.mutemusic.name = 静音
setting.sfxvol.name = 音效音量
setting.mutesound.name = 静音
+setting.crashreport.name = 发送匿名崩溃报告
text.keybind.title = 重新绑定按键
category.general.name = 普通
category.view.name = 查看
category.multiplayer.name = 多人
-command.attack = Attack
-command.retreat = Retreat
-command.patrol = Patrol
-keybind.press = 按一下键...
-keybind.press.axis = 按轴或键...
-keybind.move_x.name = X轴移动
-keybind.move_y.name = Y轴移动
+command.attack = 攻击
+command.retreat = 撤退
+command.patrol = 巡逻
+keybind.press = 按一下键……
+keybind.press.axis = 按一下轴或键……
+keybind.move_x.name = 水平移动
+keybind.move_y.name = 垂直移动
keybind.select.name = 选择
keybind.break.name = 破坏
keybind.deselect.name = 取消
@@ -405,47 +406,47 @@ mode.waves.name = 普通
mode.waves.description = 普通模式,有限的资源和自动生成敌人。
mode.sandbox.name = 沙盒
mode.sandbox.description = 无限的资源,不会自动生成敌人。
-mode.custom.warning = 请注意,在区域内解锁之前,区块不能用于自定义游戏.\n\n[LIGHT_GRAY]如果您没有解锁任何块,则不会出现任何块.
-mode.custom.warning.read = Just to make sure you've read it:\n[scarlet]UNLOCKS IN CUSTOM GAMES DO NOT CARRY OVER TO SECTORS OR OTHER MODES!\n\n[LIGHT_GRAY](I wish this wasn't necessary, but apparently it is)
+mode.custom.warning = 请注意,方块在区域内解锁之前,不能用于自定义游戏。\n\n[LIGHT_GRAY]如果您没有解锁任何方块,则不会出现任何方块。
+mode.custom.warning.read = 确保你已经阅读过它:\n[scarlet]自定义游戏的解锁不带至区域或其他模式!\n\n[LIGHT_GRAY](我希望这不是必要的,但显然是必要的)
mode.freebuild.name = 自由建造
mode.freebuild.description = 有限的资源,不会自动生成敌人。
mode.pvp.name = PvP
-mode.pvp.description = fight against other players locally.
+mode.pvp.description = 和本地玩家对战.
content.item.name = 物品
content.liquid.name = 液体
-content.unit.name = 单位
+content.unit.name = 部队
content.recipe.name = 方块
content.mech.name = 机甲
item.stone.name = 石头
item.stone.description = 一种常见的原料。用于分离和提炼成其他材料,或熔化成熔岩。
item.copper.name = 铜
-item.copper.description = 有用的结构材料。在各种类型的方块中广泛使用。
+item.copper.description = 一种有用的结构材料。在各种类型的方块中广泛使用。
item.lead.name = 铅
-item.lead.description = 基本的起始材料。被广泛用于电气和液体运输方块。
+item.lead.description = 一种基本的起始材料。被广泛用于电子设备和液体运输方块。
item.coal.name = 煤
item.coal.description = 一种常见并容易获得的燃料。
item.dense-alloy.name = 致密合金
-item.dense-alloy.description = 由铅和铜制成的坚韧合金。 用于高级的运输方块和深层钻头。
+item.dense-alloy.description = 一种由铅和铜制成的坚韧合金。用于高级的运输方块和高级钻头。
item.titanium.name = 钛
-item.titanium.description = 一种罕见的超轻金属,被广泛运用于液体运输,钻机和飞机。
+item.titanium.description = 一种罕见的超轻金属,被广泛运用于液体运输、钻头和飞机。
item.thorium.name = 钍
-item.thorium.description = 一种致密的放射性金属,用作支撑结构和核燃料。
+item.thorium.description = 一种致密的放射性金属,用作结构支撑和核燃料。
item.silicon.name = 硅
-item.silicon.description = 非常有用的半导体,被用于太阳能电池板和很多复杂的电子设备。
-item.plastanium.name = 塑料
+item.silicon.description = 一种非常有用的半导体,被用于太阳能电池板和很多复杂的电子设备。
+item.plastanium.name = 塑钢
item.plastanium.description = 一种轻质,可延展的材料,用于高级的飞机和碎片弹药。
-item.phase-fabric.name = Phase Fabric
-item.phase-fabric.description = A near-weightless substance used in advanced electronics and self-repairing technology.
+item.phase-fabric.name = 相织物
+item.phase-fabric.description = 一种接近0重量的物质,用于先进的电子技术和自我修复技术。
item.surge-alloy.name = 巨浪合金
-item.surge-alloy.description = An advanced alloy with unique electrical properties.
+item.surge-alloy.description = 一种具有独特电气性能的高级合金。
item.biomatter.name = 生物质
-item.biomatter.description = 一种有机糊;用于转化为油或作为基本燃料。
-item.sand.name = 沙子
-item.sand.description = 一种常见的材料,广泛用于冶炼,制作合金和助熔剂。
+item.biomatter.description = 一种有机物;用于转化为油或作为基本燃料。
+item.sand.name = 沙
+item.sand.description = 一种常见的材料,广泛用于冶炼,包括制作合金和助熔剂。
item.blast-compound.name = 爆炸混合物
-item.blast-compound.description = 一种用于炸弹和炸药的挥发性化合物。虽然它可以作为燃料燃烧,但不建议这样做。
+item.blast-compound.description = 一种用于炸弹和炸药的挥发性混合物。虽然它可以作为燃料燃烧,但不建议这样做。
item.pyratite.name = 硫
-item.pyratite.description = 燃烧武器中使用的极易燃物质。
+item.pyratite.description = 一种燃烧武器中使用的极易燃物质。
liquid.water.name = 水
liquid.lava.name = 岩浆
liquid.oil.name = 石油
@@ -469,32 +470,32 @@ mech.omega-mech.description = 一种装甲厚重的机甲,用于在前线攻
mech.dart-ship.name = Dart
mech.dart-ship.weapon = 机枪
mech.dart-ship.description = 标准飞船。快速轻便,但攻击能力低,采矿速度快。
-mech.javelin-ship.name = Javelin
+mech.javelin-ship.name = 标枪
mech.javelin-ship.description = 一艘一击即退的攻击船。虽然最初很慢,但它可以加速到很快的速度,并飞过敌人的前哨,利用其闪电能力和导弹造成大量伤害。
mech.javelin-ship.weapon = 爆裂导弹
mech.javelin-ship.ability = 放电助推器
-mech.trident-ship.name = Trident
-mech.trident-ship.description = 一个重型轰炸机。有厚装甲。
+mech.trident-ship.name = 三叉戟
+mech.trident-ship.description = 一种重型轰炸机。有厚装甲。
mech.trident-ship.weapon = 炸弹
mech.glaive-ship.name = Glaive
-mech.glaive-ship.description = 一个大型,装甲厚重的武装直升机。配备燃烧机枪。有优秀的加速能力和最快的速度。
+mech.glaive-ship.description = 一种大型,装甲厚重的武装直升机。配备燃烧机枪。有优秀的加速能力和最快的速度。
mech.glaive-ship.weapon = 火焰机枪
-text.item.explosiveness = [LIGHT_GRAY]爆炸威力:{0}
+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.unit.health = [LIGHT_GRAY]生命值: {0}
-text.unit.speed = [LIGHT_GRAY]速度: {0}
-text.mech.weapon = [LIGHT_GRAY]武器: {0}
-text.mech.armor = [LIGHT_GRAY]装甲: {0}
-text.mech.itemcapacity = [LIGHT_GRAY]物品容量: {0}
-text.mech.minespeed = [LIGHT_GRAY]采矿速度: {0}
-text.mech.minepower = [LIGHT_GRAY]采矿能量: {0}
-text.mech.ability = [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}
+text.mech.armor = [LIGHT_GRAY]装甲:{0}
+text.mech.itemcapacity = [LIGHT_GRAY]物品容量:{0}
+text.mech.minespeed = [LIGHT_GRAY]采矿速度:{0}
+text.mech.minepower = [LIGHT_GRAY]采矿力量:{0}
+text.mech.ability = [LIGHT_GRAY]能力:{0}
text.liquid.heatcapacity = [LIGHT_GRAY]热容量:{0}
text.liquid.viscosity = [LIGHT_GRAY]粘度:{0}
text.liquid.temperature = [LIGHT_GRAY]温度:{0}
-block.spawn.name = Enemy Spawn
+block.spawn.name = 敌人出生点
block.core.name = 核心
block.metalfloor.name = 金属地板
block.deepwater.name = 深水
@@ -514,18 +515,18 @@ block.blackrock.name = 黑岩
block.icerock.name = 冰岩
block.copper-wall.name = 铜墙
block.copper-wall-large.name = 大型铜墙
-block.dense-alloy-wall.name = Dense Alloy Wall
-block.dense-alloy-wall-large.name = Large Dense Alloy Wall
-block.phase-wall.name = 相位墙
-block.phase-wall-large.name = 大型相位墙
+block.dense-alloy-wall.name = 致密合金墙
+block.dense-alloy-wall-large.name = 大型致密合金墙
+block.phase-wall.name = 相织布墙
+block.phase-wall-large.name = 大型相织布墙
block.thorium-wall.name = 钍墙
block.thorium-wall-large.name = 大型钍墙
block.door.name = 门
block.door-large.name = 大门
-block.duo.name = 炮
+block.duo.name = 双管炮
block.scorch.name = 灼烧炮
-block.hail.name = Hail
-block.lancer.name = 枪骑兵
+block.hail.name = 冰雹炮
+block.lancer.name = 蓝瑟炮
block.conveyor.name = 传送带
block.titanium-conveyor.name = 钛传送带
block.junction.name = 连接点
@@ -538,7 +539,7 @@ block.overflow-gate.description = 分离器和路由器的组合,如果前面
block.smelter.name = 冶炼厂
block.arc-smelter.name = 电弧冶炼厂
block.silicon-smelter.name = 硅冶炼厂
-block.phase-weaver.name = 相位编织器
+block.phase-weaver.name = 相织布编织器
block.pulverizer.name = 粉碎机
block.cryofluidmixer.name = 冷冻液混合器
block.melter.name = 熔炉
@@ -557,47 +558,47 @@ block.pneumatic-drill.name = 气动钻头
block.laser-drill.name = 激光钻头
block.water-extractor.name = 抽水机
block.cultivator.name = 耕种机
-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.glaive-ship-pad.name = Glaive Ship Pad
-block.omega-mech-pad.name = Omega Mech Pad
-block.tau-mech-pad.name = Tau Mech Pad
+block.alpha-mech-pad.name = Alpha 机甲平台
+block.dart-ship-pad.name = Dart 机甲平台
+block.delta-mech-pad.name = Delta 机甲平台
+block.javelin-ship-pad.name = 标枪 机甲平台
+block.trident-ship-pad.name = 三叉戟 机甲平台
+block.glaive-ship-pad.name = Glaive 机甲平台
+block.omega-mech-pad.name = Omega 机甲平台
+block.tau-mech-pad.name = Tau 机甲平台
block.conduit.name = 导管
block.mechanical-pump.name = 机械泵
block.itemsource.name = 物品源
-block.itemvoid.name = Item Void
+block.itemvoid.name = 物品黑洞
block.liquidsource.name = 液体源
-block.powervoid.name = Power Void
+block.powervoid.name = 能源黑洞
block.powerinfinite.name = 无限能源
block.unloader.name = 装卸器
block.vault.name = 仓库
block.wave.name = 波浪
block.swarmer.name = 蜂群
block.salvo.name = 齐射炮
-block.ripple.name = 波纹
-block.phase-conveyor.name = 相位传送带
+block.ripple.name = 浪涌
+block.phase-conveyor.name = 相织布传送带
block.bridge-conveyor.name = 传送带桥
-block.plastanium-compressor.name = 塑料压缩机
+block.plastanium-compressor.name = 塑钢压缩机
block.pyratite-mixer.name = 硫混合器
block.blast-mixer.name = 爆炸混合器
-block.solidifer.name = 凝固剂
+block.solidifer.name = 凝固器
block.solar-panel.name = 太阳能电池
block.solar-panel-large.name = 大型太阳能电池
block.oil-extractor.name = 石油钻井
-block.spirit-factory.name = Spirit Drone Factory
-block.phantom-factory.name = Phantom Drone Factory
-block.wraith-factory.name = Wraith Fighter Factory
-block.ghoul-factory.name = Ghoul Bomber Factory
-block.dagger-factory.name = Dagger Mech Factory
-block.titan-factory.name = Titan Mech Factory
-block.fortress-factory.name = Fortress Mech Factory
-block.revenant-factory.name = Revenant Fighter Factory
+block.spirit-factory.name = 轻型无人机工厂
+block.phantom-factory.name = 鬼怪无人机工厂
+block.wraith-factory.name = 幻影战机工厂
+block.ghoul-factory.name = 食尸鬼轰炸机工厂
+block.dagger-factory.name = 尖刀机甲工厂
+block.titan-factory.name = 泰坦机甲工厂
+block.fortress-factory.name = 堡垒机甲工厂
+block.revenant-factory.name = 亡魂战机工厂
block.repair-point.name = 维修点
block.pulse-conduit.name = 脉冲导管
-block.phase-conduit.name = 相位导管
+block.phase-conduit.name = 相织布导管
block.liquid-router.name = 液体路由器
block.liquid-tank.name = 储液罐
block.liquid-junction.name = 液体连接点
@@ -610,171 +611,171 @@ block.blast-drill.name = 爆破钻头
block.thermal-pump.name = 热能泵
block.thermal-generator.name = 热能发电机
block.alloy-smelter.name = 合金冶炼厂
-block.mend-projector.name = 修理投影机
-block.surge-wall.name = 浪涌墙
-block.surge-wall-large.name = 大浪涌墙
-block.cyclone.name = 气旋
-block.fuse.name = 保险丝
-block.shock-mine.name = Shock Mine
-block.overdrive-projector.name = 超速投影机
-block.force-projector.name = Force Projector
-block.arc.name = Arc
-block.rtg-generator.name = RTG Generator
-block.spectre.name = Spectre
-block.meltdown.name = Meltdown
-block.container.name = Container
-block.core.description = The most important building in the game.
-team.blue.name = blue
-team.red.name = red
-team.orange.name = orange
-team.none.name = gray
-team.green.name = green
-team.purple.name = purple
+block.mend-projector.name = 修理投影器
+block.surge-wall.name = 波动墙
+block.surge-wall-large.name = 大型波动墙
+block.cyclone.name = 气旋炮
+block.fuse.name = 融合炮
+block.shock-mine.name = 休克地雷
+block.overdrive-projector.name = 超速投影器
+block.force-projector.name = 力墙投影器
+block.arc.name = 电弧
+block.rtg-generator.name = RTG 发电机
+block.spectre.name = 幽灵
+block.meltdown.name = 熔毁
+block.container.name = 容器
+block.core.description = 游戏中最重要的建筑。
+team.blue.name = 蓝
+team.red.name = 红
+team.orange.name = 橙
+team.none.name = 灰
+team.green.name = 绿
+team.purple.name = 紫
unit.alpha-drone.name = Alpha 无人机
-unit.spirit.name = Spirit Drone
-unit.spirit.description = The starter drone unit. Spawns in the core by default. Automatically mines ores, collects items and repairs blocks.
-unit.phantom.name = Phantom Drone
-unit.phantom.description = An advanced drone unit. Automatically mines ores, collects items and repairs blocks. Significantly more effective than a drone.
+unit.spirit.name = 轻型无人机
+unit.spirit.description = 初始无人机。默认情况下在内核中生成。自动开采矿石,收集物品和修理块。
+unit.phantom.name = 鬼怪无人机
+unit.phantom.description = 一种先进的无人机单位。自动开采矿石,收集物品和修理块。比初始无人机有效得多。
unit.dagger.name = 尖刀
unit.dagger.description = 基础的地面单位,在蜂群中很有用。
unit.titan.name = 泰坦
unit.titan.description = 高级的有武装地面单位,使用电石作为弹药.攻击地面单位和空中单位.
-unit.ghoul.name = Ghoul Bomber
-unit.ghoul.description = A heavy carpet bomber. Uses blast compound or pyratite as ammo.
-unit.wraith.name = Wraith Fighter
-unit.wraith.description = A fast, hit-and-run interceptor unit.
-unit.fortress.name = Fortress
-unit.fortress.description = A heavy artillery ground unit.
-unit.revenant.name = Revenant
-unit.revenant.description = A heavy laser platform.
-tutorial.begin = Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this.
-tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein.
-tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.
-tutorial.morecopper = More copper is required.\n\nEither mine it manually, or place more drills.
-tutorial.turret = Defensive structures must be built to repel the[LIGHT_GRAY] enemy[].\nBuild a duo turret near your base.
-tutorial.drillturret = Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill next to the turret to supply it with mined copper.
-tutorial.waves = The[LIGHT_GRAY] enemy[] approaches.\n\nDefend your core for 2 waves. Build more turrets.
-tutorial.lead = More ores are available. Explore and mine[accent] lead[].\n\nDrag from your unit to the core to transfer resources.
-tutorial.smelter = Copper and lead are weak metals.\nSuperior[accent] Dense Alloy[] can be created in a smelter.\n\nBuild one.
-tutorial.densealloy = The smelter will now produce alloy.\nGet some.\nImprove the production if necessary.
-tutorial.siliconsmelter = The core will now create a[accent] spirit drone[] for mining and repairing blocks.\n\nFactories for other units can be created with [accent] silicon.\nMake a silicon smelter.
-tutorial.silicondrill = Silicon requires[accent] coal[] and[accent] sand[].\nStart by making drills.
-tutorial.generator = This technology requires power.\nCreate a[accent] combustion generator[] for it.
-tutorial.generatordrill = Combustion generators need fuel.\nFuel it with coal from a drill.
-tutorial.node = Power requires transport.\nCreate a[accent] power node[] next to your combustion generator to transfer its power.
-tutorial.nodelink = Power can be transferred through contacting power blocks and generators, or by linked power nodes.\n\nLink power by tapping the node and selecting the generator and silicon smelter.
-tutorial.silicon = Silicon is being produced. Get some.\n\nImproving the production system is advised.
-tutorial.daggerfactory = Construct a[accent] dagger mech factory.[]\n\nThis will be used to create attack mechs.
-tutorial.router = Factories need resources to function.\nCreate a router to split conveyor resources.
-tutorial.dagger = Link power nodes to the factory.\nOnce requirements are met, a mech will be created.\n\nCreate more drills, generators and conveyors as necessary.
-tutorial.battle = The[LIGHT_GRAY] enemy[] has revealed their core.\nDestroy it with your unit and dagger mechs.
-block.copper-wall.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.
-block.copper-wall-large.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.\nSpans multiple tiles.
-block.dense-alloy-wall.description = A standard defensive block.\nAdequate protection from enemies.
-block.dense-alloy-wall-large.description = A standard defensive block.\nAdequate protection from enemies.\nSpans multiple tiles.
-block.thorium-wall.description = A strong defensive block.\nGood protection from enemies.
-block.thorium-wall-large.description = A strong defensive block.\nGood protection from enemies.\nSpans multiple tiles.
-block.phase-wall.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful.
-block.phase-wall-large.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful.\nSpans multiple tiles.
-block.surge-wall.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.
-block.surge-wall-large.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.\nSpans multiple tiles.
-block.door.description = A small door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through.
-block.door-large.description = A large door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through.\nSpans multiple tiles.
-block.mend-projector.description = Periodically heals buildings in its vicinity.
-block.overdrive-projector.description = Increases the speed of nearby buildings like drills and conveyors.
-block.force-projector.description = Creates a hexagonal force field around itself, protecting buildings and units inside from damage through bullets.
-block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy.
-block.duo.description = A small, cheap turret.
-block.arc.description = A small turret which shoots electricity in a random arc towards the enemy.
-block.hail.description = A small artillery turret.
-block.lancer.description = A medium-sized turret which shoots charged electricity beams.
-block.wave.description = A medium-sized rapid-fire turret which shoots liquid bubbles.
-block.salvo.description = A medium-sized turret which fires shots in salvos.
-block.swarmer.description = A medium-sized turret which shoots burst missiles.
-block.ripple.description = A large artillery turret which fires several shots simultaneously.
-block.cyclone.description = A large rapid fire turret.
-block.fuse.description = A large turret which shoots powerful short-range beams.
-block.spectre.description = A large turret which shoots two powerful bullets at once.
-block.meltdown.description = A large turret which shoots powerful long-range beams.
-block.conveyor.description = Basic item transport block. Moved items forward and automatically deposits them into turrets or crafters. Rotatable.
-block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors.
-block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles.
-block.junction.description = Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations.
-block.mass-driver.description = Ultimate item transport block. Collects several items and then shoots them to another mass driver over a long range.
-block.smelter.description = Burns coal for smelting copper and lead into dense alloy.
-block.arc-smelter.description = Smelts copper and lead into dense alloy by using an external power source.
-block.silicon-smelter.description = Reduces sand with highly pure coke in order to produce silicon.
-block.plastanium-compressor.description = Produces plastanium from oil and titanium.
-block.phase-weaver.description = Produces phase fabric from radioactive thorium and high amounts of sand.
-block.alloy-smelter.description = Produces surge alloy from titanium, lead, silicon and copper.
-block.pulverizer.description = Crushes stone into sand. Useful when there is a lack of natural sand.
-block.pyratite-mixer.description = Mixes coal, lead and sand into highly flammable pyratite.
-block.blast-mixer.description = Uses oil for transforming pyratite into the less flammable but more explosive blast compound.
-block.cryofluidmixer.description = Combines water and titanium into cryofluid which is much more efficient for cooling.
-block.solidifer.description = Cools lava to stone at a fast pace.
-block.melter.description = Heats up stone to very high temperatures to obtain lava.
-block.incinerator.description = Gets rid of any excess item or liquid.
-block.biomattercompressor.description = Compresses biomatter in order to retrieve oil.
-block.separator.description = Exposes stone to water pressure in order to obtain various minerals contained in the stone.
-block.centrifuge.description = More efficient than the separator, but also more expensive to build and requires power.
-block.power-node.description = Transmits power to connected nodes. Up to four power sources, sinks or nodes can be connected. The node will receive power from or supply power to any adjacent blocks.
-block.power-node-large.description = Has a larger radius than the power node and connects to up to six power sources, sinks or nodes.
-block.battery.description = Stores power whenever there is an abundance and provides power whenever there is a shortage, as long as there is capacity left.
-block.battery-large.description = Stores much more power than a regular battery.
-block.combustion-generator.description = Generates power by burning oil or flammable materials.
-block.turbine-generator.description = More efficient than a combustion generator, but requires additional water.
-block.thermal-generator.description = Generates a large amount of power from lava.
-block.solar-panel.description = Provides a small amount of power from the sun.
-block.solar-panel-large.description = Provides much better power supply than a standard solar panel, but is also much more expensive to build.
-block.thorium-reactor.description = Generates huge amounts of power from highly radioactive thorium. Requires constant cooling. Will explode violently if insufficient amounts of coolant are supplied.
-block.rtg-generator.description = A radioisotope thermoelectric generator which does not require cooling but provides less power than a thorium reactor.
-block.unloader.description = Unloads items from a container, vault or core onto a conveyor or directly into an adjacent block. The type of item to be unloaded can be changed by tapping on the unloader.
-block.container.description = Stores a small amount of items. Use it for creating buffers when there is a non-constant demand of materials. An[LIGHT_GRAY] unloader[] can be used to retrieve items from the container.
-block.vault.description = Stores a large amount of items. Use it for creating buffers when there is a non-constant demand of materials. An[LIGHT_GRAY] unloader[] can be used to retrieve items from the vault.
-block.mechanical-drill.description = A cheap drill. When placed on appropriate tiles, outputs items at a slow pace indefinitely.
-block.pneumatic-drill.description = An improved drill which is faster and able to process harder materials by making use of air pressure.
-block.laser-drill.description = Allows drilling even faster through laser technology, but requires power. Additionally, radioactive thorium can be retrieved with this drill.
-block.blast-drill.description = The ultimate drill. Requires large amounts of power.
-block.water-extractor.description = Extracts water from the ground. Use it when there is no lake nearby.
-block.cultivator.description = Cultivates the soil with water in order to obtain biomatter.
-block.oil-extractor.description = Uses large amounts of power in order to extract oil from sand. Use it when there is no direct source of oil nearby.
-block.dart-ship-pad.description = Leave your current vessel and change into a basic fighter aircraft.\nUse the pad by double tapping while standing on it.
-block.trident-ship-pad.description = Leave your current vessel and change into a reasonably well armored heavy bomber.\nUse the pad by double tapping while standing on it.
-block.javelin-ship-pad.description = Leave your current vessel and change into a strong and fast interceptor with lightning weapons.\nUse the pad by double tapping while standing on it.
-block.glaive-ship-pad.description = Leave your current vessel and change into a large, well-armored gunship.\nUse the pad by double tapping while standing on it.
-block.tau-mech-pad.description = Leave your current vessel and change into a support mech which can heal friendly buildings and units.\nUse the pad by double tapping while standing on it.
-block.delta-mech-pad.description = Leave your current vessel and change into a fast, lightly-armored mech made for hit-and-run attacks.\nUse the pad by double tapping while standing on it.
-block.omega-mech-pad.description = Leave your current vessel and change into a bulky and well-armored mech, made for front-line assaults.\nUse the pad by double tapping while standing on it.
-block.spirit-factory.description = Produces light drones which mine ore and repair blocks.
-block.phantom-factory.description = Produces advanced drone units which are significantly more effective than a spirit drone.
-block.wraith-factory.description = Produces fast, hit-and-run interceptor units.
-block.ghoul-factory.description = Produces heavy carpet bombers.
-block.dagger-factory.description = Produces basic ground units.
-block.titan-factory.description = Produces advanced, armored ground units.
-block.fortress-factory.description = Produces heavy artillery ground units.
-block.revenant-factory.description = Produces heavy laser ground units.
-block.repair-point.description = Continuously heals the closest damaged unit in its vicinity.
-block.command-center.description = Allows changing friendly AI behavior. Currently, attack, retreat and patrol commands are supported.
-block.conduit.description = Basic liquid transport block. Works like a conveyor, but with liquids. Best used with extractors, pumps or other conduits.
-block.pulse-conduit.description = Advanced liquid transport block. Transports liquids faster and stores more than standard conduits.
-block.phase-conduit.description = Advanced liquid transport block. Uses power to teleport liquids to a connected phase conduit over several tiles.
-block.liquid-router.description = Accepts liquids from one direction and outputs them to up to 3 other directions equally. Can also store a certain amount of liquid. Useful for splitting the liquids from one source to multiple targets.
-block.liquid-tank.description = Stores a large amount of liquids. Use it for creating buffers when there is a non-constant demand of materials or as a safeguard for cooling vital blocks.
-block.liquid-junction.description = Acts as a bridge for two crossing conduits. Useful in situations with two different conduits carrying different liquids to different locations.
-block.bridge-conduit.description = Advanced liquid transport block. Allows transporting liquids over up to 3 tiles of any terrain or building.
-block.mechanical-pump.description = A cheap pump with slow output, but no power consumption.
-block.rotary-pump.description = An advanced pump which doubles up speed by using power.
-block.thermal-pump.description = The ultimate pump. Three times as fast as a mechanical pump and the only pump which is able to retrieve lava.
-block.router.description = Accepts items from one direction and outputs them to up to 3 other directions equally. Useful for splitting the materials from one source to multiple targets.
-block.distributor.description = An advanced router which splits items to up to 7 other directions equally.
-block.bridge-conveyor.description = Advanced item transport block. Allows transporting items over up to 3 tiles of any terrain or building.
-block.alpha-mech-pad.description = When given enough power, rebuilds your ship into the[accent] Alpha[] mech.
-block.itemsource.description = Infinitely outputs items. Sandbox only.
-block.liquidsource.description = Infinitely outputs liquids. Sandbox only.
-block.itemvoid.description = Destroys any items which go into it without using power. Sandbox only.
-block.powerinfinite.description = Infinitely outputs power. Sandbox only.
-block.powervoid.description = Voids all power inputted into it. Sandbox only.
-liquid.water.description = Commonly used for cooling machines and waste processing.
-liquid.lava.description = Can be transformed into[LIGHT_GRAY] stone[], used for generating power or used as ammo for certain turrets.
-liquid.oil.description = Can be burnt, exploded or used as a coolant.
-liquid.cryofluid.description = The most efficient liquid for cooling things down.
+unit.ghoul.name = 食尸鬼轰炸机
+unit.ghoul.description = 重型地毯轰炸机。用爆炸化合物或黄铁矿作为弹药。
+unit.wraith.name = 幻影战机
+unit.wraith.description = 一种快速,打了就跑的截击机。
+unit.fortress.name = 堡垒
+unit.fortress.description = 一种重炮地面部队。
+unit.revenant.name = 亡魂
+unit.revenant.description = 一种重型激光平台。
+tutorial.begin = 你的任务是消灭[LIGHT_GRAY] 敌人 [].\n\n首先开始[accent] 采集铜矿 []。点击核心附近的铜矿开始。
+tutorial.drill = 手动采矿效率低.\n[accent] 钻头 []可以自动采矿.\n放一个在铜矿上吧.
+tutorial.conveyor = [accent]传送带[] 可以把物资传送到核心.\n请造一个传送线,从钻头到核心.
+tutorial.morecopper = 需要更多的铜.\n\n手动采矿或者放更多的钻头吧.
+tutorial.turret = 必须建造防御建筑来击退[LIGHT_GRAY] 敌人[].\n请在你核心附近造一个双人炮塔.
+tutorial.drillturret = 双人炮塔需要[accent] 铜质弹药 []来射击.\n可以放一个钻头在炮塔附近供应铜.
+tutorial.waves = [LIGHT_GRAY]敌人[] 来了.\n\n保护基地,防御2波攻击. 造更多的炮塔.
+tutorial.lead = 有更多的矿可用. 探索和采集[accent] 铅[].\n\n按住你的采矿单位拖放到核心来传送资源.
+tutorial.smelter = 铜和铅是弱金属.\n超级[accent] 致密合金[] 可以从冶炼厂生产.\n\n造一个吧.
+tutorial.densealloy = 冶炼厂将生产合金.\n生产一些.\n有必要可以改进一下生产.
+tutorial.siliconsmelter = 基地现在将制作一个[accent] 无人机[] 来采矿和维修方块.\n\n其他单位的工程可以用[accent] 硅 []来建造.\n造一个硅冶炼厂.
+tutorial.silicondrill = 硅需要[accent] 煤[] 和[accent] 沙[].\n开始制作钻头吧.
+tutorial.generator = 这项技术需要能源.\n造一个[accent] 燃烧发电机[] 来发电.
+tutorial.generatordrill = 燃烧发电机需要燃料.\n用钻头采集煤来供给燃料.
+tutorial.node = 能源需要传输.\n造一个[accent] 能量节点[] 靠近火力发电机来传输它的能源.
+tutorial.nodelink = 使耗能方块紧靠发电机或者用能源节点连接来传输电力.\n\n点击能源节点并选择发电机和硅冶炼厂来链接能源.
+tutorial.silicon = 正在生产硅. 多生产点.\n\n建议优化一下生产系统.
+tutorial.daggerfactory = 建造一个[accent] 尖刀机甲工厂.[]\n\n它可以用来生产机甲
+tutorial.router = 工厂需要资源来运作.\n造一个路由器来分发传送资源.
+tutorial.dagger = 链接能源节点到工厂.\n一旦需求满足, 将会制作一个机甲.\n\n根据需要制作更多的钻头,发电机,传送带.
+tutorial.battle = [LIGHT_GRAY] 敌人[] 的核心已经暴露。\n用你的尖刀机甲摧毁它。
+block.copper-wall.description = 廉价的防守区块。\n用于保护前几波中的核心和炮塔。
+block.copper-wall-large.description = 廉价的防御块。\n用于保护前几个波浪中的核心和炮塔。\n跨越多个块。
+block.dense-alloy-wall.description = 标准的防守区块。\n可以较好的防御敌人。
+block.dense-alloy-wall-large.description = 标准的防守区块。\n可以较好的防御敌人。\n跨越多个块。
+block.thorium-wall.description = 强大的防守区块。\n很好的防御敌人。
+block.thorium-wall-large.description = 强大的防守区块。\n很好地防御敌人。\n跨越多个块。
+block.phase-wall.description = 没有钍墙那样坚固,但是它可以使不太强的子弹发生偏转。
+block.phase-wall-large.description = 没有钍墙那样坚固,但是它可以使不太强的子弹发生偏转。\n跨越多个块。
+block.surge-wall.description = 强大的防守区块。\n有很小的机会向攻击者发射闪电。
+block.surge-wall-large.description = 强大的防御区块。\n有很小的机会向攻击者发射闪电。\n跨越多个区块。
+block.door.description = 一扇小门,可以通过点击打开和关闭。\n如果打开,敌人可以射击并穿过。
+block.door-large.description = 一扇大门,可以通过点击打开和关闭。\n如果打开,敌人可以射击并穿过。\n扫过多个瓷砖。
+block.mend-projector.description = 定期修复附近的建筑物。
+block.overdrive-projector.description = 提高附近建筑物的速度,如钻机和传送带。
+block.force-projector.description = 自身周围创建一个六边形力场,保护建筑物和内部单位免受子弹的伤害。
+block.shock-mine.description = 伤害踩到它的敌人。敌人几乎看不到它。
+block.duo.description = 小而便宜的炮塔。
+block.arc.description = 小型炮塔,发射电弧。
+block.hail.description = 小型炮兵炮台。
+block.lancer.description = 中型炮塔,发射带电的电子束。
+block.wave.description = 中型快速炮塔,射出液体泡泡。
+block.salvo.description = 中型炮塔,齐射射击。
+block.swarmer.description = 发射爆炸导弹的中型炮塔。
+block.ripple.description = 大型炮兵炮塔,可同时向多个目标开火。
+block.cyclone.description = 大型快速炮塔。
+block.fuse.description = 发射强大的短程光束的大型炮塔。
+block.spectre.description = 大型炮塔,一次射出两颗强大的子弹。
+block.meltdown.description = 发射强大的远程光束的大型炮塔。
+block.conveyor.description = 初级传送带。将物品向前移动并自动将它们放入炮塔或工厂中。可旋转方向。
+block.titanium-conveyor.description = 高级传送带。能比初级传送带更快地移动物品。
+block.phase-conveyor.description = 高级传送带。使用电力将物品传送到距离几个块的相位传送带上。
+block.junction.description = 为两条交叉传送带的桥梁。适用于两种不同传送带将不同材料运送到不同位置的情况。
+block.mass-driver.description = 终极传送带。收集几件物品,然后将它们射向长距离外的另一个批量传送带。
+block.smelter.description = 烧煤,用于冶炼铜和铅成致密合金。
+block.arc-smelter.description = 用外部电源熔炼铜和铅成致密合金。
+block.silicon-smelter.description = 用高纯度的焦炭来加工沙子以生产硅。
+block.plastanium-compressor.description = 用油和钛生产塑钢。
+block.phase-weaver.description = 用放射性钍和大量沙子生产相织物。
+block.alloy-smelter.description = 用钛,铅,硅和铜生产浪涌合金。
+block.pulverizer.description = 将石头压成沙子。当缺少天然沙子时很有用。
+block.pyratite-mixer.description = 用煤,铅和沙子混合成高度易燃的硫。
+block.blast-mixer.description = 用油将硫转化为不易燃但更具爆炸性的爆炸化合物。
+block.cryofluidmixer.description = 水和钛结合到低温流体中,冷却效率更高。
+block.solidifer.description = 快速冷却熔岩为石头。
+block.melter.description = 石头加热到很高的温度以获得熔岩。
+block.incinerator.description = 用于除掉任何多余的物品或液体。
+block.biomattercompressor.description = 压缩生物质以获取油。
+block.separator.description = 将石头暴露在水压下,以获得石头中含有的各种矿物质。
+block.centrifuge.description = 比分离器更有效,但构建起来也更昂贵并且需要动力。
+block.power-node.description = 连接节点传输电源。最多可连接四个电源,接收器或节点。节点将从任何相邻块接收电力或向其供电。
+block.power-node-large.description = 传输径大于电源节点,最多可连接六个电源,接收器或节点。
+block.battery.description = 储存电力,当储存有能量时,可在电力短缺时提供电力。
+block.battery-large.description = 比普通电池容量更大。
+block.combustion-generator.description = 通过燃烧油或易燃材料产生电力。
+block.turbine-generator.description = 比燃烧发电机更有效,但需要额外的水。
+block.thermal-generator.description = 从熔岩中产生大量的能量。
+block.solar-panel.description = 标准太阳能面板,提供少量电力。
+block.solar-panel-large.description = 比标准太阳能电池板提供更好的电源,但构建起来要贵得多。
+block.thorium-reactor.description = 高放射性钍产生大量电力。需要持续冷却。如果供应的冷却剂量不足,会剧烈爆炸。
+block.rtg-generator.description = 一种放射性同位素热电发电机,它不需要冷却,但功率低于钍反应堆。
+block.unloader.description = 物品从容器,仓库或核心卸载到传送带上或直接卸载到相邻的块中。可以通过点击卸载器来更改要卸载的项目类型。
+block.container.description = 存储少量物品。当存在非恒定的材料需求时,使用它来创建缓冲区。 [LIGHT_GRAY]卸载器[]可用于从容器中获取物品。
+block.vault.description = 存储大量物品。当存在非恒定的材料需求时,使用它来创建缓冲区。 [LIGHT_GRAY]卸载器[]可用于从仓库中获取物品。
+block.mechanical-drill.description = 便宜的钻头。放置在适当的块上时,无限期地以缓慢的速度输出物品。
+block.pneumatic-drill.description = 一种改进的钻头,它更快,能够利用气压处理更硬的材料。
+block.laser-drill.description = 通过激光技术更快地钻孔,但需要电源。此外,这种钻头可以回收放射性钍。
+block.blast-drill.description = 终极钻头,需要大量电力。
+block.water-extractor.description = 从地下提取水。当附近没有湖泊时使用它。
+block.cultivator.description = 用水培育土壤以获得生物物质。
+block.oil-extractor.description = 使用大量的电力从沙子中提取石油。当附近没有直接的石油来源时使用它。
+block.dart-ship-pad.description = 离开你当前的装置,换成基本的战斗机。\n站在上面时双击切换。
+block.trident-ship-pad.description = 离开你当前的装置,换成一个装甲合理的重型轰炸机。\n站在上面时双击切换。
+block.javelin-ship-pad.description = 离开你当前的装置,换上一个强大而快速的截击机,用闪电武器。\n站在上面时双击切换。
+block.glaive-ship-pad.description = 离开现有的装置,换成装甲良好的大型武装直升机。\n站在上面时双击切换。
+block.tau-mech-pad.description = 离开你当前的装置并换成一个可以治愈友方建筑物和单位的支撑机械。\n站在上面时双击切换。
+block.delta-mech-pad.description = 离开你当前的装置并换成一个快速,轻装甲的机械装置,用于快速攻击。\n站在上面时双击切换。
+block.omega-mech-pad.description = 离开你当前的装置并换成一个笨重且装甲良好的机甲,用于前线攻击。\n站在上面时双击切换。
+block.spirit-factory.description = 生产轻型无人机,用于开采矿石和修复块。
+block.phantom-factory.description = 生产高级无人机单元,它比轻型无人机更有效。
+block.wraith-factory.description = 生产快速截击机。
+block.ghoul-factory.description = 生产重型地毯轰炸机。
+block.dagger-factory.description = 生产基本地面单位。
+block.titan-factory.description = 生产先进的装甲地面单位。
+block.fortress-factory.description = 生产重型火炮地面部队。
+block.revenant-factory.description = 生产重型激光地面单元。
+block.repair-point.description = 连续治疗附近最近的受损单位。
+block.command-center.description = 允许更改友方AI行为。目前支持攻击,撤退和巡逻命令。
+block.conduit.description = 基本液体传输块。像输送机一样工作,但用于液体。最适用于提取器,泵或其他导管。
+block.pulse-conduit.description = 高级液体传输块。比标准导管更快地输送液体并储存更多液体。
+block.phase-conduit.description = 高级液体传输块。使用电力将液体传送到多个块上的连接相管道。
+block.liquid-router.description = 接受来自一个方向的液体并将它们平均输出到最多3个其他方向。也可以储存一定量的液体。用于将液体从一个源分成多个目标。
+block.liquid-tank.description = 存储大量液体。当存在对材料的非恒定需求或作为冷却重要块的安全措施时,将其用于创建缓冲区。
+block.liquid-junction.description = 作为两个交叉管道的桥梁。适用于两种不同导管将不同液体输送到不同位置的情况。
+block.bridge-conduit.description = 高级液体传输块。允许在任何地形或建筑物的最多3个块上运输液体。
+block.mechanical-pump.description = 一种输出速度慢但没有功耗的廉价泵。
+block.rotary-pump.description = 一种先进的泵,通过使用动力使速度加倍。
+block.thermal-pump.description = 终级水泵。速度是机械泵的三倍。是唯一能够回收熔岩的泵。
+block.router.description = 从一个方向接受物品,并将它们平均输出到最多3个其他方向。用于将材料从一个源分割为多个目标。
+block.distributor.description = 一个高级路由器,可以将物品分成最多7个方向。
+block.bridge-conveyor.description = 高级项目传输块。允许在跨越任何地形或建筑物上运输物品,最多跨越3个块。
+block.alpha-mech-pad.description = 当给予足够的电力时,将你的装置重建为[accent] Alpha []机甲。
+block.itemsource.description = 无限输出物品。仅限沙箱。
+block.liquidsource.description = 无限输出液体。仅限沙箱。
+block.itemvoid.description = 在不使用电源的情况下销毁任何进入它的物品。仅限沙箱。
+block.powerinfinite.description = 无限输出功率。仅限沙箱。
+block.powervoid.description = 消耗输入的所有功率。仅限沙箱。
+liquid.water.description = 通常用于冷却和废物处理。
+liquid.lava.description = 可以转换成[LIGHT_GRAY] 石头 [],用于发电或用作某些炮塔的弹药。
+liquid.oil.description = 可以燃烧,爆炸或用作冷却液。
+liquid.cryofluid.description = 用于降温的最有效液体。
diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties
index 3d18289129..2fbc722f89 100644
--- a/core/assets/bundles/bundle_zh_TW.properties
+++ b/core/assets/bundles/bundle_zh_TW.properties
@@ -1,118 +1,118 @@
text.credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!)
text.credits = 致謝名單
-text.discord = 加入 Mindustry 的 Discord 聊天室
+text.discord = 加入 Mindustry 的 Discord 聊天室!
text.link.discord.description = 官方 Mindustry Discord 聊天室
text.link.github.description = 遊戲原始碼
text.link.dev-builds.description = 開發中版本
text.link.trello.description = 官方 Trello 功能規劃看板
-text.link.itch.io.description = 電腦版與網頁版(itch.io 頁面)
+text.link.itch.io.description = itch.io 電腦版下載與網頁版
text.link.google-play.description = Google Play 商店頁面
text.link.wiki.description = 官方 Mindustry 維基
-text.linkfail = 無法打開連結!我們已將該網址複製到您的剪貼簿。
-text.editor.web = 線上版本不支援地圖編輯器!請下載遊戲已使用這項功能。
-text.web.unsupported = The web version does not support this feature! Download the game to use it.
+text.linkfail = 無法打開連結!\n我們已將該網址複製到您的剪貼簿。
+text.editor.web = 線上版本不支援地圖編輯器!\n請下載遊戲以使用這項功能。
+text.web.unsupported = 線上版本不支援此功能!請下載遊戲以使用這項功能。
text.gameover = 核心已被摧毀。
-text.gameover.pvp = The[accent] {0}[] team is victorious!
-text.sector.gameover = This sector has been lost. Re-deploy?
-text.sector.retry = Retry
-text.highscore = [YELLOW]新的高分紀錄!
-text.wave.lasted = You lasted until wave [accent]{0}[].
-text.level.highscore = 最高分:[accent] {0}
+text.gameover.pvp = [accent]{0}[]隊得到勝利!
+text.sector.gameover = 這個區域失守了,重新部署?
+text.sector.retry = 重試
+text.highscore = [accent]新的高分紀錄!
+text.wave.lasted = 你維持到第[accent]{0}[]波。
+text.level.highscore = 最高分:[accent]{0}
text.level.delete.title = 確認刪除
-text.map.delete = Are you sure you want to delete the map "[accent]{0}[]"?
+text.map.delete = 確認要刪除「[accent]{0}[]」地圖嗎?
text.level.select = 選擇關卡
text.level.mode = 遊戲模式:
-text.construction.desktop = Desktop controls have been changed.\nTo deselect a block or stop building, [accent]use space[].
-text.construction.title = Block Construction Guide
-text.construction = You've just selected [accent]block construction mode[].\n\nTo begin placing, simply tap a valid location near your ship.\nOnce you have selected some blocks, press the checkbox to confirm, and your ship will begin constructing them.\n\n- [accent]Remove blocks[] from your selection by tapping them.\n- [accent]Shift the selection[] by holding and dragging any block in the selection.\n- [accent]Place blocks in a line[] by tapping and holding an empty spot, then dragging in a direction.\n- [accent]Cancel construction or selection[] by pressing the X at the bottom left.
-text.deconstruction.title = Block Deconstruction Guide
-text.deconstruction = You've just selected [accent]block deconstruction mode[].\n\nTo begin breaking, simply tap a block near your ship.\nOnce you have selected some blocks, press the checkbox to confirm, and your ship will begin de-constructing them.\n\n- [accent]Remove blocks[] from your selection by tapping them.\n- [accent]Remove blocks in an area[] by tapping and holding an empty spot, then dragging in a direction.\n- [accent]Cancel deconstruction or selection[] by pressing the X at the bottom left.
-text.showagain = Don't show again next session
-text.coreattack = < Core is under attack! >
-text.unlocks = Unlocks
+text.construction.desktop = 電腦控制已更改。\n要取消選擇或停止建設,[accent]按空格鍵[]。
+text.construction.title = 方塊建設指南
+text.construction = 你選擇了[accent]方塊建設模式[]。\n\n要放置方塊,點擊你的船附近的有效位置。\n選擇了方塊後,點擊複選框就會開始建設。\n\n- 點擊方塊以從選擇區[accent]移除方塊[]。\n- 按住並拖動以[accent]直線放置方塊[]。\n- 點擊左下角的「X」以[accent]取消建設或取消選擇[]。
+text.deconstruction.title = 方塊移除指南
+text.deconstruction = 你選擇了[accent]方塊移除模式[]。\n\n要移除方塊,點擊你的船附近的方塊。\n選擇了方塊後,點擊複選框就會開始移除。\n\n- 點擊方塊以從選擇區[accent]移除方塊[]。\n- 按住一個空點向任何方向拖動以[accent]移除選中區域的方塊[]。\n- 點擊左下角的「X」以[accent]取消移除或取消選擇[]。
+text.showagain = 下次不再顯示
+text.coreattack = 〈核心正在受到攻擊!〉
+text.unlocks = 已解鎖
text.savegame = 儲存遊戲
text.loadgame = 載入遊戲
text.joingame = 多人連線
-text.addplayers = Add/Remove Players
-text.customgame = Custom Game
-text.sectors = Sectors
-text.sector = Selected Sector: [LIGHT_GRAY]{0}
-text.sector.time = Time: [LIGHT_GRAY]{0}
-text.sector.deploy = Deploy
-text.sector.abandon = Abandon
-text.sector.abandon.confirm = Are you sure you want to abandon all progress at this sector?\nThis cannot be undone!
-text.sector.resume = Resume
+text.addplayers = 增加/移除玩家
+text.customgame = 自訂遊戲
+text.sectors = 區域
+text.sector = 區域︰[LIGHT_GRAY]{0}
+text.sector.time = 時間︰[LIGHT_GRAY]{0}
+text.sector.deploy = 部署
+text.sector.abandon = 放棄
+text.sector.abandon.confirm = 確認要放棄這區域所有進度嗎?\n此操作不可撤回!
+text.sector.resume = 繼續
text.sector.locked = [scarlet][[Incomplete]
text.sector.unexplored = [accent][[Unexplored]
-text.missions = Missions:[LIGHT_GRAY] {0}
-text.mission = Mission:[LIGHT_GRAY] {0}
-text.mission.main = Main Mission:[LIGHT_GRAY] {0}
-text.mission.info = Mission Info
-text.mission.complete = Mission complete!
-text.mission.complete.body = Sector {0},{1} has been conquered.
-text.mission.wave = Survive[accent] {0}/{1} []waves\nWave in {2}
-text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
-text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
-text.mission.wave.menu = Survive[accent] {0} []waves
-text.mission.battle = Destroy the enemy base.
-text.mission.resource.menu = Obtain {0} x{1}
-text.mission.resource = Obtain {0}:\n[accent]{1}/{2}[]
-text.mission.block = Create {0}
-text.mission.unit = Create {0} Unit
-text.mission.command = Send Command {0} To Units
-text.mission.linknode = Link Power Node
-text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0}
-text.mission.mech = Switch to mech[accent] {0}[]
-text.mission.create = Create[accent] {0}[]
-text.none =
-text.close = Close
+text.missions = 任務︰[LIGHT_GRAY]{0}
+text.mission = 任務︰[LIGHT_GRAY]{0}
+text.mission.main = 主要任務︰[LIGHT_GRAY]{0}
+text.mission.info = 任務資訊
+text.mission.complete = 任務完成!
+text.mission.complete.body = 區域{0},{1}已被佔領。
+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}[]波
+text.mission.battle = 摧毀敵方基地。
+text.mission.resource.menu = 獲取{0}x{1}
+text.mission.resource = 獲取{0}︰\n[accent]{1}/{2}[]
+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 = 轉換至[accent]{0}[]機甲
+text.mission.create = 製造[accent]{0}[]
+text.none = <沒有>
+text.close = 關閉
text.quit = 退出
-text.maps = Maps
-text.continue = Continue
-text.nextmission = Next Mission
-text.maps.none = [LIGHT_GRAY]No maps found!
+text.maps = 地圖
+text.continue = 繼續
+text.nextmission = 下一個任務
+text.maps.none = [LIGHT_GRAY]找不到地圖!
text.about.button = 關於
-text.name = 姓名:
-text.filename = File Name:
-text.unlocked = New Block Unlocked!
-text.unlocked.plural = New Blocks Unlocked!
-text.players = {0} 個線上玩家
-text.players.single = {0} 個線上玩家
-text.server.closing = [accent] 正在關閉伺服器...
+text.name = 名稱:
+text.filename = 檔案名稱︰
+text.unlocked = 新方塊已解鎖!
+text.unlocked.plural = 新方塊已解鎖!
+text.players = {0}個線上玩家
+text.players.single = {0}個線上玩家
+text.server.closing = [accent]正在關閉伺服器……
text.server.kicked.kick = 您已被踢出伺服器!
-text.server.kicked.serverClose = Server closed.
-text.server.kicked.sectorComplete = Sector completed.
-text.server.kicked.sectorComplete.text = Your mission is complete.\nThe server will now continue at the next sector.
+text.server.kicked.serverClose = 伺服器已關閉。
+text.server.kicked.sectorComplete = 區域已完成。
+text.server.kicked.sectorComplete.text = 任務已完成。\n服務器將於下一個區域繼續。
text.server.kicked.clientOutdated = 客戶端版本過舊!請更新遊戲!
text.server.kicked.serverOutdated = 伺服器版本過舊!請聯絡伺服主更新伺服器!
text.server.kicked.banned = 您已經從這個伺服器被封禁。
text.server.kicked.recentKick = 您已經從伺服器被踢除。\n請稍後再進行連線。
-text.server.kicked.nameInUse = There is someone with that name\nalready on this server.
-text.server.kicked.nameEmpty = Your name must contain at least one character or number.
-text.server.kicked.idInUse = You are already on this server! Connecting with two accounts is not permitted.
-text.server.kicked.customClient = This server does not support custom builds. Download an official version.
-text.host.info = 目前伺服器監聽於連接埠 [scarlet]6567[] 與 [scarlet]6568[]。\n所有跟您在同一個[LIGHT_GRAY]無線網路或區域網路[]環境的玩家應該能在他們的伺服器清單中找到您的伺服器。\n如果您希望網際網路上的玩家透過 IP 位址連線到您的伺服器,您必須設定[accent]連接埠轉發[]。\n\n[LIGHT_GRAY]注意:如果區域網路內有玩家無法連線至您的伺服器,請務必確認您已於防火牆設定中開放 Mindustry 存取您的區域網路。
-text.join.info = 您可以在此輸入欲連線的伺服器[accent] IP 位址[],或尋找[accent]區域網路[]內的伺服器。目前支援區域網路與網際網路連線。\n\n [LIGHT_GRAY]注意:這裡沒有網際網路伺服器清單,如果您想透過 IP 位址連線到某人的伺服器,您必須向他們詢問 IP 位址。
+text.server.kicked.nameInUse = 伺服器中已經\n有人有相同的名稱了。
+text.server.kicked.nameEmpty = 你的名稱必須至少包含一個字母或數字。
+text.server.kicked.idInUse = 你已經在伺服器中!不允許用兩個賬號。
+text.server.kicked.customClient = 這個伺服器不支持自訂客戶端,請下載官方版本。
+text.host.info = 目前伺服器監聽於連接埠[scarlet]6567[]。\n所有跟您在同一個[LIGHT_GRAY]網路或區域網路[]環境的玩家應該能在他們的伺服器清單中找到您的伺服器。\n\n如果您希望網際網路上的玩家透過IP 位址連線到您的伺服器,您必須設定[accent]連接埠轉發[]。\n\n[LIGHT_GRAY]注意:如果區域網路內有玩家無法連線至您的伺服器,請務必確認您已於防火牆設定中開放Mindustry存取您的區域網路。
+text.join.info = 您可以在此輸入欲連線的[accent]伺服器的IP位址[],或尋找[accent]區域網路[]內的伺服器。目前支援區域網路與網際網路連線。\n\n[LIGHT_GRAY]注意:這裡沒有網際網路伺服器清單,如果您想透過IP位址連線到某人的伺服器,您必須向他們詢問IP位址。
text.hostserver = 建立伺服器
-text.hostserver.mobile = Host\nGame
+text.hostserver.mobile = 建立\n伺服器
text.host = 建立
-text.hosting = [accent]伺服器啟動中...
+text.hosting = [accent]伺服器啟動中……
text.hosts.refresh = 刷新
text.hosts.discovering = 搜尋區域網路遊戲
text.server.refreshing = 刷新伺服器
text.hosts.none = [lightgray]找不到區域網路伺服器!
text.host.invalid = [scarlet]無法連線至伺服器。
text.trace = 跟隨玩家
-text.trace.playername = 玩家名稱:[accent] {0}
-text.trace.ip = IP:[accent] {0}
-text.trace.id = ID:[accent] {0}
-text.trace.android = Android 客戶端:[accent] {0}
-text.trace.modclient = 自訂客戶端:[accent] {0}
-text.trace.totalblocksbroken = 方塊拆除總數:[accent] {0}
-text.trace.structureblocksbroken = 結構方塊拆除數:[accent] {0}
-text.trace.lastblockbroken = 最後拆除的方塊:[accent] {0}
-text.trace.totalblocksplaced = 方塊建造數:[accent] {0}
-text.trace.lastblockplaced = 最後建造的方塊:[accent] {0}
+text.trace.playername = 玩家名稱:[accent]{0}
+text.trace.ip = IP:[accent]{0}
+text.trace.id = ID:[accent]{0}
+text.trace.android = Android 客戶端:[accent]{0}
+text.trace.modclient = 自訂客戶端:[accent]{0}
+text.trace.totalblocksbroken = 方塊拆除總數:[accent]{0}
+text.trace.structureblocksbroken = 結構方塊拆除數:[accent]{0}
+text.trace.lastblockbroken = 最後拆除的方塊:[accent]{0}
+text.trace.totalblocksplaced = 方塊建造數:[accent]{0}
+text.trace.lastblockplaced = 最後建造的方塊:[accent]{0}
text.invalidid = 無效的客戶端 ID!請提交錯誤報告。
text.server.bans = 封禁
text.server.bans.none = 沒有玩家被封禁!
@@ -120,57 +120,57 @@ text.server.admins = 管理員
text.server.admins.none = 找不到管理員!
text.server.add = 新增伺服器
text.server.delete = 您確定要刪除這個伺服器嗎?
-text.server.hostname = 主機: {0}
+text.server.hostname = 主機:{0}
text.server.edit = 編輯伺服器
text.server.outdated = [crimson]伺服器版本過舊![]
text.server.outdated.client = [crimson]客戶端版本過舊![]
-text.server.version = [lightgray]版本: {0}
+text.server.version = [lightgray]版本:{0}
text.server.custombuild = [yellow]自訂組建
text.confirmban = 您確定要封禁該玩家嗎?
-text.confirmkick = Are you sure you want to kick this player?
+text.confirmkick = 您確定要踢出該玩家嗎?
text.confirmunban = 您確定要解除封禁該玩家嗎?
text.confirmadmin = 您確定要提升這個玩家為管理員嗎?
text.confirmunadmin = 您確定要解除這個玩家的管理員嗎?
text.joingame.title = 加入遊戲
-text.joingame.ip = IP 位址:
+text.joingame.ip = IP位址:
text.disconnect = 已中斷連線。
text.disconnect.data = 無法載入地圖資料!
-text.connecting = [accent]連線中...
-text.connecting.data = [accent]正在載入地圖資料...
+text.connecting = [accent]連線中……
+text.connecting.data = [accent]正在載入地圖資料……
text.server.port = 連接埠:
text.server.addressinuse = 該位址已使用中!
text.server.invalidport = 無效的連接埠!
-text.server.error = [crimson]建立伺服器時發生錯誤:[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.server.error = [crimson]建立伺服器時發生錯誤:[accent]{0}
+text.save.old = 這個存檔屬於舊版本,無法使用了。\n\n[LIGHT_GRAY]舊存檔兼容將在正式4.0版本中實現。
text.save.new = 新存檔
text.save.overwrite = 您確定要覆蓋存檔嗎?
-text.overwrite = 覆蓋存檔
+text.overwrite = 覆蓋
text.save.none = 找不到存檔!
-text.saveload = [accent]存檔中...
+text.saveload = [accent]存檔中……
text.savefail = 無法存檔!
text.save.delete.confirm = 您確定要刪除這個存檔嗎?
-text.save.delete = 刪除存檔
+text.save.delete = 刪除
text.save.export = 匯出存檔
-text.save.import.invalid = [accent]這是個無效的存檔!\n\n請注意您[scarlet]無法[accent]匯入自訂地圖存檔!
-text.save.import.fail = [crimson]無法匯入存檔: [accent]{0}
-text.save.export.fail = [crimson]無法匯出存檔: [accent] {0}
+text.save.import.invalid = [accent]這是個無效的存檔!
+text.save.import.fail = [crimson]無法匯入存檔:[accent]{0}
+text.save.export.fail = [crimson]無法匯出存檔:[accent]{0}
text.save.import = 匯入存檔
text.save.newslot = 存檔名稱:
text.save.rename = 重新命名
text.save.rename.text = 新名稱:
text.selectslot = 選取一個存檔。
-text.slot = [accent]存檔 {0}
-text.save.corrupted = [accent]此存檔無效或已損毀!
-text.sector.corrupted = [accent]A save file for this sector was found, but loading failed.\nA new one has been created.
+text.slot = [accent]存檔{0}
+text.save.corrupted = [accent]此存檔無效或已損毀!\n如果你剛剛升級了遊戲,那麼這可能是因為存檔格式改變了而[scarlet]不是[]錯誤。
+text.sector.corrupted = [accent]找到此區域的存檔,但是加載失敗。\n已經創建了一個新的存檔。
text.empty = <空白>
text.on = 開啟
text.off = 關閉
text.save.autosave = 自動存檔:{0}
-text.save.map = 地圖: {0}
-text.save.wave = 波次: {0}
-text.save.difficulty = 難度: {0}
+text.save.map = 地圖:{0}
+text.save.wave = 波次:{0}
+text.save.difficulty = 難度:{0}
text.save.date = 最後存檔時間:{0}
-text.save.playtime = Playtime: {0}
+text.save.playtime = 遊玩時間: {0}
text.confirm = 確認
text.delete = 刪除
text.ok = 確定
@@ -181,70 +181,70 @@ text.copylink = 複製連結
text.back = 返回
text.quit.confirm = 您確定要退出嗎?
text.changelog.title = 更新日誌
-text.changelog.loading = 正在取得更新日誌...
-text.changelog.error.android = [accent]請注意,更新日誌有時無法在 Android 4.4 或更低版本使用!這是因為 Android 的內部 Bug 導致。
-text.changelog.error.ios = [accent]目前無法在 iOS 系統中使用更新日誌。
+text.changelog.loading = 正在取得更新日誌……
+text.changelog.error.android = [accent]請注意,更新日誌有時無法在Android 4.4或更低版本使用!這是因為 Android 的內部錯誤導致。
+text.changelog.error.ios = [accent]目前無法在iOS系統中使用更新日誌。
text.changelog.error = [scarlet]無法取得更新日誌!請檢查您的網路連線!
-text.changelog.current = [yellow][[目前版本]
-text.changelog.latest = [accent][[最新版本]
-text.loading = [accent]載入中...
-text.saving = [accent]Saving...
-text.wave = [accent]第 {0} 波
-text.wave.waiting = 將於 {0} 秒後抵達
-text.waiting = 等待中...
-text.waiting.players = Waiting for players...
-text.wave.enemies = [LIGHT_GRAY]{0} Enemies Remaining
-text.wave.enemy = [LIGHT_GRAY]{0} Enemy Remaining
+text.changelog.current = [yellow][[Current version]
+text.changelog.latest = [accent][[Latest version]
+text.loading = [accent]載入中……
+text.saving = [accent]儲存中……
+text.wave = [accent]第{0}波
+text.wave.waiting = 將於{0}秒後抵達
+text.waiting = 等待中……
+text.waiting.players = 等待玩家中……
+text.wave.enemies = [LIGHT_GRAY]剩下{0}敵人
+text.wave.enemy = [LIGHT_GRAY]剩下{0}敵人
text.loadimage = 載入圖像
text.saveimage = 儲存圖像
-text.unknown = Unknown
-text.custom = Custom
-text.builtin = Built-In
-text.map.delete.confirm = Are you sure you want to delete this map? This action cannot be undone!
-text.map.random = [accent]Random Map
-text.map.nospawn = This map does not have any cores for the player to spawn in! Add a [ROYAL]blue[] core to this map in the editor.
-text.map.nospawn.pvp = This map does not have any enemy cores for player to spawn into! Add[SCARLET] red[] cores to this map in the editor.
-text.map.invalid = Error loading map: corrupted or invalid map file.
-text.editor.brush = Brush
+text.unknown = 未知
+text.custom = 自訂
+text.builtin = 内建
+text.map.delete.confirm = 確認要刪除地圖嗎?此操作無法撤回!
+text.map.random = [accent]隨機地圖
+text.map.nospawn = 這個地圖沒有核心!請在編輯器中添加一個[ROYAL]藍色[]的核心。
+text.map.nospawn.pvp = 這個地圖沒有核心讓敵人重生!請在編輯器中添加一個[SCARLET]紅色[]的核心。
+text.map.invalid = 地圖載入錯誤:地圖可能已經損壞。
+text.editor.brush = 粉刷
text.editor.slope = \\
-text.editor.openin = Open In Editor
-text.editor.oregen = Ore Generation
-text.editor.oregen.info = Ore Generation:
-text.editor.mapinfo = Map Info
-text.editor.author = Author:
-text.editor.description = Description:
-text.editor.name = Name:
-text.editor.teams = Teams
-text.editor.elevation = Elevation
-text.editor.errorimageload = 載入圖像檔時發生錯誤:[accent] {0}
-text.editor.errorimagesave = 儲存圖像檔時發生錯誤:[橙色] {0}
+text.editor.openin = 在編輯器中開啟
+text.editor.oregen = 礦石產生
+text.editor.oregen.info = 礦石產生:
+text.editor.mapinfo = 地圖資訊
+text.editor.author = 作者:
+text.editor.description = 描述:
+text.editor.name = 名稱:
+text.editor.teams = 隊伍
+text.editor.elevation = 高度
+text.editor.errorimageload = 載入圖像檔時發生錯誤:[accent]{0}
+text.editor.errorimagesave = 儲存圖像檔時發生錯誤:[橙色]{0}
text.editor.generate = 產生
text.editor.resize = 調整大小
text.editor.loadmap = 載入地圖
text.editor.savemap = 儲存地圖
-text.editor.saved = Saved!
-text.editor.save.noname = Your map does not have a name! Set one in the 'map info' menu.
-text.editor.save.overwrite = Your map overwrites a built-in map! Pick a different name in the 'map info' menu.
-text.editor.import.exists = [scarlet]Unable to import:[] a built-in map named '{0}' already exists!
-text.editor.import = Import...
-text.editor.importmap = Import Map
-text.editor.importmap.description = Import an already existing map
-text.editor.importfile = Import File
-text.editor.importfile.description = Import an external map file
-text.editor.importimage = Import Terrain Image
-text.editor.importimage.description = Import an external map image file
-text.editor.export = Export...
-text.editor.exportfile = Export File
-text.editor.exportfile.description = Export a map file
-text.editor.exportimage = Export Terrain Image
-text.editor.exportimage.description = Export a map image file
+text.editor.saved = 已儲存!
+text.editor.save.noname = 您的地圖沒有名稱!在「地圖資訊」畫面設置一個名稱。
+text.editor.save.overwrite = 您的地圖覆寫一個內建的地圖!在「地圖信息」畫面設置一個不同的名稱。
+text.editor.import.exists = [scarlet]匯入失敗:[]一個叫「{0}」的內建地圖已存在!
+text.editor.import = 匯入……
+text.editor.importmap = 匯入地圖
+text.editor.importmap.description = 匯入一個已存在的地圖
+text.editor.importfile = 匯入檔案
+text.editor.importfile.description = 匯入一個外部的地圖檔案
+text.editor.importimage = 匯入地形圖像檔
+text.editor.importimage.description = 匯入一個外部的地形圖像檔
+text.editor.export = 匯出……
+text.editor.exportfile = 匯出檔案
+text.editor.exportfile.description = 匯出一個地圖檔案
+text.editor.exportimage = 匯出地形圖像檔
+text.editor.exportimage.description = 匯出一個地形圖像檔
text.editor.loadimage = 載入圖像
text.editor.saveimage = 儲存圖像
text.editor.unsaved = [scarlet]尚未儲存變更![]\n您確定要退出嗎?
text.editor.resizemap = 調整地圖大小
text.editor.mapname = 地圖名稱:
text.editor.overwrite = [accent]警告!這將會覆蓋現有的地圖。
-text.editor.overwrite.confirm = [scarlet]Warning![] A map with this name already exists. Are you sure you want to overwrite it?
+text.editor.overwrite.confirm = [scarlet]警告![]同名地圖存在,確定要覆蓋現有地圖?
text.editor.selectmap = 選取要載入的地圖:
text.width = 寬度:
text.height = 長度:
@@ -252,104 +252,104 @@ text.menu = 主選單
text.play = 開始
text.load = 載入
text.save = 儲存
-text.fps = FPS: {0}
-text.tps = TPS: {0}
-text.ping = Ping: {0}ms
+text.fps = 螢幕刷新率:{0}
+text.tps = TPS:{0}
+text.ping = 延遲:{0}ms
text.language.restart = 請重新啟動遊戲以使選取的語言生效。
text.settings = 設定
text.tutorial = 教學
text.editor = 地圖編輯器
text.mapeditor = 地圖編輯器
text.donate = 贊助
-text.connectfail = [crimson]無法連線到伺服器: [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.connectfail = [crimson]無法連線到伺服器:[accent]{0}
+text.error.unreachable = 無法到達伺服器。
+text.error.invalidaddress = 無效地址。
+text.error.timedout = 超時連接!\n確保伺服器設置了連接埠轉發,並且地址正確!
+text.error.mismatch = 包裹錯誤:\n客戶端/伺服器版本可能不匹配。 n確保客戶端和伺服器有最新版本的Mindustry!
+text.error.alreadyconnected = 已連接。
+text.error.mapnotfound = 找不到地圖!
+text.error.any = 未知網絡錯誤。
text.settings.language = 語言
text.settings.reset = 重設為預設設定
-text.settings.rebind = Rebind
+text.settings.rebind = 重新綁定
text.settings.controls = 操作
text.settings.game = 遊戲
text.settings.sound = 音效
text.settings.graphics = 圖形
-text.settings.cleardata = Clear Game Data...
-text.settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone!
-text.settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit.
-text.settings.clearsectors = Clear Sectors
-text.settings.clearunlocks = Clear Unlocks
-text.settings.clearall = Clear All
+text.settings.cleardata = 清除遊戲數據……
+text.settings.clear.confirm = 您確定要清除數據嗎?\n此操作無法撤回!
+text.settings.clearall.confirm = [scarlet]警告![]\n這將清除所有數據,包括存檔、地圖、解鎖和熱鍵綁定。\n按「是」後,遊戲將刪除所有數據並自動退出。
+text.settings.clearsectors = 清除區域
+text.settings.clearunlocks = 清除已解鎖
+text.settings.clearall = 清除所有
text.paused = 已暫停
-text.yes = Yes
-text.no = No
+text.yes = 是
+text.no = 否
text.info.title = [accent]資訊
text.error.title = [crimson]發生錯誤
text.error.crashtitle = 發生錯誤
text.blocks.blockinfo = 方塊資訊
text.blocks.powercapacity = 蓄電量
-text.blocks.powershot = 每發射擊功耗
-text.blocks.targetsair = Targets Air
-text.blocks.itemspeed = Units Moved
-text.blocks.shootrange = Range
+text.blocks.powershot = 能源/射擊
+text.blocks.targetsair = 攻擊空中目標
+text.blocks.itemspeed = 移動速度
+text.blocks.shootrange = 範圍
text.blocks.size = 尺寸
text.blocks.liquidcapacity = 液體容量
text.blocks.maxitemssecond = 最高產量
text.blocks.powerrange = 輸出範圍
-text.blocks.poweruse = Power Use
-text.blocks.powerdamage = Power/Damage
-text.blocks.inputitemcapacity = Input Item Capacity
-text.blocks.outputitemcapacity = Input Item Capacity
-text.blocks.itemcapacity = 材料容量
-text.blocks.basepowergeneration = Base Power Generation
-text.blocks.powertransferspeed = Power Transfer
-text.blocks.craftspeed = Production Speed
+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 = Aux Liquid
-text.blocks.inputitem = 輸入材料
-text.blocks.inputitems = Input Items
-text.blocks.outputitem = Output Item
-text.blocks.drilltier = Drillables
-text.blocks.drillspeed = Base Drill Speed
-text.blocks.liquidoutput = Liquid Output
-text.blocks.liquidoutputspeed = Liquid Output Speed
-text.blocks.liquiduse = Liquid Use
-text.blocks.coolant = Coolant
-text.blocks.coolantuse = Coolant Use
-text.blocks.inputliquidfuel = Fuel Liquid
-text.blocks.liquidfueluse = Liquid Fuel Use
-text.blocks.explosive = 易爆裂物!
+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.inaccuracy = 誤差
text.blocks.shots = 射擊數
-text.blocks.reload = Reload
-text.blocks.inputfuel = Fuel
-text.blocks.fuelburntime = Fuel Burn Time
+text.blocks.reload = 重裝彈藥
+text.blocks.inputfuel = 燃料
+text.blocks.fuelburntime = 燃燒燃料時間
text.blocks.inputcapacity = 輸入容量
text.blocks.outputcapacity = 輸出容量
-text.unit.blocks = blocks
-text.unit.powersecond = power units/second
-text.unit.liquidsecond = liquid units/second
-text.unit.itemssecond = items/second
-text.unit.pixelssecond = pixels/second
-text.unit.liquidunits = liquid units
-text.unit.powerunits = power units
-text.unit.degrees = degrees
-text.unit.seconds = seconds
-text.unit.items = items
-text.category.general = General
-text.category.power = Power
-text.category.liquids = Liquids
-text.category.items = Items
-text.category.crafting = Crafting
-text.category.shooting = Shooting
-setting.autotarget.name = Auto-Target
-setting.fpscap.name = Max FPS
-setting.fpscap.none = None
-setting.fpscap.text = {0} FPS
-setting.difficulty.training = training
+text.unit.blocks = 方塊
+text.unit.powersecond = 能源單位/秒
+text.unit.liquidsecond = 液體單位/秒
+text.unit.itemssecond = 物品/秒
+text.unit.pixelssecond = 像素/秒
+text.unit.liquidunits = 液體單位
+text.unit.powerunits = 能源單位
+text.unit.degrees = 度
+text.unit.seconds = 秒
+text.unit.items = 物品
+text.category.general = 一般
+text.category.power = 能源
+text.category.liquids = 液體
+text.category.items = 物品
+text.category.crafting = 合成
+text.category.shooting = 射擊
+setting.autotarget.name = 自動射擊
+setting.fpscap.name = 最大螢幕刷新率
+setting.fpscap.none = 没有
+setting.fpscap.text = {0}螢幕刷新率
+setting.difficulty.training = 訓練
setting.difficulty.easy = 簡單
setting.difficulty.normal = 普通
setting.difficulty.hard = 困難
@@ -359,31 +359,32 @@ setting.screenshake.name = 畫面抖動
setting.effects.name = 顯示特效
setting.sensitivity.name = 控制器靈敏度
setting.saveinterval.name = 自動存檔間隔
-setting.seconds = {0} 秒
+setting.seconds = {0}秒
setting.fullscreen.name = 全螢幕
setting.multithread.name = 多執行緒
setting.fps.name = 顯示螢幕刷新率
setting.vsync.name = 垂直同步
setting.lasers.name = 顯示雷射光束
-setting.minimap.name = Show Minimap
+setting.minimap.name = 顯示小地圖
setting.musicvol.name = 音樂音量
setting.mutemusic.name = 靜音
setting.sfxvol.name = 音效音量
setting.mutesound.name = 靜音
+setting.crashreport.name = Send Anonymous Crash Reports
text.keybind.title = 重新綁定按鍵
-category.general.name = General
-category.view.name = View
-category.multiplayer.name = Multiplayer
-command.attack = Attack
-command.retreat = Retreat
-command.patrol = Patrol
-keybind.press = Press a key...
-keybind.press.axis = Press an axis or key...
+category.general.name = 一般
+category.view.name = 查看
+category.multiplayer.name = 多人
+command.attack = 攻擊
+command.retreat = 撤退
+command.patrol = 巡邏
+keybind.press = 按一下鍵
+keybind.press.axis = 按一下軸心或鍵
keybind.move_x.name = 水平移動
keybind.move_y.name = 垂直移動
keybind.select.name = 選取
keybind.break.name = 拆除
-keybind.deselect.name = Deselect
+keybind.deselect.name = 取消選取
keybind.shoot.name = 射擊
keybind.zoom_hold.name = 按住縮放
keybind.zoom.name = 縮放
@@ -394,200 +395,201 @@ keybind.chat.name = 聊天
keybind.player_list.name = 玩家列表
keybind.console.name = 終端機
keybind.rotate.name = 旋轉
-keybind.toggle_menus.name = Toggle menus
-keybind.chat_history_prev.name = Chat history prev
-keybind.chat_history_next.name = Chat history next
-keybind.chat_scroll.name = Chat scroll
-keybind.drop_unit.name = drop unit
-keybind.zoom_minimap.name = Zoom minimap
+keybind.toggle_menus.name = 切換畫面
+keybind.chat_history_prev.name = 之前的聊天記錄
+keybind.chat_history_next.name = 之後的聊天記錄
+keybind.chat_scroll.name = 聊天記錄滾動
+keybind.drop_unit.name = 放下單位
+keybind.zoom_minimap.name = 縮放小地圖
mode.text.help.title = 模式說明
mode.waves.name = 一般
mode.waves.description = 一般模式,有限的資源與自動來襲的波次。
mode.sandbox.name = 沙盒
mode.sandbox.description = 無限的資源,與不倒數計時的波次。
-mode.custom.warning = Note that blocks cannot be used in custom games until they are unlocked in sectors.\n\n[LIGHT_GRAY]If you have not unlocked any blocks, none will appear.
-mode.custom.warning.read = Just to make sure you've read it:\n[scarlet]UNLOCKS IN CUSTOM GAMES DO NOT CARRY OVER TO SECTORS OR OTHER MODES!\n\n[LIGHT_GRAY](I wish this wasn't necessary, but apparently it is)
+mode.custom.warning = 請注意,方塊在區域內解鎖之前,不能用於自訂遊戲。\n\n[LIGHT_GRAY]如果您沒有解鎖任何方塊,則不會出現任何方塊。
+mode.custom.warning.read = 確保你已閱讀過它:\n[scarlet]自訂遊戲的解鎖不帶至區域或其他模式!\n\n[LIGHT_GRAY](我希望這不是必要的,但顯然是必要的)
mode.freebuild.name = 自由建造
mode.freebuild.description = 有限的資源,與不倒數計時的波次。
-mode.pvp.name = PvP
-mode.pvp.description = fight against other players locally.
-content.item.name = Items
-content.liquid.name = Liquids
-content.unit.name = Units
-content.recipe.name = Blocks
-content.mech.name = Mechs
+mode.pvp.name = 對戰
+mode.pvp.description = 和其他玩家鬥爭。
+content.item.name = 物品
+content.liquid.name = 液體
+content.unit.name = 機組
+content.recipe.name = 方塊
+content.mech.name = 機甲
item.stone.name = 石材
-item.stone.description = A common raw material. Used for separating and refining into other materials, or melting into lava.
-item.copper.name = Copper
-item.copper.description = A useful structure material. Used extensively in all types of blocks.
-item.lead.name = Lead
-item.lead.description = A basic starter material. Used extensively in electronics and liquid transportation blocks.
-item.coal.name = 煤礦
-item.coal.description = A common and readily available fuel.
-item.dense-alloy.name = Dense Alloy
-item.dense-alloy.description = A tough alloy made with lead and copper. Used in advanced transportation blocks and high-tier drills.
+item.stone.description = 一種常見的原料。用於分離和提煉成其他材料,或熔化成熔岩。
+item.copper.name = 銅
+item.copper.description = 一種有用的結構材料。在各種類型的方塊中廣泛使用。
+item.lead.name = 鉛
+item.lead.description = 一種基本的起始材料。被廣泛用於電子設備和運輸液體方塊。
+item.coal.name = 煤
+item.coal.description = 一種常見並容易獲得的燃料。
+item.dense-alloy.name = 稠密合金
+item.dense-alloy.description = 一種由鉛和銅製成的堅韌合金。用於高級的運輸方塊和高級鑽頭。
item.titanium.name = 鈦
-item.titanium.description = A rare super-light metal used extensively in liquid transportation, drills and aircraft.
-item.thorium.name = Thorium
-item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel.
-item.silicon.name = Silicon
-item.silicon.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics.
-item.plastanium.name = Plastanium
-item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition.
-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 = Surge Alloy
-item.surge-alloy.description = An advanced alloy with unique electrical properties.
-item.biomatter.name = Biomatter
-item.biomatter.description = A clump of organic mush; used for conversion into oil or as a basic fuel.
+item.titanium.description = 一種罕見的超輕金屬,被廣泛運用於運輸液體、鑽頭和飛機。
+item.thorium.name = 釷
+item.thorium.description = 一種稠密的放射性金屬,用作支撐結構和核燃料。
+item.silicon.name = 矽
+item.silicon.description = 一種非常有用的半導體,被用於太陽能電池板和很多複雜的電子設備。
+item.plastanium.name = 塑料
+item.plastanium.description = 一種輕量、可延展的材料,用於高級的飛機和碎彈藥。
+item.phase-fabric.name = 相織布
+item.phase-fabric.description = 一種近乎無重量的物質,用於先進的電子設備和自修復技術。
+item.surge-alloy.name = 波動合金
+item.surge-alloy.description = 一種具有獨特電子特性的高級合金。
+item.biomatter.name = 生物物質
+item.biomatter.description = 一叢有機糊;用於轉化為油或作為基本燃料。
item.sand.name = 沙
-item.sand.description = A common material that is used extensively in smelting, both in alloying and as a flux.
-item.blast-compound.name = Blast Compound
-item.blast-compound.description = A volatile compound used in bombs and explosives. While it can burned as fuel, this is not advised.
-item.pyratite.name = Pyratite
-item.pyratite.description = An extremely flammable substance used in incendiary weapons.
+item.sand.description = 一種常見的材料,廣泛用於冶煉,包括製作合金和助熔劑。
+item.blast-compound.name = 爆炸混合物
+item.blast-compound.description = 一種用於炸彈和炸藥的揮發性混合物。雖然它可以作為燃料燃燒,但不建議這樣做。
+item.pyratite.name = 硫
+item.pyratite.description = 一種在燃燒武器中使用的極易燃物質。
liquid.water.name = 水
liquid.lava.name = 岩漿
liquid.oil.name = 原油
-liquid.cryofluid.name = Cryofluid
-mech.alpha-mech.name = Alpha
-mech.alpha-mech.weapon = Heavy Repeater
-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.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.tau-mech.name = Tau
-mech.tau-mech.weapon = Restruct Laser
-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.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.dart-ship.description = The standard ship. Reasonably fast and light, but has little offensive capability and low mining speed.
-mech.javelin-ship.name = Javelin
-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.weapon = Burst Missiles
-mech.javelin-ship.ability = Discharge Booster
-mech.trident-ship.name = Trident
-mech.trident-ship.description = A heavy bomber. Reasonably well armored.
-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.weapon = Flame Repeater
-text.item.explosiveness = [LIGHT_GRAY]Explosiveness: {0}
-text.item.flammability = [LIGHT_GRAY]Flammability: {0}
-text.item.radioactivity = [LIGHT_GRAY]Radioactivity: {0}
-text.item.fluxiness = [LIGHT_GRAY]Flux Power: {0}
-text.unit.health = [LIGHT_GRAY]Health: {0}
-text.unit.speed = [LIGHT_GRAY]Speed: {0}
-text.mech.weapon = [LIGHT_GRAY]Weapon: {0}
-text.mech.armor = [LIGHT_GRAY]Armor: {0}
-text.mech.itemcapacity = [LIGHT_GRAY]Item Capacity: {0}
-text.mech.minespeed = [LIGHT_GRAY]Mining Speed: {0}
-text.mech.minepower = [LIGHT_GRAY]Mining Power: {0}
-text.mech.ability = [LIGHT_GRAY]Ability: {0}
-text.liquid.heatcapacity = [LIGHT_GRAY]Heat Capacity: {0}
-text.liquid.viscosity = [LIGHT_GRAY]Viscosity: {0}
-text.liquid.temperature = [LIGHT_GRAY]Temperature: {0}
-block.spawn.name = Enemy Spawn
-block.core.name = Core
-block.metalfloor.name = Metal Floor
-block.deepwater.name = deepwater
-block.water.name = water
-block.lava.name = lava
-block.tar.name = Tar
-block.blackstone.name = blackstone
-block.stone.name = stone
-block.dirt.name = dirt
-block.sand.name = sand
-block.ice.name = ice
-block.snow.name = snow
-block.grass.name = grass
-block.shrub.name = shrub
-block.rock.name = rock
-block.blackrock.name = blackrock
-block.icerock.name = icerock
-block.copper-wall.name = Copper Wall
-block.copper-wall-large.name = Large Copper Wall
-block.dense-alloy-wall.name = Dense Alloy Wall
-block.dense-alloy-wall-large.name = Large Dense Alloy Wall
-block.phase-wall.name = Phase Wall
-block.phase-wall-large.name = Large Phase Wall
-block.thorium-wall.name = Thorium Wall
-block.thorium-wall-large.name = Large Thorium Wall
+liquid.cryofluid.name = 冷凍液
+mech.alpha-mech.name = 阿爾法
+mech.alpha-mech.weapon = 重型機關槍
+mech.alpha-mech.ability = 無人機群
+mech.alpha-mech.description = 標準的機甲。具有不錯的速度和傷害輸出;可以製造多達3架無人機以提高進攻能力。
+mech.delta-mech.name = 德爾塔
+mech.delta-mech.weapon = 電弧生成機
+mech.delta-mech.ability = 放電
+mech.delta-mech.description = 一种快速、轻铠的机甲,是用於打了就跑的攻擊。对结构造成的伤害很小,但可以用弧形闪电武器很快杀死大量敌方机组。
+mech.tau-mech.name = Tau机甲
+mech.tau-mech.weapon = 重構激光
+mech.tau-mech.ability = 修复陣
+mech.tau-mech.description = 支援機甲。射擊友好方塊以治療它們。可以使用它的修復能力熄滅火焰並治療一定範圍內的友軍。
+mech.omega-mech.name = 奧米伽
+mech.omega-mech.weapon = 導彈群
+mech.omega-mech.ability = 裝甲配置
+mech.omega-mech.description = 一種笨重、裝甲重的機甲,用於在前線突擊。它的裝甲能力可以阻擋高達90%的傷害。
+mech.dart-ship.name = 鏢船
+mech.dart-ship.weapon = 機關槍
+mech.dart-ship.description = 標準飛船。快速、輕便,但有低的攻擊能力和慢的採礦速度。
+mech.javelin-ship.name = 標槍
+mech.javelin-ship.description = 一種打了就跑的侵襲船。雖然最初很慢,但它可以加速到很快的速度,並飛過敵人的前哨站,利用其閃電能力和導彈造成大量的傷害。
+mech.javelin-ship.weapon = 爆發導彈
+mech.javelin-ship.ability = 放電助推器
+mech.trident-ship.name = 三叉
+mech.trident-ship.description = 一种重型轰炸机。有比較厚的装甲。
+mech.trident-ship.weapon = 炸彈
+mech.glaive-ship.name = 長柄
+mech.glaive-ship.description = 一種大型、裝甲厚的武裝直升機。配備燃燒機關槍。有優秀的加速能力與最快的速度。
+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.unit.health = [LIGHT_GRAY]耐久度:{0}
+text.unit.speed = [LIGHT_GRAY]速度:{0}
+text.mech.weapon = [LIGHT_GRAY]武器:{0}
+text.mech.armor = [LIGHT_GRAY]裝甲:{0}
+text.mech.itemcapacity = [LIGHT_GRAY]物品容量:{0}
+text.mech.minespeed = [LIGHT_GRAY]採礦速度:{0}
+text.mech.minepower = [LIGHT_GRAY]採礦力度:{0}
+text.mech.ability = [LIGHT_GRAY]能力:{0}
+text.liquid.heatcapacity = [LIGHT_GRAY]熱容量:{0}
+text.liquid.viscosity = [LIGHT_GRAY]粘性:{0}
+text.liquid.temperature = [LIGHT_GRAY]温度:{0}
+block.constructing = {0}\n[LIGHT_GRAY](Constructing)
+block.spawn.name = 敵人生成
+block.core.name = 核心
+block.metalfloor.name = 金屬地板
+block.deepwater.name = 深水
+block.water.name = 水
+block.lava.name = 岩浆
+block.tar.name = 焦油
+block.blackstone.name = 黑石頭
+block.stone.name = 石頭
+block.dirt.name = 泥土
+block.sand.name = 沙
+block.ice.name = 冰
+block.snow.name = 雪
+block.grass.name = 草
+block.shrub.name = 灌木
+block.rock.name = 岩石
+block.blackrock.name = 黑岩石
+block.icerock.name = 冰岩石
+block.copper-wall.name = 銅牆
+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.thorium-wall.name = 釷牆
+block.thorium-wall-large.name = 大型釷牆
block.door.name = 門
block.door-large.name = 大門
-block.duo.name = Duo
-block.scorch.name = Scorch
-block.hail.name = Hail
-block.lancer.name = Lancer
+block.duo.name = 雙炮
+block.scorch.name = 灼燒炮
+block.hail.name = 冰雹炮
+block.lancer.name = 藍瑟炮
block.conveyor.name = 輸送帶
-block.titanium-conveyor.name = Titanium Conveyor
+block.titanium-conveyor.name = 鈦輸送帶
block.junction.name = 樞紐
block.router.name = 分配器
-block.distributor.name = Distributor
+block.distributor.name = 大型分配器
block.sorter.name = 分類器
-block.sorter.description = Sorts items. If an item matches the selection, it is allowed to pass. Otherwise, the item is outputted to the left and right.
-block.overflow-gate.name = Overflow Gate
-block.overflow-gate.description = A combination splitter and router that only outputs to the left and right if the front path is blocked.
+block.sorter.description = 對物品進行分類。如果物品與所選種類匹配,則允許其通過。否則,物品將從左邊和右邊輸出。
+block.overflow-gate.name = 溢流器
+block.overflow-gate.description = 分離器和分配器的組合。如果前面被擋住,則向從左邊和右邊輸出物品。
block.smelter.name = 煉鋼廠
-block.arc-smelter.name = Arc Smelter
-block.silicon-smelter.name = Silicon Smelter
-block.phase-weaver.name = Phase Weaver
-block.pulverizer.name = Pulverizer
-block.cryofluidmixer.name = Cryofluid Mixer
-block.melter.name = Melter
-block.incinerator.name = Incinerator
-block.biomattercompressor.name = Biomatter Compressor
-block.separator.name = Separator
-block.centrifuge.name = Centrifuge
-block.power-node.name = Power Node
-block.power-node-large.name = Large Power Node
-block.battery.name = Battery
-block.battery-large.name = Large Battery
-block.combustion-generator.name = Combustion Generator
-block.turbine-generator.name = Turbine Generator
-block.mechanical-drill.name = Mechanical Drill
-block.pneumatic-drill.name = Pneumatic Drill
-block.laser-drill.name = Laser Drill
-block.water-extractor.name = Water Extractor
-block.cultivator.name = Cultivator
-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.glaive-ship-pad.name = Glaive Ship Pad
-block.omega-mech-pad.name = Omega Mech Pad
-block.tau-mech-pad.name = Tau Mech Pad
+block.arc-smelter.name = 電弧煉鋼廠
+block.silicon-smelter.name = 煉矽廠
+block.phase-weaver.name = 相織布編織器
+block.pulverizer.name = 粉碎機
+block.cryofluidmixer.name = 冷凍液混合器
+block.melter.name = 熔爐
+block.incinerator.name = 焚化爐
+block.biomattercompressor.name = 生物物質壓縮機
+block.separator.name = 分離機
+block.centrifuge.name = 離心機
+block.power-node.name = 能源節點
+block.power-node-large.name = 大型能源節點
+block.battery.name = 電池
+block.battery-large.name = 大型電池
+block.combustion-generator.name = 燃燒發電機
+block.turbine-generator.name = 渦輪發電機
+block.mechanical-drill.name = 機械鑽頭
+block.pneumatic-drill.name = 氣動鑽頭
+block.laser-drill.name = 激光鑽頭
+block.water-extractor.name = 水提取器
+block.cultivator.name = 耕種機
+block.alpha-mech-pad.name = 阿爾法機甲墊
+block.dart-ship-pad.name = 鏢船墊
+block.delta-mech-pad.name = 德爾塔機甲墊
+block.javelin-ship-pad.name = 標槍機甲墊
+block.trident-ship-pad.name = 三叉船墊
+block.glaive-ship-pad.name = 長柄船墊
+block.omega-mech-pad.name = 奧米伽機甲墊
+block.tau-mech-pad.name = Tau機甲墊
block.conduit.name = 管線
-block.mechanical-pump.name = Mechanical Pump
-block.itemsource.name = Item Source
-block.itemvoid.name = Item Void
-block.liquidsource.name = Liquid Source
-block.powervoid.name = Power Void
-block.powerinfinite.name = Power Infinite
-block.unloader.name = Unloader
-block.vault.name = Vault
-block.wave.name = Wave
-block.swarmer.name = Swarmer
-block.salvo.name = Salvo
-block.ripple.name = Ripple
-block.phase-conveyor.name = Phase Conveyor
-block.bridge-conveyor.name = Bridge Conveyor
-block.plastanium-compressor.name = Plastanium Compressor
-block.pyratite-mixer.name = Pyratite Mixer
-block.blast-mixer.name = Blast Mixer
-block.solidifer.name = Solidifer
-block.solar-panel.name = Solar Panel
-block.solar-panel-large.name = Large Solar Panel
-block.oil-extractor.name = Oil Extractor
-block.spirit-factory.name = Spirit Drone Factory
+block.mechanical-pump.name = 機械泵
+block.itemsource.name = 物品源
+block.itemvoid.name = 物品空虚
+block.liquidsource.name = 液體源
+block.powervoid.name = 能源空虛
+block.powerinfinite.name = 無限能量
+block.unloader.name = 裝卸器
+block.vault.name = 存儲庫
+block.wave.name = 波浪炮
+block.swarmer.name = 群炮
+block.salvo.name = 齊射炮
+block.ripple.name = 波紋炮
+block.phase-conveyor.name = 相織布傳送帶
+block.bridge-conveyor.name = 傳送帶橋
+block.plastanium-compressor.name = 塑料壓縮機
+block.pyratite-mixer.name = 硫混合器
+block.blast-mixer.name = 爆炸混合器
+block.solidifer.name = 凝固器
+block.solar-panel.name = 太陽能板
+block.solar-panel-large.name = 大型太陽能板
+block.oil-extractor.name = 石油鑽井
+block.spirit-factory.name = 精神無人機工廠
block.phantom-factory.name = Phantom Drone Factory
block.wraith-factory.name = Wraith Fighter Factory
block.ghoul-factory.name = Ghoul Bomber Factory
@@ -595,43 +597,43 @@ block.dagger-factory.name = Dagger Mech Factory
block.titan-factory.name = Titan Mech Factory
block.fortress-factory.name = Fortress Mech Factory
block.revenant-factory.name = Revenant Fighter Factory
-block.repair-point.name = Repair Point
-block.pulse-conduit.name = Pulse Conduit
-block.phase-conduit.name = Phase Conduit
-block.liquid-router.name = Liquid Router
-block.liquid-tank.name = Liquid Tank
-block.liquid-junction.name = Liquid Junction
-block.bridge-conduit.name = Bridge Conduit
-block.rotary-pump.name = Rotary Pump
-block.thorium-reactor.name = Thorium Reactor
-block.command-center.name = Command Center
-block.mass-driver.name = Mass Driver
-block.blast-drill.name = Blast Drill
-block.thermal-pump.name = Thermal Pump
-block.thermal-generator.name = Thermal Generator
-block.alloy-smelter.name = Alloy Smtler
-block.mend-projector.name = Mend Projector
-block.surge-wall.name = Surge Wall
-block.surge-wall-large.name = Large Surge Wall
-block.cyclone.name = Cyclone
-block.fuse.name = Fuse
-block.shock-mine.name = Shock Mine
-block.overdrive-projector.name = Overdrive Projector
-block.force-projector.name = Force Projector
-block.arc.name = Arc
-block.rtg-generator.name = RTG Generator
-block.spectre.name = Spectre
-block.meltdown.name = Meltdown
-block.container.name = Container
-block.core.description = The most important building in the game.
-team.blue.name = blue
-team.red.name = red
-team.orange.name = orange
-team.none.name = gray
-team.green.name = green
-team.purple.name = purple
-unit.alpha-drone.name = Alpha Drone
-unit.spirit.name = Spirit Drone
+block.repair-point.name = 維修點
+block.pulse-conduit.name = 脈衝管線
+block.phase-conduit.name = 相織管線
+block.liquid-router.name = 液體分配器
+block.liquid-tank.name = 液體儲罐
+block.liquid-junction.name = 液體連接點
+block.bridge-conduit.name = 導管橋
+block.rotary-pump.name = 迴旋泵
+block.thorium-reactor.name = 釷反應堆
+block.command-center.name = 指令中心
+block.mass-driver.name = 質量驅動器
+block.blast-drill.name = 爆破鑽頭
+block.thermal-pump.name = 熱能泵
+block.thermal-generator.name = 熱能發電機
+block.alloy-smelter.name = 合金冶煉廠
+block.mend-projector.name = 修理投影器
+block.surge-wall.name = 波動牆
+block.surge-wall-large.name = 大型波動牆
+block.cyclone.name = 氣旋炮
+block.fuse.name = 融合炮
+block.shock-mine.name = 休克地雷
+block.overdrive-projector.name = 超速投影器
+block.force-projector.name = 力牆投影器
+block.arc.name = 電弧
+block.rtg-generator.name = 放射性同位素熱電發電機
+block.spectre.name = 幽靈炮
+block.meltdown.name = 熔毀炮
+block.container.name = 容器
+block.core.description = 遊戲中最重要的建築。
+team.blue.name = 藍
+team.red.name = 紅
+team.orange.name = 橙
+team.none.name = 灰
+team.green.name = 綠
+team.purple.name = 紫
+unit.alpha-drone.name = 阿爾法無人機
+unit.spirit.name = 精神無人機
unit.spirit.description = The starter drone unit. Spawns in the core by default. Automatically mines ores, collects items and repairs blocks.
unit.phantom.name = Phantom Drone
unit.phantom.description = An advanced drone unit. Automatically mines ores, collects items and repairs blocks. Significantly more effective than a drone.
diff --git a/core/assets/fonts/pixel.ttf b/core/assets/fonts/pixel.ttf
index 137848310c..177fff5182 100644
Binary files a/core/assets/fonts/pixel.ttf and b/core/assets/fonts/pixel.ttf differ
diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java
index a11a7dbdcb..ed21672801 100644
--- a/core/src/io/anuke/mindustry/Vars.java
+++ b/core/src/io/anuke/mindustry/Vars.java
@@ -17,12 +17,12 @@ import io.anuke.mindustry.game.Version;
import io.anuke.mindustry.gen.Serialization;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.world.blocks.defense.ForceProjector.ShieldEntity;
+import io.anuke.ucore.core.Settings;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.EffectEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.scene.ui.layout.Unit;
-import io.anuke.ucore.util.OS;
import io.anuke.ucore.util.Translator;
import java.util.Arrays;
@@ -170,7 +170,7 @@ public class Vars{
ios = Gdx.app.getType() == ApplicationType.iOS;
android = Gdx.app.getType() == ApplicationType.Android;
- dataDirectory = OS.getAppDataDirectory(appName);
+ dataDirectory = Settings.getDataDirectory(appName);
customMapDirectory = dataDirectory.child("maps/");
saveDirectory = dataDirectory.child("saves/");
baseCameraScale = Math.round(Unit.dp.scl(4));
diff --git a/core/src/io/anuke/mindustry/ai/BlockIndexer.java b/core/src/io/anuke/mindustry/ai/BlockIndexer.java
index 1213bd2721..04c5c04cb8 100644
--- a/core/src/io/anuke/mindustry/ai/BlockIndexer.java
+++ b/core/src/io/anuke/mindustry/ai/BlockIndexer.java
@@ -247,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/Recipes.java b/core/src/io/anuke/mindustry/content/Recipes.java
index bdc35d2cbd..08a7f8fac1 100644
--- a/core/src/io/anuke/mindustry/content/Recipes.java
+++ b/core/src/io/anuke/mindustry/content/Recipes.java
@@ -131,7 +131,7 @@ public class Recipes implements ContentList{
new Recipe(power, PowerBlocks.thoriumReactor, new ItemStack(Items.lead, 600), new ItemStack(Items.silicon, 400), new ItemStack(Items.densealloy, 300), new ItemStack(Items.thorium, 300));
new Recipe(power, PowerBlocks.rtgGenerator, new ItemStack(Items.lead, 200), new ItemStack(Items.silicon, 150), new ItemStack(Items.phasefabric, 50), new ItemStack(Items.plastanium, 150), new ItemStack(Items.thorium, 100));
- new Recipe(distribution, StorageBlocks.unloader, new ItemStack(Items.densealloy, 40), new ItemStack(Items.silicon, 50));
+ new Recipe(distribution, StorageBlocks.unloader, new ItemStack(Items.densealloy, 50), new ItemStack(Items.silicon, 60));
new Recipe(distribution, StorageBlocks.container, new ItemStack(Items.densealloy, 200));
new Recipe(distribution, StorageBlocks.vault, new ItemStack(Items.densealloy, 500), new ItemStack(Items.thorium, 250));
//core disabled due to being broken
diff --git a/core/src/io/anuke/mindustry/content/blocks/Blocks.java b/core/src/io/anuke/mindustry/content/blocks/Blocks.java
index 67e031d4a6..101539b893 100644
--- a/core/src/io/anuke/mindustry/content/blocks/Blocks.java
+++ b/core/src/io/anuke/mindustry/content/blocks/Blocks.java
@@ -45,6 +45,8 @@ public class Blocks extends BlockList implements ContentList{
}
};
+ //Registers build blocks from size 1-6
+ //no reference is needed here since they can be looked up by name later
for(int i = 1; i <= 6; i++){
new BuildBlock("build" + i);
}
diff --git a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java
index 1c13f76742..c5c7f58232 100644
--- a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java
+++ b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java
@@ -4,12 +4,11 @@ import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.world.Block;
-import io.anuke.mindustry.world.blocks.distribution.WarpGate;
import io.anuke.mindustry.world.blocks.power.*;
public class PowerBlocks extends BlockList implements ContentList{
public static Block combustionGenerator, thermalGenerator, turbineGenerator, rtgGenerator, solarPanel, largeSolarPanel,
- thoriumReactor, fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge, warpGate;
+ thoriumReactor, fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge;
@Override
public void load(){
@@ -85,7 +84,5 @@ public class PowerBlocks extends BlockList implements ContentList{
shadow = "shadow-round-2";
}};
- warpGate = new WarpGate("warp-gate");
-
}
}
diff --git a/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java b/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java
index d00275a05f..460a79da77 100644
--- a/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java
+++ b/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java
@@ -17,16 +17,16 @@ public class StorageBlocks extends BlockList implements ContentList{
vault = new Vault("vault"){{
size = 3;
- itemCapacity = 1000;
+ itemCapacity = 900;
}};
container = new Vault("container"){{
size = 2;
- itemCapacity = 250;
+ itemCapacity = 200;
}};
unloader = new SortedUnloader("unloader"){{
- speed = 5;
+ speed = 12f;
}};
}
}
diff --git a/core/src/io/anuke/mindustry/core/GameState.java b/core/src/io/anuke/mindustry/core/GameState.java
index 4e20c5ba75..bde128eb91 100644
--- a/core/src/io/anuke/mindustry/core/GameState.java
+++ b/core/src/io/anuke/mindustry/core/GameState.java
@@ -8,6 +8,9 @@ import io.anuke.mindustry.game.Teams;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.core.Events;
+import static io.anuke.mindustry.Vars.unitGroups;
+import static io.anuke.mindustry.Vars.waveTeam;
+
public class GameState{
public int wave = 1;
public float wavetime;
@@ -16,8 +19,13 @@ public class GameState{
public Difficulty difficulty = Difficulty.normal;
public WaveSpawner spawner = new WaveSpawner();
public Teams teams = new Teams();
+ public int enemies;
private State state = State.menu;
+ public int enemies(){
+ return Net.client() ? enemies : unitGroups[waveTeam.ordinal()].size();
+ }
+
public void set(State astate){
Events.fire(new StateChangeEvent(state, astate));
state = astate;
diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java
index f4aa97922b..5063a29b0b 100644
--- a/core/src/io/anuke/mindustry/core/Logic.java
+++ b/core/src/io/anuke/mindustry/core/Logic.java
@@ -34,7 +34,6 @@ import static io.anuke.mindustry.Vars.*;
* This class should not call any outside methods to change state of modules, but instead fire events.
*/
public class Logic extends Module{
- public boolean doUpdate = true;
public Logic(){
Events.on(TileChangeEvent.class, event -> {
@@ -125,7 +124,7 @@ public class Logic extends Module{
}
private void updateSectors(){
- if(world.getSector() == null) return;
+ if(world.getSector() == null || state.gameOver) return;
world.getSector().currentMission().update();
@@ -172,7 +171,6 @@ public class Logic extends Module{
@Override
public void update(){
- if(threads.isEnabled() && !threads.isOnThread()) return;
if(Vars.control != null){
control.runUpdateLogic();
@@ -219,12 +217,6 @@ public class Logic extends Module{
if(group.isEmpty()) continue;
EntityQuery.collideGroups(bulletGroup, group);
- EntityQuery.collideGroups(group, playerGroup);
-
- for(EntityGroup other : unitGroups){
- if(other.isEmpty()) continue;
- EntityQuery.collideGroups(group, other);
- }
}
EntityQuery.collideGroups(bulletGroup, playerGroup);
@@ -238,9 +230,5 @@ public class Logic extends Module{
checkGameOver();
}
}
-
- if(threads.isEnabled()){
- netServer.update();
- }
}
}
diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java
index 91b52c1cdf..99a224da9b 100644
--- a/core/src/io/anuke/mindustry/core/NetClient.java
+++ b/core/src/io/anuke/mindustry/core/NetClient.java
@@ -45,7 +45,7 @@ import static io.anuke.mindustry.Vars.*;
public class NetClient extends Module{
private final static float dataTimeout = 60 * 18;
private final static float playerSyncTime = 2;
- private final static float viewScale = 1.75f;
+ public final static float viewScale = 2f;
private Timer timer = new Timer(5);
/**Whether the client is currently connecting.*/
@@ -284,6 +284,7 @@ public class NetClient extends Module{
//read wave info
state.wavetime = input.readFloat();
state.wave = input.readInt();
+ state.enemies = input.readInt();
byte cores = input.readByte();
for(int i = 0; i < cores; i++){
@@ -399,11 +400,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);
}
@@ -414,11 +415,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 6fefd332ba..25ee6de9a4 100644
--- a/core/src/io/anuke/mindustry/core/NetServer.java
+++ b/core/src/io/anuke/mindustry/core/NetServer.java
@@ -412,11 +412,19 @@ public class NetServer extends Module{
}
public boolean isWaitingForPlayers(){
- return state.mode.isPvp && playerGroup.size() < 2;
+ if(state.mode.isPvp){
+ int used = 0;
+ for(Team t : Team.all){
+ if(playerGroup.count(p -> p.getTeam() == t) > 0){
+ used ++;
+ }
+ }
+ return used < 2;
+ }
+ return false;
}
public void update(){
- if(threads.isEnabled() && !threads.isOnThread()) return;
if(!headless && !closing && Net.server() && state.is(State.menu)){
closing = true;
@@ -469,6 +477,7 @@ public class NetServer extends Module{
//write wave datas
dataStream.writeFloat(state.wavetime);
dataStream.writeInt(state.wave);
+ dataStream.writeInt(state.enemies());
ObjectSet cores = state.teams.get(player.getTeam()).cores;
@@ -495,7 +504,7 @@ public class NetServer extends Module{
//check for syncable groups
for(EntityGroup> group : Entities.getAllGroups()){
if(group.isEmpty() || !(group.all().get(0) instanceof SyncTrait)) continue;
- //clipping is done by represntatives
+ //clipping is done by representatives
SyncTrait represent = (SyncTrait) group.all().get(0);
//make sure mapping is enabled for this group
diff --git a/core/src/io/anuke/mindustry/core/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java
index ec7e0308ca..63695bac48 100644
--- a/core/src/io/anuke/mindustry/core/Platform.java
+++ b/core/src/io/anuke/mindustry/core/Platform.java
@@ -1,13 +1,21 @@
package io.anuke.mindustry.core;
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Base64Coder;
+import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings;
+import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.Consumer;
+import io.anuke.ucore.scene.ui.Dialog;
import io.anuke.ucore.scene.ui.TextField;
+import io.anuke.ucore.util.Log;
import java.util.Random;
+import static io.anuke.mindustry.Vars.mobile;
+
public abstract class Platform {
/**Each separate game platform should set this instance to their own implementation.*/
public static Platform instance = new Platform() {};
@@ -17,7 +25,34 @@ public abstract class Platform {
addDialog(field, 16);
}
/**See addDialog().*/
- public void addDialog(TextField field, int maxLength){}
+ public void addDialog(TextField field, int maxLength){
+ if(!mobile) return; //this is mobile only, desktop doesn't need dialogs
+
+ field.tapped(() -> {
+ Log.info("yappd");
+ Dialog dialog = new Dialog("", "dialog");
+ dialog.setFillParent(true);
+ dialog.content().top();
+ dialog.content().defaults().height(65f);
+ TextField to = dialog.content().addField(field.getText(), t-> {}).pad(15).width(250f).get();
+ to.setMaxLength(maxLength);
+ to.keyDown(Keys.ENTER, () -> dialog.content().find("okb").fireClick());
+ dialog.content().addButton("$text.ok", () -> {
+ field.clearText();
+ field.appendText(to.getText());
+ field.change();
+ dialog.hide();
+ Gdx.input.setOnscreenKeyboardVisible(false);
+ }).width(90f).name("okb");
+
+ dialog.show();
+ Timers.runTask(1f, () -> {
+ to.setCursorPosition(to.getText().length());
+ Core.scene.setKeyboardFocus(to);
+ Gdx.input.setOnscreenKeyboardVisible(true);
+ });
+ });
+ }
/**Update discord RPC.*/
public void updateRPC(){}
/**Called when the game is exited.*/
diff --git a/core/src/io/anuke/mindustry/core/ThreadHandler.java b/core/src/io/anuke/mindustry/core/ThreadHandler.java
index f439a6670e..700b816a92 100644
--- a/core/src/io/anuke/mindustry/core/ThreadHandler.java
+++ b/core/src/io/anuke/mindustry/core/ThreadHandler.java
@@ -1,80 +1,34 @@
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;
+public class ThreadHandler{
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 Float.isNaN(result) || Float.isInfinite(result) ? 1f : Math.min(result, 60f / 10f);
});
}
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 +49,6 @@ 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;
- }
-
- @Override
- public boolean isOnGraphicsThread() {
- return !enabled || Thread.currentThread() == graphicsThread;
- }
-
- 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 8120e2212a..ab1c29244c 100644
--- a/core/src/io/anuke/mindustry/core/UI.java
+++ b/core/src/io/anuke/mindustry/core/UI.java
@@ -28,7 +28,6 @@ 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.*;
@@ -155,6 +154,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();
@@ -165,7 +165,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();
@@ -240,8 +239,6 @@ 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());
@@ -250,9 +247,7 @@ public class UI extends SceneModule{
}
public void showInfo(String info){
- Threads.assertGraphics();
-
- new Dialog("$text.info.title", "dialog"){{
+ new Dialog("", "dialog"){{
getCell(content()).growX();
content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center);
buttons().addButton("$text.ok", this::hide).size(90, 50).pad(4);
@@ -260,9 +255,7 @@ public class UI extends SceneModule{
}
public void showInfo(String info, Runnable clicked){
- Threads.assertGraphics();
-
- new Dialog("$text.info.title", "dialog"){{
+ new Dialog("", "dialog"){{
getCell(content()).growX();
content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center);
buttons().addButton("$text.ok", () -> {
diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java
index 8e4dc2f682..376a8591de 100644
--- a/core/src/io/anuke/mindustry/entities/Player.java
+++ b/core/src/io/anuke/mindustry/entities/Player.java
@@ -16,6 +16,7 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Trail;
+import io.anuke.mindustry.io.TypeIO;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetConnection;
import io.anuke.mindustry.type.ContentType;
@@ -70,7 +71,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);
@@ -292,7 +293,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float x = snappedX(), y = snappedY();
if(!movement.isZero() && moved && !state.isPaused()){
- walktime += Timers.delta() * movement.len() / 0.7f * getFloorOn().speedMultiplier;
+ walktime += movement.len() / 0.7f * getFloorOn().speedMultiplier;
baseRotation = Mathf.slerpDelta(baseRotation, movement.angle(), 0.13f);
}
@@ -421,55 +422,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
@@ -551,8 +550,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
updateBuilding(this);
- x = Mathf.clamp(x, 0, world.width() * tilesize);
- y = Mathf.clamp(y, 0, world.height() * tilesize);
+ x = Mathf.clamp(x, tilesize, world.width() * tilesize - tilesize);
+ y = Mathf.clamp(y, tilesize, world.height() * tilesize - tilesize);
}
protected void updateMech(){
@@ -609,11 +608,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
pointerY = vec.y;
updateShooting();
- movement.limit(speed * Timers.delta());
+ movement.limit(speed).scl(Timers.delta());
if(getCarrier() == null){
if(!ui.chatfrag.chatOpen()){
- velocity.add(movement);
+ velocity.add(movement.x, movement.y);
}
float prex = x, prey = y;
updateVelocityStatus();
@@ -810,6 +809,12 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
//region read and write methods
+
+ @Override
+ public boolean isClipped(){
+ return false;
+ }
+
@Override
public void writeSave(DataOutput stream) throws IOException{
stream.writeBoolean(isLocal);
@@ -849,7 +854,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
@Override
public void write(DataOutput buffer) throws IOException{
super.writeSave(buffer, !isLocal);
- buffer.writeUTF(name); //TODO writing strings is very inefficient
+ TypeIO.writeStringData(buffer, name); //TODO writing strings is very inefficient
buffer.writeByte(Bits.toByte(isAdmin) | (Bits.toByte(dead) << 1) | (Bits.toByte(isBoosting) << 2));
buffer.writeInt(Color.rgba8888(color));
buffer.writeByte(mech.id);
@@ -864,7 +869,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
public void read(DataInput buffer, long time) throws IOException{
float lastx = x, lasty = y, lastrot = rotation;
super.readSave(buffer);
- name = buffer.readUTF();
+ name = TypeIO.readStringData(buffer);
byte bools = buffer.readByte();
isAdmin = (bools & 1) != 0;
dead = (bools & 2) != 0;
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 e7d4644401..ef6bdfecfe 100644
--- a/core/src/io/anuke/mindustry/entities/Unit.java
+++ b/core/src/io/anuke/mindustry/entities/Unit.java
@@ -233,7 +233,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
status.update(this);
- velocity.limit(getMaxVelocity()).scl(status.getSpeedMultiplier());
+ velocity.limit(getMaxVelocity()).scl(1f + (status.getSpeedMultiplier()-1f) * Timers.delta());
if(isFlying()){
x += velocity.x * Timers.delta();
diff --git a/core/src/io/anuke/mindustry/entities/Units.java b/core/src/io/anuke/mindustry/entities/Units.java
index e546b727cd..0d0584371c 100644
--- a/core/src/io/anuke/mindustry/entities/Units.java
+++ b/core/src/io/anuke/mindustry/entities/Units.java
@@ -13,7 +13,6 @@ import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.EnumSet;
import io.anuke.ucore.util.Geometry;
-import io.anuke.ucore.util.Threads;
import static io.anuke.mindustry.Vars.*;
@@ -63,45 +62,20 @@ public class Units{
/**Can be called from any thread.*/
public static boolean anyEntities(Rectangle rect){
- if(Threads.isLogic()){
- boolResult = false;
+ boolResult = false;
- Units.getNearby(rect, unit -> {
- if(boolResult) return;
- if(!unit.isFlying()){
- unit.getHitbox(hitrect);
+ Units.getNearby(rect, unit -> {
+ if(boolResult) return;
+ if(!unit.isFlying()){
+ unit.getHitbox(hitrect);
- if(hitrect.overlaps(rect)){
- boolResult = true;
- }
+ if(hitrect.overlaps(rect)){
+ boolResult = true;
}
- });
-
- return boolResult;
- }else{
- boolResultGraphics = false;
-
- for(EntityGroup extends BaseUnit> g : unitGroups){
- g.forEach(u -> {
- if(u.isFlying()) return;
- u.getHitbox(rectGraphics);
- if(rectGraphics.overlaps(rect)){
- boolResultGraphics = true;
- }
- });
- if(boolResultGraphics) return true;
}
+ });
- playerGroup.forEach(u -> {
- if(u.isFlying()) return;
- u.getHitbox(rectGraphics);
- if(rectGraphics.overlaps(rect)){
- boolResultGraphics = true;
- }
- });
-
- return boolResultGraphics;
- }
+ return boolResult;
}
/**Returns whether there are any entities on this tile, with the hitbox expanded.*/
diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java
index a086bea466..3129e67c64 100644
--- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java
+++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java
@@ -84,30 +84,28 @@ 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(position % world.width(), position / world.width());
- }else{ //place
- byte recipe = input.readByte();
- byte rotation = input.readByte();
- request = new BuildRequest(position % world.width(), position / world.width(), rotation, content.recipe(recipe));
- }
+ if(type == 1){ //remove
+ request = new BuildRequest(position % world.width(), position / world.width());
+ }else{ //place
+ byte recipe = input.readByte();
+ byte rotation = input.readByte();
+ request = new BuildRequest(position % world.width(), position / world.width(), 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;
}
}
}
@@ -122,13 +120,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;
}
}
@@ -142,18 +138,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);
}
/**
@@ -161,9 +155,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();
}
/**
@@ -275,18 +267,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){
@@ -311,10 +300,6 @@ public interface BuilderTrait extends Entity{
float x1 = tmptr[0].x, y1 = tmptr[0].y,
x3 = tmptr[1].x, y3 = tmptr[1].y;
- Translator close = Geometry.findClosest(unit.x, unit.y, tmptr);
- float x2 = close.x, y2 = close.y;
-
- Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f));
Draw.alpha(1f);
diff --git a/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java b/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java
index fff2468020..9509e4eb68 100644
--- a/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java
+++ b/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java
@@ -1,7 +1,10 @@
package io.anuke.mindustry.entities.traits;
+import io.anuke.mindustry.core.NetClient;
import io.anuke.mindustry.net.Interpolator;
+import io.anuke.ucore.core.Core;
import io.anuke.ucore.entities.trait.Entity;
+import io.anuke.ucore.util.Tmp;
import java.io.DataInput;
import java.io.DataOutput;
@@ -24,8 +27,21 @@ public interface SyncTrait extends Entity, TypeTrait{
/**Interpolate entity position only. Override if you need to interpolate rotations or other values.*/
default void interpolate(){
- if(getInterpolator() == null)
+ if(getInterpolator() == null){
throw new RuntimeException("This entity must have an interpolator to interpolate()!");
+ }
+
+ if(isClipped()){
+ //move off screen when no longer in bounds
+ Tmp.r1.setSize(Core.camera.viewportWidth * Core.camera.zoom * NetClient.viewScale,
+ Core.camera.viewportHeight * Core.camera.zoom * NetClient.viewScale)
+ .setCenter(Core.camera.position.x, Core.camera.position.y);
+
+ if(!Tmp.r1.contains(getX(), getY()) && !Tmp.r1.contains(getInterpolator().last.x, getInterpolator().last.y)){
+ set(-99999f, -99999f);
+ return;
+ }
+ }
getInterpolator().update();
diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java
index 3a4a8c7c36..b9fe70456b 100644
--- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java
+++ b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java
@@ -320,10 +320,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
if(target != null) behavior();
- if(!isWave && !isFlying()){
- x = Mathf.clamp(x, tilesize/2f, world.width() * tilesize - tilesize/2f);
- y = Mathf.clamp(y, tilesize/2f, world.height() * tilesize - tilesize/2f);
- }
+ x = Mathf.clamp(x, tilesize, world.width() * tilesize - tilesize);
+ y = Mathf.clamp(y, tilesize, world.height() * tilesize - tilesize);
}
@Override
diff --git a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java b/core/src/io/anuke/mindustry/entities/units/GroundUnit.java
index 8bdec0d39b..db01ba1ab1 100644
--- a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java
+++ b/core/src/io/anuke/mindustry/entities/units/GroundUnit.java
@@ -238,7 +238,7 @@ public abstract class GroundUnit extends BaseUnit{
}
protected void patrol(){
- vec.trns(baseRotation, type.speed);
+ vec.trns(baseRotation, type.speed * Timers.delta());
velocity.add(vec.x, vec.y);
vec.trns(baseRotation, type.hitsizeTile);
Tile tile = world.tileWorld(x + vec.x, y + vec.y);
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 d5c3d283f0..35c254ce2a 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);
}
}
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..e900b2feef 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.crect(Draw.getBlankRegion(), 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/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/io/TypeIO.java b/core/src/io/anuke/mindustry/io/TypeIO.java
index 7a0f2d3069..6061472054 100644
--- a/core/src/io/anuke/mindustry/io/TypeIO.java
+++ b/core/src/io/anuke/mindustry/io/TypeIO.java
@@ -23,15 +23,18 @@ import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.entities.Entities;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import static io.anuke.mindustry.Vars.*;
/** Class for specifying read/write methods for code generation.*/
@SuppressWarnings("unused")
public class TypeIO{
- private static final Charset charset = Charset.forName("UTF-8");
@WriteClass(Player.class)
public static void writePlayer(ByteBuffer buffer, Player player){
@@ -329,19 +332,29 @@ public class TypeIO{
@WriteClass(String.class)
public static void writeString(ByteBuffer buffer, String string){
if(string != null){
+ Charset charset = Charset.defaultCharset();
+ byte[] nameBytes = charset.name().getBytes(StandardCharsets.UTF_8);
+ buffer.put((byte)nameBytes.length);
+ buffer.put(nameBytes);
+
byte[] bytes = string.getBytes(charset);
buffer.putShort((short) bytes.length);
buffer.put(bytes);
}else{
- buffer.putShort((short) -1);
+ buffer.put((byte) -1);
}
}
@ReadClass(String.class)
public static String readString(ByteBuffer buffer){
- short length = buffer.getShort();
+ byte length = buffer.get();
if(length != -1){
- byte[] bytes = new byte[length];
+ byte[] cbytes = new byte[length];
+ buffer.get(cbytes);
+ Charset charset = Charset.forName(new String(cbytes, StandardCharsets.UTF_8));
+
+ short slength = buffer.getShort();
+ byte[] bytes = new byte[slength];
buffer.get(bytes);
return new String(bytes, charset);
}else{
@@ -362,4 +375,35 @@ public class TypeIO{
buffer.get(bytes);
return bytes;
}
+
+ public static void writeStringData(DataOutput buffer, String string) throws IOException{
+ if(string != null){
+ Charset charset = Charset.defaultCharset();
+ byte[] nameBytes = charset.name().getBytes(StandardCharsets.UTF_8);
+ buffer.writeByte((byte)nameBytes.length);
+ buffer.write(nameBytes);
+
+ byte[] bytes = string.getBytes(charset);
+ buffer.writeShort((short) bytes.length);
+ buffer.write(bytes);
+ }else{
+ buffer.writeByte((byte) -1);
+ }
+ }
+
+ public static String readStringData(DataInput buffer) throws IOException{
+ byte length = buffer.readByte();
+ if(length != -1){
+ byte[] cbytes = new byte[length];
+ buffer.readFully(cbytes);
+ Charset charset = Charset.forName(new String(cbytes, StandardCharsets.UTF_8));
+
+ short slength = buffer.readShort();
+ byte[] bytes = new byte[slength];
+ buffer.readFully(bytes);
+ return new String(bytes, charset);
+ }else{
+ return null;
+ }
+ }
}
diff --git a/core/src/io/anuke/mindustry/maps/SectorPresets.java b/core/src/io/anuke/mindustry/maps/SectorPresets.java
index 29540e1d5b..08fa7f1b19 100644
--- a/core/src/io/anuke/mindustry/maps/SectorPresets.java
+++ b/core/src/io/anuke/mindustry/maps/SectorPresets.java
@@ -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/generation/pathfinding/FlowPathFinder.java b/core/src/io/anuke/mindustry/maps/generation/pathfinding/FlowPathFinder.java
deleted file mode 100644
index aef01f0688..0000000000
--- a/core/src/io/anuke/mindustry/maps/generation/pathfinding/FlowPathFinder.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package io.anuke.mindustry.maps.generation.pathfinding;
-
-import com.badlogic.gdx.math.GridPoint2;
-import com.badlogic.gdx.math.MathUtils;
-import com.badlogic.gdx.utils.Array;
-import com.badlogic.gdx.utils.Queue;
-import io.anuke.mindustry.world.Tile;
-import io.anuke.ucore.function.Predicate;
-import io.anuke.ucore.util.Geometry;
-
-public class FlowPathFinder extends TilePathfinder{
- protected float[][] weights;
-
- public FlowPathFinder(Tile[][] tiles){
- super(tiles);
- this.weights = new float[tiles.length][tiles[0].length];
- }
-
- @Override
- public void search(Tile start, Tile end, Array out){
-
- }
-
- public void search(Tile start, Predicate result, Array out){
- Queue queue = new Queue<>();
-
- for(int i = 0; i < weights.length; i++){
- for(int j = 0; j < weights[0].length; j++){
- if(result.test(tiles[i][j])){
- weights[i][j] = 100000;
- queue.addLast(tiles[i][j]);
- }else{
- weights[i][j] = 0f;
- }
- }
- }
-
- while(queue.size > 0){
- Tile tile = queue.first();
- for(GridPoint2 point : Geometry.d4){
- int nx = tile.x + point.x, ny = tile.y + point.y;
- if(inBounds(nx, ny) && weights[nx][ny] < weights[tile.x][tile.y] - 1f && tiles[nx][ny].passable()){
- weights[nx][ny] = weights[tile.x][tile.y] - 1;
- queue.addLast(tiles[nx][ny]);
- if(result.test(tiles[nx][ny])){
- break;
- }
- }
- }
- }
-
- out.add(start);
- while(true){
- Tile tile = out.peek();
-
- Tile max = null;
- float maxf = weights[tile.x][tile.y];
- for(GridPoint2 point : Geometry.d4){
- int nx = tile.x + point.x, ny = tile.y + point.y;
- if(inBounds(nx, ny) && (weights[nx][ny] > maxf)){
- max = tiles[nx][ny];
- maxf = weights[nx][ny];
-
- if(MathUtils.isEqual(maxf, 100000)){
- out.add(max);
- return;
- }
- }
- }
- if(max == null){
- break;
- }
- out.add(max);
- }
- }
-
-}
diff --git a/core/src/io/anuke/mindustry/maps/generation/pathfinding/TilePathfinder.java b/core/src/io/anuke/mindustry/maps/generation/pathfinding/TilePathfinder.java
deleted file mode 100644
index a332f5a353..0000000000
--- a/core/src/io/anuke/mindustry/maps/generation/pathfinding/TilePathfinder.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package io.anuke.mindustry.maps.generation.pathfinding;
-
-import com.badlogic.gdx.utils.Array;
-import io.anuke.mindustry.world.Tile;
-import io.anuke.ucore.util.Structs;
-
-public abstract class TilePathfinder{
- protected Tile[][] tiles;
-
- public TilePathfinder(Tile[][] tiles){
- this.tiles = tiles;
- }
-
- protected boolean inBounds(int x, int y){
- return Structs.inBounds(x, y, tiles);
- }
-
- public abstract void search(Tile start, Tile end, Array out);
-}
diff --git a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java
index 5a257192a4..be7d83bf46 100644
--- a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java
+++ b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java
@@ -1,14 +1,12 @@
package io.anuke.mindustry.maps.missions;
import com.badlogic.gdx.utils.Array;
-import io.anuke.mindustry.Vars;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.SpawnGroup;
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.*;
@@ -62,9 +60,9 @@ public class WaveMission extends MissionWithStartingCore{
public String displayString(){
return state.wave > target ?
Bundles.format(
- Vars.unitGroups[Vars.waveTeam.ordinal()].size() > 1 && !Net.client() ?
+ state.enemies() > 1 ?
"text.mission.wave.enemies" :
- "text.mission.wave.enemy", target, target, Vars.unitGroups[Vars.waveTeam.ordinal()].size()) :
+ "text.mission.wave.enemy", target, target, state.enemies()) :
Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60));
}
@@ -82,6 +80,6 @@ public class WaveMission extends MissionWithStartingCore{
@Override
public boolean isComplete(){
- return state.wave > target && Vars.unitGroups[Vars.waveTeam.ordinal()].size() == 0;
+ return state.wave > target && state.enemies() == 0;
}
}
diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java
index 78941f012f..14ab812242 100644
--- a/core/src/io/anuke/mindustry/net/Net.java
+++ b/core/src/io/anuke/mindustry/net/Net.java
@@ -20,7 +20,6 @@ import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Pooling;
-import io.anuke.ucore.util.Threads;
import java.io.IOException;
@@ -51,7 +50,6 @@ public class Net{
public static void showError(Throwable e){
if(!headless){
- Threads.assertGraphics();
Throwable t = e;
while(t.getCause() != null){
@@ -59,7 +57,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/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java
index 5f23abf5b3..6e7687948e 100644
--- a/core/src/io/anuke/mindustry/net/NetworkIO.java
+++ b/core/src/io/anuke/mindustry/net/NetworkIO.java
@@ -145,9 +145,6 @@ public class NetworkIO{
}
}
- /**
- * Return whether a custom map is expected, and thus whether the client should wait for additional data.
- */
public static void loadWorld(InputStream is){
Player player = players[0];
@@ -165,6 +162,8 @@ public class NetworkIO{
world.sectors.createSector(Bits.getLeftShort(sector), Bits.getRightShort(sector));
world.setSector(world.sectors.get(sector));
world.getSector().completedMissions = missions;
+ }else{
+ world.setSector(null);
}
ObjectMap tags = new ObjectMap<>();
diff --git a/core/src/io/anuke/mindustry/type/Liquid.java b/core/src/io/anuke/mindustry/type/Liquid.java
index c357e2d041..3dbb52fbe9 100644
--- a/core/src/io/anuke/mindustry/type/Liquid.java
+++ b/core/src/io/anuke/mindustry/type/Liquid.java
@@ -18,7 +18,7 @@ public class Liquid extends UnlockableContent{
public float flammability;
/**temperature: 0.5 is 'room' temperature, 0 is very cold, 1 is molten hot*/
public float temperature = 0.5f;
- /**how much heat this liquid can store. 0.75=water (high), anything lower is probably less dense and bad at cooling.*/
+ /**how much heat this liquid can store. 0.4=water (decent), anything lower is probably less dense and bad at cooling.*/
public float heatCapacity = 0.5f;
/**how thick this liquid is. 0.5=water (relatively viscous), 1 would be something like tar (very slow)*/
public float viscosity = 0.5f;
diff --git a/core/src/io/anuke/mindustry/ui/Links.java b/core/src/io/anuke/mindustry/ui/Links.java
index 09ebd501d8..891e44f7f8 100644
--- a/core/src/io/anuke/mindustry/ui/Links.java
+++ b/core/src/io/anuke/mindustry/ui/Links.java
@@ -8,13 +8,13 @@ public class Links{
private static void createLinks(){
links = new LinkEntry[]{
- new LinkEntry("discord", "https://discord.gg/BKADYds", Color.valueOf("7289da")),
- new LinkEntry("trello", "https://trello.com/b/aE2tcUwF", Color.valueOf("026aa7")),
- new LinkEntry("wiki", "http://mindustry.wikia.com/wiki/Mindustry_Wiki", Color.valueOf("0f142f")),
- new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Color.valueOf("fa5c5c")),
- new LinkEntry("google-play", "https://play.google.com/store/apps/details?id=io.anuke.mindustry", Color.valueOf("689f38")),
- new LinkEntry("github", "https://github.com/Anuken/Mindustry/", Color.valueOf("24292e")),
- new LinkEntry("dev-builds", "https://github.com/Anuken/Mindustry/wiki", Color.valueOf("fafbfc"))
+ new LinkEntry("discord", "https://discord.gg/BKADYds", Color.valueOf("7289da")),
+ new LinkEntry("trello", "https://trello.com/b/aE2tcUwF", Color.valueOf("026aa7")),
+ new LinkEntry("wiki", "http://mindustry.wikia.com/wiki/Mindustry_Wiki", Color.valueOf("0f142f")),
+ new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Color.valueOf("fa5c5c")),
+ new LinkEntry("google-play", "https://play.google.com/store/apps/details?id=io.anuke.mindustry", Color.valueOf("689f38")),
+ new LinkEntry("github", "https://github.com/Anuken/Mindustry/", Color.valueOf("24292e")),
+ new LinkEntry("dev-builds", "https://jenkins.hellomouse.net/job/mindustry/", Color.valueOf("fafbfc"))
};
}
diff --git a/core/src/io/anuke/mindustry/ui/SelectionTable.java b/core/src/io/anuke/mindustry/ui/SelectionTable.java
new file mode 100644
index 0000000000..27e41eeb43
--- /dev/null
+++ b/core/src/io/anuke/mindustry/ui/SelectionTable.java
@@ -0,0 +1,52 @@
+package io.anuke.mindustry.ui;
+
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import io.anuke.mindustry.world.Block;
+import io.anuke.mindustry.world.Tile;
+import io.anuke.mindustry.world.blocks.OreBlock;
+import io.anuke.ucore.core.Graphics;
+import io.anuke.ucore.graphics.Draw;
+import io.anuke.ucore.scene.style.TextureRegionDrawable;
+import io.anuke.ucore.scene.ui.Image;
+import io.anuke.ucore.scene.ui.layout.Table;
+import io.anuke.ucore.util.Mathf;
+
+import static io.anuke.mindustry.Vars.world;
+
+public class SelectionTable extends Table{
+ Tile lastTile;
+
+ public SelectionTable(){
+ super("clear");
+
+ margin(5f);
+
+ update(() -> {
+ Block result;
+ Tile tile = world.tileWorld(Graphics.mouseWorld().x, Graphics.mouseWorld().y);
+ if(tile != null){
+ tile = tile.target();
+ result = tile.block().synthetic() ? tile.block() : tile.floor() instanceof OreBlock ? tile.floor() : null;
+ }else{
+ result = null;
+ }
+
+ if(result != null){
+ lastTile = tile;
+ }
+
+ getTranslation().y = Mathf.lerp(getTranslation().y, result == null ? -getHeight() : 0f, 0.2f);
+ });
+
+ Image image = new Image(new TextureRegionDrawable(new TextureRegion(Draw.region("clear"))));
+ image.update(() ->
+ ((TextureRegionDrawable)image.getDrawable()).setRegion(lastTile == null ? Draw.getBlankRegion() :
+ (lastTile.block().synthetic() ? lastTile.block() : lastTile.floor()).getDisplayIcon(lastTile)));
+
+ add(image).size(8*5).padRight(4);
+ label(() -> lastTile == null ? "" : (lastTile.block().synthetic() ? lastTile.block() : lastTile.floor()).getDisplayName(lastTile));
+
+ pack();
+ getTranslation().y = - getHeight();
+ }
+}
diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java
index afcf8abfd3..e4d2324560 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java
@@ -12,6 +12,7 @@ import io.anuke.ucore.scene.ui.layout.Cell;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.utils.UIUtils;
import io.anuke.ucore.util.OS;
+import io.anuke.ucore.util.Strings;
import static io.anuke.mindustry.Vars.ios;
import static io.anuke.mindustry.Vars.ui;
@@ -55,7 +56,7 @@ public class AboutDialog extends FloatingDialog{
}).size(h - 5, h);
table.table(inset -> {
- inset.add("[accent]" + link.name.replace("-", " ")).growX().left();
+ inset.add("[accent]" + Strings.capitalize(link.name.replace("-", " "))).growX().left();
inset.row();
inset.labelWrap(link.description).width(w - 100f).color(Color.LIGHT_GRAY).growX();
}).padLeft(8);
@@ -93,7 +94,7 @@ public class AboutDialog extends FloatingDialog{
public void showCredits(){
FloatingDialog dialog = new FloatingDialog("$text.credits");
dialog.addCloseButton();
- dialog.content().add("$text.credits.text");
+ dialog.content().labelWrap("$text.credits.text").width(400f);
dialog.show();
}
}
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/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java
index 1c0f04abc9..a8931f70a7 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java
@@ -190,11 +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/BlockConsumeFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java
index 1fbd83d39b..78ec16761b 100644
--- a/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java
+++ b/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java
@@ -36,7 +36,7 @@ public class BlockConsumeFragment extends Fragment{
tile = tile.target();
if(tile != lastTile){
- if(tile.block().consumes.hasAny()){
+ if(tile.getTeam() == players[0].getTeam() && tile.block().consumes.hasAny()){
show(tile);
}else if(visible){
hide();
diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java
index 2d6b439442..50c63e4596 100644
--- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java
+++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java
@@ -128,7 +128,7 @@ public class BlocksFragment extends Fragment{
recipeTable.margin(4).top().left().marginRight(15);
//add a new row here when needed
- if(cati == secrows){
+ if(cati % secrows == 0){
catTable = new Table();
selectTable.row();
selectTable.add(catTable).colspan(secrows).padTop(-5).growX();
diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java
index 0341a51de1..3da203e15a 100644
--- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java
+++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java
@@ -16,6 +16,7 @@ import io.anuke.mindustry.net.Packets.AdminAction;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.IntFormat;
import io.anuke.mindustry.ui.Minimap;
+import io.anuke.mindustry.ui.SelectionTable;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.ucore.core.*;
import io.anuke.ucore.graphics.Hue;
@@ -107,7 +108,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 +127,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);
@@ -199,6 +199,12 @@ public class HudFragment extends Fragment{
t.add("$text.saveload");
});
+ //tapped block indicator
+ parent.fill(t -> {
+ t.bottom().visible(() -> !state.is(State.menu));
+ t.add(new SelectionTable());
+ });
+
blockfrag.build(Core.scene.getRoot());
}
@@ -367,15 +373,15 @@ public class HudFragment extends Fragment{
table.labelWrap(() ->
world.getSector() == null ?
- (unitGroups[waveTeam.ordinal()].size() > 0 && state.mode.disableWaveTimer ?
- wavef.get(state.wave) + "\n" + (unitGroups[waveTeam.ordinal()].size() == 1 ?
- enemyf.get(unitGroups[waveTeam.ordinal()].size()) :
- enemiesf.get(unitGroups[waveTeam.ordinal()].size())) :
+ (state.enemies() > 0 && state.mode.disableWaveTimer ?
+ wavef.get(state.wave) + "\n" + (state.enemies() == 1 ?
+ enemyf.get(state.enemies()) :
+ enemiesf.get(state.enemies())) :
wavef.get(state.wave) + "\n" +
(!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/ui/fragments/PlayerListFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java
index 8b8633baf3..80a96b3ffb 100644
--- a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java
+++ b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java
@@ -97,7 +97,7 @@ public class PlayerListFragment extends Fragment{
button.labelWrap("[#" + player.color.toString().toUpperCase() + "]" + player.name).width(170f).pad(10);
button.add().grow();
- button.addImage("icon-admin").size(14 * 2).visible(() -> player.isAdmin && !(!player.isLocal && Net.server())).padRight(5);
+ button.addImage("icon-admin").size(14 * 2).visible(() -> player.isAdmin && !(!player.isLocal && Net.server())).padRight(5).get().updateVisibility();
if((Net.server() || players[0].isAdmin) && !player.isLocal && (!player.isAdmin || Net.server())){
button.add().growY();
@@ -124,12 +124,13 @@ public class PlayerListFragment extends Fragment{
}else{
ui.showConfirm("$text.confirm", "$text.confirmadmin", () -> netServer.admins.adminPlayer(id, player.usid));
}
- }).update(b -> {
- b.setChecked(player.isAdmin);
- b.setDisabled(Net.client());
- }).get().setTouchable(() -> Net.client() ? Touchable.disabled : Touchable.enabled);
+ })
+ .update(b -> b.setChecked(player.isAdmin))
+ .disabled(b -> Net.client())
+ .touchable(() -> Net.client() ? Touchable.disabled : Touchable.enabled)
+ .checked(player.isAdmin);
- t.addImageButton("icon-zoom-small", 14 * 2, () -> Call.onAdminRequest(player, AdminAction.trace));
+ t.addImageButton("icon-zoom-small", 14 * 2, () -> ui.showError("Currently unimplemented.")/*Call.onAdminRequest(player, AdminAction.trace)*/);
}).padRight(12).padTop(-5).padLeft(0).padBottom(-10).size(bs + 10f, bs);
diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java
index bb4466221f..35f88b88af 100644
--- a/core/src/io/anuke/mindustry/world/BaseBlock.java
+++ b/core/src/io/anuke/mindustry/world/BaseBlock.java
@@ -95,7 +95,7 @@ public abstract class BaseBlock extends MappableContent{
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return hasLiquids && tile.entity.liquids.get(liquid) + amount < liquidCapacity &&
- (!singleLiquid || (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.01f)) &&
+ (!singleLiquid || (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f)) &&
(!consumes.has(ConsumeLiquid.class) || consumes.liquid() == liquid);
}
diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java
index e12050bbb5..093d9b77de 100644
--- a/core/src/io/anuke/mindustry/world/Block.java
+++ b/core/src/io/anuke/mindustry/world/Block.java
@@ -452,6 +452,14 @@ public class Block extends BaseBlock {
}
}
+ public String getDisplayName(Tile tile){
+ return formalName;
+ }
+
+ public TextureRegion getDisplayIcon(Tile tile){
+ return getEditorIcon();
+ }
+
public TextureRegion getEditorIcon(){
if(editorIcon == null){
editorIcon = Draw.region("block-icon-" + name, Draw.region("clear"));
diff --git a/core/src/io/anuke/mindustry/world/Build.java b/core/src/io/anuke/mindustry/world/Build.java
index d596422410..6ffab178db 100644
--- a/core/src/io/anuke/mindustry/world/Build.java
+++ b/core/src/io/anuke/mindustry/world/Build.java
@@ -17,7 +17,6 @@ import static io.anuke.mindustry.Vars.*;
public class Build{
private static final Rectangle rect = new Rectangle();
- private static final Rectangle hitrect = new Rectangle();
/**Returns block type that was broken, or null if unsuccesful.*/
public static void beginBreak(Team team, int x, int y){
diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java
index f6ea510048..b75b89e433 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.
@@ -147,33 +146,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){
@@ -270,7 +263,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()){
@@ -292,7 +285,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;
@@ -394,52 +387,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/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java
index e2fe0f5865..f5a1ba14e9 100644
--- a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java
+++ b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java
@@ -16,6 +16,7 @@ import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.input.CursorType;
+import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.world.BarType;
@@ -26,6 +27,7 @@ import io.anuke.mindustry.world.modules.ItemModule;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.graphics.Draw;
+import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Mathf;
import java.io.DataInput;
@@ -68,6 +70,18 @@ public class BuildBlock extends Block{
}
}
+ @Override
+ public String getDisplayName(Tile tile){
+ BuildEntity entity = tile.entity();
+ return Bundles.format("block.constructing", entity.recipe == null ? entity.previous.formalName : entity.recipe.result.formalName);
+ }
+
+ @Override
+ public TextureRegion getDisplayIcon(Tile tile){
+ BuildEntity entity = tile.entity();
+ return (entity.recipe == null ? entity.previous : entity.recipe.result).getEditorIcon();
+ }
+
@Override
public boolean isSolidFor(Tile tile){
BuildEntity entity = tile.entity();
diff --git a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java
index 7333c7dcd2..6abb723921 100644
--- a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java
+++ b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java
@@ -24,6 +24,11 @@ public class OreBlock extends Floor{
this.edge = base.name;
}
+ @Override
+ public String getDisplayName(Tile tile){
+ return drops.item.localizedName();
+ }
+
@Override
public TextureRegion getEditorIcon(){
if(editorIcon == null){
diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java
index 0a3af1b97d..fdb8b5dfa0 100644
--- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java
+++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java
@@ -396,7 +396,7 @@ public class Conveyor extends Block{
public void read(DataInput stream) throws IOException{
convey.clear();
int amount = stream.readInt();
- convey.ensureCapacity(amount);
+ convey.ensureCapacity(Math.min(amount, 10));
for(int i = 0; i < amount; i++){
convey.add(ItemPos.toLong(stream.readInt()));
diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java b/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java
deleted file mode 100644
index 5ea2c97709..0000000000
--- a/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java
+++ /dev/null
@@ -1,363 +0,0 @@
-package io.anuke.mindustry.world.blocks.distribution;
-
-import com.badlogic.gdx.graphics.Color;
-import com.badlogic.gdx.utils.Array;
-import com.badlogic.gdx.utils.ObjectSet;
-import io.anuke.annotations.Annotations.Loc;
-import io.anuke.annotations.Annotations.Remote;
-import io.anuke.mindustry.content.Liquids;
-import io.anuke.mindustry.content.fx.BlockFx;
-import io.anuke.mindustry.entities.Player;
-import io.anuke.mindustry.entities.TileEntity;
-import io.anuke.mindustry.gen.Call;
-import io.anuke.mindustry.type.Item;
-import io.anuke.mindustry.type.Liquid;
-import io.anuke.mindustry.world.Tile;
-import io.anuke.mindustry.world.blocks.PowerBlock;
-import io.anuke.ucore.core.Effects;
-import io.anuke.ucore.core.Effects.Effect;
-import io.anuke.ucore.core.Graphics;
-import io.anuke.ucore.core.Timers;
-import io.anuke.ucore.graphics.Draw;
-import io.anuke.ucore.graphics.Fill;
-import io.anuke.ucore.graphics.Hue;
-import io.anuke.ucore.graphics.Lines;
-import io.anuke.ucore.scene.ui.ButtonGroup;
-import io.anuke.ucore.scene.ui.ImageButton;
-import io.anuke.ucore.scene.ui.layout.Table;
-import io.anuke.ucore.util.Mathf;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import static io.anuke.mindustry.Vars.tilesize;
-
-//TODO implement
-public class WarpGate extends PowerBlock{
- public static final Color[] colorArray = {Color.ROYAL, Color.ORANGE, Color.SCARLET, Color.LIME,
- Color.PURPLE, Color.GOLD, Color.PINK, Color.LIGHT_GRAY};
- public static final int colors = colorArray.length;
- private static ObjectSet[] teleporters = new ObjectSet[colors];
- private static Color color = new Color();
- private static byte lastColor = 0;
-
- static{
- for(int i = 0; i < colors; i++){
- teleporters[i] = new ObjectSet<>();
- }
- }
-
- protected int timerTeleport = timers++;
- protected float warmupTime = 60f;
- //time between teleports
- protected float teleportMax = 400f;
- protected float teleportLiquidUse = 0.3f;
- protected Liquid inputLiquid = Liquids.cryofluid;
- protected Effect activateEffect = BlockFx.teleportActivate;
- protected Effect teleportEffect = BlockFx.teleport;
- protected Effect teleportOutEffect = BlockFx.teleportOut;
- private Array removal = new Array<>();
- private Array returns = new Array<>();
-
- public WarpGate(String name){
- super(name);
- update = true;
- solid = true;
- health = 80;
- powerCapacity = 300f;
- size = 3;
- itemCapacity = 100;
- hasLiquids = true;
- hasItems = true;
- liquidCapacity = 100f;
- configurable = true;
- }
-
- @Remote(targets = Loc.both, called = Loc.both, forward = true)
- public static void setTeleporterColor(Player player, Tile tile, byte color){
- TeleporterEntity entity = tile.entity();
- entity.color = color;
- }
-
- @Override
- public void playerPlaced(Tile tile){
- Call.setTeleporterColor(null, tile, lastColor);
- }
-
- @Override
- public void draw(Tile tile){
- super.draw(tile);
-
- TeleporterEntity entity = tile.entity();
- float time = entity.time;
- float rad = entity.activeScl;
-
- if(entity.liquidLackScl > 0.01f){
- Graphics.setAdditiveBlending();
- Draw.color(1f, 0.3f, 0.3f, 0.4f * entity.liquidLackScl);
- Fill.square(tile.drawx(), tile.drawy(), size * tilesize);
- Graphics.setNormalBlending();
- }
-
- Draw.color(getColor(tile, 0));
- Draw.rect(name + "-top", tile.drawx(), tile.drawy());
- Draw.reset();
-
- if(rad <= 0.0001f) return;
-
- Draw.color(getColor(tile, 0));
-
- Fill.circle(tile.drawx(), tile.drawy(), rad * (7f + Mathf.absin(time + 55, 8f, 1f)));
-
- Draw.color(getColor(tile, -1));
-
- Fill.circle(tile.drawx(), tile.drawy(), rad * (2f + Mathf.absin(time, 7f, 3f)));
-
- for(int i = 0; i < 11; i++){
- Lines.swirl(tile.drawx(), tile.drawy(),
- rad * (2f + i / 3f + Mathf.sin(time - i * 75, 20f + i, 3f)),
- 0.3f + Mathf.sin(time + i * 33, 10f + i, 0.1f),
- time * (1f + Mathf.randomSeedRange(i + 1, 1f)) + Mathf.randomSeedRange(i, 360f));
- }
-
- Draw.color(getColor(tile, 1));
-
- Lines.stroke(2f);
- Lines.circle(tile.drawx(), tile.drawy(), rad * (7f + Mathf.absin(time + 55, 8f, 1f)));
- Lines.stroke(1f);
-
- for(int i = 0; i < 11; i++){
- Lines.swirl(tile.drawx(), tile.drawy(),
- rad * (3f + i / 3f + Mathf.sin(time + i * 93, 20f + i, 3f)),
- 0.2f + Mathf.sin(time + i * 33, 10f + i, 0.1f),
- time * (1f + Mathf.randomSeedRange(i + 1, 1f)) + Mathf.randomSeedRange(i, 360f));
- }
-
- Draw.reset();
- }
-
- @Override
- public void update(Tile tile){
- TeleporterEntity entity = tile.entity();
-
- teleporters[entity.color].add(tile);
-
- if(entity.items.total() > 0){
- tryDump(tile);
- }
-
- if(!entity.active){
- entity.activeScl = Mathf.lerpDelta(entity.activeScl, 0f, 0.01f);
-
- if(entity.power.amount >= powerCapacity){
- Color resultColor = new Color();
- resultColor.set(getColor(tile, 0));
-
- entity.active = true;
- entity.power.amount = 0f;
- Effects.effect(activateEffect, resultColor, tile.drawx(), tile.drawy());
- }
- }else{
- entity.activeScl = Mathf.lerpDelta(entity.activeScl, 1f, 0.015f);
- /*
-
- if (entity.power.amount >= powerUsed) {
- entity.power.amount -= powerUsed;
- entity.powerLackScl = Mathf.lerpDelta(entity.powerLackScl, 0f, 0.1f);
- }else{
- entity.power.amount = 0f;
- entity.powerLackScl = Mathf.lerpDelta(entity.powerLackScl, 1f, 0.1f);
- }
-
- if(entity.powerLackScl >= 0.999f){
- catastrophicFailure(tile);
- }
-
- if (entity.liquids.amount >= liquidUsed) {
- entity.liquids.amount -= liquidUsed;
- entity.liquidLackScl = Mathf.lerpDelta(entity.liquidLackScl, 0f, 0.1f);
- }else{
- entity.liquids.amount = 0f;
- entity.liquidLackScl = Mathf.lerpDelta(entity.liquidLackScl, 1f, 0.1f);
- }*/
-
- if(entity.liquidLackScl >= 0.999f){
- catastrophicFailure(tile);
- }
-
- //TODO draw warning info!
-
- if(entity.teleporting){
- entity.speedScl = Mathf.lerpDelta(entity.speedScl, 2f, 0.01f);
- //liquidUsed = Math.min(liquidCapacity, teleportLiquidUse * Timers.delta());
-
- //if (entity.liquids.amount >= liquidUsed) {
- // entity.liquids.amount -= liquidUsed;
- //} else {
- catastrophicFailure(tile);
- //}
- }else{
- entity.speedScl = Mathf.lerpDelta(entity.speedScl, 1f, 0.04f);
- }
-
- entity.time += Timers.delta() * entity.speedScl;
-/*
- if (!entity.teleporting && entity.items.total() >= itemCapacity && entity.power.amount >= powerCapacity - 0.01f - powerUse &&
- entity.timer.get(timerTeleport, teleportMax)) {
- Array testLinks = findLinks(tile);
-
- if (testLinks.size == 0) return;
-
- Color resultColor = new Color();
- resultColor.set(getColor(tile, 0));
-
- entity.teleporting = true;
-
- Effects.effect(teleportEffect, resultColor, tile.drawx(), tile.drawy());
- Timers.run(warmupTime, () -> {
- Array links = findLinks(tile);
-
- for (Tile other : links) {
- int canAccept = itemCapacity - other.entity.items.total();
- int total = entity.items.total();
- if (total == 0) break;
- Effects.effect(teleportOutEffect, resultColor, other.drawx(), other.drawy());
- for (int i = 0; i < canAccept && i < total; i++) {
- other.entity.items.add(entity.items.take(), 1);
- }
- }
- Effects.effect(teleportOutEffect, resultColor, tile.drawx(), tile.drawy());
- entity.power.amount = 0f;
- entity.teleporting = false;
- });
- }*/
- }
- }
-
- @Override
- public void buildTable(Tile tile, Table table){
- TeleporterEntity entity = tile.entity();
-
- //TODO call event for change
-
- ButtonGroup group = new ButtonGroup<>();
- Table cont = new Table();
-
- for(int i = 0; i < colors; i++){
- final int f = i;
- ImageButton button = cont.addImageButton("white", "toggle", 24, () -> {
- lastColor = (byte) f;
- Call.setTeleporterColor(null, tile, (byte) f);
- }).size(34, 38).padBottom(-5.1f).group(group).get();
- button.getStyle().imageUpColor = colorArray[f];
- button.setChecked(entity.color == f);
-
- if(i % 4 == 3){
- cont.row();
- }
- }
-
- table.add(cont);
- }
-
- @Override
- public boolean acceptItem(Item item, Tile tile, Tile source){
- TeleporterEntity entity = tile.entity();
- return entity.items.total() < itemCapacity;
- }
-
- @Override
- public TileEntity newEntity(){
- return new TeleporterEntity();
- }
-
- @Override
- public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
- return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid;
- }
-
- @Override
- public void onDestroyed(Tile tile){
- super.onDestroyed(tile);
-
- TeleporterEntity entity = tile.entity();
-
- if(entity.activeScl < 0.5f) return;
-
- //TODO catastrophic failure
- }
-
- private void catastrophicFailure(Tile tile){
- tile.entity.damage(tile.entity.health + 1);
- //TODO fail gloriously
- }
-
- private Color getColor(Tile tile, int shift){
- TeleporterEntity entity = tile.entity();
-
- Color target = colorArray[entity.color];
- float ss = 0.5f;
- float bs = 0.2f;
-
- return Hue.shift(Hue.multiply(color.set(target), 1, ss), 2, shift * bs + (entity.speedScl - 1f) / 3f);
- }
-
- private Array findLinks(Tile tile){
- TeleporterEntity entity = tile.entity();
-
- removal.clear();
- returns.clear();
-
- for(Tile other : teleporters[entity.color]){
- if(other != tile){
- if(other.block() instanceof WarpGate){
- TeleporterEntity oe = other.entity();
- if(!oe.active) continue;
- if(oe.color != entity.color){
- removal.add(other);
- }else if(other.entity.items.total() == 0){
- returns.add(other);
- }
- }else{
- removal.add(other);
- }
- }
- }
-
- for(Tile remove : removal){
- teleporters[entity.color].remove(remove);
- }
-
- return returns;
- }
-
- public static class TeleporterEntity extends TileEntity{
- public byte color = 0;
- public boolean teleporting;
- public boolean active;
- public float activeScl = 0f;
- public float speedScl = 1f;
- public float powerLackScl, liquidLackScl;
- public float time;
-
- @Override
- public void write(DataOutput stream) throws IOException{
- stream.writeByte(color);
- stream.writeBoolean(active);
- stream.writeFloat(activeScl);
- stream.writeFloat(speedScl);
- stream.writeFloat(powerLackScl);
- }
-
- @Override
- public void read(DataInput stream) throws IOException{
- color = stream.readByte();
- active = stream.readBoolean();
- activeScl = stream.readFloat();
- speedScl = stream.readFloat();
- powerLackScl = stream.readFloat();
- }
- }
-
-}
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 d817d423a2..6f6ce996e8 100644
--- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java
+++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java
@@ -5,7 +5,6 @@ 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;
@@ -100,7 +99,7 @@ public class PowerGraph{
public void clear(){
for(Tile other : all){
- other.entity.power.graph = null;
+ if(other.entity != null && other.entity.power != null) other.entity.power.graph = null;
}
all.clear();
producers.clear();
diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java
index ac641ca4f7..f0232c5cf3 100644
--- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java
+++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java
@@ -25,7 +25,6 @@ import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.layout.Cell;
import io.anuke.ucore.util.Mathf;
-import io.anuke.ucore.util.Threads;
import static io.anuke.mindustry.Vars.content;
public class Drill extends Block{
@@ -221,7 +220,7 @@ public class Drill extends Block{
@Override
public boolean canPlaceOn(Tile tile){
if(isMultiblock()){
- for(Tile other : tile.getLinkedTilesAs(this, Threads.isLogic() ? tempTiles : drawTiles)){
+ for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
if(isValid(other)){
return true;
}
diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java b/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java
index c50509f413..dd7374536a 100644
--- a/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java
+++ b/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java
@@ -15,9 +15,11 @@ import io.anuke.ucore.scene.ui.layout.Table;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
-import static io.anuke.mindustry.Vars.*;
+
+import static io.anuke.mindustry.Vars.content;
public class SortedUnloader extends Unloader implements SelectionTrait{
+ protected float speed = 1f;
public SortedUnloader(String name){
super(name);
@@ -35,13 +37,13 @@ public class SortedUnloader extends Unloader implements SelectionTrait{
public void update(Tile tile){
SortedUnloaderEntity entity = tile.entity();
- if(entity.items.total() == 0 && entity.timer.get(timerUnload, speed)){
- tile.allNearby(other -> {
+ if(tile.entity.timer.get(timerUnload, speed) && tile.entity.items.total() == 0){
+ for(Tile other : tile.entity.proximity()){
if(other.getTeam() == tile.getTeam() && other.block() instanceof StorageBlock && entity.items.total() == 0 &&
((entity.sortItem == null && other.entity.items.total() > 0) || ((StorageBlock) other.block()).hasItem(other, entity.sortItem))){
offloadNear(tile, ((StorageBlock) other.block()).removeItem(other, entity.sortItem));
}
- });
+ }
}
if(entity.items.total() > 0){
diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java b/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java
index ab7c951836..f07756b4d2 100644
--- a/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java
+++ b/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java
@@ -5,9 +5,8 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockGroup;
-public class Unloader extends Block{
+public abstract class Unloader extends Block{
protected final int timerUnload = timers++;
- protected int speed = 5;
public Unloader(String name){
super(name);
@@ -18,22 +17,6 @@ public class Unloader extends Block{
hasItems = true;
}
- @Override
- public void update(Tile tile){
- if(tile.entity.items.total() == 0 && tile.entity.timer.get(timerUnload, speed)){
- tile.allNearby(other -> {
- if(other.getTeam() == tile.getTeam() && other.block() instanceof StorageBlock && tile.entity.items.total() == 0 &&
- ((StorageBlock) other.block()).hasItem(other, null)){
- offloadNear(tile, ((StorageBlock) other.block()).removeItem(other, null));
- }
- });
- }
-
- if(tile.entity.items.total() > 0){
- tryDump(tile);
- }
- }
-
@Override
public boolean canDump(Tile tile, Tile to, Item item){
Block block = to.target().block();
diff --git a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java
index ae7b2f98c5..d7856bf1b3 100644
--- a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java
+++ b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java
@@ -51,7 +51,7 @@ public class UnitFactory extends Block{
hasItems = true;
solid = false;
itemCapacity = 10;
- flags = EnumSet.of(BlockFlag.producer);
+ flags = EnumSet.of(BlockFlag.producer, BlockFlag.target);
consumes.require(ConsumeItems.class);
}
@@ -71,7 +71,7 @@ public class UnitFactory extends Block{
if(!Net.client()){
BaseUnit unit = factory.type.create(tile.getTeam());
unit.setSpawner(tile);
- unit.set(tile.drawx(), tile.drawy());
+ unit.set(tile.drawx() + Mathf.range(4), tile.drawy() + Mathf.range(4));
unit.add();
unit.getVelocity().y = factory.launchVelocity;
}
diff --git a/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java b/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java
index 1f29c1a906..4d434e32ee 100644
--- a/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java
+++ b/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java
@@ -85,7 +85,7 @@ public class CrashHandler{
try{
Path path = Paths.get(OS.getAppDataDirectoryString(Vars.appName), "crashes",
- "crash-report-" + DateTimeFormatter.ofPattern("MM-dd-yyyy-HH:mm:ss").format(LocalDateTime.now()) + ".txt");
+ "crash-report-" + DateTimeFormatter.ofPattern("MM dd yyyy HH mm ss").format(LocalDateTime.now()) + ".txt");
Files.createDirectories(Paths.get(OS.getAppDataDirectoryString(Vars.appName), "crashes"));
Files.write(path, parseException(e).getBytes());
@@ -117,7 +117,7 @@ public class CrashHandler{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
- return sw.toString().replace(e.getMessage(), e.getMessage().replace(System.getProperty("user.name"), "[USERNAME]"));
+ return sw.toString();
}
private static void ex(Runnable r){
diff --git a/ios/robovm.properties b/ios/robovm.properties
index f6b10f99b5..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=25
+app.build=27
app.name=Mindustry
diff --git a/ios/src/io/anuke/mindustry/IOSLauncher.java b/ios/src/io/anuke/mindustry/IOSLauncher.java
index e6bd6469ed..5b7c7fbf3e 100644
--- a/ios/src/io/anuke/mindustry/IOSLauncher.java
+++ b/ios/src/io/anuke/mindustry/IOSLauncher.java
@@ -10,7 +10,6 @@ import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.game.Saves.SaveSlot;
import io.anuke.mindustry.io.SaveIO;
import io.anuke.mindustry.net.Net;
-import io.anuke.ucore.scene.ui.TextField;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Strings;
@@ -40,16 +39,6 @@ public class IOSLauncher extends IOSApplication.Delegate {
Platform.instance = new Platform() {
- @Override
- public void addDialog(TextField field) {
- TextFieldDialogListener.add(field, 16);
- }
-
- @Override
- public void addDialog(TextField field, int maxLength) {
- TextFieldDialogListener.add(field, maxLength);
- }
-
@Override
public void shareFile(FileHandle file){
FileHandle to = Gdx.files.absolute(getDocumentsDirectory()).child(file.name());
diff --git a/ios/src/io/anuke/mindustry/TextFieldDialogListener.java b/ios/src/io/anuke/mindustry/TextFieldDialogListener.java
deleted file mode 100644
index f8557f72a8..0000000000
--- a/ios/src/io/anuke/mindustry/TextFieldDialogListener.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package io.anuke.mindustry;
-
-import com.badlogic.gdx.Gdx;
-import io.anuke.ucore.scene.event.ClickListener;
-import io.anuke.ucore.scene.event.InputEvent;
-import io.anuke.ucore.scene.event.InputListener;
-import io.anuke.ucore.scene.ui.TextField;
-import org.robovm.apple.foundation.NSRange;
-import org.robovm.apple.uikit.*;
-import org.robovm.rt.bro.annotation.ByVal;
-
-public class TextFieldDialogListener {
-
- public static void add(TextField field, int maxLength){
- field.addListener(new ClickListener(){
- public void clicked(final InputEvent event, float x, float y){
- show(field, maxLength);
- event.cancel();
- }
- });
- field.addListener(new InputListener(){
- public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
- Gdx.input.setOnscreenKeyboardVisible(false);
- return false;
- }
- });
- }
-
- @SuppressWarnings("deprecation")
- private static void show(TextField field, int maxLength){
-
- UIAlertViewDelegateAdapter delegate = new UIAlertViewDelegateAdapter() {
-
- @Override
- public void didDismiss(UIAlertView alertView, long buttonIndex) {
- if (buttonIndex == 1) {
- UITextField textField = alertView.getTextField(0);
- final String result = textField.getText();
-
- Gdx.app.postRunnable(() -> {
- field.setText(result);
- field.change();
- });
- }
- }
-
- @Override
- public void clicked(UIAlertView alertView, long buttonIndex) {
-
- }
-
- @Override
- public void cancel(UIAlertView alertView) {
-
- }
-
- @Override
- public void willPresent(UIAlertView alertView) {
-
- }
-
- @Override
- public void didPresent(UIAlertView alertView) {
-
- }
-
- @Override
- public void willDismiss(UIAlertView alertView, long buttonIndex) {
-
- }
-
- @Override
- public boolean shouldEnableFirstOtherButton(UIAlertView alertView) {
- return false;
- }
- };
-
- String[] otherButtons = new String[1];
- otherButtons[0] = "OK";
-
- UIAlertView alertView = new UIAlertView("", "", delegate, "Cancel", otherButtons);
-
- alertView.setAlertViewStyle(UIAlertViewStyle.PlainTextInput);
-
- UITextField uiTextField = alertView.getTextField(0);
- uiTextField.setText(field.getText());
-
- uiTextField.setDelegate(new UITextFieldDelegateAdapter() {
- @Override
- public boolean shouldChangeCharacters(UITextField textField, @ByVal NSRange nsRange, String additionalText) {
-
- if (textField.getText().length() + additionalText.length() > maxLength) {
- String oldText = textField.getText();
- String newText = oldText + additionalText;
- textField.setText(newText.substring(0, maxLength));
- return false;
- }
- return true;
- }
- });
-
- alertView.show();
-
- }
-}
diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java
index c0a43aae57..e4be13ed40 100644
--- a/server/src/io/anuke/mindustry/server/ServerControl.java
+++ b/server/src/io/anuke/mindustry/server/ServerControl.java
@@ -355,13 +355,20 @@ public class ServerControl extends Module{
err("Not playing. Host first.");
return;
}
-
- for(Item item : content.items()){
- if(item.type == ItemType.material){
- state.teams.get(Team.blue).cores.first().entity.items.add(item, 2000);
+
+ try{
+ Team team = Team.valueOf(arg[0]);
+
+ for(Item item : content.items()){
+ if(item.type == ItemType.material){
+ state.teams.get(team).cores.first().entity.items.add(item, 2000);
+ }
}
+
+ info("Core filled.");
+ }catch(IllegalArgumentException ignored){
+ err("No such team exists.");
}
- info("Core filled.");
});
handler.register("crashreport", "", "Disables or enables automatic crash reporting", arg -> {
diff --git a/server/src/io/anuke/mindustry/server/ServerLauncher.java b/server/src/io/anuke/mindustry/server/ServerLauncher.java
index b9c82c56d6..fb7fd882dc 100644
--- a/server/src/io/anuke/mindustry/server/ServerLauncher.java
+++ b/server/src/io/anuke/mindustry/server/ServerLauncher.java
@@ -7,8 +7,8 @@ import com.badlogic.gdx.backends.headless.HeadlessApplicationConfiguration;
import io.anuke.kryonet.KryoClient;
import io.anuke.kryonet.KryoServer;
import io.anuke.mindustry.net.Net;
+import io.anuke.ucore.core.Settings;
import io.anuke.ucore.util.EmptyLogger;
-import io.anuke.ucore.util.OS;
public class ServerLauncher extends HeadlessApplication{
@@ -26,7 +26,7 @@ public class ServerLauncher extends HeadlessApplication{
Net.setServerProvider(new KryoServer());
HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
- config.preferencesDirectory = OS.getAppDataDirectoryString("Mindustry");
+ Settings.setPrefHandler((appName) -> Gdx.files.local("config"));
new ServerLauncher(new MindustryServer(args), config);
}catch(Throwable t){
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.");
+ }
+ }
+}