Merge branch 'master' of https://github.com/Anuken/Mindustry into new-sectors

This commit is contained in:
Anuken
2018-10-30 22:18:07 -04:00
155 changed files with 1581 additions and 2452 deletions

View File

@@ -16,22 +16,24 @@ Bleeding-edge live builds are generated automatically for every commit. You can
If you'd rather compile on your own, follow these instructions. If you'd rather compile on your own, follow these instructions.
First, make sure you have Java 8 and JDK 8 installed. Open a terminal in the root directory, and run the following commands: First, make sure you have Java 8 and JDK 8 installed. Open a terminal in the root directory, and run the following commands:
#### Windows
**_Windows_** _Running:_ `gradlew desktop:run`
_Building:_ `gradlew desktop:dist`
_Running:_ `gradlew.bat desktop:run` #### Linux
_Building:_ `gradlew.bat desktop:dist`
**_Linux_**
_Running:_ `./gradlew desktop:run` _Running:_ `./gradlew desktop:run`
_Building:_ `./gradlew desktop:dist` _Building:_ `./gradlew desktop:dist`
#### For Server Builds...
Server builds are bundled with each released build (in Releases). If you'd rather compile on your own, replace 'desktop' with 'server' i.e. `gradlew server:dist`.
--- ---
Gradle may take up to several minutes to download files. Be patient. <br> Gradle may take up to several minutes to download files. Be patient. <br>
After building, the output .JAR file should be in `/desktop/build/libs/desktop-release.jar.` After building, the output .JAR file should be in `/desktop/build/libs/desktop-release.jar` for desktop builds, and in `/server/build/libs/server-release.jar` for server builds.
### Downloads ### Downloads

View File

@@ -1,3 +1,16 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
google()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
}
}
apply plugin: "com.android.application" apply plugin: "com.android.application"
@@ -14,9 +27,9 @@ repositories {
dependencies { dependencies {
implementation project(":core") implementation project(":core")
implementation project(":kryonet") implementation project(":kryonet")
implementation 'com.android.support:support-v4:25.3.1' implementation 'com.android.support:support-v4:28.0.0'
implementation 'org.sufficientlysecure:donations:2.5' implementation 'org.sufficientlysecure:donations:2.5'
implementation 'com.google.android.gms:play-services-auth:11.8.0' implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi" natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi"

View File

@@ -19,11 +19,9 @@ import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException; import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException; import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.security.ProviderInstaller; import com.google.android.gms.security.ProviderInstaller;
import io.anuke.kryonet.DefaultThreadImpl;
import io.anuke.kryonet.KryoClient; import io.anuke.kryonet.KryoClient;
import io.anuke.kryonet.KryoServer; import io.anuke.kryonet.KryoServer;
import io.anuke.mindustry.core.Platform; import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
import io.anuke.mindustry.game.Saves.SaveSlot; import io.anuke.mindustry.game.Saves.SaveSlot;
import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.io.SaveIO;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
@@ -43,7 +41,6 @@ import java.text.NumberFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Locale;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -75,26 +72,15 @@ public class AndroidLauncher extends PatchedAndroidApplication{
TextFieldDialogListener.add(field, 0, length); TextFieldDialogListener.add(field, 0, length);
} }
@Override
public String getLocaleName(Locale locale){
return locale.getDisplayName(locale);
}
@Override @Override
public void openDonations(){ public void openDonations(){
showDonations(); showDonations();
} }
@Override
public ThreadProvider getThreadProvider(){
return new DefaultThreadImpl();
}
@Override @Override
public String getUUID(){ public String getUUID(){
try{ try{
String s = Secure.getString(getContext().getContentResolver(), String s = Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
Secure.ANDROID_ID);
int len = s.length(); int len = s.length();
byte[] data = new byte[len / 2]; byte[] data = new byte[len / 2];
for(int i = 0; i < len; i += 2){ for(int i = 0; i < len; i += 2){

View File

@@ -1,4 +1,6 @@
apply plugin: "java" apply plugin: "java"
sourceCompatibility = 1.8 sourceCompatibility = 1.8
sourceSets.main.java.srcDirs = [ "src/" ] sourceSets.main.java.srcDirs = [ "src/main/java/" ]
sourceSets.main.resources.srcDirs = [ "src/main/resources/" ]

View File

@@ -1,5 +1,7 @@
package io.anuke.annotations; package io.anuke.annotations;
import io.anuke.annotations.MethodEntry;
import java.util.ArrayList; import java.util.ArrayList;
/** Represents a class witha list method entries to include in it. */ /** Represents a class witha list method entries to include in it. */

View File

@@ -2,6 +2,8 @@ package io.anuke.annotations;
import com.squareup.javapoet.*; import com.squareup.javapoet.*;
import io.anuke.annotations.IOFinder.ClassSerializer; import io.anuke.annotations.IOFinder.ClassSerializer;
import io.anuke.annotations.MethodEntry;
import io.anuke.annotations.Utils;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;

View File

@@ -52,7 +52,7 @@ public class SerializeAnnotationProcessor extends AbstractProcessor{
TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("") TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("")
.addSuperinterface(ParameterizedTypeName.get( .addSuperinterface(ParameterizedTypeName.get(
ClassName.get(Class.forName("io.anuke.ucore.io.TypeSerializer")), type)); ClassName.bestGuess("io.anuke.ucore.io.TypeSerializer"), type));
MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write") MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write")
.returns(void.class) .returns(void.class)

View File

@@ -0,0 +1,2 @@
io.anuke.annotations.RemoteMethodAnnotationProcessor
io.anuke.annotations.SerializeAnnotationProcessor

View File

@@ -8,8 +8,6 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.0' classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.0'
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "com.badlogicgames.gdx:gdx-tools:1.9.8" classpath "com.badlogicgames.gdx:gdx-tools:1.9.8"
} }
} }
@@ -27,7 +25,7 @@ allprojects {
appName = 'Mindustry' appName = 'Mindustry'
gdxVersion = '1.9.8' gdxVersion = '1.9.8'
roboVMVersion = '2.3.0' roboVMVersion = '2.3.0'
uCoreVersion = '6080b6fb8c81f9c8e8dcb5809c2399061e15a63f' uCoreVersion = 'dec41336067c013f04f0e17db3b06e24d3c11f6a'
getVersionString = { getVersionString = {
String buildVersion = getBuildVersion() String buildVersion = getBuildVersion()
@@ -101,24 +99,6 @@ project(":desktop") {
} }
} }
project(":html") {
apply plugin: "gwt"
apply plugin: "war"
dependencies {
compile project(":core")
compileOnly project(":annotations")
compile "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion"
compile "com.badlogicgames.gdx:gdx:$gdxVersion:sources"
compile "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion:sources"
compile "com.badlogicgames.gdx:gdx-controllers:$gdxVersion:sources"
compile "com.badlogicgames.gdx:gdx-controllers-gwt:$gdxVersion"
compile "com.badlogicgames.gdx:gdx-controllers-gwt:$gdxVersion:sources"
}
}
project(":ios") { project(":ios") {
apply plugin: "java" apply plugin: "java"
apply plugin: "robovm" apply plugin: "robovm"
@@ -160,7 +140,6 @@ project(":core") {
} }
dependencies { dependencies {
compileOnly project(":annotations")
build.finalizedBy(finish) build.finalizedBy(finish)
def comp = System.properties["release"] == null || System.properties["release"] == "false" def comp = System.properties["release"] == null || System.properties["release"] == "false"
@@ -178,11 +157,10 @@ project(":core") {
compile "com.badlogicgames.gdx:gdx:$gdxVersion" compile "com.badlogicgames.gdx:gdx:$gdxVersion"
compile "com.badlogicgames.gdx:gdx-controllers:$gdxVersion" compile "com.badlogicgames.gdx:gdx-controllers:$gdxVersion"
}
compileJava.options.compilerArgs = [ compileOnly project(":annotations")
"-processor", "io.anuke.annotations.RemoteMethodAnnotationProcessor,io.anuke.annotations.SerializeAnnotationProcessor" annotationProcessor project(":annotations")
] }
} }
project(":server") { project(":server") {
@@ -195,7 +173,6 @@ project(":server") {
} }
dependencies { dependencies {
compileOnly project(":annotations")
compile project(":core") compile project(":core")
compile project(":kryonet") compile project(":kryonet")

View File

Before

Width:  |  Height:  |  Size: 75 B

After

Width:  |  Height:  |  Size: 75 B

View File

Before

Width:  |  Height:  |  Size: 119 B

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

View File

@@ -77,7 +77,6 @@ text.unlocked = New Block Unlocked\!
text.unlocked.plural = New Blocks Unlocked\! text.unlocked.plural = New Blocks Unlocked\!
text.players = {0} players online text.players = {0} players online
text.players.single = {0} player online text.players.single = {0} player online
text.server.mismatch = Packet error\: possible client/server version mismatch.\nMake sure you and the host have the\nlatest version of Mindustry\!
text.server.closing = [accent]Closing server... text.server.closing = [accent]Closing server...
text.server.kicked.kick = You have been kicked from the server\! text.server.kicked.kick = You have been kicked from the server\!
text.server.kicked.serverClose = Server closed. text.server.kicked.serverClose = Server closed.
@@ -137,7 +136,6 @@ text.disconnect = Disconnected.
text.disconnect.data = Failed to load world data\! text.disconnect.data = Failed to load world data\!
text.connecting = [accent]Connecting... text.connecting = [accent]Connecting...
text.connecting.data = [accent]Loading world data... text.connecting.data = [accent]Loading world data...
text.connectfail = [crimson]Failed to connect to server\: [orange]{0}
text.server.port = Port\: text.server.port = Port\:
text.server.addressinuse = Address already in use\! text.server.addressinuse = Address already in use\!
text.server.invalidport = Invalid port number\! text.server.invalidport = Invalid port number\!
@@ -217,7 +215,6 @@ text.editor.description = Description\:
text.editor.name = Name\: text.editor.name = Name\:
text.editor.teams = Teams text.editor.teams = Teams
text.editor.elevation = Elevation text.editor.elevation = Elevation
text.editor.badsize = [orange]Invalid image dimensions\![]\nValid map dimensions\: {0}
text.editor.errorimageload = Error loading file\:\n[orange]{0} text.editor.errorimageload = Error loading file\:\n[orange]{0}
text.editor.errorimagesave = Error saving file\:\n[orange]{0} text.editor.errorimagesave = Error saving file\:\n[orange]{0}
text.editor.generate = Generate text.editor.generate = Generate
@@ -263,6 +260,15 @@ text.tutorial = Tutorial
text.editor = Editor text.editor = Editor
text.mapeditor = Map Editor text.mapeditor = Map Editor
text.donate = Donate text.donate = Donate
text.connectfail = [crimson]Failed to connect to server\:\n\n[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.any = Unkown network error.
text.settings.language = Language text.settings.language = Language
text.settings.reset = Reset to Defaults text.settings.reset = Reset to Defaults
text.settings.rebind = Rebind text.settings.rebind = Rebind
@@ -348,10 +354,8 @@ setting.difficulty.easy = easy
setting.difficulty.normal = normal setting.difficulty.normal = normal
setting.difficulty.hard = hard setting.difficulty.hard = hard
setting.difficulty.insane = insane setting.difficulty.insane = insane
setting.difficulty.purge = purge
setting.difficulty.name = Difficulty\: setting.difficulty.name = Difficulty\:
setting.screenshake.name = Screen Shake setting.screenshake.name = Screen Shake
setting.indicators.name = Enemy Indicators
setting.effects.name = Display Effects setting.effects.name = Display Effects
setting.sensitivity.name = Controller Sensitivity setting.sensitivity.name = Controller Sensitivity
setting.saveinterval.name = Autosave Interval setting.saveinterval.name = Autosave Interval
@@ -361,7 +365,6 @@ setting.multithread.name = Multithreading
setting.fps.name = Show FPS setting.fps.name = Show FPS
setting.vsync.name = VSync setting.vsync.name = VSync
setting.lasers.name = Show Power Lasers setting.lasers.name = Show Power Lasers
setting.healthbars.name = Show Entity Health bars
setting.minimap.name = Show Minimap setting.minimap.name = Show Minimap
setting.musicvol.name = Music Volume setting.musicvol.name = Music Volume
setting.mutemusic.name = Mute Music setting.mutemusic.name = Mute Music
@@ -428,11 +431,13 @@ item.titanium.description = A rare super-light metal used extensively in liquid
item.thorium.name = Thorium item.thorium.name = Thorium
item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel. item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel.
item.silicon.name = Silicon item.silicon.name = Silicon
item.silcion.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics. item.silicon.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics.
item.plastanium.name = Plastanium item.plastanium.name = Plastanium
item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition. item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition.
item.phase-matter.name = Phase Matter 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.name = Surge Alloy
item.surge-alloy.description = An advanced alloy with unique electrical properties.
item.biomatter.name = Biomatter item.biomatter.name = Biomatter
item.biomatter.description = A clump of organic mush; used for conversion into oil or as a basic fuel. item.biomatter.description = A clump of organic mush; used for conversion into oil or as a basic fuel.
item.sand.name = Sand item.sand.name = Sand
@@ -495,7 +500,7 @@ block.metalfloor.name = Metal Floor
block.deepwater.name = deepwater block.deepwater.name = deepwater
block.water.name = water block.water.name = water
block.lava.name = lava block.lava.name = lava
block.oil.name = oil block.tar.name = Tar
block.blackstone.name = blackstone block.blackstone.name = blackstone
block.stone.name = stone block.stone.name = stone
block.dirt.name = dirt block.dirt.name = dirt

View File

@@ -428,7 +428,7 @@ item.titanium.description = Ein seltenes sehr leichtes Metal. Häufig in Flüssi
item.thorium.name = Uran item.thorium.name = Uran
item.thorium.description = Ein dichtes radioaktives Metal, welches als strukturelle Unterstützung und nuklearer Kraftstoff verwendet wird. item.thorium.description = Ein dichtes radioaktives Metal, welches als strukturelle Unterstützung und nuklearer Kraftstoff verwendet wird.
item.silicon.name = Silikon item.silicon.name = Silikon
item.silcion.description = Ein sehr nützlicher Halbleiter. Findet Anwendung in Solar Anlagen und komplexer Elektronik. item.silicon.description = Ein sehr nützlicher Halbleiter. Findet Anwendung in Solar Anlagen und komplexer Elektronik.
item.plastanium.name = Plastanium item.plastanium.name = Plastanium
item.plastanium.description = Ein leichtes dehnbares Material welches in Flugzeugen und Splittermunition verwendet wird. item.plastanium.description = Ein leichtes dehnbares Material welches in Flugzeugen und Splittermunition verwendet wird.
item.phase-matter.name = Phase Materie item.phase-matter.name = Phase Materie

View File

@@ -12,7 +12,7 @@ text.linkfail = ¡Error al abrir el enlace\!\nLa URL ha sido copiada a su portap
text.editor.web = ¡La versión web no es compatible con el editor\!\nDescargue el juego para usarlo. text.editor.web = ¡La versión web no es compatible con el editor\!\nDescargue el juego para usarlo.
text.web.unsupported = ¡La versión web no soporta esta característica\! Descarga el juego para poder usarla. text.web.unsupported = ¡La versión web no soporta esta característica\! Descarga el juego para poder usarla.
text.gameover = Tu núcleo ha sido destruido. text.gameover = Tu núcleo ha sido destruido.
text.gameover.pvp = The[accent] {0}[] team is victorious\! text.gameover.pvp = El equipo[accent] {0}[] ha ganado\!
text.sector.gameover = Este sector ha sido perdido. ¿Re-instaurar? text.sector.gameover = Este sector ha sido perdido. ¿Re-instaurar?
text.sector.retry = Reintentar text.sector.retry = Reintentar
text.highscore = [accent]¡Nueva mejor puntuación\! text.highscore = [accent]¡Nueva mejor puntuación\!
@@ -22,7 +22,7 @@ text.level.delete.title = Confirmar Eliminación
text.map.delete = ¿Estás seguro que quieres borrar el mapa "[orange]{0}[]"? text.map.delete = ¿Estás seguro que quieres borrar el mapa "[orange]{0}[]"?
text.level.select = Selección de nivel text.level.select = Selección de nivel
text.level.mode = Modo de juego\: text.level.mode = Modo de juego\:
text.construction.desktop = Desktop controls have been changed.\nTo deselect a block or stop building, [accent]use space[]. text.construction.desktop = Los controles de la versión de escritorio han cambiado.\nPara deseleccionar un bloque o dejar de construir, [accent]usa la barra espaciadora[].
text.construction.title = Guía de Construcción de Bloques text.construction.title = Guía de Construcción de Bloques
text.construction = Acaba de seleccionar el [accent]modo de construcción de bloques[].\n\nPara empezar a colocar, simplemente presione en una localización valida cerca de su nave.\nCuando haya terminado de seleccionar algunos bloques, presiona la casilla para confirmar, y su nave empezara a construirlos.\n\n- [accent]Remueve bloques[] de tu selección presionando en ellos.\n- [accent]Cambia tu selección de lugar[] manteniendo y arrastrando cualquier bloque en la selección.\n- [accent]Coloca bloques en línea[] presionando y manteniendo en un espacio vacío, y arrastrando hacia cualquier dirección.\n- [accent]Cancela la construcción o selección[] presionando la X abajo a la izquierda. text.construction = Acaba de seleccionar el [accent]modo de construcción de bloques[].\n\nPara empezar a colocar, simplemente presione en una localización valida cerca de su nave.\nCuando haya terminado de seleccionar algunos bloques, presiona la casilla para confirmar, y su nave empezara a construirlos.\n\n- [accent]Remueve bloques[] de tu selección presionando en ellos.\n- [accent]Cambia tu selección de lugar[] manteniendo y arrastrando cualquier bloque en la selección.\n- [accent]Coloca bloques en línea[] presionando y manteniendo en un espacio vacío, y arrastrando hacia cualquier dirección.\n- [accent]Cancela la construcción o selección[] presionando la X abajo a la izquierda.
text.deconstruction.title = Guía de Deconstrucción de Bloques text.deconstruction.title = Guía de Deconstrucción de Bloques
@@ -39,31 +39,31 @@ text.sectors = Sectores
text.sector = Sector\: [LIGHT_GRAY]{0} text.sector = Sector\: [LIGHT_GRAY]{0}
text.sector.time = Tiempo\: [LIGHT_GRAY]{0} text.sector.time = Tiempo\: [LIGHT_GRAY]{0}
text.sector.deploy = Desplegar text.sector.deploy = Desplegar
text.sector.abandon = Abandon text.sector.abandon = Abandonar
text.sector.abandon.confirm = Are you sure you want to abandon all progress at this sector?\nThis cannot be undone\! text.sector.abandon.confirm = ¿Definitivamente quieres abandonar todo el progreso hecho en este sector?\nEsto no se puede deshacer\!
text.sector.resume = Resumir text.sector.resume = Resumir
text.sector.locked = [scarlet][[Incompleto] text.sector.locked = [scarlet][[Incompleto]
text.sector.unexplored = [accent][[Inexplorado] text.sector.unexplored = [accent][[Inexplorado]
text.missions = Missions\:[LIGHT_GRAY] {0} text.missions = Missions\:[LIGHT_GRAY] {0}
text.mission = Misión\:[LIGHT_GRAY] {0} text.mission = Misión\:[LIGHT_GRAY] {0}
text.mission.main = Main Mission\:[LIGHT_GRAY] {0} text.mission.main = Misión Principal\:[LIGHT_GRAY] {0}
text.mission.info = Mission Info text.mission.info = Información de la Misión
text.mission.complete = ¡Misión completada\! text.mission.complete = ¡Misión completada\!
text.mission.complete.body = Sector {0},{1} ha sido conquistado. text.mission.complete.body = El Sector {0},{1} ha sido conquistado.
text.mission.wave = Sobrevive [accent]{0}[] hordas. text.mission.wave = Sobrevive [accent]{0}[] hordas.
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies text.mission.wave.enemies = Sobrevive[accent] {0}/{1} []hordas\n{2} Enemigas
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy text.mission.wave.enemy = Sobrevive[accent] {0}/{1} []hordas\n{2} Enemigas
text.mission.wave.menu = Survive[accent] {0} []waves text.mission.wave.menu = Sobrevive[accent] {0} []hordas
text.mission.battle = Destruye la base enemiga. text.mission.battle = Destruye la base enemiga.
text.mission.resource.menu = Obtain {0} x{1} text.mission.resource.menu = Obtener {0} x{1}
text.mission.resource = Obtén {0} x{1} text.mission.resource = Obtén {0} x{1}
text.mission.block = Create {0} text.mission.block = Crear {0}
text.mission.unit = Create {0} Unit text.mission.unit = Crear {0} Unit
text.mission.command = Send Command {0} To Units text.mission.command = Enviar Comando {0} A Las Unidades
text.mission.linknode = Link Power Node text.mission.linknode = Link Power Node
text.mission.display = [accent]Mission\:\n[LIGHT_GRAY]{0} text.mission.display = [accent]Misn\:\n[LIGHT_GRAY]{0}
text.mission.mech = Switch to mech[accent] {0}[] text.mission.mech = Cambiar a mech[accent] {0}[]
text.mission.create = Create[accent] {0}[] text.mission.create = Crear[accent] {0}[]
text.none = <no hay> text.none = <no hay>
text.close = Cerrar text.close = Cerrar
text.quit = Salir text.quit = Salir
@@ -94,7 +94,7 @@ text.server.kicked.customClient = Este servidor no soporta versiones personaliza
text.host.info = El botón [accent]hostear[] hostea un servidor en el puerto [scarlet]6567[]. \nCualquier persona en la misma [LIGHT_GRAY]wifi o red local[] debería poder ver tu servidor en la lista de servidores.\n\nSi quieres que cualquier persona se pueda conectar de cualquier lugar por IP, la [accent]asignación de puertos[] es requerida.\n\n[LIGHT_GRAY]Nota\: Si alguien experimenta problemas conectándose a tu partida LAN, asegúrate de permitir a Mindustry acceso a tu red local mediante la configuración de tu firewall. text.host.info = El botón [accent]hostear[] hostea un servidor en el puerto [scarlet]6567[]. \nCualquier persona en la misma [LIGHT_GRAY]wifi o red local[] debería poder ver tu servidor en la lista de servidores.\n\nSi quieres que cualquier persona se pueda conectar de cualquier lugar por IP, la [accent]asignación de puertos[] es requerida.\n\n[LIGHT_GRAY]Nota\: Si alguien experimenta problemas conectándose a tu partida LAN, asegúrate de permitir a Mindustry acceso a tu red local mediante la configuración de tu firewall.
text.join.info = Acá, tu puedes escribir la [accent]IP de un servidor[] para conectarte, o para descubrir servidores de [accent]red local[] para conectarte.\nLAN y WAN es soportado para jugar en multijugador.\n\n[LIGHT_GRAY]Nota\: No hay lista automática global de servidores; si quieres conectarte por IP, tendrás que preguntarle al anfitrión por la IP. text.join.info = Acá, tu puedes escribir la [accent]IP de un servidor[] para conectarte, o para descubrir servidores de [accent]red local[] para conectarte.\nLAN y WAN es soportado para jugar en multijugador.\n\n[LIGHT_GRAY]Nota\: No hay lista automática global de servidores; si quieres conectarte por IP, tendrás que preguntarle al anfitrión por la IP.
text.hostserver = Hostear Servidor text.hostserver = Hostear Servidor
text.hostserver.mobile = Host\nGame text.hostserver.mobile = Hostear\nJuego
text.host = Hostear text.host = Hostear
text.hosting = [accent]Abriendo servidor... text.hosting = [accent]Abriendo servidor...
text.hosts.refresh = Actualizar text.hosts.refresh = Actualizar
@@ -193,9 +193,9 @@ text.saving = [accent]Guardando...
text.wave = [orange]Horda {0} text.wave = [orange]Horda {0}
text.wave.waiting = Horda en {0} text.wave.waiting = Horda en {0}
text.waiting = Esperando... text.waiting = Esperando...
text.waiting.players = Waiting for players... text.waiting.players = Esperando por jugafores...
text.wave.enemies = [LIGHT_GRAY]{0} Enemies Remaining text.wave.enemies = [LIGHT_GRAY]{0} Enemigos Restantes
text.wave.enemy = [LIGHT_GRAY]{0} Enemy Remaining text.wave.enemy = [LIGHT_GRAY]{0} Enemigo Restante
text.loadimage = Cargar Imagen text.loadimage = Cargar Imagen
text.saveimage = Guardar Imagen text.saveimage = Guardar Imagen
text.unknown = Desconocido text.unknown = Desconocido
@@ -270,12 +270,12 @@ text.settings.controls = Controles
text.settings.game = Juego text.settings.game = Juego
text.settings.sound = Sonido text.settings.sound = Sonido
text.settings.graphics = Gráficos text.settings.graphics = Gráficos
text.settings.cleardata = Clear Game Data... text.settings.cleardata = Limpiar Datos del Juego...
text.settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone\! text.settings.clear.confirm = ¿Estas seguro de querer limpiar estos datos?\nEsta accion no puede deshacerse\!
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.clearall.confirm = [scarlet]ADVERTENCIA\![]\nEsto va a eliminar todos tus datos, incluyendo saves, mapas, desbloqueos y keybinds.\nUna vez presiones 'ok' el juego va a borrrar todos tus datos y a salir del juego automáticamente.
text.settings.clearsectors = Clear Sectors text.settings.clearsectors = Limpiar Sectores
text.settings.clearunlocks = Clear Unlocks text.settings.clearunlocks = Limpiar Desbloqueos
text.settings.clearall = Clear All text.settings.clearall = Limpiar Todo
text.paused = Pausado text.paused = Pausado
text.yes = Si text.yes = Si
text.no = No text.no = No
@@ -308,7 +308,7 @@ text.blocks.outputitem = Objeto de Salida
text.blocks.drilltier = Taladrable text.blocks.drilltier = Taladrable
text.blocks.drillspeed = Velocidad de Base del Taladro text.blocks.drillspeed = Velocidad de Base del Taladro
text.blocks.liquidoutput = Líquido de Salida text.blocks.liquidoutput = Líquido de Salida
text.blocks.liquidoutputspeed = Liquid Output Speed text.blocks.liquidoutputspeed = Velocidad de Salida del Líquido
text.blocks.liquiduse = Uso del Líquido text.blocks.liquiduse = Uso del Líquido
text.blocks.coolant = Refrigerante text.blocks.coolant = Refrigerante
text.blocks.coolantuse = Uso del Refrigerante text.blocks.coolantuse = Uso del Refrigerante
@@ -343,7 +343,7 @@ setting.autotarget.name = Auto-Target
setting.fpscap.name = Max FPS setting.fpscap.name = Max FPS
setting.fpscap.none = Nada setting.fpscap.none = Nada
setting.fpscap.text = {0} FPS setting.fpscap.text = {0} FPS
setting.difficulty.training = training setting.difficulty.training = entrenamiento
setting.difficulty.easy = fácil setting.difficulty.easy = fácil
setting.difficulty.normal = normal setting.difficulty.normal = normal
setting.difficulty.hard = difícil setting.difficulty.hard = difícil
@@ -371,17 +371,17 @@ text.keybind.title = Reasignar Teclas
category.general.name = General category.general.name = General
category.view.name = View category.view.name = View
category.multiplayer.name = Multiplayer category.multiplayer.name = Multiplayer
command.attack = Attack command.attack = Atacar
command.retreat = Retreat command.retreat = Retirada
command.patrol = Patrol command.patrol = Patrullar
keybind.press = Press a key... keybind.press = Presiona una tecla...
keybind.press.axis = Press an axis or key... keybind.press.axis = Press an axis or key...
keybind.move_x.name = Mover x keybind.move_x.name = Mover x
keybind.move_y.name = Mover y keybind.move_y.name = Mover y
keybind.select.name = Seleccionar keybind.select.name = Seleccionar
keybind.break.name = Remover keybind.break.name = Remover
keybind.deselect.name = Deselect keybind.deselect.name = Deseleccionar
keybind.shoot.name = Dispar keybind.shoot.name = Disparar
keybind.zoom_hold.name = Mantener Zoom keybind.zoom_hold.name = Mantener Zoom
keybind.zoom.name = Zoom keybind.zoom.name = Zoom
keybind.menu.name = Menu keybind.menu.name = Menu
@@ -391,12 +391,12 @@ keybind.chat.name = Chat
keybind.player_list.name = Lista de jugadores keybind.player_list.name = Lista de jugadores
keybind.console.name = consola keybind.console.name = consola
keybind.rotate.name = Rotar keybind.rotate.name = Rotar
keybind.toggle_menus.name = Toggle menus keybind.toggle_menus.name = Alternar menús
keybind.chat_history_prev.name = Chat history prev keybind.chat_history_prev.name = Historial de chat anterior
keybind.chat_history_next.name = Chat history next keybind.chat_history_next.name = Historial de chat siguiente
keybind.chat_scroll.name = Chat scroll keybind.chat_scroll.name = Chat scroll
keybind.drop_unit.name = drop unit keybind.drop_unit.name = drop unit
keybind.zoom_minimap.name = Zoom minimap keybind.zoom_minimap.name = Zoom minimapa
mode.text.help.title = Descripción de modos mode.text.help.title = Descripción de modos
mode.waves.name = hordas mode.waves.name = hordas
mode.waves.description = el modo normal. con recursos limitados y entrada de hordas automática. mode.waves.description = el modo normal. con recursos limitados y entrada de hordas automática.
@@ -428,7 +428,7 @@ item.titanium.description = Un metal raro super ligero usado extensivamente en t
item.thorium.name = Torio item.thorium.name = Torio
item.thorium.description = Un metal radiactivo, muy denso usado en soporte de estructuras y combustible nuclear. item.thorium.description = Un metal radiactivo, muy denso usado en soporte de estructuras y combustible nuclear.
item.silicon.name = Silicona item.silicon.name = Silicona
item.silcion.description = Un semiconductor muy útil, se usa para paneles solares y muchos electrónicos complejos. item.silicon.description = Un semiconductor muy útil, se usa para paneles solares y muchos electrónicos complejos.
item.plastanium.name = Plastanio item.plastanium.name = Plastanio
item.plastanium.description = Un material dúctil, ligero usado en aeronaves y proyectiles de fragmentación. item.plastanium.description = Un material dúctil, ligero usado en aeronaves y proyectiles de fragmentación.
item.phase-matter.name = Materia de Fase item.phase-matter.name = Materia de Fase

View File

@@ -428,7 +428,7 @@ item.titanium.description = Un métal rare super-léger largement utilisé dans
item.thorium.name = Thorium item.thorium.name = Thorium
item.thorium.description = Un métal dense, et radioactif utilisé comme support structurel et comme carburant nucléaire. item.thorium.description = Un métal dense, et radioactif utilisé comme support structurel et comme carburant nucléaire.
item.silicon.name = Silicon item.silicon.name = Silicon
item.silcion.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics. item.silicon.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics.
item.plastanium.name = Plastanium 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.plastanium.description = Un matériau léger et docile utilisé dans l'aviation avancée et dans les munitions à fragmentation.
item.phase-matter.name = Matière phasée item.phase-matter.name = Matière phasée

View File

@@ -428,7 +428,7 @@ item.titanium.description = Un métal rare super-léger largement utilisé dans
item.thorium.name = Thorium item.thorium.name = Thorium
item.thorium.description = Un métal dense, et radioactif utilisé comme support structurel et comme carburant nucléaire. item.thorium.description = Un métal dense, et radioactif utilisé comme support structurel et comme carburant nucléaire.
item.silicon.name = Silicone item.silicon.name = Silicone
item.silcion.description = Un matériau semi-conducteur extrêmement utile, avec des utilisations dans les panneaux solaires et beaucoup d'autre composants électroniques complexes. 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.name = Plastanium
item.plastanium.description = Un matériau léger et docile utilisé dans l'aviation avancée et dans les munitions à fragmentation. item.plastanium.description = Un matériau léger et docile utilisé dans l'aviation avancée et dans les munitions à fragmentation.
item.phase-matter.name = Matière phasée item.phase-matter.name = Matière phasée

View File

@@ -428,7 +428,7 @@ item.titanium.description = A rare super-light metal used extensively in liquid
item.thorium.name = thorium item.thorium.name = thorium
item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel. item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel.
item.silicon.name = Silicon item.silicon.name = Silicon
item.silcion.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics. item.silicon.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics.
item.plastanium.name = Plastanium item.plastanium.name = Plastanium
item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition. item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition.
item.phase-matter.name = Phase Matter item.phase-matter.name = Phase Matter

View File

@@ -428,7 +428,7 @@ item.titanium.description = Un raro metallo super leggero usato ampiamente nel t
item.thorium.name = Torio item.thorium.name = Torio
item.thorium.description = Un materiale denso e radioattivo, utilizzato nella costruzione di strutture e come carburante del reattore nucleare. item.thorium.description = Un materiale denso e radioattivo, utilizzato nella costruzione di strutture e come carburante del reattore nucleare.
item.silicon.name = Silicio item.silicon.name = Silicio
item.silcion.description = Un semiconduttore molto utile che viene utilizzato nei pannelli solari e nei macchinari elettronici. item.silicon.description = Un semiconduttore molto utile che viene utilizzato nei pannelli solari e nei macchinari elettronici.
item.plastanium.name = Plastaniu item.plastanium.name = Plastaniu
item.plastanium.description = Un materiale leggero e duttile, utilizzato nelle navi avanzete e come munizione. item.plastanium.description = Un materiale leggero e duttile, utilizzato nelle navi avanzete e come munizione.
item.phase-matter.name = Vaporizzatore di materia item.phase-matter.name = Vaporizzatore di materia

View File

@@ -1,6 +1,6 @@
text.credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet\!) text.credits.text = 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.credits = 제작자
text.discord = Mindustry Discord 에 참여하세요\! text.discord = Mindustry Discord 에 참여하세요!
text.link.discord.description = 공식 Mindustry Discord 채팅방 text.link.discord.description = 공식 Mindustry Discord 채팅방
text.link.github.description = 게임 소스코드 text.link.github.description = 게임 소스코드
text.link.dev-builds.description = 개발중인 빌드 text.link.dev-builds.description = 개발중인 빌드
@@ -8,27 +8,27 @@ text.link.trello.description = 다음 출시될 기능들을 게시한 공식 Tr
text.link.itch.io.description = PC 버전 다운로드와 HTML5 버전이 있는 itch.io 사이트 text.link.itch.io.description = PC 버전 다운로드와 HTML5 버전이 있는 itch.io 사이트
text.link.google-play.description = Google Play 스토어 정보 text.link.google-play.description = Google Play 스토어 정보
text.link.wiki.description = 공식 Mindustry 위키 (영어) text.link.wiki.description = 공식 Mindustry 위키 (영어)
text.linkfail = 링크를 여는데 실패했습니다\! URL이 기기의 클립보드에 복사되었습니다. text.linkfail = 링크를 여는데 실패했습니다! URL이 기기의 클립보드에 복사되었습니다.
text.editor.web = HTML5 버전은 에디터 기능을 지원하지 않습니다\! 게임을 다운로드 한 뒤에 사용 해 주세요. text.editor.web = HTML5 버전은 에디터 기능을 지원하지 않습니다! 게임을 다운로드 한 뒤에 사용 해 주세요.
text.web.unsupported = HTML5 버전은 이 기능을 지원하지 않습니다\! 게임을 다운로드 한 뒤에 사용 해 주세요. text.web.unsupported = HTML5 버전은 이 기능을 지원하지 않습니다! 게임을 다운로드 한 뒤에 사용 해 주세요.
text.gameover = 코어가 터졌습니다. 게임 오버\! text.gameover = 코어가 터졌습니다. 게임 오버!
text.gameover.pvp = [accent]{0}[] 팀이 승리했습니다\! text.gameover.pvp = [accent]{0}[] 팀이 승리했습니다!
text.sector.gameover = 이 구역을 공략하는데 실패했습니다. 다시 배치하시겠습니까? text.sector.gameover = 이 구역을 공략하는데 실패했습니다. 다시 배치하시겠습니까?
text.sector.retry = 다시할 text.sector.retry = 다시할
text.highscore = [YELLOW]최고점수 달성\! text.highscore = [YELLOW]최고점수 달성!
text.wave.lasted = [accent]{0}[] 까지 버티셨습니다. text.wave.lasted = [accent]{0}[] 까지 버티셨습니다.
text.level.highscore = 최고 점수 \: [accent]{0} text.level.highscore = 최고 점수 : [accent]{0}
text.level.delete.title = 삭제 확인 text.level.delete.title = 삭제 확인
text.map.delete = 정말로 "[orange]{0}[]" 맵을 삭제하시겠습니까? text.map.delete = 정말로 "[orange]{0}[]" 맵을 삭제하시겠습니까?
text.level.select = 맵 선택 text.level.select = 맵 선택
text.level.mode = 게임모드 \: text.level.mode = 게임모드 :
text.construction.desktop = PC 에서의 조작 방법이 변경되었습니다.\n블록 선택을 해제하거나 건설을 중지하려면 [accent]스페이스 바[]를 누르세요. text.construction.desktop = PC 에서의 조작 방법이 변경되었습니다.\n블록 선택을 해제하거나 건설을 중지하려면 [accent]스페이스 바[]를 누르세요.
text.construction.title = 블록 배치 안내서 text.construction.title = 블록 배치 안내서
text.construction = [accent]블록 배치 모드[]를 선택하셨습니다.\n\n블록을 설치하고 싶으면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 배치 작업을 진행할 것입니다.\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요. \n- [accent]블록을 넓게 배치[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.- [accent]블록을 한줄로 배치[]하고 싶다면 배치하고 싶은 시작 영역을 한번 탭 하고 길게 누르면서 드래그 하면 됩니다. \n- [accent]블록 배치 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다. text.construction = [accent]블록 배치 모드[]를 선택하셨습니다.\n\n블록을 설치하고 싶으면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 배치 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요. \n- [accent]블록을 넓게 배치[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록을 한줄로 배치[]하고 싶다면 배치하고 싶은 시작 영역을 한번 탭 하고 길게 누르면서 드래그 하면 됩니다. \n- [accent]블록 배치 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다.
text.deconstruction.title = 블록 삭제 안내서 text.deconstruction.title = 블록 삭제 안내서
text.deconstruction = [accent]블록 삭제 모드[]를 선택하셨습니다\n블록을 삭제하고 싶다면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 파괴 작업을 진행할 것입니다.\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요- [accent]블록을 넓은 범위로 삭제[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.- [accent]블록 삭제 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다. text.deconstruction = [accent]블록 삭제 모드[]를 선택하셨습니다\n\n블록을 삭제하고 싶다면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 파괴 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요\n- [accent]블록을 넓은 범위로 삭제[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록 삭제 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다.
text.showagain = 다음 세션에서 이 메세지를 표시하지 않습니다 text.showagain = 다음 세션에서 이 메세지를 표시하지 않습니다
text.coreattack = < 코어가 공격받고 있습니다 \! > text.coreattack = < 코어가 공격받고 있습니다 ! >
text.unlocks = 아이템들 text.unlocks = 아이템들
text.savegame = 게임 저장 text.savegame = 게임 저장
text.loadgame = 게임 불러오기 text.loadgame = 게임 불러오기
@@ -36,62 +36,63 @@ text.joingame = 게임 참가
text.addplayers = 플레이어 추가/제거 text.addplayers = 플레이어 추가/제거
text.customgame = 커스텀 게임 text.customgame = 커스텀 게임
text.sectors = 구역 text.sectors = 구역
text.sector = 선택된 구역 \: [LIGHT_GRAY]{0} text.sector = 구역 : [LIGHT_GRAY]{0}
text.sector.time = 시간 \: [LIGHT_GRAY]{0} text.sector.time = 시간 : [LIGHT_GRAY]{0}
text.sector.deploy = 시작 text.sector.deploy = 시작
text.sector.abandon = 초기화 text.sector.abandon = 초기화
text.sector.abandon.confirm = 정말로 이 구역의 모든 진행상활을 초기화 하겠습니까?\n이 작업은 되돌릴 수 없습니다\! text.sector.abandon.confirm = 정말로 이 구역의 모든 진행상활을 초기화 하겠습니까?\n이 작업은 되돌릴 수 없습니다!
text.sector.resume = 계속하기 text.sector.resume = 계속하기
text.sector.locked = [scarlet][[완료안됨] text.sector.locked = [scarlet][[완료안됨]
text.sector.unexplored = [accent][[탐색안됨] text.sector.unexplored = [accent][[탐색안됨]
text.missions = 목표 \: [LIGHT_GRAY] {0} text.missions = 목표 : [LIGHT_GRAY] {0}
text.mission = 목표 \: [LIGHT_GRAY] {0} text.mission = 목표 : [LIGHT_GRAY] {0}
text.mission.main = 주요 목표 : [LIGHT_GRAY]{0}
text.mission.info = 미션 정보 text.mission.info = 미션 정보
text.mission.complete = 미션 성공\! text.mission.complete = 미션 성공!
text.mission.complete.body = 구역 {0},{1} 탐색 성공. text.mission.complete.body = 구역 {0},{1} 클리어.
text.mission.wave = [accent]{0}[]단계가 될때까지 생존하세요. text.mission.wave = [accent]{0}[]단계가 될때까지 생존하세요.
text.mission.wave.enemies = [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.enemy = [accent] {0}/{1} []단계동안 생존하세요.\n{2}마리 남음
text.mission.wave.menu = [accent] {0} []단계 text.mission.wave.menu = [accent]{0} []단계
text.mission.battle = 적 본부를 파괴하세요. text.mission.battle = 적 본부를 파괴하세요.
text.mission.resource.menu = {0} {1}개 수집 text.mission.resource.menu = {0} {1}개 수집
text.mission.resource = {0} 자원을 {1}개 모으세요. text.mission.resource = {0} 자원을 수집하세요 :\n[accent]{1}/{2}[]
text.mission.block = {0}를 만드세요. text.mission.block = 이것을 만드세요 :\n{0}
text.mission.unit = {0}유닛을 만드세요. text.mission.unit = 유닛을 만드세요 :\n{0}
text.mission.command = 유닛에게 {0} 명령을 보내세요 text.mission.command = 유닛에게 명령을 보내세요 :\n{0}
text.mission.linknode = 전력 노드를 연결하세요. text.mission.linknode = 전력 노드를 연결하세요.
text.mission.display = [accent]미션 \: \n[LIGHT_GRAY]{0} text.mission.display = [accent]미션 : \n[LIGHT_GRAY]{0}
text.mission.mech = [accent] {0}[] 기체로 바꾸세요. text.mission.mech = 이 기체로 바꾸세요 :\n[accent]{0}
text.mission.create = [accent] {0}[] 를 만드세요. text.mission.create = 이 자원을 만드세요 :\n[accent]{0}
text.none = <없음> text.none = <없음>
text.close = 닫기 text.close = 닫기
text.quit = 나가기 text.quit = 나가기
text.maps = text.maps =
text.continue = 계속하기 text.continue = 계속하기
text.nextmission = 다음 임무 text.nextmission = 다음 임무
text.maps.none = [LIGHT_GRAY]맵을 찾을 수 없습니다\! text.maps.none = [LIGHT_GRAY]맵을 찾을 수 없습니다!
text.about.button = 정보 text.about.button = 정보
text.name = 이름 \: text.name = 이름 :
text.unlocked = 새 블록 잠금 해제 text.unlocked = 새 블록 잠금 해제
text.unlocked.plural = 새 블록 잠금 해제 text.unlocked.plural = 잠금 해제
text.players = 현재 {0}명 접속중 text.players = 현재 {0}명 접속중
text.players.single = 현재 {0}명만 있음. text.players.single = 현재 {0}명만 있음.
text.server.mismatch = 클라이언트와 서버 버전이 일치하지 않습니다. 자신이 서버를 호스트하거나 최신 버전을 사용 해 주세요\! text.server.mismatch = 클라이언트와 서버 버전이 일치하지 않습니다.\n자신이 서버를 호스트하거나 최신 버전을 사용 해 주세요!
text.server.closing = [accent]서버 닫는중... text.server.closing = [accent]서버 닫는중...
text.server.kicked.kick = 서버에서 추방되었습니다\! text.server.kicked.kick = 서버에서 추방되었습니다!
text.server.kicked.serverClose = 서버 종료됨. text.server.kicked.serverClose = 서버 종료됨.
text.server.kicked.sectorComplete = 구역 클리어. text.server.kicked.sectorComplete = 구역 클리어.
text.server.kicked.sectorComplete.text = 임무 성공.\n서버가 다음구역 맵으로 이동되었습니다. text.server.kicked.sectorComplete.text = 임무 성공.\n서버가 다음구역 맵으로 이동되었습니다.
text.server.kicked.clientOutdated = 오래된 버전의 클라이언트 입니다\! 게임을 업데이트 하세요\! text.server.kicked.clientOutdated = 오래된 버전의 클라이언트 입니다! 게임을 업데이트 하세요!
text.server.kicked.serverOutdated = 오래된 버전의 서버입니다\! 서버 호스트 관리자에게 문의하세요\! text.server.kicked.serverOutdated = 오래된 버전의 서버입니다! 서버 호스트 관리자에게 문의하세요!
text.server.kicked.banned = 서버에서 영 좋지 않은 행위를 하여 영구 차단되었습니다. text.server.kicked.banned = 뭘 하셨는지는 모르겠지만, 이제 영원히 서버에 접속할 수 없습니다.
text.server.kicked.recentKick = 방금 추방처리 되었습니다. 잠시 기다린 후에 접속 해 주세요. text.server.kicked.recentKick = 방금 추방처리 되었습니다. 잠시 기다린 후에 접속 해 주세요.
text.server.kicked.nameInUse = 이 닉네임이 이미 서버에서 사용중입니다. text.server.kicked.nameInUse = 이 닉네임이 이미 서버에서 사용중입니다.
text.server.kicked.nameEmpty = 닉네임에는 반드시 영어 또는 숫자가 있어야 합니다. text.server.kicked.nameEmpty = 닉네임에는 반드시 영어 또는 숫자가 있어야 합니다.
text.server.kicked.idInUse = 이미 서버에 접속중입니다\! 다중 계정은 허용되지 않습니다. text.server.kicked.idInUse = 이미 서버에 접속중입니다! 다중 계정은 허용되지 않습니다.
text.server.kicked.customClient = 이 서버는 직접 빌드한 버전을 지원하지 않습니다. 공식 버전을 사용하세요. text.server.kicked.customClient = 이 서버는 직접 빌드한 버전을 지원하지 않습니다. 공식 버전을 사용하세요.
text.host.info = [accent]호스트[] 버튼은 현재 네트워크의 [scarlet]6567[] 과 [scarlet]6568[] 포트를 사용합니다.\n[LIGHY_GRAY]같은 Wi-Fi 또는 로컬 네트워크[] 에서 서버 목록을 볼 수 있습니다.\n\n만약 플레이어들이 이 IP를 통해 어디에서나 연결할 수 있게 하고 싶다면, 공유기 설정에서 [accent]포트 포워딩[]을 해야 합니다.\n\n[LIGHT_GRAY]참고 \: LAN 게임 연결에 문제가 있는 사람이 있다면, 방화벽 설정에서 Mindustry 가 로컬 네트워크에 액세스하도록 허용했는지 확인 해 주세요. text.host.info = [accent]호스트[] 버튼은 현재 네트워크의 [scarlet]6567[] 과 [scarlet]6568[] 포트를 사용합니다.\n[LIGHY_GRAY]같은 Wi-Fi 또는 로컬 네트워크[] 에서 서버 목록을 볼 수 있습니다.\n\n만약 플레이어들이 이 IP를 통해 어디에서나 연결할 수 있게 하고 싶다면, 공유기 설정에서 [accent]포트 포워딩[]을 해야 합니다.\n\n[LIGHT_GRAY]참고 : LAN 게임 연결에 문제가 있는 사람이 있다면, 방화벽 설정에서 Mindustry 가 로컬 네트워크에 액세스하도록 허용했는지 확인 해 주세요.
text.join.info = 여기서 [accent]서버 IP[]를 입력하여 다른 서버에 접속할 수 있습니다.\n또는 [accent]로컬 네트워크(LAN)[] 서버를 검색하여 접속할 수 있습니다.\nLAN 및 WAN 멀티 플레이어 모두 지원됩니다.\n\n[LIGHT_GRAY]참고\:여기에서는 자동으로 글로벌 서버를 추가하지 않습니다. IP로 다른 사람의 서버에 접속할려면 서버장에게 IP를 요청해야 합니다. text.join.info = 여기서 [accent]서버 IP[]를 입력하여 다른 서버에 접속할 수 있습니다.\n또는 [accent]로컬 네트워크(LAN)[] 서버를 검색하여 접속할 수 있습니다.\nLAN 및 WAN 멀티 플레이어 모두 지원됩니다.\n\n[LIGHT_GRAY]참고:여기에서는 자동으로 글로벌 서버를 추가하지 않습니다. IP로 다른 사람의 서버에 접속할려면 서버장에게 IP를 요청해야 합니다.
text.hostserver = 서버 열기 text.hostserver = 서버 열기
text.hostserver.mobile = 게임\n호스트 text.hostserver.mobile = 게임\n호스트
text.host = 호스트 text.host = 호스트
@@ -99,31 +100,31 @@ text.hosting = [accent]서버 여는중..
text.hosts.refresh = 새로고침 text.hosts.refresh = 새로고침
text.hosts.discovering = LAN 게임 찾기 text.hosts.discovering = LAN 게임 찾기
text.server.refreshing = 서버 목록 새로고치는중... text.server.refreshing = 서버 목록 새로고치는중...
text.hosts.none = [lightgray]LAN 게임을 찾을 수 없습니다\! text.hosts.none = [lightgray]LAN 게임을 찾을 수 없습니다!
text.host.invalid = [scarlet]서버에 연결할 수 없습니다\! text.host.invalid = [scarlet]서버에 연결할 수 없습니다!
text.trace = 플레이어 정보 보기 text.trace = 플레이어 정보 보기
text.trace.playername = 이름 \: [accent]{0} text.trace.playername = 이름 : [accent]{0}
text.trace.ip = IP \: [accent]{0} text.trace.ip = IP : [accent]{0}
text.trace.id = 고유 ID \: [accent]{0} text.trace.id = 고유 ID : [accent]{0}
text.trace.android = Android 클라이언트 \: [accent]{0} text.trace.android = Android 클라이언트 : [accent]{0}
text.trace.modclient = 수정된 클라이언트 \: [accent]{0} text.trace.modclient = 수정된 클라이언트 : [accent]{0}
text.trace.totalblocksbroken = 총 블록 파괴 개수 \: [accent]{0} text.trace.totalblocksbroken = 총 블록 파괴 개수 : [accent]{0}
text.trace.structureblocksbroken = 구조 블록 파괴 수 \: [accent]{0} text.trace.structureblocksbroken = 구조 블록 파괴 수 : [accent]{0}
text.trace.lastblockbroken = 마지막으로 파괴한 블록 \: [accent]{0} text.trace.lastblockbroken = 마지막으로 파괴한 블록 : [accent]{0}
text.trace.totalblocksplaced = 총 설치한 블록 개수 \: [accent]{0} text.trace.totalblocksplaced = 총 설치한 블록 개수 : [accent]{0}
text.trace.lastblockplaced = 마지막으로 설치한 블록 \: [accent]{0} text.trace.lastblockplaced = 마지막으로 설치한 블록 : [accent]{0}
text.invalidid = 잘못된 클라이언트 ID 입니다\! 공식 Mindustry Discord 으로 버그 보고서를 제출 해 주세요. text.invalidid = 잘못된 클라이언트 ID 입니다! 공식 Mindustry Discord 으로 버그 보고서를 제출 해 주세요.
text.server.bans = 차단된 유저 text.server.bans = 차단된 유저
text.server.bans.none = 차단된 플레이어가 없습니다. text.server.bans.none = 차단된 플레이어가 없습니다.
text.server.admins = text.server.admins = 관리
text.server.admins.none = 자가 없습니다\! text.server.admins.none = 관리자가 없습니다!
text.server.add = 서버 추가 text.server.add = 서버 추가
text.server.delete = 이 서버를 삭제 하시겠습니까? text.server.delete = 이 서버를 삭제 하시겠습니까?
text.server.hostname = 호스트 \: {0} text.server.hostname = 호스트 : {0}
text.server.edit = 서버 수정 text.server.edit = 서버 수정
text.server.outdated = [crimson]서버 버전이 낮습니다\![] text.server.outdated = [crimson]서버 버전이 낮습니다![]
text.server.outdated.client = [Crimson]클라이언트 버전이 낮습니다\![] text.server.outdated.client = [Crimson]클라이언트 버전이 낮습니다![]
text.server.version = [lightgray]서버 버전 \: {0} text.server.version = [lightgray]서버 버전 : {0}
text.server.custombuild = [yellow]커스텀 서버 text.server.custombuild = [yellow]커스텀 서버
text.confirmban = 이 플레이어를 차단하시겠습니까? text.confirmban = 이 플레이어를 차단하시겠습니까?
text.confirmkick = 정말로 이 플레이어를 추방시키겠습니까? text.confirmkick = 정말로 이 플레이어를 추방시키겠습니까?
@@ -131,46 +132,46 @@ text.confirmunban = 이 플레이어를 차단해제 하시겠습니까?
text.confirmadmin = 이 플레이어를 영자로 만들겠습니까? text.confirmadmin = 이 플레이어를 영자로 만들겠습니까?
text.confirmunadmin = 이 플레이어를 일반 유저로 만들겠습니까? text.confirmunadmin = 이 플레이어를 일반 유저로 만들겠습니까?
text.joingame.title = 게임 참가 text.joingame.title = 게임 참가
text.joingame.ip = IP \: text.joingame.ip = IP :
text.disconnect = 서버와 연결이 해제되었습니다. text.disconnect = 서버와 연결이 해제되었습니다.
text.disconnect.data = 맵 데이터를 받아오는데 실패했습니다. text.disconnect.data = 맵 데이터를 받아오는데 실패했습니다.
text.connecting = [accent]연결중... text.connecting = [accent]연결중...
text.connecting.data = [accent]맵 데이터 다운로드중... text.connecting.data = [accent]맵 데이터 다운로드중...
text.connectfail = [crimson]{0}[orange] 서버에 연결하지 못했습니다.[] text.connectfail = [crimson]{0}[orange] 서버에 연결하지 못했습니다.[]
text.server.port = 포트 \: text.server.port = 포트 :
text.server.addressinuse = 이 주소는 이미 사용중입니다\! text.server.addressinuse = 이 주소는 이미 사용중입니다!
text.server.invalidport = 포트 번호가 잘못되었습니다. text.server.invalidport = 포트 번호가 잘못되었습니다.
text.server.error = [crimson]{0}[orange]서버를 여는데 오류가 발생했습니다.[] text.server.error = [crimson]{0}[orange]서버를 여는데 오류가 발생했습니다.[]
text.save.old = 이 저장파일은 이전 버전의 게임용이며, 지금은 사용할 수 없습니다. \n\n[LIGHT_GRAY]4.0 정식때 이전 게임버전에서 만든 저장파일과 호환됩니다. text.save.old = 이 저장파일은 이전 버전의 게임용이며, 지금은 사용할 수 없습니다. \n\n[LIGHT_GRAY]4.0 정식때 이전 게임버전에서 만든 저장파일과 호환됩니다.
text.save.new = 새로 저장 text.save.new = 새로 저장
text.save.overwrite = 이 저장 슬롯을 덮어씌우겠습니까? text.save.overwrite = 이 저장 슬롯을 덮어씌우겠습니까?
text.overwrite = 덮어쓰기 text.overwrite = 덮어쓰기
text.save.none = 저장 파일을 찾지 못했습니다\! text.save.none = 저장 파일을 찾지 못했습니다!
text.saveload = [accent]저장중... text.saveload = [accent]저장중...
text.savefail = 게임을 저장하지 못했습니다\! text.savefail = 게임을 저장하지 못했습니다!
text.save.delete.confirm = 이 저장파일을 삭제 하시겠습니까? text.save.delete.confirm = 이 저장파일을 삭제 하시겠습니까?
text.save.delete = 삭제 text.save.delete = 삭제
text.save.export = 저장파일 내보내기 text.save.export = 저장파일 내보내기
text.save.import.invalid = [orange]파일이 잘못되었습니다\! text.save.import.invalid = [orange]파일이 잘못되었습니다!
text.save.import.fail = [crimson]저장파일을 불러오지 못함 \: [orange]{0} text.save.import.fail = [crimson]저장파일을 불러오지 못함 : [orange]{0}
text.save.export.fail = [crimson]저장파일을 내보내지 못함 \: [orange]{0} text.save.export.fail = [crimson]저장파일을 내보내지 못함 : [orange]{0}
text.save.import = 저장파일 불러오기 text.save.import = 저장파일 불러오기
text.save.newslot = 저장 파일이름 \: text.save.newslot = 저장 파일이름 :
text.save.rename = 이름 변경 text.save.rename = 이름 변경
text.save.rename.text = 새 이름 \: text.save.rename.text = 새 이름 :
text.selectslot = 저장슬롯을 선택하십시오. text.selectslot = 저장슬롯을 선택하십시오.
text.slot = [accent]{0}번째 슬롯 text.slot = [accent]{0}번째 슬롯
text.save.corrupted = [orange]세이브 파일이 손상되었거나 잘못된 파일입니다\! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[]. text.save.corrupted = [orange]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[].
text.sector.corrupted = [orange]저장 파일에서 구역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다. text.sector.corrupted = [orange]저장 파일에서 구역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다.
text.empty = <비어있음> text.empty = <비어있음>
text.on = 켜기 text.on = 켜기
text.off = 끄기 text.off = 끄기
text.save.autosave = 자동저장 \: {0} text.save.autosave = 자동저장 : {0}
text.save.map = \: {0} text.save.map = 맵 : {0}
text.save.wave = {0}단계[] text.save.wave = {0}단계[]
text.save.difficulty = 난이도 \: {0} text.save.difficulty = 난이도 : {0}
text.save.date = 마지막 저장날짜 \: {0} text.save.date = 마지막 저장날짜 : {0}
text.save.playtime = 플레이시간 \: {0} text.save.playtime = 플레이시간 : {0}
text.confirm = 확인 text.confirm = 확인
text.delete = 삭제 text.delete = 삭제
text.ok = 확인 text.ok = 확인
@@ -184,7 +185,7 @@ text.changelog.title = 변경사항
text.changelog.loading = 변경사항 가져오는중... text.changelog.loading = 변경사항 가져오는중...
text.changelog.error.android = [orange]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다.이것은 내부 Android 버그 때문입니다. text.changelog.error.android = [orange]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다.이것은 내부 Android 버그 때문입니다.
text.changelog.error.ios = [orange]현재 iOS에서는 변경 사항을 지원하지 않습니다. text.changelog.error.ios = [orange]현재 iOS에서는 변경 사항을 지원하지 않습니다.
text.changelog.error = [scarlet]게임 변경사항을 가져오는 중 오류가 발생했습니다\![]\n인터넷 연결을 확인하십시오. text.changelog.error = [scarlet]게임 변경사항을 가져오는 중 오류가 발생했습니다![]\n인터넷 연결을 확인하십시오.
text.changelog.current = [orange][[현재 버전] text.changelog.current = [orange][[현재 버전]
text.changelog.latest = [orange][[최신 버전] text.changelog.latest = [orange][[최신 버전]
text.loading = [accent]불러오는중... text.loading = [accent]불러오는중...
@@ -199,34 +200,34 @@ text.loadimage = 사진 불러오기
text.saveimage = 사진 저장 text.saveimage = 사진 저장
text.unknown = 알 수 없음 text.unknown = 알 수 없음
text.custom = 커스텀 text.custom = 커스텀
text.builtin = 내장 text.builtin = 기본맵
text.map.delete.confirm = 이 맵을 삭제하시겠습니까? 이 명령은 취소할 수 없습니다\! text.map.delete.confirm = 이 맵을 삭제하시겠습니까? 이 명령은 취소할 수 없습니다!
text.map.random = [accent]랜덤 맵 text.map.random = [accent]랜덤 맵
text.map.nospawn = 이 맵에 플레이어가 스폰 할 코어가 없습니다\! 맵 편집기에서 [ROYAL]파란색[]코어를 맵에 추가하세요. text.map.nospawn = 이 맵에 플레이어가 스폰 할 코어가 없습니다! 맵 편집기에서 [ROYAL]파란색[]코어를 맵에 추가하세요.
text.map.nospawn.pvp = 이 맵에는 적팀 코어가 없습니다\! 에디터에서 [scarlet]빨간팀[] 코어를 추가하세요. text.map.nospawn.pvp = 이 맵에는 적팀 코어가 없습니다! 에디터에서 [scarlet]빨간팀[] 코어를 추가하세요.
text.map.invalid = 파일이 잘못되었거나 손상되어 맵을 열 수 없습니다. text.map.invalid = 파일이 잘못되었거나 손상되어 맵을 열 수 없습니다.
text.editor.brush = 브러쉬 text.editor.brush = 브러쉬
text.editor.slope = \\ text.editor.slope = \\
text.editor.openin = 편집기 열기 text.editor.openin = 편집기 열기
text.editor.oregen = 광물 무작위 생성 text.editor.oregen = 광물 무작위 생성
text.editor.oregen.info = 광물 무작위 생성 \: text.editor.oregen.info = 광물 무작위 생성 :
text.editor.mapinfo = 맵 정보 text.editor.mapinfo = 맵 정보
text.editor.author = 만든이 \: text.editor.author = 만든이 :
text.editor.description = 설명 \: text.editor.description = 설명 :
text.editor.name = 이름 \: text.editor.name = 이름 :
text.editor.teams = text.editor.teams =
text.editor.elevation = 높이 text.editor.elevation = 지형 높이
text.editor.badsize = [orange]사진 크기가 잘못되었습니다\![] 유효한 맵 크기 \: {0} text.editor.badsize = [orange]사진 크기가 잘못되었습니다![] 유효한 맵 크기 : {0}
text.editor.errorimageload = [orange]{0}[] 파일을 불러오는데 오류가 발생했습니다. text.editor.errorimageload = [orange]{0}[] 파일을 불러오는데 오류가 발생했습니다.
text.editor.errorimagesave = [orange]{0}[] 파일 저장중 오류가 발생했습니다. text.editor.errorimagesave = [orange]{0}[] 파일 저장중 오류가 발생했습니다.
text.editor.generate = 생성 text.editor.generate = 생성
text.editor.resize = 맵 크기조정 text.editor.resize = 맵 크기조정
text.editor.loadmap = 맵 불러오기 text.editor.loadmap = 맵 불러오기
text.editor.savemap = 맵 저장 text.editor.savemap = 맵 저장
text.editor.saved = 저장됨\! text.editor.saved = 저장됨!
text.editor.save.noname = 지도에 이름이 없습니다\! '맵 정보' 메뉴에서 설정하세요. text.editor.save.noname = 지도에 이름이 없습니다! '맵 정보' 메뉴에서 설정하세요.
text.editor.save.overwrite = 이 맵의 이름은 기존에 있던 맵을 덮어씁니다\! '맵 정보' 메뉴에서 다른 이름을 선택하세요. text.editor.save.overwrite = 이 맵의 이름은 기존에 있던 맵을 덮어씁니다! '맵 정보' 메뉴에서 다른 이름을 선택하세요.
text.editor.import.exists = [scarlet]맵을 불러올 수 없음 \: [] 기존에 있던 '{0}' 맵이 이미 존재합니다\! text.editor.import.exists = [scarlet]맵을 불러올 수 없음 : [] 기존에 있던 '{0}' 맵이 이미 존재합니다!
text.editor.import = 가져오기 text.editor.import = 가져오기
text.editor.importmap = 맵 가져오기 text.editor.importmap = 맵 가져오기
text.editor.importmap.description = 이미 존재하는 맵 가져오기 text.editor.importmap.description = 이미 존재하는 맵 가져오기
@@ -241,21 +242,21 @@ text.editor.exportimage = 지형 이미지 내보내기
text.editor.exportimage.description = 맵 이미지 파일 내보내기 text.editor.exportimage.description = 맵 이미지 파일 내보내기
text.editor.loadimage = 지형 가져오기 text.editor.loadimage = 지형 가져오기
text.editor.saveimage = 지형 내보내기 text.editor.saveimage = 지형 내보내기
text.editor.unsaved = [scarlet]변경사항을 저장하지 않았습니다\![]\n정말로 나가시겠습니까? text.editor.unsaved = [scarlet]변경사항을 저장하지 않았습니다![]\n정말로 나가시겠습니까?
text.editor.resizemap = 맵 크기 조정 text.editor.resizemap = 맵 크기 조정
text.editor.mapname = 맵 이름 \: text.editor.mapname = 맵 이름 :
text.editor.overwrite = [accept]경고\!이 명령은 기존 맵을 덮어씌우게 됩니다. text.editor.overwrite = [accept]경고!이 명령은 기존 맵을 덮어씌우게 됩니다.
text.editor.overwrite.confirm = [scarlet]경고\![] 이 이름을 가진 맵이 이미 있습니다. 덮어 쓰시겠습니까? text.editor.overwrite.confirm = [scarlet]경고![] 이 이름을 가진 맵이 이미 있습니다. 덮어 쓰시겠습니까?
text.editor.selectmap = 불러올 맵 선택 \: text.editor.selectmap = 불러올 맵 선택 :
text.width = 넓이 \: text.width = 넓이 :
text.height = 높이 \: text.height = 높이 :
text.menu = 메뉴 text.menu = 메뉴
text.play = 플레이 text.play = 플레이
text.load = 불러오기 text.load = 불러오기
text.save = 저장 text.save = 저장
text.fps = {0}FPS text.fps = {0}FPS
text.tps = {0}TPS text.tps = {0}TPS
text.ping = ping \: {0}ms text.ping = ping : {0}ms
text.language.restart = 언어를 변경하려면 게임을 다시시작 해 주세요. text.language.restart = 언어를 변경하려면 게임을 다시시작 해 주세요.
text.settings = 설정 text.settings = 설정
text.tutorial = 게임 방법 text.tutorial = 게임 방법
@@ -270,8 +271,8 @@ text.settings.game = 게임
text.settings.sound = 소리 text.settings.sound = 소리
text.settings.graphics = 화면 text.settings.graphics = 화면
text.settings.cleardata = 게임 데이터 초기화... text.settings.cleardata = 게임 데이터 초기화...
text.settings.clear.confirm = 정말로 초기화 하겠습니까?\n이 작업을 되돌릴 수 없습니다\! text.settings.clear.confirm = 정말로 초기화 하겠습니까?\n이 작업을 되돌릴 수 없습니다!
text.settings.clearall.confirm = [scarlet]경고\![]\n이 작업은 저장된 맵, 맵파일, 잠금 해제된 목록과 키 매핑, 그리고 모든 데이터를 삭제합니다.\n확인 버튼을 다시 눌러 모든 데이터를 삭제하고 게임에서 나갑니다. text.settings.clearall.confirm = [scarlet]경고![]\n이 작업은 저장된 맵, 맵파일, 잠금 해제된 목록과 키 매핑, 그리고 모든 데이터를 삭제합니다.\n확인 버튼을 다시 눌러 모든 데이터를 삭제하고 게임에서 나갑니다.
text.settings.clearsectors = 구역 초기화 text.settings.clearsectors = 구역 초기화
text.settings.clearunlocks = 잠금 해제 초기화 text.settings.clearunlocks = 잠금 해제 초기화
text.settings.clearall = 모두 초기화 text.settings.clearall = 모두 초기화
@@ -313,7 +314,7 @@ text.blocks.coolant = 냉각제
text.blocks.coolantuse = 냉각수 사용 text.blocks.coolantuse = 냉각수 사용
text.blocks.inputliquidfuel = 연료 액 text.blocks.inputliquidfuel = 연료 액
text.blocks.liquidfueluse = 액체 연료 사용 text.blocks.liquidfueluse = 액체 연료 사용
text.blocks.explosive = 이게 터지면 펑 터지면서 주변 블록에게 피해를 입힙니다\! text.blocks.explosive = 이게 터지면 펑 터지면서 주변 블록에게 피해를 입힙니다!
text.blocks.health = 체력 text.blocks.health = 체력
text.blocks.inaccuracy = 오차각 text.blocks.inaccuracy = 오차각
text.blocks.shots = 발포 횟수 text.blocks.shots = 발포 횟수
@@ -348,7 +349,7 @@ setting.difficulty.normal = 보통
setting.difficulty.hard = 어려움 setting.difficulty.hard = 어려움
setting.difficulty.insane = 이걸 할수있을까? setting.difficulty.insane = 이걸 할수있을까?
setting.difficulty.purge = 위이이이잉 setting.difficulty.purge = 위이이이잉
setting.difficulty.name = 난이도 \: setting.difficulty.name = 난이도 :
setting.screenshake.name = 화면 흔들기 setting.screenshake.name = 화면 흔들기
setting.indicators.name = 적 위치 표시 화살표 setting.indicators.name = 적 위치 표시 화살표
setting.effects.name = 화면 효과 setting.effects.name = 화면 효과
@@ -402,7 +403,7 @@ mode.waves.description = 이것은 일반 모드입니다. 제한된 자원과
mode.sandbox.name = 샌드박스 mode.sandbox.name = 샌드박스
mode.sandbox.description = 무한한 자원과 다음단계 시작을 위한 타이머가 없습니다. mode.sandbox.description = 무한한 자원과 다음단계 시작을 위한 타이머가 없습니다.
mode.custom.warning = [scarlet]서버에서 잠금해제한 블록은 저장되지 않습니다.[]\n\n구역을 플레이 하여 잠금해제하세요. mode.custom.warning = [scarlet]서버에서 잠금해제한 블록은 저장되지 않습니다.[]\n\n구역을 플레이 하여 잠금해제하세요.
mode.custom.warning.read = 꼭 읽어보시길 바랍니다 \:\n[scarlet]커스텀 게임에서 잠금해제한 블록은 구역 플레이나 다른 모드에서 적용되지 않습니다\!\n\n[LIGHT_GRAY](이게 필요하지 않았으면 좋겠는데) mode.custom.warning.read = 꼭 읽어보시길 바랍니다 :\n[scarlet]커스텀 게임에서 잠금해제한 블록은 구역 플레이나 다른 모드에서 적용되지 않습니다!\n\n[LIGHT_GRAY](이게 필요하지 않았으면 좋겠는데)
mode.freebuild.name = 자유 건축 mode.freebuild.name = 자유 건축
mode.freebuild.description = 제한된 자원과 다음단계 시작을 위한 타이머가 없습니다. mode.freebuild.description = 제한된 자원과 다음단계 시작을 위한 타이머가 없습니다.
mode.pvp.name = PvP mode.pvp.name = PvP
@@ -413,88 +414,90 @@ content.unit.name = 유닛
content.recipe.name = 블록 content.recipe.name = 블록
content.mech.name = 기체 content.mech.name = 기체
item.stone.name = item.stone.name =
item.stone.description = 흔히 찾을 수 있는 자원. 바닥에서 돌을 캐거나 용암을 사용하여 얻을 수 있습니다. item.stone.description = 주로 용암을 사용하여 얻을 수 있습니다.
item.copper.name = 구리 item.copper.name = 구리
item.copper.description = 기본 블록 재료입니다. 모든 유형의 블록에서 광범위하게 사용니다. item.copper.description = 모든 유형의 블록에서 광범위하게 사용되는 자원입니다.
item.lead.name = item.lead.name =
item.lead.description = 기본적인 시작 자원. 전자 및 액체 수송 블록에서 광범위하게 사용니다. item.lead.description = 쉽게 구할 수 있는 자원.\n전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다.
item.coal.name = 석탄 item.coal.name = 석탄
item.coal.description = 일반적이고 쉽게 이용할 수 있는 연료. item.coal.description = 쉽게 할 수 있으며, 주로 제련소 등에서 연료로 사용됩니다.
item.dense-alloy.name = 합금 item.dense-alloy.name = 합금
item.dense-alloy.description = 납과 구리로 만든 튼튼한 합금. 고급 수송 블록이나 상위 티어 블록을 건설하는데 사용됩니다. item.dense-alloy.description = 납과 구리로 만든 튼튼한 합금.\n고급 수송 블록이나 상위 티어 블록을 건설하는데 사용됩니다.
item.titanium.name = 티타늄 item.titanium.name = 티타늄
item.titanium.description = 물 운반이나 드릴, 비행기등에서 재료로 사용되는 자원입니다. item.titanium.description = 파이프 재료나 고급 드릴, 비행기/기체 등에서 재료로 사용되는 자원입니다.
item.thorium.name = 토륨 item.thorium.name = 토륨
item.thorium.description = 건물 탄약 또는 핵연료로 사용되는 방사성 금속. item.thorium.description = 건물의 재료, 포탑의 탄약 또는 핵연료로 사용되는 방사성 금속입니다.
item.silicon.name = 실리콘 item.silicon.name = 실리콘
item.silcion.description = 매우 유용한 반도체로, 태양 전지판과 복잡한 전자 제품에 용할 수 있습니다. item.silicon.description = 매우 유용한 반도체로, 태양 전지판과 복잡한 전자 제품에 용할 수 있습니다.
item.plastanium.name = 플라스 item.plastanium.name = 플라스
item.plastanium.description = 고급 항공기 및 분열 탄약에 사용되는 가벼운 연성 재료. item.plastanium.description = 고급 항공기 및 분열 탄약에 사용되는 가벼운 연성 재료.
item.phase-matter.name = 메타 item.phase-matter.name = 메타
item.surge-alloy.name = 설탕 item.phase-matter.description = 최고급 자원. 최상위 기체/비행기나 방어 건물등에 사용됩니다.
item.surge-alloy.name = 설금
item.surge-alloy.description = 주로 건물의 재료로 사용되는 자원입니다
item.biomatter.name = 바이오메터 item.biomatter.name = 바이오메터
item.biomatter.description = 이것은 유기농 덤불입니다\! 석유로 전환하거나 기본 연료로 사용됩니다. item.biomatter.description = 이것은 유기농 덤불입니다!\n석유로 전환하거나 연료로 사용됩니다.
item.sand.name = 모래 item.sand.name = 모래
item.sand.description = 합금 플렉스 모두에서 제련시 광범위하게 사용되는 일반적인 재료. item.sand.description = 합금이나 플렉스 에서 제련시 광범위하게 사용되는 일반적인 재료입니다.
item.blast-compound.name = 폭발 화합물 item.blast-compound.name = 화합물
item.blast-compound.description = 폭탄폭발물에 사용되는 휘발성 화합물. 이 연료로 불을 낼 수 있지만, 별로 추천하지는 않습니다. item.blast-compound.description = 포탑건설의 재료로 사용되는 휘발성 화합물.\n연료로도 사용할 수 있지만, 별로 추천하지는 않습니다.
item.pyratite.name = 러레이트 item.pyratite.name = 라테
item.pyratite.description = 화염 무기에 사용되는 엄청난 가연성 물질. item.pyratite.description = 폭발성을 가진 재료로, 주로 포탑의 탄약으로 사용됩니다.
liquid.water.name = liquid.water.name =
liquid.lava.name = 용암 liquid.lava.name = 용암
liquid.oil.name = 석유 liquid.oil.name = 석유
liquid.cryofluid.name = 냉각수 liquid.cryofluid.name = 냉각수
mech.alpha-mech.name = 알파 mech.alpha-mech.name = 알파
mech.alpha-mech.weapon = Heavy Repeater mech.alpha-mech.weapon = 중무장 소총
mech.alpha-mech.ability = Drone Swarm mech.alpha-mech.ability = 드론 소환
mech.alpha-mech.description = 표준 기체. 적절한 속도와 공격력을 갖추고 있으며, 공격 능력을 높이기 위해 최대 3대의 드론을 만들 수 있습니다. mech.alpha-mech.description = 표준 기체.\n적절한 속도와 공격력을 갖추고 있으며, 공격 능력을 높이기 위해 최대 3대의 드론을 만들 수 있습니다.
mech.delta-mech.name = 델타 mech.delta-mech.name = 델타
mech.delta-mech.weapon = Arc Generator mech.delta-mech.weapon = 전격 생산기
mech.delta-mech.ability = Discharge mech.delta-mech.ability = 충전
mech.delta-mech.description = 치고 빠지는 공격을 위해 만든 빠르고 가벼운 기체. 구조물에는 거의 피해를 주지 않지만, 번개 무기를 사용하여 많은 적군을 매우 빠르게 죽일 수 있습니다. mech.delta-mech.description = 빠르게 이동하는 적을 처치하기 위한 가벼운 기체.\n구조물에는 거의 피해를 주지 않지만, 전격 무기를 사용하여 많은 적군을 매우 빠르게 죽일 수 있습니다.
mech.tau-mech.name = Tau mech.tau-mech.name = 타우
mech.tau-mech.weapon = Restruct Laser mech.tau-mech.weapon = 건물 수리총
mech.tau-mech.ability = Repair Burst mech.tau-mech.ability = 유닛 치료
mech.tau-mech.description = 지원형 기체. 총을 발사하여 건물을 치료하고 회복 능력 사용으로 화재를 진압하거나 반경 내 아군을 치유시킵니다. mech.tau-mech.description = 지원형 기체.\n총을 발사하여 건물을 치료하고 회복 능력 사용으로 화재를 진압하거나, 반경 내 아군을 치유시킵니다.
mech.omega-mech.name = 오메가 mech.omega-mech.name = 오메가
mech.omega-mech.weapon = Swarm Missiles mech.omega-mech.weapon = 전방 유도미사일
mech.omega-mech.ability = Armored Configuration mech.omega-mech.ability = 방어모드
mech.omega-mech.description = 전방 공격용으로 만든 부피가 크고 튼튼한 기체. 방어 능력은 최대 90%의 피해를 흡수할 수 있습니다. mech.omega-mech.description = 지상 기체 최종판이자 건물 파괴용으로 적합한 부피가 크고 튼튼한 기체. 방어 모드는 최대 90% 의 피해를 줄일 수 있습니다.
mech.dart-ship.name = Dart mech.dart-ship.name = 다트
mech.dart-ship.weapon = Repeater mech.dart-ship.weapon = 소총
mech.dart-ship.description = 표준 비행선. 빠르고 가볍지만 공격력이 거의 없고 채광 속도가 느립니다. mech.dart-ship.description = 표준 비행선. 빠르고 가볍지만 공격력이 거의 없고 채광 속도가 느립니다.
mech.javelin-ship.name = Javelin mech.javelin-ship.name = 자비린
mech.javelin-ship.description = 치고 빠지는 공격을 위한 비행선. 처음에는 느리지만, 가속도가 붙어 엄청난 속도로 미사일 피해를 입힐 수 있으며, 번개 능력을 사용할 수 있습니다. mech.javelin-ship.description = 치고 빠지는 공격을 위한 비행선. 처음에는 느리지만, 가속도가 붙어 엄청난 속도로 미사일 피해를 입힐 수 있으며, 전격 능력을 사용할 수 있습니다.
mech.javelin-ship.weapon = Burst Missiles mech.javelin-ship.weapon = 유도 미사일
mech.javelin-ship.ability = Discharge Booster mech.javelin-ship.ability = 가속 전격 생성기
mech.trident-ship.name = Trident mech.trident-ship.name = 삼지창
mech.trident-ship.description = 대형 공중 폭격기. 당연하게도 엄청 단단합니다. mech.trident-ship.description = 대형 공중 폭격기. 당연하게도 엄청 단단합니다.
mech.trident-ship.weapon = Bomb Bay mech.trident-ship.weapon = 폭탄 저장고
mech.glaive-ship.name = Glaive mech.glaive-ship.name = 글레브
mech.glaive-ship.description = 크고 잘 무장된 총을 가진 비행선. 방화용 리피터가 장착되어 있으며, 가속도와 최대속도가 높습니다. mech.glaive-ship.description = 크고 잘 무장된 총을 가진 비행선. 방화용 리피터가 장착되어 있으며, 가속도와 최대속도가 높습니다.
mech.glaive-ship.weapon = Flame Repeater mech.glaive-ship.weapon = 방화총
text.item.explosiveness = [LIGHT_GRAY]폭발력 \: {0} text.item.explosiveness = [LIGHT_GRAY]폭발력 : {0}
text.item.flammability = [LIGHT_GRAY]인화성 \: {0} text.item.flammability = [LIGHT_GRAY]인화성 : {0}
text.item.radioactivity = [LIGHT_GRAY]방사능 \: {0} text.item.radioactivity = [LIGHT_GRAY]방사능 : {0}
text.item.fluxiness = [LIGHT_GRAY]플렉스 파워 \: {0} text.item.fluxiness = [LIGHT_GRAY]플렉스 파워 : {0}
text.unit.health = [LIGHT_GRAY]체력 \: {0} text.unit.health = [LIGHT_GRAY]체력 : {0}
text.unit.speed = [LIGHT_GRAY]속도 \: {0} text.unit.speed = [LIGHT_GRAY]속도 : {0}
text.mech.weapon = [LIGHT_GRAY]무기 \: {0} text.mech.weapon = [LIGHT_GRAY]무기 : {0}
text.mech.armor = [LIGHT_GRAY]방어 \: {0} text.mech.armor = [LIGHT_GRAY]방어 : {0}
text.mech.itemcapacity = [LIGHT_GRAY]아이템 수용 용량 \: {0} text.mech.itemcapacity = [LIGHT_GRAY]아이템 수용 용량 : {0}
text.mech.minespeed = [LIGHT_GRAY]채광 속도 \: {0} text.mech.minespeed = [LIGHT_GRAY]채광 속도 : {0}
text.mech.minepower = [LIGHT_GRAY]채광 레벨 \: {0} text.mech.minepower = [LIGHT_GRAY]채광 레벨 : {0}
text.mech.ability = [LIGHT_GRAY]능력 \: {0} text.mech.ability = [LIGHT_GRAY]능력 : {0}
text.liquid.heatcapacity = [LIGHT_GRAY]발열량 \: {0} text.liquid.heatcapacity = [LIGHT_GRAY]발열량 : {0}
text.liquid.viscosity = [LIGHT_GRAY]점도 \: {0} text.liquid.viscosity = [LIGHT_GRAY]점도 : {0}
text.liquid.temperature = [LIGHT_GRAY]온도 \: {0} text.liquid.temperature = [LIGHT_GRAY]온도 : {0}
block.spawn.name = 적 스폰지점 block.spawn.name = 적 스폰지점
block.core.name = 코어 block.core.name = 코어
block.metalfloor.name = Metal Floor block.metalfloor.name = 메탈 바닥
block.deepwater.name = 깊은물 block.deepwater.name = 깊은물
block.water.name = block.water.name =
block.lava.name = 용암 block.lava.name = 용암
block.oil.name = 석유 block.tar.name = 타르
block.blackstone.name = 검은돌 block.blackstone.name = 검은돌
block.stone.name = block.stone.name =
block.dirt.name = block.dirt.name =
@@ -510,9 +513,9 @@ block.copper-wall.name = 구리벽
block.copper-wall-large.name = 큰 구리벽 block.copper-wall-large.name = 큰 구리벽
block.dense-alloy-wall.name = 합금 벽 block.dense-alloy-wall.name = 합금 벽
block.dense-alloy-wall-large.name = 큰 합금 벽 block.dense-alloy-wall-large.name = 큰 합금 벽
block.phase-wall.name = Phase Wall block.phase-wall.name = 메타벽
block.phase-wall-large.name = Large Phase Wall block.phase-wall-large.name = 메타벽
block.thorium-wall.name = block.thorium-wall.name =
block.thorium-wall-large.name = 대형 토륨벽 block.thorium-wall-large.name = 대형 토륨벽
block.door.name = block.door.name =
block.door-large.name = 대형문 block.door-large.name = 대형문
@@ -532,13 +535,13 @@ block.sorter.description = 아이템을 넣어서 필터에 설정된 아이템
block.overflow-gate.name = 오버플로 게이트 block.overflow-gate.name = 오버플로 게이트
block.overflow-gate.description = 정면 경로가 차단된 경우 왼쪽과 오른쪽으로만 출력하는 복합 분배기입니다. block.overflow-gate.description = 정면 경로가 차단된 경우 왼쪽과 오른쪽으로만 출력하는 복합 분배기입니다.
block.bridgeconveyor.name = 터널 block.bridgeconveyor.name = 터널
block.bridgeconveyor.description = 최대 2블록을 건너 뛰고 자원을 운반하게 해 주는 블록. block.bridgeconveyor.description = 최대 4블록을 건너 뛰고 자원을 운반하게 해 주는 블록.
block.smelter.name = 제련소 block.smelter.name = 제련소
block.arc-smelter.name = 대형 제련소 block.arc-smelter.name = 대형 제련소
block.silicon-smelter.name = 실리콘 제련소 block.silicon-smelter.name = 실리콘 제련소
block.phase-weaver.name = 메타 합성기 block.phase-weaver.name = 메타 합성기
block.pulverizer.name = 분쇄기 block.pulverizer.name = 분쇄기
block.cryofluidmixer.name = 냉각수 혼합 block.cryofluidmixer.name = 냉각수 제조
block.melter.name = 융해기 block.melter.name = 융해기
block.incinerator.name = 소각로 block.incinerator.name = 소각로
block.biomattercompressor.name = 바이오메터 압축기 block.biomattercompressor.name = 바이오메터 압축기
@@ -550,26 +553,26 @@ block.battery.name = 배터리
block.battery-large.name = 대형 배터리 block.battery-large.name = 대형 배터리
block.combustion-generator.name = 석탄 발전기 block.combustion-generator.name = 석탄 발전기
block.turbine-generator.name = 터빈 발전기 block.turbine-generator.name = 터빈 발전기
block.mechanical-drill.name = Mechanical Drill block.mechanical-drill.name = 기계식 드릴
block.pneumatic-drill.name = Pneumatic Drill block.pneumatic-drill.name = 강철 드릴
block.laser-drill.name = 레이저 드릴 block.laser-drill.name = 레이저 드릴
block.water-extractor.name = 물 추출기 block.water-extractor.name = 물 추출기
block.cultivator.name = 온실 block.cultivator.name = 온실
block.alpha-mech-pad.name = 알파 기체 패드 block.alpha-mech-pad.name = 알파 기체 패드
block.dart-ship-pad.name = 다트 비행선 패드 block.dart-ship-pad.name = 다트 비행선 패드
block.delta-mech-pad.name = 델타 기체 패드 block.delta-mech-pad.name = 델타 기체 패드
block.javelin-ship-pad.name = 린 비행선 패드 block.javelin-ship-pad.name = 린 비행선 패드
block.trident-ship-pad.name = 삼지창 비행선 패드 block.trident-ship-pad.name = 삼지창 비행선 패드
block.glaive-ship-pad.name = 글레브 비행선 패드 block.glaive-ship-pad.name = 글레브 비행선 패드
block.omega-mech-pad.name = 오메가 기체 패드 block.omega-mech-pad.name = 오메가 기체 패드
block.tau-mech-pad.name = Tau 기체 패드 block.tau-mech-pad.name = 타우 기체 패드
block.conduit.name = 파이프 block.conduit.name = 파이프
block.mechanical-pump.name = 기계식 펌프 block.mechanical-pump.name = 기계식 펌프
block.itemsource.name = 아이템 소스 block.itemsource.name = 아이템 소스
block.itemvoid.name = 아이템 무효 block.itemvoid.name = 히오스
block.liquidsource.name = 액체 소스 block.liquidsource.name = 무한 액체공급 장치
block.powervoid.name = 무효 전력 block.powervoid.name = 방전장치
block.powerinfinite.name = 무한한 힘 block.powerinfinite.name = 무한 전력공급 장치
block.unloader.name = 언로더 block.unloader.name = 언로더
block.sortedunloader.name = 정렬된 언로더 block.sortedunloader.name = 정렬된 언로더
block.vault.name = 창고 block.vault.name = 창고
@@ -580,20 +583,20 @@ block.ripple.name = 립플
block.phase-conveyor.name = 메타 컨베이어 block.phase-conveyor.name = 메타 컨베이어
block.bridge-conveyor.name = 터널 block.bridge-conveyor.name = 터널
block.plastanium-compressor.name = 플라스터늄 압축기 block.plastanium-compressor.name = 플라스터늄 압축기
block.pyratite-mixer.name = 터레이트 혼합 block.pyratite-mixer.name = 라테 제조
block.blast-mixer.name = 폭발 화합물 혼합 block.blast-mixer.name = 화합물 제조
block.solidifer.name = 고체 block.solidifer.name = 고체
block.solar-panel.name = 태양 전지판 block.solar-panel.name = 태양 전지판
block.solar-panel-large.name = 대형 태양 전지판 block.solar-panel-large.name = 대형 태양 전지판
block.oil-extractor.name = 석유 추출기 block.oil-extractor.name = 석유 추출기
block.spirit-factory.name = Spirit 드론 공장 block.spirit-factory.name = 스피릿 드론 공장
block.phantom-factory.name = 팬텀 드론 공장 block.phantom-factory.name = 팬텀 드론 공장
block.wraith-factory.name = Wraith Fighter Factory block.wraith-factory.name = 유령 전투기 공장
block.ghoul-factory.name = Ghoul Bomber Factory block.ghoul-factory.name = 구울 폭격기 공장
block.dagger-factory.name = 디거 기체 공장 block.dagger-factory.name = 디거 기체 공장
block.titan-factory.name = 타이탄 기체 공장 block.titan-factory.name = 타이탄 기체 공장
block.fortress-factory.name = Fortress Mech Factory block.fortress-factory.name = 포트리스 기체 공장
block.revenant-factory.name = Revenant Fighter Factory block.revenant-factory.name = 레비던트 전투기 공장
block.repair-point.name = 정비소 block.repair-point.name = 정비소
block.pulse-conduit.name = 퓨즈 파이프 block.pulse-conduit.name = 퓨즈 파이프
block.phase-conduit.name = 메타 파이프 block.phase-conduit.name = 메타 파이프
@@ -602,33 +605,36 @@ block.liquid-tank.name = 물탱크
block.liquid-junction.name = 액체 교차기 block.liquid-junction.name = 액체 교차기
block.bridge-conduit.name = 다리 파이프 block.bridge-conduit.name = 다리 파이프
block.rotary-pump.name = 동력 펌프 block.rotary-pump.name = 동력 펌프
block.thorium-reactor.name = Thorium Reactor block.thorium-reactor.name = 핵 발전소
block.command-center.name = 명령 본부 block.command-center.name = 명령 본부
block.mass-driver.name = 물질 이동기 block.mass-driver.name = 물질 이동기
block.blast-drill.name = 고속 발열 드릴 block.blast-drill.name = 고속 발열 드릴
block.thermal-pump.name = 지열 펌프 block.thermal-pump.name = 지열 펌프
block.thermal-generator.name = 지열 발전기 block.thermal-generator.name = 지열 발전기
block.alloy-smelter.name = Alloy Smtler block.alloy-smelter.name = 설금 제련소
block.mend-projector.name = Mend Projector block.mend-projector.name = 치료 프로젝터
block.surge-wall.name = Surge Wall block.surge-wall.name = 설금벽
block.surge-wall-large.name = Large Surge Wall block.surge-wall-large.name = 큰 설금벽
block.cyclone.name = 사이클론 block.cyclone.name = 사이클론
block.fuse.name = 퓨즈 block.fuse.name = 퓨즈
block.shock-mine.name = Shock Mine block.shock-mine.name = 전격 지뢰
block.overdrive-projector.name = Overdrive Projector block.overdrive-projector.name = 가속 프로젝터
block.force-projector.name = Force Projector block.force-projector.name = 강제 프로젝터
block.arc.name = Arc block.arc.name = 아크
block.rtg-generator.name = RTG Generator block.rtg-generator.name = 토륨 발전소
block.spectre.name = Spectre block.spectre.name = 스펙터
block.meltdown.name = Meltdown block.meltdown.name = 멜트다운
block.container.name = 컨테이너 block.container.name = 컨테이너
team.blue.name = 블루팀 team.blue.name = 블루팀
team.red.name = 레드팀 team.red.name = 레드팀
team.orange.name = 오렌지팀 team.orange.name = 오렌지팀
team.none.name = 공기팀 team.none.name = 공기팀
team.green.name = 그린팀 team.green.name = 그린팀
team.purple.name = 보라색팀 team.purple.name = 보라색팀
unit.alpha-drone.name = Alpha Drone
unit.alpha-drone.name = 알파 드론
unit.alpha-drone.description =
unit.spirit.name = 스피릿 드론 unit.spirit.name = 스피릿 드론
unit.spirit.description = 기본 드론 유닛. 기본적으로 코어에서 1개가 스폰됩니다. 자동으로 채광하며 아이템을 수집하고, 블록을 수리합니다. unit.spirit.description = 기본 드론 유닛. 기본적으로 코어에서 1개가 스폰됩니다. 자동으로 채광하며 아이템을 수집하고, 블록을 수리합니다.
unit.phantom.name = 팬텀 드론 unit.phantom.name = 팬텀 드론
@@ -637,14 +643,15 @@ unit.dagger.name = 디거
unit.dagger.description = 기본 지상 유닛입니다. 스웜과 같이 쓰면 유용합니다. unit.dagger.description = 기본 지상 유닛입니다. 스웜과 같이 쓰면 유용합니다.
unit.titan.name = 타이탄 unit.titan.name = 타이탄
unit.titan.description = 고급 지상 유닛입니다. 합금을 탄약으로 사용하며 지상과 공중 둘다 공격할 수 있습니다. unit.titan.description = 고급 지상 유닛입니다. 합금을 탄약으로 사용하며 지상과 공중 둘다 공격할 수 있습니다.
unit.ghoul.name = Ghoul Bomber unit.ghoul.name = 구울 폭격기
unit.ghoul.description = A heavy carpet bomber. Uses blast compound or pyratite as ammo. unit.ghoul.description = 무거운 지상 폭격기 입니다. 화합물 또는 피라테를 탄약으로 사용합니다.
unit.wraith.name = Wraith Fighter unit.wraith.name = 유령 전투기
unit.wraith.description = 빠르고, 치고 빠지는 공격방식을 사용합니다. unit.wraith.description = 코어를 집중적으로 공격하는 방식을 사용하는 전투기 입니다.
unit.fortress.name = Fortress unit.fortress.name = 포트리스
unit.fortress.description = 중포 지상 부대 유닛. unit.fortress.description = 중포 지상 유닛. 높은 공격력과 체력을 가지고 있습니다.
unit.revenant.name = Revenant unit.revenant.name = 레비던트
unit.revenant.description = A heavy laser platform. unit.revenant.description = 대형 레이저를 발사하는 공중 유닛입니다.
tutorial.begin = 플레이어의 임무는 [LIGHT_GRAY]적군[]을 제거하는 것입니다.\n\n[accent]구리를 채광[]하는 것으로 시작합니다. 이것을 하기 위해 플레이어의 중심부 근처에 있는 구리 광맥을 누르세요. tutorial.begin = 플레이어의 임무는 [LIGHT_GRAY]적군[]을 제거하는 것입니다.\n\n[accent]구리를 채광[]하는 것으로 시작합니다. 이것을 하기 위해 플레이어의 중심부 근처에 있는 구리 광맥을 누르세요.
tutorial.drill = 수동으로 채광하는 것은 비효율 적입니다.\n[accent]드릴[]은 자동으로 채광 작업을 합니다.\n구리 광맥에 표시된 영역에 드릴을 하나를 놓으세요. tutorial.drill = 수동으로 채광하는 것은 비효율 적입니다.\n[accent]드릴[]은 자동으로 채광 작업을 합니다.\n구리 광맥에 표시된 영역에 드릴을 하나를 놓으세요.
tutorial.conveyor = [accent]컨베이어[]를 사용하여 아이템을 코어로 운반합니다.\n드릴에서 코어까지 컨베이어 라인을 만드세요. tutorial.conveyor = [accent]컨베이어[]를 사용하여 아이템을 코어로 운반합니다.\n드릴에서 코어까지 컨베이어 라인을 만드세요.
@@ -655,14 +662,128 @@ tutorial.waves = [LIGHT_GRAY]적[]이 접근합니다.\n\n2단계 동안 코어
tutorial.lead = 더 많은 광석을 이용할 수 있습니다. [accent]납[]을 찾아 탐색하세요.\n\n아이템을 코어로 전송할려면 플레이어 기체 또는 비행기에서 코어로 드래그 하세요. tutorial.lead = 더 많은 광석을 이용할 수 있습니다. [accent]납[]을 찾아 탐색하세요.\n\n아이템을 코어로 전송할려면 플레이어 기체 또는 비행기에서 코어로 드래그 하세요.
tutorial.smelter = 구리와 납은 약한 금속입니다.\n[accent]합금[]은 제련소에서 만들 수 있습니다.\n\n하나 만드세요. tutorial.smelter = 구리와 납은 약한 금속입니다.\n[accent]합금[]은 제련소에서 만들 수 있습니다.\n\n하나 만드세요.
tutorial.densealloy = 이 제련소는 이제 합금을 생산할 것입니다.\n몇개 더 생산하세요.\n필요한 경우 더 만드세요. tutorial.densealloy = 이 제련소는 이제 합금을 생산할 것입니다.\n몇개 더 생산하세요.\n필요한 경우 더 만드세요.
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.siliconsmelter = 이제 이코어는 채굴과 수리하기 위한[accent] 스피릿 드론[]을 생성 할 것 입니다.\n\n[accent]실리콘[]을 사용해 다른 유닛을 생성하기 위한 공장을 만들 수 있습니다.\n실리콘 제련기를 제작하세요!
tutorial.silicondrill = Silicon requires[accent] coal[] and[accent] sand[].\nStart by making drills. tutorial.silicondrill = 실리콘을 제작하려면[accent] 석탄[] 과[accent] 모래[]가 필요합니다.\n드릴을 먼저 건설해보는건 어떤가요?
tutorial.generator = This technology requires power.\nCreate a[accent] combustion generator[] for it. tutorial.generator = 이 기술은[LIGHT_YELLOW] 애너지[]가 필요합니다.\n[accent] 석탄 발전기[]를 건설하세요.
tutorial.generatordrill = Combustion generators need fuel.\nFuel it with coal from a drill. tutorial.generatordrill = [accent] 석탄 발전기[]는 연료가 필요합니다.\n[accent] 석탄[]을 드릴로 채굴해서 연료를 체워주세요.
tutorial.node = Power requires transport.\nCreate a[accent] power node[] next to your combustion generator to transfer its power. tutorial.node = 전력은 송신해줄 송신기가 필요합니다.\n[accent] 전력 송신기[]를 석탄 등등 발전기 옆에 설치해서 생산된 전기를 다른곳으로 송신합시다.
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.nodelink = 전력은 전력 블록과 발전기에 연결하거나, 연결된 전력 송신기를 통해 전송이 가능합니다. \n\n전력 송신기를 누르고 발전기와 실리콘 제련기를 선택하여 전원을 연결합시다.
tutorial.silicon = Silicon is being produced. Get some.\n\nImproving the production system is advised. tutorial.silicon = 실리콘이 생산되고 있습니다.\n\n생산 시스템의 개선을 권고 드립니다.
tutorial.daggerfactory = Construct a[accent] dagger mech factory.[]\n\nThis will be used to create attack mechs. tutorial.daggerfactory = 이[accent] 디거 기체 공장[]\n\n공격하는 기체를 생산하기 위해 사용됩니다.
tutorial.router = 공장을 작동시키기 위해 자원이 필요합니다.\n컨베이어에 운반되고 있는 자원을 분할할 분배기를 만드세요. tutorial.router = 공장을 작동시키기 위해 자원이 필요합니다.\n컨베이어에 운반되고 있는 자원을 분할할 분배기를 만드세요.
tutorial.dagger = 전력 노드를 공장에 연결하세요.\n일단 요구 사항이 충족되면 기체 생산을 시작합니다.\n\n필요에 따라 드릴 및 발전기, 컨베이어를 더 많이 만들 수 있습니다. tutorial.dagger = 전력 노드를 공장에 연결하세요.\n일단 요구 사항이 충족되면 기체 생산을 시작합니다.\n\n필요에 따라 드릴 및 발전기, 컨베이어를 더 많이 만들 수 있습니다.
tutorial.battle = [LIGHT_GRAY]적[]의 코어가 드러났습니다.\n당신의 부대와 디거를 사용하여 파괴하세요. tutorial.battle = [LIGHT_GRAY]적[]의 코어가 드러났습니다.\n당신의 부대와 디거를 사용하여 파괴하세요.
liquid.water.description = 유닛이 이 위를 지나가면 이동속도가 느려지고, 깊은 물에 빠지면 죽습니다.
liquid.lava.description = 유닛이 이 위를 지나가면 이동속도가 매우 느려지고, 지속적으로 데미지를 입습니다.
liquid.oil.description = 일부 조합 블록에서 사용되는 자원입니다.
liquid.cryofluid.description = 포탑 및 핵 발전소에서 사용되는 자원입니다. 누출시 폭발 및 방화의 위험성이 있습니다.
block.core.description = 게임에서 가장 중요한 건물입니다.\n파괴되면 게임이 끝납니다.
block.copper-wall.description = 구리로 만든 벽.
block.copper-wall-large.description = 구리로 만든 큰 벽.
block.dense-alloy-wall.description = 합금으로 만든 벽. 구리벽보다 체력이 높습니다.
block.dense-alloy-wall-large.description = 합금으로 만든 큰 벽.
block.phase-wall.description = 날라오는 모든 총알을 튕겨내고 데미지를 입는 특수한 벽입니다.
block.phase-wall-large.description = 메타로 제작한 큰 벽. 날라오는 총알을 모두 튕겨냅니다.
block.thorium-wall.description = 토륨으로 만든 벽.
block.thorium-wall-large.description = 토륨으로 만든 큰 벽.
block.door.description = 유닛이 지나갈 수 있도록 만든 문. 클릭하면 열고 닫습니다.
block.door-large.description = 유닛이 자나갈 수 있도록 만든 큰 문. 클릭하면 열고 닫습니다.
block.duo.description = 범용성을 가진 터렛.\n지상 및 공중공격을 하며, 초중반에 유용합니다.
block.scorch.description = 근거리 화염 방사기 터렛입니다.\n이 터렛에 가까이 있는 적들을 지져버립니다.
block.hail.description = 장거리 지상 공격을 하는 터렛입니다.\n적이 오기 전에 쓸어버릴 수 있습니다.
block.lancer.description = 중거리 레이져 포탑입니다.\n적을 관통하기 때문에 뭉쳐있는 적들에게 매우 효과적입니다.
block.conveyor.description = 느린 속도로 자원을 수송할 수 있는 컨베이어.
block.titanium-conveyor.description = 빠른 속도로 자원을 수송할 수 있는 컨베이어.
block.junction.description = 컨베이어를 교차시켜 자원을 수송할 때 사용할 수 있는 블록입니다.
block.smelter.description = 합금을 제작할 수 있는 건물입니다.
block.arc-smelter.description = 합금을 제작할 수 있는 건물이지만, 이 건물은 석탄이 필요 없고 좀더 빠른 속도로 합금을 생산해낼 수 있습니다.
block.silicon-smelter.description = 실리콘을 제작할 수 있는 건물입니다.
block.phase-weaver.description = 메타를 제작할 수 있는 건물입니다.
block.pulverizer.description = 돌을 갈아서 모래로 만들 수 있는 건물입니다.
block.cryofluidmixer.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 = 흔히 아는 충전식 배터리입니다.\n전력 생산건물에서 전력이 떨어질경우, 이 배터리를 전력 노드에 연결하면 이 배터리에 에 있는 전력을 사용하여 전기를 소모하는 건물에 전력을 지속적으로 공급할 수 있습니다.
block.battery-large.description = 일반 배터리보다 용량이 매우 커진 커진 배터리.
block.combustion-generator.description = 석탄을 연료로 전기를 생산해내는 발전소 입니다.
block.turbine-generator.description = 석탄 발전기보다 더 많은량의 전기를 생산하는 발전기입니다.
block.mechanical-drill.description = 구리로 제작할 수 있는 기본 드릴입니다.
block.pneumatic-drill.description = 돌, 티타늄을 채광할 수 있는 고급 드릴입니다.
block.laser-drill.description = 토륨을 채광할 수 있는 최고급 드릴입니다.\n전력과 물을 공급하여 빠른 속도로 채광할 수 있습니다.
block.water-extractor.description = 바닥에서 물을 추출하여 건물에 공급할 수 있는 건물입니다.
block.cultivator.description = 잔디에서 바이오메터를 추출할 수 있는 건물입니다.
block.alpha-mech-pad.description = 알파 기체로 바꿀 수 있는 패드입니다.
block.dart-ship-pad.description = 다트 비행선으로 바꿀 수 있는 패드입니다.
block.delta-mech-pad.description = 델타 기체로 바꿀 수 있는 패드입니다.
block.javelin-ship-pad.description = 자비린 비행선으로 바꿀 수 있는 패드입니다.
block.trident-ship-pad.description = 삼지창 비행선으로 바꿀 수 있는 패드입니다.
block.glaive-ship-pad.description = 글레브 비행선으로 바꿀 수 있는 패드입니다.
block.omega-mech-pad.description = 오메가 기체로 바꿀 수 있는 패드
block.tau-mech-pad.description = 타우 기체로 바꿀 수 있는 패드
block.conduit.description = 일반 파이프. 액체가 지나갈 수 있도록 해 줍니다.
block.liquidrouter.description = 파이프에 공급되고 있는 액체를 다른 방향으로 보낼 수 있게 해 줍니다.
block.bridge-conduit.description = 다리와 다리 사이를 연결하여 액체가 지나갈 수 있게 해 줍니다.\n주로 다리 사이에 지나갈 수 없는 장애물이 있을 때 사용합니다.
block.mechanical-pump.description = 구리로 제작할 수 있는 기계식 물펌프입니다.
block.itemsource.description = 자원을 선택하면 그 자원이 무한하게 튀어나오는 블록입니다.
block.itemvoid.description = 아이템을 시공으로 빠트려 사라지게 만듭니다.
block.liquidsource.description = 무한한 액체를 출력해냅니다.
block.powervoid.description = 무한한 아이템을 출력해냅니다.
block.powerinfinite.description = 무한한 전력을 출력해냅니다.
block.unloader.description = 해당 창고 및 코어에서 자원을 빼내는데 사용됩니다.
block.sortedunloader.description = 알 수 없음.
block.vault.description = 아이템을 임시로 저장할 수 있는 대형 창고
block.wave.description = 적이 있는 자리에 액체를 뿌립니다.\n이 포탑을 활용하여 액체를 뿌린 곳에 불을 붙이거나 적을 느리게 할 수 있습니다.
block.swarmer.description = 4발씩 끊어 발사하고, 유도 미사일을 가진 포탑입니다.
block.salvo.description = 명중률이 높고, 3발씩 끊어 발사하는 포탑입니다.
block.ripple.description = 4개의 탄약으로 나눠 발사하여 명중률이 낮지만, 사거리가 매우 긴 포탑입니다.
block.phase-conveyor.description = 자원을 순간이동 시켜 주는 컨베이어 입니다.
block.bridge-conveyor.description = 교차기와 다르게 이 블록은 사이에 있는 블록들을 건너 띄우고 자원들을 운반할 수 있습니다. 주로 언덕간 자원 수송에서 사용됩니다.
block.plastanium-compressor.description = 플라스터늄을 제조할 수 있는 건물입니다.
block.pyratite-mixer.description = 피라테를 제조할 수 있는 건물입니다.
block.blast-mixer.description = 화합물을 제조할 수 있는 건물입니다.
block.solidifer.description = 용암을 돌로 만들 수 있는 건물입니다.
block.solar-panel.description = 태양열을 받아 자기 스스로 전력을 생산하는 블록입니다.
block.solar-panel-large.description = 태양열을 받아 자기 스스로 전력을 생산하지만, 이 블록은 더 빨리 전력을 생산할 수 있습니다.
block.oil-extractor.description = 기름을 추출 해 주는 건물.
block.spirit-factory.description = 스피릿 유닛을 생산하는 공장입니다.
block.phantom-factory.description = 유닛 팬텀을 생산하는 공장입니다.
block.wraith-factory.description = 유닛 유령 전투기를 소환하는 공장입니다.
block.fortress-factory.description = 포트리스를 생산하는 공장입니다.
block.ghoul-factory.description = 구울 유닛을 생산하는 공장입니다.
block.dagger-factory.description = 디거를 생산하는 공장입니다.
block.titan-factory.description = 타이탄 유닛을 생산할 수 있는 공장
block.revenant-factory.description = 레비던트 유닛을 생산할 수 있는 공장
block.repair-point.description = 근처 유닛들을 수리하는 건물입니다.
block.pulse-conduit.description = 티타늄으로 만들어 졌으며, 일반 파이프보다 액체 수용량이 높습니다.
block.phase-conduit.description = 물을 먼거리로 순간이동 시켜 주는 장치입니다.
block.liquid-router.description = 물펌프를 다른 방향으로 분배할 수 있게 하는 블럭입니다.
block.liquid-tank.description = 액체 종류를 저장할 수 있는 물탱크 입니다.
block.liquid-junction.description = 물펌프와 다른 물펌프를 서로 교차시키게 할 수 있는 블럭입니다.
block.rotary-pump.description = 일반 물 펌프보다 더 빠른 속도로 물을 끌어올릴 수 있는 펌프입니다.
block.thorium-reactor.description = 토륨을 원료로 하는 핵 발전소 입니다.\n많은 전력을 생산하지만 엄청난 열을 발생시키기 때문에, 많은 량의 물 또는 냉각수가 있어야 터지지 않고 작동합니다.
block.command-center.description = 생산된 유닛들을 제어할 수 있는 건물입니다.\n첫번째 버튼은 적 기지로 공격하며, 두번째는 대기 상태, 세번째는 기지 근처를 돌며 정찰합니다.
block.mass-driver.description = 자원을 받아서 다른 물질 이동기로 전달할 수 있는 블록입니다.\n엄청난 사거리를 가지고 있으며, 주로 컨베이어가 접근할 수 없는 곳에 유용하게 사용됩니다.
block.blast-drill.description = 최상위 드릴입니다. 엄청난 양의 전력과 물을 소모하는 대신, 매우 빠른 속도로 채광합니다.
block.thermal-pump.description = 용암 위에서 사용할 수 있는 펌프입니다.
block.thermal-generator.description = 용암을 원료로 전력을 생산할 수 있는 발전소입니다.
block.alloy-smelter.description = 설금을 제작할 수 있는 건물입니다.
block.mend-projector.description = 주위 건물을 치료하는 건물입니다.
block.surge-wall.description = 데미지를 입으면 번개를 일으켜 대상에게 피해를 입히는 특수한 벽입니다.
block.surge-wall-large.description = 설금을 재료로 한 큰 벽.\n데미지를 입으면 번개를 일으켜 대상에게 피해를 입힙니다.
block.cyclone.description = 낮은 명중률과 높은 RPM 을 가진 포탑입니다.\n탄약이 남아있는 한 멈추지 않고 계속 연사합니다.
block.fuse.description = 단거리에서 범위형 레이저를 발사하는 포탑입니다.
block.shock-mine.description = 적이 이 블록을 지나가면 전격 공격을 하는 함정형 방어 건물입니다.
block.overdrive-projector.description = 범위 내 모든 행동의 속도를 높여주는 보조형 방어 건물입니다.
block.force-projector.description = 보호막을 생성하는 건물입니다.\n기본적으로 전기만 있으면 작동하지만, 메타를 넣어 보호막의 범위를 크게 확장시킬 수 있습니다.
block.arc.description = 목표 방향으로 전격 공격을 하는 포탑입니다.
block.spectre.description = 높은 명중률과 RPM 을 가진 포탑입니다.\n탄약이 남아있는 한 멈추지 않고 계속 연사합니다.
block.meltdown.description = 목표를 따라 초대형 레이져를 발사하는 포탑입니다.\n뭉쳐있는 몹에게 매우 효과가 좋습니다.
block.container.description = 자원을 운반하기 위한 수송 블록입니다.
text.filename = 파일 이름 :

View File

@@ -428,7 +428,7 @@ item.titanium.description = Rzadki i bardzo lekki materiał. Używany w bardzo z
item.thorium.name = uran item.thorium.name = uran
item.thorium.description = Zwarty i radioaktywny materiał używany w struktucrach i paliwie nuklearnym. Nie trzymaj go w rękach\! item.thorium.description = Zwarty i radioaktywny materiał używany w struktucrach i paliwie nuklearnym. Nie trzymaj go w rękach\!
item.silicon.name = Krzem item.silicon.name = Krzem
item.silcion.description = Niesamowicie przydatny półprzewodnk uźywany w panelach słonecznych i skomplikowanej elektronice. Nie, w Dolinie Krzemowej już nie ma krzemu. item.silicon.description = Niesamowicie przydatny półprzewodnk uźywany w panelach słonecznych i skomplikowanej elektronice. Nie, w Dolinie Krzemowej już nie ma krzemu.
item.plastanium.name = Plastan item.plastanium.name = Plastan
item.plastanium.description = Lekki i plastyczny materiał używany w amunicji odłamkowej i samolotach. Używany też w w klockach LEGO (Dlatego są niezniszczalne) item.plastanium.description = Lekki i plastyczny materiał używany w amunicji odłamkowej i samolotach. Używany też w w klockach LEGO (Dlatego są niezniszczalne)
item.phase-matter.name = Materia Fazowa item.phase-matter.name = Materia Fazowa

View File

@@ -428,7 +428,7 @@ item.titanium.description = Um Material raro super leve, metal usado intensivame
item.thorium.name = Urânio item.thorium.name = Urânio
item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel. item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel.
item.silicon.name = Sílicio item.silicon.name = Sílicio
item.silcion.description = Condutor extremamente importante,Com aplicação em paneis solares e dispositivos complexos. item.silicon.description = Condutor extremamente importante,Com aplicação em paneis solares e dispositivos complexos.
item.plastanium.name = Plastanio item.plastanium.name = Plastanio
item.plastanium.description = Leve, Material dutil Usado em aeronaves Avançadas E munição de fragmentação. item.plastanium.description = Leve, Material dutil Usado em aeronaves Avançadas E munição de fragmentação.
item.phase-matter.name = Materia fase item.phase-matter.name = Materia fase

View File

@@ -428,7 +428,7 @@ item.titanium.description = Редкий сверхлёгкий металл ш
item.thorium.name = Торий item.thorium.name = Торий
item.thorium.description = Плотный радиоактивный металл используется в качестве структурной поддержки и ядерного топлива. item.thorium.description = Плотный радиоактивный металл используется в качестве структурной поддержки и ядерного топлива.
item.silicon.name = Кремень item.silicon.name = Кремень
item.silcion.description = Очень полезный полупроводник с применениями в солнечных батареях и множестве сложной электроники. item.silicon.description = Очень полезный полупроводник с применениями в солнечных батареях и множестве сложной электроники.
item.plastanium.name = Пластиний item.plastanium.name = Пластиний
item.plastanium.description = Легкий, пластичный материал, используемый в современных самолетах и боеприпасах для фрагментации. item.plastanium.description = Легкий, пластичный материал, используемый в современных самолетах и боеприпасах для фрагментации.
item.phase-matter.name = Фазовая материя item.phase-matter.name = Фазовая материя

View File

@@ -428,7 +428,7 @@ item.titanium.description = Nadir ve hafif bir materyal. Hava araclarinda, Kazma
item.thorium.name = Toryum item.thorium.name = Toryum
item.thorium.description = Nukleer yakit olarak kullanilan sert ve nukleer bir materyal. item.thorium.description = Nukleer yakit olarak kullanilan sert ve nukleer bir materyal.
item.silicon.name = Silikon item.silicon.name = Silikon
item.silcion.description = Gunes panellerinde ve gelismis materallerde kullanilan bir materyal item.silicon.description = Gunes panellerinde ve gelismis materallerde kullanilan bir materyal
item.plastanium.name = Plastanyum item.plastanium.name = Plastanyum
item.plastanium.description = hafif bir madde, hava makinelerinde ve silahlara kursun olarak kullanilir. item.plastanium.description = hafif bir madde, hava makinelerinde ve silahlara kursun olarak kullanilir.
item.phase-matter.name = Faz maddesi item.phase-matter.name = Faz maddesi

View File

@@ -428,7 +428,7 @@ item.titanium.description = A rare super-light metal used extensively in liquid
item.thorium.name = Thorium item.thorium.name = Thorium
item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel. item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel.
item.silicon.name = Silicon item.silicon.name = Silicon
item.silcion.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics. item.silicon.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics.
item.plastanium.name = Plastanium item.plastanium.name = Plastanium
item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition. item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition.
item.phase-matter.name = Phase Matter item.phase-matter.name = Phase Matter

View File

@@ -428,7 +428,7 @@ item.titanium.description = Рідкий суперлегкий метал ши
item.thorium.name = Торій item.thorium.name = Торій
item.thorium.description = Густий, радіоактивний метал, що використовується як структурна підтримка та ядерне паливо. item.thorium.description = Густий, радіоактивний метал, що використовується як структурна підтримка та ядерне паливо.
item.silicon.name = Кремній item.silicon.name = Кремній
item.silcion.description = Надзвичайно корисний напівпровідник з застосуванням в сонячних батареях та багатьох складних електроніках. item.silicon.description = Надзвичайно корисний напівпровідник з застосуванням в сонячних батареях та багатьох складних електроніках.
item.plastanium.name = Пластиній item.plastanium.name = Пластиній
item.plastanium.description = Легкий, пластичний матеріал, що використовується в сучасних літальних апаратах, та боєприпаси для фрагментації. item.plastanium.description = Легкий, пластичний матеріал, що використовується в сучасних літальних апаратах, та боєприпаси для фрагментації.
item.phase-matter.name = Фазова матерія item.phase-matter.name = Фазова матерія

View File

@@ -428,7 +428,7 @@ item.titanium.description = 一种罕见的超轻金属,被广泛运用于液
item.thorium.name = item.thorium.name =
item.thorium.description = 一种致密的放射性金属,用作支撑结构和核燃料。 item.thorium.description = 一种致密的放射性金属,用作支撑结构和核燃料。
item.silicon.name = item.silicon.name =
item.silcion.description = 非常有用的半导体,被用于太阳能电池板和很多复杂的电子设备。 item.silicon.description = 非常有用的半导体,被用于太阳能电池板和很多复杂的电子设备。
item.plastanium.name = 塑料 item.plastanium.name = 塑料
item.plastanium.description = 一种轻质,可延展的材料,用于高级的飞机和碎片弹药。 item.plastanium.description = 一种轻质,可延展的材料,用于高级的飞机和碎片弹药。
item.phase-matter.name = 相位问题 item.phase-matter.name = 相位问题

View File

@@ -428,7 +428,7 @@ item.titanium.description = A rare super-light metal used extensively in liquid
item.thorium.name = Thorium item.thorium.name = Thorium
item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel. item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel.
item.silicon.name = Silicon item.silicon.name = Silicon
item.silcion.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics. item.silicon.description = An extremely useful semiconductor, with applications in solar panels and many complex electronics.
item.plastanium.name = Plastanium item.plastanium.name = Plastanium
item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition. item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition.
item.phase-matter.name = Phase Matter item.phase-matter.name = Phase Matter

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

View File

@@ -3,15 +3,15 @@ common lineHeight=32 base=26 scaleW=2048 scaleH=2048 pages=3 packed=0
page id=0 file="square1.png" page id=0 file="square1.png"
page id=1 file="square2.png" page id=1 file="square2.png"
page id=2 file="square3.png" page id=2 file="square3.png"
chars count=11449 chars count=11450
char id=13 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=0 xadvance=0 page=0 chnl=0 char id=10 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=0 xadvance=0 page=0 chnl=0
char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=0 xadvance=16 page=0 chnl=0 char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=0 xadvance=16 page=0 chnl=0
char id=33 x=2039 y=147 width=7 height=23 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 char id=33 x=2039 y=147 width=7 height=23 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0
char id=34 x=147 y=2032 width=15 height=11 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=0 char id=34 x=147 y=2032 width=15 height=11 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=0
char id=36 x=7 y=0 width=23 height=31 xoffset=-1 yoffset=0 xadvance=24 page=0 chnl=0 char id=36 x=7 y=0 width=23 height=31 xoffset=-1 yoffset=0 xadvance=24 page=0 chnl=0
char id=39 x=2040 y=263 width=7 height=11 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 char id=39 x=2040 y=263 width=7 height=11 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0
char id=40 x=2036 y=1278 width=11 height=23 xoffset=-1 yoffset=4 xadvance=12 page=0 chnl=0 char id=40 x=2036 y=1278 width=11 height=23 xoffset=-1 yoffset=4 xadvance=12 page=0 chnl=0
char id=41 x=2036 y=1365 width=11 height=23 xoffset=-1 yoffset=4 xadvance=12 page=0 chnl=0 char id=41 x=2034 y=1365 width=11 height=23 xoffset=-1 yoffset=4 xadvance=12 page=0 chnl=0
char id=44 x=2040 y=263 width=7 height=11 xoffset=-1 yoffset=20 xadvance=8 page=0 chnl=0 char id=44 x=2040 y=263 width=7 height=11 xoffset=-1 yoffset=20 xadvance=8 page=0 chnl=0
char id=45 x=196 y=2032 width=23 height=7 xoffset=-1 yoffset=12 xadvance=24 page=0 chnl=0 char id=45 x=196 y=2032 width=23 height=7 xoffset=-1 yoffset=12 xadvance=24 page=0 chnl=0
char id=46 x=2037 y=292 width=7 height=7 xoffset=-1 yoffset=20 xadvance=8 page=0 chnl=0 char id=46 x=2037 y=292 width=7 height=7 xoffset=-1 yoffset=20 xadvance=8 page=0 chnl=0
@@ -27,39 +27,39 @@ char id=96 x=2033 y=1829 width=11 height=9 xoffset=3 yoffset=2 x
char id=113 x=2022 y=1249 width=23 height=27 xoffset=-1 yoffset=4 xadvance=24 page=0 chnl=0 char id=113 x=2022 y=1249 width=23 height=27 xoffset=-1 yoffset=4 xadvance=24 page=0 chnl=0
char id=124 x=0 y=0 width=7 height=31 xoffset=-1 yoffset=0 xadvance=8 page=0 chnl=0 char id=124 x=0 y=0 width=7 height=31 xoffset=-1 yoffset=0 xadvance=8 page=0 chnl=0
char id=126 x=177 y=2032 width=19 height=9 xoffset=-1 yoffset=6 xadvance=16 page=0 chnl=0 char id=126 x=177 y=2032 width=19 height=9 xoffset=-1 yoffset=6 xadvance=16 page=0 chnl=0
char id=192 x=2031 y=669 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=192 x=2029 y=640 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=193 x=2027 y=698 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=193 x=2031 y=669 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=194 x=2022 y=292 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0 char id=194 x=2022 y=292 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0
char id=195 x=2029 y=814 width=17 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=195 x=2027 y=698 width=17 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=196 x=2029 y=843 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=196 x=2029 y=814 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=197 x=2027 y=321 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0 char id=197 x=2027 y=321 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0
char id=199 x=2029 y=901 width=15 height=27 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=0 char id=199 x=2029 y=843 width=15 height=27 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=0
char id=200 x=2029 y=930 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=200 x=2029 y=901 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=201 x=2029 y=959 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=201 x=2029 y=930 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=202 x=2022 y=350 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0 char id=202 x=2022 y=350 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0
char id=203 x=2029 y=1191 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=203 x=2029 y=959 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=204 x=2036 y=1133 width=11 height=27 xoffset=3 yoffset=0 xadvance=16 page=0 chnl=0 char id=204 x=2036 y=1133 width=11 height=27 xoffset=3 yoffset=0 xadvance=16 page=0 chnl=0
char id=205 x=2033 y=1162 width=11 height=27 xoffset=3 yoffset=0 xadvance=16 page=0 chnl=0 char id=205 x=2033 y=1162 width=11 height=27 xoffset=3 yoffset=0 xadvance=16 page=0 chnl=0
char id=206 x=2022 y=408 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0 char id=206 x=2022 y=408 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0
char id=207 x=2029 y=1220 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=207 x=2029 y=1191 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=209 x=2019 y=1365 width=17 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=209 x=2029 y=1220 width=17 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=210 x=2024 y=1423 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=210 x=2019 y=1365 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=211 x=2030 y=1510 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=211 x=2024 y=1423 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=212 x=2024 y=466 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0 char id=212 x=2024 y=466 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0
char id=213 x=2023 y=1539 width=17 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=213 x=2030 y=1510 width=17 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=214 x=2030 y=1568 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=214 x=2023 y=1539 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=217 x=2023 y=1597 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=217 x=2030 y=1568 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=218 x=2022 y=1655 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=218 x=2023 y=1597 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=219 x=2023 y=524 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0 char id=219 x=2023 y=524 width=15 height=29 xoffset=1 yoffset=-2 xadvance=16 page=0 chnl=0
char id=220 x=2024 y=1684 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=220 x=2022 y=1655 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=221 x=2024 y=1742 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=221 x=2024 y=1684 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=224 x=2023 y=1974 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=0 chnl=0 char id=224 x=2023 y=1974 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=0 chnl=0
char id=253 x=30 y=0 width=17 height=31 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=0 char id=1025 x=2024 y=1742 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=254 x=2023 y=1800 width=15 height=27 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=0 char id=1031 x=2029 y=553 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=255 x=2029 y=553 width=17 height=29 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=0 char id=1038 x=2023 y=1800 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=1031 x=2029 y=582 width=15 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0 char id=1049 x=2029 y=582 width=17 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=1049 x=2029 y=640 width=17 height=27 xoffset=1 yoffset=0 xadvance=16 page=0 chnl=0
char id=1081 x=2029 y=1916 width=17 height=25 xoffset=1 yoffset=2 xadvance=16 page=0 chnl=0 char id=1081 x=2029 y=1916 width=17 height=25 xoffset=1 yoffset=2 xadvance=16 page=0 chnl=0
char id=1118 x=30 y=0 width=17 height=31 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=0
char id=1168 x=2029 y=1858 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=0 chnl=0 char id=1168 x=2029 y=1858 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=0 chnl=0
char id=12623 x=2033 y=31 width=13 height=29 xoffset=13 yoffset=0 xadvance=32 page=0 chnl=0 char id=12623 x=2033 y=31 width=13 height=29 xoffset=13 yoffset=0 xadvance=32 page=0 chnl=0
char id=12624 x=2031 y=89 width=13 height=29 xoffset=11 yoffset=0 xadvance=32 page=0 chnl=0 char id=12624 x=2031 y=89 width=13 height=29 xoffset=11 yoffset=0 xadvance=32 page=0 chnl=0
@@ -4704,29 +4704,32 @@ char id=48697 x=1923 y=2003 width=29 height=29 xoffset=1 yoffset=0 x
char id=48698 x=1952 y=2003 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=0 chnl=0 char id=48698 x=1952 y=2003 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=0 chnl=0
char id=48699 x=1983 y=2003 width=29 height=29 xoffset=1 yoffset=0 xadvance=32 page=0 chnl=0 char id=48699 x=1983 y=2003 width=29 height=29 xoffset=1 yoffset=0 xadvance=32 page=0 chnl=0
char id=48700 x=2012 y=2003 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=0 chnl=0 char id=48700 x=2012 y=2003 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=0 chnl=0
char id=47 x=2029 y=1885 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0 char id=47 x=2030 y=1653 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0
char id=49 x=2029 y=1334 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0 char id=49 x=2028 y=1160 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0
char id=60 x=2030 y=1653 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0 char id=60 x=2026 y=1508 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0
char id=62 x=2031 y=1856 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0 char id=62 x=2029 y=1624 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0
char id=65 x=2024 y=1450 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=1 chnl=0 char id=65 x=2023 y=1218 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=1 chnl=0
char id=66 x=2023 y=1566 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=1 chnl=0 char id=66 x=2024 y=1450 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=1 chnl=0
char id=67 x=2024 y=1769 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=1 chnl=0 char id=67 x=2023 y=1566 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=1 chnl=0
char id=68 x=2019 y=1827 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=1 chnl=0 char id=68 x=2024 y=1769 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=1 chnl=0
char id=69 x=2019 y=1827 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=1 chnl=0
char id=73 x=2032 y=1015 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0 char id=73 x=2032 y=1015 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0
char id=92 x=2029 y=1943 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0 char id=92 x=2031 y=1856 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0
char id=105 x=2032 y=1015 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0 char id=105 x=2032 y=1015 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0
char id=123 x=2026 y=1508 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0 char id=123 x=2027 y=1305 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0
char id=125 x=2029 y=1624 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0 char id=125 x=2029 y=1334 width=15 height=23 xoffset=-1 yoffset=4 xadvance=16 page=1 chnl=0
char id=215 x=1131 y=2030 width=15 height=17 xoffset=1 yoffset=8 xadvance=16 page=1 chnl=0 char id=215 x=1131 y=2030 width=15 height=17 xoffset=1 yoffset=8 xadvance=16 page=1 chnl=0
char id=225 x=2029 y=58 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=225 x=2029 y=58 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=226 x=2029 y=87 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=226 x=2029 y=87 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=227 x=2029 y=1972 width=17 height=23 xoffset=1 yoffset=4 xadvance=16 page=1 chnl=0 char id=227 x=2029 y=1885 width=17 height=23 xoffset=1 yoffset=4 xadvance=16 page=1 chnl=0
char id=228 x=2029 y=2001 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=1 chnl=0 char id=228 x=2029 y=1943 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=1 chnl=0
char id=229 x=2029 y=145 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=229 x=2029 y=145 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=230 x=1146 y=2030 width=19 height=17 xoffset=-1 yoffset=10 xadvance=16 page=1 chnl=0 char id=230 x=1146 y=2030 width=19 height=17 xoffset=-1 yoffset=10 xadvance=16 page=1 chnl=0
char id=231 x=2029 y=1972 width=15 height=23 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=232 x=2029 y=174 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=232 x=2029 y=174 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=233 x=2029 y=203 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=233 x=2029 y=203 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=234 x=2019 y=232 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=234 x=2019 y=232 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=235 x=2029 y=2001 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=1 chnl=0
char id=236 x=2019 y=319 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=236 x=2019 y=319 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=237 x=2029 y=406 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=237 x=2029 y=406 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=238 x=2029 y=435 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=238 x=2029 y=435 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
@@ -4734,13 +4737,9 @@ char id=242 x=2029 y=464 width=15 height=25 xoffset=1 yoffset=2 x
char id=243 x=2028 y=493 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=243 x=2028 y=493 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=244 x=2019 y=580 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=244 x=2019 y=580 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=247 x=1165 y=2030 width=15 height=17 xoffset=1 yoffset=8 xadvance=16 page=1 chnl=0 char id=247 x=1165 y=2030 width=15 height=17 xoffset=1 yoffset=8 xadvance=16 page=1 chnl=0
char id=248 x=1180 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1044 x=2024 y=725 width=19 height=23 xoffset=-1 yoffset=6 xadvance=16 page=1 chnl=0
char id=249 x=2024 y=725 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=1062 x=2020 y=1044 width=17 height=23 xoffset=1 yoffset=6 xadvance=16 page=1 chnl=0
char id=250 x=2025 y=754 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0 char id=1065 x=2026 y=1131 width=17 height=23 xoffset=1 yoffset=6 xadvance=16 page=1 chnl=0
char id=251 x=2023 y=841 width=15 height=25 xoffset=1 yoffset=2 xadvance=16 page=1 chnl=0
char id=1044 x=2020 y=1044 width=19 height=23 xoffset=-1 yoffset=6 xadvance=16 page=1 chnl=0
char id=1062 x=2023 y=1218 width=17 height=23 xoffset=1 yoffset=6 xadvance=16 page=1 chnl=0
char id=1065 x=2027 y=1305 width=17 height=23 xoffset=1 yoffset=6 xadvance=16 page=1 chnl=0
char id=1072 x=787 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1072 x=787 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1074 x=802 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1074 x=802 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1075 x=817 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1075 x=817 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
@@ -4754,20 +4753,23 @@ char id=1084 x=945 y=2030 width=17 height=17 xoffset=1 yoffset=10 x
char id=1085 x=962 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1085 x=962 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1086 x=977 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1086 x=977 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1087 x=992 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1087 x=992 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1088 x=2029 y=986 width=15 height=23 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1088 x=2029 y=928 width=15 height=23 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1089 x=1007 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1089 x=1007 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1090 x=1022 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1090 x=1022 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1091 x=2026 y=1131 width=17 height=23 xoffset=-1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1091 x=2029 y=957 width=17 height=23 xoffset=-1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1092 x=2028 y=1160 width=17 height=23 xoffset=1 yoffset=8 xadvance=16 page=1 chnl=0 char id=1092 x=2029 y=986 width=17 height=23 xoffset=1 yoffset=8 xadvance=16 page=1 chnl=0
char id=1093 x=1037 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1093 x=1037 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1095 x=1052 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1095 x=1052 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1096 x=1067 y=2030 width=17 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1096 x=1067 y=2030 width=17 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1098 x=1197 y=2030 width=17 height=17 xoffset=-1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1099 x=1180 y=2030 width=17 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1100 x=1084 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1100 x=1084 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1101 x=1214 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1102 x=1099 y=2030 width=17 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1102 x=1099 y=2030 width=17 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1103 x=1116 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1103 x=1116 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1108 x=847 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0 char id=1108 x=847 y=2030 width=15 height=17 xoffset=1 yoffset=10 xadvance=16 page=1 chnl=0
char id=1110 x=2029 y=928 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=1 chnl=0 char id=1110 x=2025 y=754 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=1 chnl=0
char id=1111 x=2029 y=957 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=1 chnl=0 char id=1111 x=2023 y=841 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=1 chnl=0
char id=12593 x=0 y=2030 width=27 height=17 xoffset=3 yoffset=6 xadvance=32 page=1 chnl=0 char id=12593 x=0 y=2030 width=27 height=17 xoffset=3 yoffset=6 xadvance=32 page=1 chnl=0
char id=12594 x=27 y=2030 width=27 height=17 xoffset=3 yoffset=6 xadvance=32 page=1 chnl=0 char id=12594 x=27 y=2030 width=27 height=17 xoffset=3 yoffset=6 xadvance=32 page=1 chnl=0
char id=12595 x=486 y=2030 width=27 height=17 xoffset=3 yoffset=6 xadvance=32 page=1 chnl=0 char id=12595 x=486 y=2030 width=27 height=17 xoffset=3 yoffset=6 xadvance=32 page=1 chnl=0
@@ -9401,7 +9403,7 @@ char id=53338 x=1905 y=2001 width=31 height=29 xoffset=1 yoffset=0 x
char id=53339 x=1936 y=2001 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=1 chnl=0 char id=53339 x=1936 y=2001 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=1 chnl=0
char id=53340 x=1967 y=2001 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=1 chnl=0 char id=53340 x=1967 y=2001 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=1 chnl=0
char id=53341 x=1998 y=2001 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=1 chnl=0 char id=53341 x=1998 y=2001 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=1 chnl=0
char id=0 x=125 y=864 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=0 x=127 y=864 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=35 x=1503 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=35 x=1503 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=37 x=1457 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=37 x=1457 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=38 x=1526 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=38 x=1526 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
@@ -9418,95 +9420,94 @@ char id=56 x=1342 y=839 width=23 height=23 xoffset=-1 yoffset=4 x
char id=57 x=1365 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=57 x=1365 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=63 x=1411 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=63 x=1411 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=64 x=1434 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=64 x=1434 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=69 x=2019 y=29 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=70 x=2019 y=29 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=70 x=2020 y=377 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=71 x=2020 y=377 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=71 x=2020 y=522 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=72 x=2020 y=522 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=72 x=2023 y=638 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=74 x=2023 y=638 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=74 x=744 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=75 x=744 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=75 x=767 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=76 x=767 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=76 x=790 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=77 x=790 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=77 x=813 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=78 x=813 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=78 x=836 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=79 x=836 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=79 x=859 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=80 x=859 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=80 x=882 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=82 x=882 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=82 x=905 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=83 x=905 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=83 x=928 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=84 x=928 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=84 x=951 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=85 x=951 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=85 x=974 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=86 x=974 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=86 x=997 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=87 x=997 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=87 x=1020 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=88 x=1020 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=88 x=1043 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=89 x=1043 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=89 x=1066 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=90 x=1066 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=90 x=1089 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=97 x=1089 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=97 x=1112 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=98 x=1112 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=98 x=1135 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=99 x=1135 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=99 x=1158 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=100 x=1158 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=100 x=1181 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=101 x=1181 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=101 x=2019 y=29 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=102 x=2019 y=29 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=102 x=2020 y=377 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=103 x=2020 y=377 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=103 x=2020 y=522 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=104 x=2020 y=522 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=104 x=2023 y=638 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=106 x=2023 y=638 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=106 x=744 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=107 x=744 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=107 x=767 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=108 x=767 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=108 x=790 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=109 x=790 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=109 x=813 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=110 x=813 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=110 x=836 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=111 x=836 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=111 x=859 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=112 x=859 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=112 x=882 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=114 x=882 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=114 x=905 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=115 x=905 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=115 x=928 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=116 x=928 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=116 x=951 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=117 x=951 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=117 x=974 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=118 x=974 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=118 x=997 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=119 x=997 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=119 x=1020 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=120 x=1020 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=120 x=1043 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=121 x=1043 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=121 x=1066 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=122 x=1066 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0
char id=122 x=1089 y=839 width=23 height=23 xoffset=-1 yoffset=4 xadvance=24 page=2 chnl=0 char id=198 x=1954 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=198 x=1984 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=208 x=1971 y=839 width=17 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0
char id=208 x=2001 y=839 width=17 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0 char id=216 x=1988 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=216 x=2018 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=222 x=2003 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=222 x=0 y=864 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=223 x=2018 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=223 x=15 y=864 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=239 x=2029 y=87 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0
char id=231 x=2029 y=87 width=15 height=23 xoffset=1 yoffset=10 xadvance=16 page=2 chnl=0 char id=240 x=0 y=864 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=235 x=2029 y=116 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0 char id=241 x=2029 y=116 width=17 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0
char id=239 x=2029 y=174 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0 char id=245 x=2029 y=174 width=17 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0
char id=240 x=30 y=864 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=246 x=2029 y=203 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0
char id=241 x=2029 y=203 width=17 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0 char id=1028 x=1617 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=245 x=2029 y=232 width=17 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0 char id=1040 x=2029 y=464 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=246 x=2029 y=464 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0 char id=1041 x=2029 y=493 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=252 x=2029 y=493 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0 char id=1042 x=2026 y=696 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1028 x=1647 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1043 x=1572 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1040 x=2029 y=667 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1045 x=1602 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1041 x=2026 y=696 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1046 x=1632 y=839 width=19 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1042 x=1587 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1047 x=1651 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1043 x=1602 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1048 x=1666 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1045 x=1632 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1050 x=1683 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1046 x=1662 y=839 width=19 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1051 x=1700 y=839 width=17 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1047 x=1681 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1052 x=1717 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1048 x=1696 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1053 x=1734 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1050 x=1713 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1054 x=1749 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1051 x=1730 y=839 width=17 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1055 x=1764 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1052 x=1747 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1056 x=1779 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1053 x=1764 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1057 x=1794 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1054 x=1779 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1058 x=1809 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1055 x=1794 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1059 x=1824 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1056 x=1809 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1060 x=1839 y=839 width=19 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1057 x=1824 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1061 x=1858 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1058 x=1839 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1063 x=1873 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1059 x=1854 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1064 x=1888 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1060 x=1869 y=839 width=19 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1067 x=15 y=864 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1061 x=1888 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1068 x=1905 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1063 x=1903 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1069 x=32 y=864 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1064 x=1918 y=839 width=17 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1070 x=1920 y=839 width=19 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1068 x=1935 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1071 x=1939 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1070 x=1950 y=839 width=19 height=21 xoffset=-1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1073 x=2029 y=667 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1071 x=1969 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1076 x=74 y=864 width=19 height=19 xoffset=-1 yoffset=10 xadvance=16 page=2 chnl=0
char id=1073 x=1572 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=1094 x=93 y=864 width=17 height=19 xoffset=1 yoffset=10 xadvance=16 page=2 chnl=0
char id=1076 x=72 y=864 width=19 height=19 xoffset=-1 yoffset=10 xadvance=16 page=2 chnl=0 char id=1097 x=110 y=864 width=17 height=19 xoffset=1 yoffset=10 xadvance=16 page=2 chnl=0
char id=1094 x=91 y=864 width=17 height=19 xoffset=1 yoffset=10 xadvance=16 page=2 chnl=0 char id=1105 x=2029 y=232 width=15 height=23 xoffset=1 yoffset=4 xadvance=16 page=2 chnl=0
char id=1097 x=108 y=864 width=17 height=19 xoffset=1 yoffset=10 xadvance=16 page=2 chnl=0 char id=1169 x=1587 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0
char id=1169 x=1617 y=839 width=15 height=21 xoffset=1 yoffset=6 xadvance=16 page=2 chnl=0 char id=12622 x=47 y=864 width=27 height=19 xoffset=3 yoffset=4 xadvance=32 page=2 chnl=0
char id=12622 x=45 y=864 width=27 height=19 xoffset=3 yoffset=4 xadvance=32 page=2 chnl=0
char id=12632 x=1797 y=783 width=33 height=29 xoffset=1 yoffset=0 xadvance=32 page=2 chnl=0 char id=12632 x=1797 y=783 width=33 height=29 xoffset=1 yoffset=0 xadvance=32 page=2 chnl=0
char id=12633 x=1830 y=783 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=2 chnl=0 char id=12633 x=1830 y=783 width=31 height=29 xoffset=1 yoffset=0 xadvance=32 page=2 chnl=0
char id=12634 x=1861 y=783 width=29 height=29 xoffset=1 yoffset=0 xadvance=32 page=2 chnl=0 char id=12634 x=1861 y=783 width=29 height=29 xoffset=1 yoffset=0 xadvance=32 page=2 chnl=0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@@ -78,8 +78,6 @@ public class Vars{
public static boolean mobile; public static boolean mobile;
public static boolean ios; public static boolean ios;
public static boolean android; public static boolean android;
//shorthand for whether or not this is running on GWT
public static boolean gwt;
//main data directory //main data directory
public static FileHandle dataDirectory; public static FileHandle dataDirectory;
//directory for user-created map data //directory for user-created map data
@@ -139,7 +137,7 @@ public class Vars{
} }
} }
Arrays.sort(locales, (l1, l2) -> Platform.instance.getLocaleName(l1).compareTo(Platform.instance.getLocaleName(l2))); Arrays.sort(locales, (l1, l2) -> l1.getDisplayName(l1).compareTo(l2.getDisplayName(l2)));
Version.init(); Version.init();
content = new ContentLoader(); content = new ContentLoader();
@@ -166,18 +164,15 @@ public class Vars{
}); });
} }
threads = new ThreadHandler(Platform.instance.getThreadProvider()); threads = new ThreadHandler();
mobile = Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS || testMobile; mobile = Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS || testMobile;
ios = Gdx.app.getType() == ApplicationType.iOS; ios = Gdx.app.getType() == ApplicationType.iOS;
android = Gdx.app.getType() == ApplicationType.Android; android = Gdx.app.getType() == ApplicationType.Android;
gwt = Gdx.app.getType() == ApplicationType.WebGL;
if(!gwt){ dataDirectory = OS.getAppDataDirectory(appName);
dataDirectory = OS.getAppDataDirectory(appName); customMapDirectory = dataDirectory.child("maps/");
customMapDirectory = dataDirectory.child("maps/"); saveDirectory = dataDirectory.child("saves/");
saveDirectory = dataDirectory.child("saves/");
}
fontScale = Math.max(Unit.dp.scl(1f) / 2f, 0.5f); fontScale = Math.max(Unit.dp.scl(1f) / 2f, 0.5f);
baseCameraScale = Math.round(Unit.dp.scl(4)); baseCameraScale = Math.round(Unit.dp.scl(4));

View File

@@ -128,7 +128,11 @@ public class BlockIndexer{
for(int ty = ry * structQuadrantSize; ty < (ry + 1) * structQuadrantSize && ty < world.height(); ty++){ for(int ty = ry * structQuadrantSize; ty < (ry + 1) * structQuadrantSize && ty < world.height(); ty++){
Tile other = world.tile(tx, ty); Tile other = world.tile(tx, ty);
if(other == null || other.entity == null || other.getTeam() != team || !pred.test(other) || !other.block().targetable) continue; if(other == null) continue;
other = other.target();
if(other.entity == null || other.getTeam() != team || !pred.test(other) || !other.block().targetable) continue;
TileEntity e = other.entity; TileEntity e = other.entity;

View File

@@ -7,7 +7,7 @@ import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemType; import io.anuke.mindustry.type.ItemType;
public class Items implements ContentList{ public class Items implements ContentList{
public static Item stone, copper, lead, densealloy, coal, titanium, thorium, silicon, plastanium, phasematter, surgealloy, public static Item stone, copper, lead, densealloy, coal, titanium, thorium, silicon, plastanium, phasefabric, surgealloy,
biomatter, sand, blastCompound, pyratite; biomatter, sand, blastCompound, pyratite;
@Override @Override
@@ -71,9 +71,11 @@ public class Items implements ContentList{
cost = 1.6f; cost = 1.6f;
}}; }};
phasematter = new Item("phase-matter", Color.valueOf("f4ba6e")){{ phasefabric = new Item("phase-fabric", Color.valueOf("f4ba6e")){{
type = ItemType.material; type = ItemType.material;
cost = 1.5f; cost = 1.5f;
fluxiness = 0.9f;
radioactivity = 0.3f;
}}; }};
surgealloy = new Item("surge-alloy", Color.valueOf("f3e979")){{ surgealloy = new Item("surge-alloy", Color.valueOf("f3e979")){{
@@ -82,7 +84,7 @@ public class Items implements ContentList{
biomatter = new Item("biomatter", Color.valueOf("648b55")){{ biomatter = new Item("biomatter", Color.valueOf("648b55")){{
flammability = 0.4f; flammability = 0.4f;
fluxiness = 0.2f; fluxiness = 0.3f;
}}; }};
sand = new Item("sand", Color.valueOf("e3d39e")){{ sand = new Item("sand", Color.valueOf("e3d39e")){{

View File

@@ -36,8 +36,8 @@ public class Recipes implements ContentList{
new Recipe(defense, DefenseBlocks.thoriumWall, new ItemStack(Items.thorium, 12)); new Recipe(defense, DefenseBlocks.thoriumWall, new ItemStack(Items.thorium, 12));
new Recipe(defense, DefenseBlocks.thoriumWallLarge, new ItemStack(Items.thorium, 12 * 4)); new Recipe(defense, DefenseBlocks.thoriumWallLarge, new ItemStack(Items.thorium, 12 * 4));
new Recipe(defense, DefenseBlocks.phaseWall, new ItemStack(Items.phasematter, 12)); new Recipe(defense, DefenseBlocks.phaseWall, new ItemStack(Items.phasefabric, 12));
new Recipe(defense, DefenseBlocks.phaseWallLarge, new ItemStack(Items.phasematter, 12 * 4)); new Recipe(defense, DefenseBlocks.phaseWallLarge, new ItemStack(Items.phasefabric, 12 * 4));
new Recipe(defense, DefenseBlocks.surgeWall, new ItemStack(Items.surgealloy, 12)); new Recipe(defense, DefenseBlocks.surgeWall, new ItemStack(Items.surgealloy, 12));
new Recipe(defense, DefenseBlocks.surgeWallLarge, new ItemStack(Items.surgealloy, 12 * 4)); new Recipe(defense, DefenseBlocks.surgeWallLarge, new ItemStack(Items.surgealloy, 12 * 4));
@@ -68,7 +68,7 @@ public class Recipes implements ContentList{
//DISTRIBUTION //DISTRIBUTION
new Recipe(distribution, DistributionBlocks.conveyor, new ItemStack(Items.copper, 1)).setAlwaysUnlocked(true); new Recipe(distribution, DistributionBlocks.conveyor, new ItemStack(Items.copper, 1)).setAlwaysUnlocked(true);
new Recipe(distribution, DistributionBlocks.titaniumconveyor, new ItemStack(Items.copper, 2), new ItemStack(Items.titanium, 1)); new Recipe(distribution, DistributionBlocks.titaniumconveyor, new ItemStack(Items.copper, 2), new ItemStack(Items.titanium, 1));
new Recipe(distribution, DistributionBlocks.phaseConveyor, new ItemStack(Items.phasematter, 10), new ItemStack(Items.silicon, 15), new ItemStack(Items.lead, 20), new ItemStack(Items.densealloy, 20)); new Recipe(distribution, DistributionBlocks.phaseConveyor, new ItemStack(Items.phasefabric, 10), new ItemStack(Items.silicon, 15), new ItemStack(Items.lead, 20), new ItemStack(Items.densealloy, 20));
//starter lead transportation //starter lead transportation
new Recipe(distribution, DistributionBlocks.junction, new ItemStack(Items.copper, 2)).setAlwaysUnlocked(true); new Recipe(distribution, DistributionBlocks.junction, new ItemStack(Items.copper, 2)).setAlwaysUnlocked(true);
@@ -125,11 +125,11 @@ public class Recipes implements ContentList{
//generators - solar //generators - solar
new Recipe(power, PowerBlocks.solarPanel, new ItemStack(Items.lead, 20), new ItemStack(Items.silicon, 30)); new Recipe(power, PowerBlocks.solarPanel, new ItemStack(Items.lead, 20), new ItemStack(Items.silicon, 30));
new Recipe(power, PowerBlocks.largeSolarPanel, new ItemStack(Items.lead, 200), new ItemStack(Items.silicon, 290), new ItemStack(Items.phasematter, 30)); new Recipe(power, PowerBlocks.largeSolarPanel, new ItemStack(Items.lead, 200), new ItemStack(Items.silicon, 290), new ItemStack(Items.phasefabric, 30));
//generators - nuclear //generators - nuclear
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.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.phasematter, 50), new ItemStack(Items.plastanium, 150), new ItemStack(Items.thorium, 100)); 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, 40), new ItemStack(Items.silicon, 50));
new Recipe(distribution, StorageBlocks.container, new ItemStack(Items.densealloy, 200)); new Recipe(distribution, StorageBlocks.container, new ItemStack(Items.densealloy, 200));
@@ -138,7 +138,7 @@ public class Recipes implements ContentList{
/*new Recipe(distribution, StorageBlocks.core, /*new Recipe(distribution, StorageBlocks.core,
new ItemStack(Items.copper, 2000), new ItemStack(Items.densealloy, 1500), new ItemStack(Items.copper, 2000), new ItemStack(Items.densealloy, 1500),
new ItemStack(Items.silicon, 1500), new ItemStack(Items.thorium, 500), new ItemStack(Items.silicon, 1500), new ItemStack(Items.thorium, 500),
new ItemStack(Items.surgealloy, 500), new ItemStack(Items.phasematter, 750) new ItemStack(Items.surgealloy, 500), new ItemStack(Items.phasefabric, 750)
);*/ );*/
//DRILLS, PRODUCERS //DRILLS, PRODUCERS
@@ -156,7 +156,7 @@ public class Recipes implements ContentList{
//bodies //bodies
new Recipe(units, UpgradeBlocks.dartPad, new ItemStack(Items.lead, 150), new ItemStack(Items.copper, 150), new ItemStack(Items.silicon, 200), new ItemStack(Items.titanium, 240)).setVisible(RecipeVisibility.desktopOnly); new Recipe(units, UpgradeBlocks.dartPad, new ItemStack(Items.lead, 150), new ItemStack(Items.copper, 150), new ItemStack(Items.silicon, 200), new ItemStack(Items.titanium, 240)).setVisible(RecipeVisibility.desktopOnly);
new Recipe(units, UpgradeBlocks.tridentPad, new ItemStack(Items.lead, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250), new ItemStack(Items.titanium, 300), new ItemStack(Items.plastanium, 200)); new Recipe(units, UpgradeBlocks.tridentPad, new ItemStack(Items.lead, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250), new ItemStack(Items.titanium, 300), new ItemStack(Items.plastanium, 200));
new Recipe(units, UpgradeBlocks.javelinPad, new ItemStack(Items.lead, 350), new ItemStack(Items.silicon, 450), new ItemStack(Items.titanium, 500), new ItemStack(Items.plastanium, 400), new ItemStack(Items.phasematter, 200)); new Recipe(units, UpgradeBlocks.javelinPad, new ItemStack(Items.lead, 350), new ItemStack(Items.silicon, 450), new ItemStack(Items.titanium, 500), new ItemStack(Items.plastanium, 400), new ItemStack(Items.phasefabric, 200));
new Recipe(units, UpgradeBlocks.glaivePad, new ItemStack(Items.lead, 450), new ItemStack(Items.silicon, 650), new ItemStack(Items.titanium, 700), new ItemStack(Items.plastanium, 600), new ItemStack(Items.surgealloy, 200)); new Recipe(units, UpgradeBlocks.glaivePad, new ItemStack(Items.lead, 450), new ItemStack(Items.silicon, 650), new ItemStack(Items.titanium, 700), new ItemStack(Items.plastanium, 600), new ItemStack(Items.surgealloy, 200));
new Recipe(units, UpgradeBlocks.alphaPad, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 100), new ItemStack(Items.copper, 150)).setVisible(RecipeVisibility.mobileOnly); new Recipe(units, UpgradeBlocks.alphaPad, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 100), new ItemStack(Items.copper, 150)).setVisible(RecipeVisibility.mobileOnly);
@@ -170,7 +170,7 @@ public class Recipes implements ContentList{
new Recipe(units, UnitBlocks.daggerFactory, new ItemStack(Items.lead, 90), new ItemStack(Items.silicon, 70)); new Recipe(units, UnitBlocks.daggerFactory, new ItemStack(Items.lead, 90), new ItemStack(Items.silicon, 70));
new Recipe(units, UnitBlocks.titanFactory, new ItemStack(Items.thorium, 90), new ItemStack(Items.lead, 140), new ItemStack(Items.silicon, 90)); new Recipe(units, UnitBlocks.titanFactory, new ItemStack(Items.thorium, 90), new ItemStack(Items.lead, 140), new ItemStack(Items.silicon, 90));
new Recipe(units, UnitBlocks.fortressFactory, new ItemStack(Items.thorium, 200), new ItemStack(Items.lead, 220), new ItemStack(Items.silicon, 150), new ItemStack(Items.surgealloy, 100), new ItemStack(Items.phasematter, 50)); new Recipe(units, UnitBlocks.fortressFactory, new ItemStack(Items.thorium, 200), new ItemStack(Items.lead, 220), new ItemStack(Items.silicon, 150), new ItemStack(Items.surgealloy, 100), new ItemStack(Items.phasefabric, 50));
new Recipe(units, UnitBlocks.wraithFactory, new ItemStack(Items.titanium, 60), new ItemStack(Items.lead, 80), new ItemStack(Items.silicon, 90)); new Recipe(units, UnitBlocks.wraithFactory, new ItemStack(Items.titanium, 60), new ItemStack(Items.lead, 80), new ItemStack(Items.silicon, 90));
new Recipe(units, UnitBlocks.ghoulFactory, new ItemStack(Items.plastanium, 80), new ItemStack(Items.titanium, 100), new ItemStack(Items.lead, 130), new ItemStack(Items.silicon, 220)); new Recipe(units, UnitBlocks.ghoulFactory, new ItemStack(Items.plastanium, 80), new ItemStack(Items.titanium, 100), new ItemStack(Items.lead, 130), new ItemStack(Items.silicon, 220));
@@ -182,7 +182,7 @@ public class Recipes implements ContentList{
//LIQUIDS //LIQUIDS
new Recipe(liquid, LiquidBlocks.conduit, new ItemStack(Items.lead, 1)).setDependencies(CraftingBlocks.smelter); new Recipe(liquid, LiquidBlocks.conduit, new ItemStack(Items.lead, 1)).setDependencies(CraftingBlocks.smelter);
new Recipe(liquid, LiquidBlocks.pulseConduit, new ItemStack(Items.titanium, 1), new ItemStack(Items.lead, 1)); new Recipe(liquid, LiquidBlocks.pulseConduit, new ItemStack(Items.titanium, 1), new ItemStack(Items.lead, 1));
new Recipe(liquid, LiquidBlocks.phaseConduit, new ItemStack(Items.phasematter, 10), new ItemStack(Items.silicon, 15), new ItemStack(Items.lead, 20), new ItemStack(Items.titanium, 20)); new Recipe(liquid, LiquidBlocks.phaseConduit, new ItemStack(Items.phasefabric, 10), new ItemStack(Items.silicon, 15), new ItemStack(Items.lead, 20), new ItemStack(Items.titanium, 20));
new Recipe(liquid, LiquidBlocks.liquidRouter, new ItemStack(Items.titanium, 4), new ItemStack(Items.lead, 4)); new Recipe(liquid, LiquidBlocks.liquidRouter, new ItemStack(Items.titanium, 4), new ItemStack(Items.lead, 4));
new Recipe(liquid, LiquidBlocks.liquidtank, new ItemStack(Items.titanium, 50), new ItemStack(Items.lead, 50)); new Recipe(liquid, LiquidBlocks.liquidtank, new ItemStack(Items.titanium, 50), new ItemStack(Items.lead, 50));

View File

@@ -52,7 +52,6 @@ public class UnitTypes implements ContentList{
drag = 0.4f; drag = 0.4f;
hitsize = 8f; hitsize = 8f;
mass = 1.75f; mass = 1.75f;
range = 40f;
weapon = Weapons.chainBlaster; weapon = Weapons.chainBlaster;
health = 130; health = 130;
}}; }};
@@ -62,7 +61,6 @@ public class UnitTypes implements ContentList{
speed = 0.18f; speed = 0.18f;
drag = 0.4f; drag = 0.4f;
mass = 3.5f; mass = 3.5f;
range = 10f;
hitsize = 9f; hitsize = 9f;
rotatespeed = 0.1f; rotatespeed = 0.1f;
weapon = Weapons.flamethrower; weapon = Weapons.flamethrower;
@@ -75,7 +73,6 @@ public class UnitTypes implements ContentList{
drag = 0.4f; drag = 0.4f;
mass = 5f; mass = 5f;
hitsize = 10f; hitsize = 10f;
range = 10f;
rotatespeed = 0.06f; rotatespeed = 0.06f;
weaponOffsetX = 1; weaponOffsetX = 1;
targetAir = false; targetAir = false;
@@ -111,6 +108,7 @@ public class UnitTypes implements ContentList{
speed = 0.14f; speed = 0.14f;
maxVelocity = 1.3f; maxVelocity = 1.3f;
drag = 0.01f; drag = 0.01f;
range = 80f;
isFlying = true; isFlying = true;
weapon = Weapons.laserBurster; weapon = Weapons.laserBurster;
}}; }};

View File

@@ -16,7 +16,7 @@ import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public class Blocks extends BlockList implements ContentList{ public class Blocks extends BlockList implements ContentList{
public static Block air, blockpart, spawn, space, metalfloor, deepwater, water, lava, oil, stone, blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock; public static Block air, blockpart, spawn, space, metalfloor, deepwater, water, lava, tar, stone, blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock;
@Override @Override
@@ -100,11 +100,11 @@ public class Blocks extends BlockList implements ContentList{
minimapColor = Color.valueOf("ed5334"); minimapColor = Color.valueOf("ed5334");
}}; }};
oil = new Floor("oil"){{ tar = new Floor("tar"){{
liquidColor = Color.valueOf("292929"); liquidColor = Color.valueOf("292929");
status = StatusEffects.tarred; status = StatusEffects.tarred;
statusIntensity = 1f; statusIntensity = 1f;
speedMultiplier = 0.2f; speedMultiplier = 0.19f;
variants = 0; variants = 0;
liquidDrop = Liquids.oil; liquidDrop = Liquids.oil;
isLiquid = true; isLiquid = true;

View File

@@ -75,7 +75,7 @@ public class CraftingBlocks extends BlockList implements ContentList{
phaseWeaver = new PhaseWeaver("phase-weaver"){{ phaseWeaver = new PhaseWeaver("phase-weaver"){{
craftEffect = BlockFx.smeltsmoke; craftEffect = BlockFx.smeltsmoke;
result = Items.phasematter; result = Items.phasefabric;
craftTime = 120f; craftTime = 120f;
powerCapacity = 50f; powerCapacity = 50f;
size = 2; size = 2;

View File

@@ -22,8 +22,8 @@ import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ImageButton; import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Table;
import java.io.DataInputStream; import java.io.DataInput;
import java.io.DataOutputStream; import java.io.DataOutput;
import java.io.IOException; import java.io.IOException;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -182,12 +182,12 @@ public class DebugBlocks extends BlockList implements ContentList{
public Liquid source = Liquids.water; public Liquid source = Liquids.water;
@Override @Override
public void write(DataOutputStream stream) throws IOException{ public void writeConfig(DataOutput stream) throws IOException{
stream.writeByte(source.id); stream.writeByte(source.id);
} }
@Override @Override
public void read(DataInputStream stream) throws IOException{ public void readConfig(DataInput stream) throws IOException{
source = content.liquid(stream.readByte()); source = content.liquid(stream.readByte());
} }
} }

View File

@@ -73,19 +73,19 @@ public class DefenseBlocks extends BlockList implements ContentList{
mendProjector = new MendProjector("mend-projector"){{ mendProjector = new MendProjector("mend-projector"){{
consumes.power(0.2f); consumes.power(0.2f);
size = 2; size = 2;
consumes.item(Items.phasematter).optional(true); consumes.item(Items.phasefabric).optional(true);
}}; }};
overdriveProjector = new OverdriveProjector("overdrive-projector"){{ overdriveProjector = new OverdriveProjector("overdrive-projector"){{
consumes.power(0.35f); consumes.power(0.35f);
size = 2; size = 2;
consumes.item(Items.phasematter).optional(true); consumes.item(Items.phasefabric).optional(true);
}}; }};
forceProjector = new ForceProjector("force-projector"){{ forceProjector = new ForceProjector("force-projector"){{
consumes.power(0.2f); consumes.power(0.2f);
size = 3; size = 3;
consumes.item(Items.phasematter).optional(true); consumes.item(Items.phasefabric).optional(true);
}}; }};
shockMine = new ShockMine("shock-mine"){{ shockMine = new ShockMine("shock-mine"){{

View File

@@ -38,7 +38,7 @@ public class ProductionBlocks extends BlockList implements ContentList{
updateEffect = BlockFx.pulverizeMedium; updateEffect = BlockFx.pulverizeMedium;
drillEffect = BlockFx.mineBig; drillEffect = BlockFx.mineBig;
consumes.power(0.16f); consumes.power(0.11f);
}}; }};
blastDrill = new Drill("blast-drill"){{ blastDrill = new Drill("blast-drill"){{
@@ -80,7 +80,7 @@ public class ProductionBlocks extends BlockList implements ContentList{
liquidCapacity = 30f; liquidCapacity = 30f;
rotateSpeed = 1.4f; rotateSpeed = 1.4f;
consumes.power(0.1f); consumes.power(0.09f);
}}; }};
oilExtractor = new Fracker("oil-extractor"){{ oilExtractor = new Fracker("oil-extractor"){{

View File

@@ -35,6 +35,7 @@ import io.anuke.ucore.util.ThreadArray;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class ContentLoader{ public class ContentLoader{
private boolean loaded = false; private boolean loaded = false;
private boolean verbose = true;
private ObjectMap<String, MappableContent>[] contentNameMap = new ObjectMap[ContentType.values().length]; private ObjectMap<String, MappableContent>[] contentNameMap = new ObjectMap[ContentType.values().length];
private Array<Content>[] contentMap = new Array[ContentType.values().length]; private Array<Content>[] contentMap = new Array[ContentType.values().length];
@@ -152,12 +153,14 @@ public class ContentLoader{
throw new ImpendingDoomException("THE TIME HAS COME. More than 256 blocks have been created."); throw new ImpendingDoomException("THE TIME HAS COME. More than 256 blocks have been created.");
} }
Log.info("--- CONTENT INFO ---"); if(verbose){
for(int k = 0; k < contentMap.length; k ++){ Log.info("--- CONTENT INFO ---");
Log.info("[{0}]: loaded {1}", ContentType.values()[k].name(), contentMap[k].size); for(int k = 0; k < contentMap.length; k++){
Log.info("[{0}]: loaded {1}", ContentType.values()[k].name(), contentMap[k].size);
}
Log.info("Total content loaded: {0}", total);
Log.info("-------------------");
} }
Log.info("Total content loaded: {0}", total);
Log.info("-------------------");
loaded = true; loaded = true;
} }
@@ -175,6 +178,10 @@ public class ContentLoader{
initialization.add(callable); initialization.add(callable);
} }
public void verbose(boolean verbose){
this.verbose = verbose;
}
public void dispose(){ public void dispose(){
//clear all content, currently not needed //clear all content, currently not needed
} }
@@ -203,7 +210,7 @@ public class ContentLoader{
if(id < 0) id += 256; if(id < 0) id += 256;
if(temporaryMapper != null && temporaryMapper[type.ordinal()] != null && temporaryMapper[type.ordinal()].length != 0){ if(temporaryMapper != null && temporaryMapper[type.ordinal()] != null && temporaryMapper[type.ordinal()].length != 0){
if(temporaryMapper[type.ordinal()][id] == null){ if(temporaryMapper[type.ordinal()].length <= id || temporaryMapper[type.ordinal()][id] == null){
return getByID(type, 0); //default value is always ID 0 return getByID(type, 0); //default value is always ID 0
} }
return (T)temporaryMapper[type.ordinal()][id]; return (T)temporaryMapper[type.ordinal()][id];

View File

@@ -26,10 +26,7 @@ import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.ucore.core.*; import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.EntityQuery; import io.anuke.ucore.entities.EntityQuery;
import io.anuke.ucore.modules.Module; import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Atlas; import io.anuke.ucore.util.*;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Strings;
import io.anuke.ucore.util.Timer;
import java.io.IOException; import java.io.IOException;
@@ -60,7 +57,7 @@ public class Control extends Module{
saves = new Saves(); saves = new Saves();
unlocks = new Unlocks(); unlocks = new Unlocks();
Inputs.useControllers(!gwt); Inputs.useControllers(true);
Gdx.input.setCatchBackKey(true); Gdx.input.setCatchBackKey(true);
@@ -397,7 +394,7 @@ public class Control extends Module{
} }
}else{ }else{
if(!state.is(State.paused) || Net.active()){ if(!state.isPaused()){
Timers.update(); Timers.update();
} }
} }

View File

@@ -10,6 +10,7 @@ import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.Teams; import io.anuke.mindustry.game.Teams;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
@@ -21,7 +22,6 @@ import io.anuke.ucore.entities.EntityQuery;
import io.anuke.ucore.modules.Module; import io.anuke.ucore.modules.Module;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
import io.anuke.mindustry.gen.Call;
/** /**
* Logic module. * Logic module.
@@ -159,16 +159,13 @@ public class Logic extends Module{
if(!state.is(State.menu)){ if(!state.is(State.menu)){
if(!state.is(State.paused) || Net.active()){
Timers.update();
}
if(!Net.client() && !world.isInvalidMap()){ if(!Net.client() && !world.isInvalidMap()){
updateSectors(); updateSectors();
checkGameOver(); checkGameOver();
} }
if(!state.is(State.paused) || Net.active()){ if(!state.isPaused()){
Timers.update();
if(!state.mode.disableWaveTimer && !state.mode.disableWaves){ if(!state.mode.disableWaveTimer && !state.mode.disableWaves){
state.wavetime -= Timers.delta(); state.wavetime -= Timers.delta();

View File

@@ -21,7 +21,6 @@ import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.NetworkIO; import io.anuke.mindustry.net.NetworkIO;
import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.net.TraceInfo;
import io.anuke.mindustry.net.ValidateException; import io.anuke.mindustry.net.ValidateException;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.modules.ItemModule; import io.anuke.mindustry.world.modules.ItemModule;
@@ -207,12 +206,6 @@ public class NetClient extends Module{
players[0].y = y; players[0].y = y;
} }
@Remote(variants = Variant.one)
public static void onTraceInfo(TraceInfo info){
Player player = playerGroup.getByID(info.playerid);
ui.traces.show(player, info);
}
@Remote @Remote
public static void onPlayerDisconnect(int playerid){ public static void onPlayerDisconnect(int playerid){
playerGroup.removeByID(playerid); playerGroup.removeByID(playerid);

View File

@@ -106,11 +106,9 @@ public class NetServer extends Module{
connection.hasBegunConnecting = true; connection.hasBegunConnecting = true;
TraceInfo trace = admins.getTraceByID(uuid);
PlayerInfo info = admins.getInfo(uuid); PlayerInfo info = admins.getInfo(uuid);
trace.uuid = uuid;
trace.ip = connection.address; connection.mobile = packet.mobile;
trace.android = packet.mobile;
if(admins.isIDBanned(uuid)){ if(admins.isIDBanned(uuid)){
kick(id, KickReason.banned); kick(id, KickReason.banned);
@@ -150,7 +148,7 @@ public class NetServer extends Module{
return; return;
} }
Log.info("Recieved connect packet for player '{0}' / UUID {1} / IP {2}", packet.name, uuid, trace.ip); Log.info("Recieved connect packet for player '{0}' / UUID {1} / IP {2}", packet.name, uuid, connection.address);
String ip = Net.getConnection(id).address; String ip = Net.getConnection(id).address;
@@ -162,7 +160,7 @@ public class NetServer extends Module{
} }
if(packet.version == -1){ if(packet.version == -1){
trace.modclient = true; connection.modclient = true;
} }
Player player = new Player(); Player player = new Player();
@@ -207,8 +205,6 @@ public class NetServer extends Module{
connections.put(id, player); connections.put(id, player);
trace.playerid = player.id;
sendWorldData(player, id); sendWorldData(player, id);
Platform.instance.updateRPC(); Platform.instance.updateRPC();
@@ -327,9 +323,9 @@ public class NetServer extends Module{
player.getPlaceQueue().clear(); player.getPlaceQueue().clear();
for(BuildRequest req : requests){ for(BuildRequest req : requests){
//auto-skip done requests //auto-skip done requests
if(req.remove && world.tile(req.x, req.y).block() == Blocks.air){ if(req.breaking && world.tile(req.x, req.y).block() == Blocks.air){
continue; continue;
}else if(!req.remove && world.tile(req.x, req.y).block() == req.recipe.result && (!req.recipe.result.rotate || world.tile(req.x, req.y).getRotation() == req.rotation)){ }else if(!req.breaking && world.tile(req.x, req.y).block() == req.recipe.result && (!req.recipe.result.rotate || world.tile(req.x, req.y).getRotation() == req.rotation)){
continue; continue;
} }
player.getPlaceQueue().addLast(req); player.getPlaceQueue().addLast(req);
@@ -395,11 +391,11 @@ public class NetServer extends Module{
netServer.kick(other.con.id, KickReason.kick); netServer.kick(other.con.id, KickReason.kick);
Log.info("&lc{0} has kicked {1}.", player.name, other.name); Log.info("&lc{0} has kicked {1}.", player.name, other.name);
}else if(action == AdminAction.trace){ }else if(action == AdminAction.trace){
//TODO //TODO implement
if(player.con != null){ if(player.con != null){
Call.onTraceInfo(player.con.id, netServer.admins.getTraceByID(other.uuid)); //Call.onTraceInfo(player.con.id, other.con.trace);
}else{ }else{
NetClient.onTraceInfo(netServer.admins.getTraceByID(other.uuid)); //NetClient.onTraceInfo(other.con.trace);
} }
Log.info("&lc{0} has requested trace info of {1}.", player.name, other.name); Log.info("&lc{0} has requested trace info of {1}.", player.name, other.name);
} }
@@ -424,7 +420,6 @@ public class NetServer extends Module{
if(!headless && !closing && Net.server() && state.is(State.menu)){ if(!headless && !closing && Net.server() && state.is(State.menu)){
closing = true; closing = true;
reset();
threads.runGraphics(() -> ui.loadfrag.show("$text.server.closing")); threads.runGraphics(() -> ui.loadfrag.show("$text.server.closing"));
Timers.runTask(5f, () -> { Timers.runTask(5f, () -> {
Net.closeServer(); Net.closeServer();
@@ -438,10 +433,6 @@ public class NetServer extends Module{
} }
} }
public void reset(){
admins.clearTraces();
}
public void kickAll(KickReason reason){ public void kickAll(KickReason reason){
for(NetConnection con : Net.getConnections()){ for(NetConnection con : Net.getConnections()){
kick(con.id, reason); kick(con.id, reason);

View File

@@ -2,13 +2,11 @@ package io.anuke.mindustry.core;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Base64Coder; import com.badlogic.gdx.utils.Base64Coder;
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
import io.anuke.ucore.function.Consumer; import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.scene.ui.TextField; import io.anuke.ucore.scene.ui.TextField;
import java.util.Date; import java.util.Date;
import java.util.Locale;
import java.util.Random; import java.util.Random;
public abstract class Platform { public abstract class Platform {
@@ -36,10 +34,6 @@ public abstract class Platform {
public boolean canDonate(){ public boolean canDonate(){
return false; return false;
} }
/**Return the localized name for the locale. This is basically a workaround for GWT not supporting getName().*/
public String getLocaleName(Locale locale){
return locale.toString();
}
/**Must be a base64 string 8 bytes in length.*/ /**Must be a base64 string 8 bytes in length.*/
public String getUUID(){ public String getUUID(){
String uuid = Settings.getString("uuid", ""); String uuid = Settings.getString("uuid", "");
@@ -55,8 +49,6 @@ public abstract class Platform {
} }
/**Only used for iOS or android: open the share menu for a map or save.*/ /**Only used for iOS or android: open the share menu for a map or save.*/
public void shareFile(FileHandle file){} public void shareFile(FileHandle file){}
/**Download a file. Only used on GWT backend.*/
public void downloadFile(String name, byte[] bytes){}
/**Show a file chooser. Desktop only. /**Show a file chooser. Desktop only.
* *
@@ -67,17 +59,6 @@ public abstract class Platform {
* @param filetype File extension to filter * @param filetype File extension to filter
*/ */
public void showFileChooser(String text, String content, Consumer<FileHandle> cons, boolean open, String filetype){} public void showFileChooser(String text, String content, Consumer<FileHandle> cons, boolean open, String filetype){}
/**Use the default thread provider from the kryonet module for this.*/
public ThreadProvider getThreadProvider(){
return new ThreadProvider() {
@Override public boolean isOnThread() {return true;}
@Override public void sleep(long ms) {}
@Override public void start(Runnable run) {}
@Override public void stop() {}
@Override public void notify(Object object) {}
@Override public void wait(Object object) {}
};
}
/**Forces the app into landscape mode. Currently Android only.*/ /**Forces the app into landscape mode. Currently Android only.*/
public void beginForceLandscape(){} public void beginForceLandscape(){}

View File

@@ -6,13 +6,15 @@ import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Log; 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.control;
import static io.anuke.mindustry.Vars.logic; import static io.anuke.mindustry.Vars.logic;
public class ThreadHandler{ public class ThreadHandler implements ThreadInfoProvider{
private final Queue<Runnable> toRun = new Queue<>(); private final Queue<Runnable> toRun = new Queue<>();
private final ThreadProvider impl; private Thread thread, graphicsThread;
private final Object updateLock = new Object(); private final Object updateLock = new Object();
private float delta = 1f; private float delta = 1f;
private float smoothDelta = 1f; private float smoothDelta = 1f;
@@ -22,11 +24,12 @@ public class ThreadHandler{
private boolean rendered = true; private boolean rendered = true;
private long lastFrameTime; private long lastFrameTime;
public ThreadHandler(ThreadProvider impl){ public ThreadHandler(){
this.impl = impl; Threads.setThreadInfoProvider(this);
graphicsThread = Thread.currentThread();
Timers.setDeltaProvider(() -> { Timers.setDeltaProvider(() -> {
float result = impl.isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f; float result = isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f;
return Math.min(Float.isNaN(result) ? 1f : result, 15f); return Math.min(Float.isNaN(result) ? 1f : result, 15f);
}); });
} }
@@ -86,7 +89,7 @@ public class ThreadHandler{
long elapsed = TimeUtils.timeSinceMillis(lastFrameTime); long elapsed = TimeUtils.timeSinceMillis(lastFrameTime);
if(elapsed < target){ if(elapsed < target){
try{ try{
impl.sleep(target - elapsed); Thread.sleep(target - elapsed);
}catch(InterruptedException e){ }catch(InterruptedException e){
e.printStackTrace(); e.printStackTrace();
} }
@@ -99,7 +102,7 @@ public class ThreadHandler{
synchronized(updateLock){ synchronized(updateLock){
rendered = true; rendered = true;
impl.notify(updateLock); updateLock.notify();
} }
} }
@@ -111,12 +114,25 @@ public class ThreadHandler{
if(enabled){ if(enabled){
logic.doUpdate = false; logic.doUpdate = false;
Timers.runTask(2f, () -> { Timers.runTask(2f, () -> {
impl.start(this::runLogic); 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; this.enabled = true;
}); });
}else{ }else{
this.enabled = false; this.enabled = false;
impl.stop(); if(thread != null){
thread.interrupt();
thread = null;
}
Timers.runTask(2f, () -> { Timers.runTask(2f, () -> {
logic.doUpdate = true; logic.doUpdate = true;
}); });
@@ -128,7 +144,17 @@ public class ThreadHandler{
} }
public boolean isOnThread(){ public boolean isOnThread(){
return impl.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(){ private void runLogic(){
@@ -157,12 +183,12 @@ public class ThreadHandler{
long target = (long) ((1000) / 60f); long target = (long) ((1000) / 60f);
if(elapsed < target){ if(elapsed < target){
impl.sleep(target - elapsed); Thread.sleep(target - elapsed);
} }
synchronized(updateLock){ synchronized(updateLock){
while(!rendered){ while(!rendered){
impl.wait(updateLock); updateLock.wait();
} }
rendered = false; rendered = false;
} }
@@ -184,18 +210,4 @@ public class ThreadHandler{
control.setError(ex); control.setError(ex);
} }
} }
public interface ThreadProvider{
boolean isOnThread();
void sleep(long ms) throws InterruptedException;
void start(Runnable run);
void stop();
void wait(Object object) throws InterruptedException;
void notify(Object object);
}
} }

View File

@@ -3,6 +3,7 @@ package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.Colors; import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Align;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
@@ -25,7 +26,6 @@ import io.anuke.ucore.scene.ui.TextField.TextFieldFilter;
import io.anuke.ucore.scene.ui.TooltipManager; import io.anuke.ucore.scene.ui.TooltipManager;
import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Structs;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
import static io.anuke.ucore.scene.actions.Actions.*; import static io.anuke.ucore.scene.actions.Actions.*;
@@ -108,12 +108,11 @@ public class UI extends SceneModule{
@Override @Override
protected void loadSkin(){ protected void loadSkin(){
skin = new Skin(Gdx.files.internal("ui/uiskin.json"), Core.atlas); skin = new Skin(Gdx.files.internal("ui/uiskin.json"), Core.atlas);
Structs.each(font -> {
for(BitmapFont font : skin.getAll(BitmapFont.class).values()){
font.setUseIntegerPositions(false); font.setUseIntegerPositions(false);
font.getData().setScale(Vars.fontScale); font.getData().setScale(Vars.fontScale);
font.getData().down += Unit.dp.scl(3f); }
font.getData().lineHeight -= Unit.dp.scl(3f);
}, skin.font(), skin.getFont("default-font-chat"), skin.getFont("trad-chinese"), skin.getFont("simp-chinese"));
} }
@Override @Override

View File

@@ -243,7 +243,7 @@ public class World extends Module{
EntityQuery.resizeTree(0, 0, width * tilesize, height * tilesize); EntityQuery.resizeTree(0, 0, width * tilesize, height * tilesize);
try{ try{
generator.loadTileData(tiles, MapIO.readTileData(map, true), map.meta.hasOreGen(), 0); generator.loadTileData(tiles, MapIO.readTileData(map, true), map.meta.hasOreGen(), Mathf.random(99999));
} catch(Exception e){ } catch(Exception e){
Log.err(e); Log.err(e);
if(!headless){ if(!headless){
@@ -257,6 +257,8 @@ public class World extends Module{
endMapLoad(); endMapLoad();
invalidMap = false;
if(!headless){ if(!headless){
if(state.teams.get(players[0].getTeam()).cores.size == 0){ if(state.teams.get(players[0].getTeam()).cores.size == 0){
ui.showError("$text.map.nospawn"); ui.showError("$text.map.nospawn");

View File

@@ -38,7 +38,6 @@ import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings; import io.anuke.ucore.util.Strings;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -113,73 +112,40 @@ public class MapEditorDialog extends Dialog implements Disposable{
}, true, mapExtension); }, true, mapExtension);
}, },
"$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Runnable)() -> { "$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Runnable)() -> {
if(gwt){ Platform.instance.showFileChooser("$text.loadimage", "Image Files", file -> {
ui.showError("$text.web.unsupported"); ui.loadGraphics(() -> {
}else { try{
Platform.instance.showFileChooser("$text.loadimage", "Image Files", file -> { MapTileData data = MapIO.readLegacyPixmap(new Pixmap(file));
ui.loadGraphics(() -> {
try{
MapTileData data = MapIO.readLegacyPixmap(new Pixmap(file));
editor.beginEdit(data, editor.getTags(), false); editor.beginEdit(data, editor.getTags(), false);
view.clearStack(); view.clearStack();
}catch (Exception e){ }catch (Exception e){
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false))); ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e); Log.err(e);
} }
}); });
}, true, "png"); }, true, "png");
}
})); }));
t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export", t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export",
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Runnable) () -> { "$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Runnable) () -> {
if(!gwt){ Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> {
Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> { file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension); FileHandle result = file;
FileHandle result = file; ui.loadGraphics(() -> {
ui.loadGraphics(() -> {
try{ try{
if(!editor.getTags().containsKey("name")){ if(!editor.getTags().containsKey("name")){
editor.getTags().put("name", result.nameWithoutExtension()); editor.getTags().put("name", result.nameWithoutExtension());
}
MapIO.writeMap(result.write(false), editor.getTags(), editor.getMap());
}catch(Exception e){
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
Log.err(e);
} }
}); MapIO.writeMap(result.write(false), editor.getTags(), editor.getMap());
}, false, mapExtension); }catch(Exception e){
}else{ ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
try{ Log.err(e);
ByteArrayOutputStream ba = new ByteArrayOutputStream(); }
MapIO.writeMap(ba, editor.getTags(), editor.getMap()); });
Platform.instance.downloadFile(editor.getTags().get("name", "unknown") + "." + mapExtension, ba.toByteArray()); }, false, mapExtension);
}catch(IOException e){ }));
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
Log.err(e);
}
}
}/*,
"$text.editor.exportimage", "$text.editor.exportimage.description", "icon-file-image", (Listenable)() -> {
if(gwt){
ui.showError("$text.web.unsupported");
}else{
Platform.instance.showFileChooser("$text.saveimage", "Image Files", file -> {
file = file.parent().child(file.nameWithoutExtension() + ".png");
FileHandle result = file;
ui.loadGraphics(() -> {
try{
Pixmaps.write(MapIO.generatePixmap(editor.getMap()), result);
}catch (Exception e){
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
Log.err(e);
}
});
}, false, "png");
}
}*/));
t.row(); t.row();
@@ -475,6 +441,14 @@ public class MapEditorDialog extends Dialog implements Disposable{
mid.table("button", t -> { mid.table("button", t -> {
Slider slider = new Slider(0, MapEditor.brushSizes.length - 1, 1, false); Slider slider = new Slider(0, MapEditor.brushSizes.length - 1, 1, false);
slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int) (float) f])); slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int) (float) f]));
slider.update(() -> {
for(int j = 0; j < MapEditor.brushSizes.length; j++){
if(editor.getBrushSize() == j){
slider.setValue(j);
return;
}
}
});
t.top(); t.top();
t.add("$text.editor.brush"); t.add("$text.editor.brush");

View File

@@ -1,5 +1,6 @@
package io.anuke.mindustry.editor; package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.Scaling;
import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.Map;
import io.anuke.mindustry.ui.BorderImage; import io.anuke.mindustry.ui.BorderImage;
import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.ui.dialogs.FloatingDialog;
@@ -58,7 +59,7 @@ public class MapLoadDialog extends FloatingDialog{
for(Map map : world.maps.all()){ for(Map map : world.maps.all()){
TextButton button = new TextButton(map.getDisplayName(), "toggle"); TextButton button = new TextButton(map.getDisplayName(), "toggle");
button.add(new BorderImage(map.texture, 2f)).size(16 * 4f); button.add(new BorderImage(map.texture, 2f).setScaling(Scaling.fit)).size(16 * 4f);
button.getCells().reverse(); button.getCells().reverse();
button.clicked(() -> selected = map); button.clicked(() -> selected = map);
button.getLabelCell().grow().left().padLeft(5f); button.getLabelCell().grow().left().padLeft(5f);

View File

@@ -295,7 +295,7 @@ public class MapView extends Element implements GestureListener{
} }
//todo is it really math.max? //todo is it really math.max?
float scaling = zoom * Math.min(width, height) / Math.max(editor.getMap().width(), editor.getMap().height()); float scaling = zoom * Math.min(width, height) / editor.getMap().width();
Draw.color(Palette.accent); Draw.color(Palette.accent);
Lines.stroke(Unit.dp.scl(1f * zoom)); Lines.stroke(Unit.dp.scl(1f * zoom));

View File

@@ -420,7 +420,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
for(BuildRequest request : getPlaceQueue()){ for(BuildRequest request : getPlaceQueue()){
if(getCurrentRequest() == request) continue; if(getCurrentRequest() == request) continue;
if(request.remove){ if(request.breaking){
Block block = world.tile(request.x, request.y).target().block(); Block block = world.tile(request.x, request.y).target().block();
//draw removal request //draw removal request

View File

@@ -28,8 +28,8 @@ import io.anuke.ucore.entities.trait.HealthTrait;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timer; import io.anuke.ucore.util.Timer;
import java.io.DataInputStream; import java.io.DataInput;
import java.io.DataOutputStream; import java.io.DataOutput;
import java.io.IOException; import java.io.IOException;
import static io.anuke.mindustry.Vars.tileGroup; import static io.anuke.mindustry.Vars.tileGroup;
@@ -120,11 +120,13 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
return dead || tile.entity != this; return dead || tile.entity != this;
} }
public void write(DataOutputStream stream) throws IOException{ public void write(DataOutput stream) throws IOException{}
}
public void read(DataInputStream stream) throws IOException{ public void writeConfig(DataOutput stream) throws IOException{}
}
public void read(DataInput stream) throws IOException{}
public void readConfig(DataInput stream) throws IOException{}
public boolean collide(Bullet other){ public boolean collide(Bullet other){
return true; return true;

View File

@@ -41,16 +41,12 @@ public class Units{
return target == null || (range != Float.MAX_VALUE && target.distanceTo(x, y) > range) || target.getTeam() == team || !target.isValid(); return target == null || (range != Float.MAX_VALUE && target.distanceTo(x, y) > range) || target.getTeam() == team || !target.isValid();
} }
/** /**See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}*/
* See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}
*/
public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y){ public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y){
return invalidateTarget(target, team, x, y, Float.MAX_VALUE); return invalidateTarget(target, team, x, y, Float.MAX_VALUE);
} }
/** /**See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}*/
* See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}
*/
public static boolean invalidateTarget(TargetTrait target, Unit targeter){ public static boolean invalidateTarget(TargetTrait target, Unit targeter){
return invalidateTarget(target, targeter.team, targeter.x, targeter.y, targeter.getWeapon().getAmmo().getRange()); return invalidateTarget(target, targeter.team, targeter.x, targeter.y, targeter.getWeapon().getAmmo().getRange());
} }
@@ -129,16 +125,12 @@ public class Units{
return value[0]; return value[0];
} }
/** /**Returns the neareset ally tile in a range.*/
* Returns the neareset ally tile in a range.
*/
public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate<Tile> pred){ public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
return world.indexer.findTile(team, x, y, range, pred); return world.indexer.findTile(team, x, y, range, pred);
} }
/** /**Returns the neareset enemy tile in a range.*/
* Returns the neareset enemy tile in a range.
*/
public static TileEntity findEnemyTile(Team team, float x, float y, float range, Predicate<Tile> pred){ public static TileEntity findEnemyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
for(Team enemy : state.teams.enemiesOf(team)){ for(Team enemy : state.teams.enemiesOf(team)){
TileEntity entity = world.indexer.findTile(enemy, x, y, range, pred); TileEntity entity = world.indexer.findTile(enemy, x, y, range, pred);
@@ -149,9 +141,7 @@ public class Units{
return null; return null;
} }
/** /**Iterates over all units on all teams, including players.*/
* Iterates over all units on all teams, including players.
*/
public static void allUnits(Consumer<Unit> cons){ public static void allUnits(Consumer<Unit> cons){
//check all unit groups first //check all unit groups first
for(EntityGroup<BaseUnit> group : unitGroups){ for(EntityGroup<BaseUnit> group : unitGroups){
@@ -183,9 +173,7 @@ public class Units{
} }
} }
/** /**Returns the closest enemy of this team. Filter by predicate.*/
* Returns the closest enemy of this team. Filter by predicate.
*/
public static Unit getClosestEnemy(Team team, float x, float y, float range, Predicate<Unit> predicate){ public static Unit getClosestEnemy(Team team, float x, float y, float range, Predicate<Unit> predicate){
result = null; result = null;
cdist = 0f; cdist = 0f;
@@ -208,9 +196,7 @@ public class Units{
return result; return result;
} }
/** /**Returns the closest ally of this team. Filter by predicate.*/
* Returns the closest ally of this team. Filter by predicate.
*/
public static Unit getClosest(Team team, float x, float y, float range, Predicate<Unit> predicate){ public static Unit getClosest(Team team, float x, float y, float range, Predicate<Unit> predicate){
result = null; result = null;
cdist = 0f; cdist = 0f;
@@ -233,9 +219,7 @@ public class Units{
return result; return result;
} }
/** /**Iterates over all units in a rectangle.*/
* Iterates over all units in a rectangle.
*/
public static void getNearby(Team team, Rectangle rect, Consumer<Unit> cons){ public static void getNearby(Team team, Rectangle rect, Consumer<Unit> cons){
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()]; EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
@@ -249,9 +233,7 @@ public class Units{
}); });
} }
/** /**Iterates over all units in a circle around this position.*/
* Iterates over all units in a circle around this position.
*/
public static void getNearby(Team team, float x, float y, float radius, Consumer<Unit> cons){ public static void getNearby(Team team, float x, float y, float radius, Consumer<Unit> cons){
rect.setSize(radius * 2).setCenter(x, y); rect.setSize(radius * 2).setCenter(x, y);
@@ -272,9 +254,7 @@ public class Units{
}); });
} }
/** /**Iterates over all units in a rectangle.*/
* Iterates over all units in a rectangle.
*/
public static void getNearby(Rectangle rect, Consumer<Unit> cons){ public static void getNearby(Rectangle rect, Consumer<Unit> cons){
for(Team team : Team.all){ for(Team team : Team.all){
@@ -288,9 +268,7 @@ public class Units{
EntityQuery.getNearby(playerGroup, rect, player -> cons.accept((Unit) player)); EntityQuery.getNearby(playerGroup, rect, player -> cons.accept((Unit) player));
} }
/** /**Iterates over all units that are enemies of this team.*/
* Iterates over all units that are enemies of this team.
*/
public static void getNearbyEnemies(Team team, Rectangle rect, Consumer<Unit> cons){ public static void getNearbyEnemies(Team team, Rectangle rect, Consumer<Unit> cons){
EnumSet<Team> targets = state.teams.enemiesOf(team); EnumSet<Team> targets = state.teams.enemiesOf(team);
@@ -309,9 +287,7 @@ public class Units{
}); });
} }
/** /**Iterates over all units.*/
* Iterates over all units.
*/
public static void getAllUnits(Consumer<Unit> cons){ public static void getAllUnits(Consumer<Unit> cons){
for(Team team : Team.all){ for(Team team : Team.all){
@@ -327,5 +303,4 @@ public class Units{
} }
} }
} }

View File

@@ -57,29 +57,21 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
private float accepting; private float accepting;
private byte generation; private byte generation;
/** /**Deserialization use only!*/
* Deserialization use only!
*/
public Puddle(){ public Puddle(){
} }
/** /**Deposists a puddle between tile and source.*/
* Deposists a puddle between tile and source.
*/
public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){ public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){
deposit(tile, source, liquid, amount, 0); deposit(tile, source, liquid, amount, 0);
} }
/** /**Deposists a puddle at a tile.*/
* Deposists a puddle at a tile.
*/
public static void deposit(Tile tile, Liquid liquid, float amount){ public static void deposit(Tile tile, Liquid liquid, float amount){
deposit(tile, tile, liquid, amount, 0); deposit(tile, tile, liquid, amount, 0);
} }
/** /**Returns the puddle on the specified tile. May return null.*/
* Returns the puddle on the specified tile. May return null.
*/
public static Puddle getPuddle(Tile tile){ public static Puddle getPuddle(Tile tile){
return map.get(tile.packedPosition()); return map.get(tile.packedPosition());
} }
@@ -119,7 +111,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
p.lastRipple = Timers.time(); p.lastRipple = Timers.time();
} }
}else{ }else{
p.amount -= reactPuddle(p.liquid, liquid, amount, p.tile, p.x, p.y); p.amount += reactPuddle(p.liquid, liquid, amount, p.tile, p.x, p.y);
} }
} }
@@ -131,9 +123,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
return liquid == Liquids.oil && other == Liquids.water; return liquid == Liquids.oil && other == Liquids.water;
} }
/** /**Reacts two liquids together at a location.*/
* Reacts two liquids together at a location.
*/
private static float reactPuddle(Liquid dest, Liquid liquid, float amount, Tile tile, float x, float y){ private static float reactPuddle(Liquid dest, Liquid liquid, float amount, Tile tile, float x, float y){
if((dest.flammability > 0.3f && liquid.temperature > 0.7f) || if((dest.flammability > 0.3f && liquid.temperature > 0.7f) ||
(liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid (liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid

View File

@@ -8,6 +8,7 @@ import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.game.EventType.BuildSelectEvent;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
@@ -18,6 +19,7 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BuildBlock; import io.anuke.mindustry.world.blocks.BuildBlock;
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity; import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.trait.Entity; import io.anuke.ucore.entities.trait.Entity;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
@@ -65,10 +67,10 @@ public interface BuilderTrait extends Entity{
BuildRequest request = getCurrentRequest(); BuildRequest request = getCurrentRequest();
if(request != null){ if(request != null){
output.writeByte(request.remove ? 1 : 0); output.writeByte(request.breaking ? 1 : 0);
output.writeInt(world.toPacked(request.x, request.y)); output.writeInt(world.toPacked(request.x, request.y));
output.writeFloat(request.progress); output.writeFloat(request.progress);
if(!request.remove){ if(!request.breaking){
output.writeByte(request.recipe.id); output.writeByte(request.recipe.id);
output.writeByte(request.rotation); output.writeByte(request.rotation);
} }
@@ -181,18 +183,16 @@ public interface BuilderTrait extends Entity{
setMineTile(null); setMineTile(null);
} }
Tile tile = world.tile(current.x, current.y); Tile tile = world.tile(current.x, current.y);
if(unit.distanceTo(tile) > placeDistance){ if(unit.distanceTo(tile) > placeDistance){
return; return;
} }
if(!(tile.block() instanceof BuildBlock) ){ if(!(tile.block() instanceof BuildBlock)){
if(canCreateBlocks() && !current.remove && Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)){ if(canCreateBlocks() && !current.breaking && Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)){
Build.beginPlace(unit.getTeam(), current.x, current.y, current.recipe, current.rotation); Build.beginPlace(unit.getTeam(), current.x, current.y, current.recipe, current.rotation);
}else if(canCreateBlocks() && current.remove && Build.validBreak(unit.getTeam(), current.x, current.y)){ }else if(canCreateBlocks() && current.breaking && Build.validBreak(unit.getTeam(), current.x, current.y)){
Build.beginBreak(unit.getTeam(), current.x, current.y); Build.beginBreak(unit.getTeam(), current.x, current.y);
}else{ }else{
getPlaceQueue().removeFirst(); getPlaceQueue().removeFirst();
@@ -222,7 +222,7 @@ public interface BuilderTrait extends Entity{
//progress is synced, thus not updated clientside //progress is synced, thus not updated clientside
if(!Net.client()){ if(!Net.client()){
//deconstructing is 2x as fast //deconstructing is 2x as fast
if(current.remove){ if(current.breaking){
entity.deconstruct(unit, core, 2f / entity.buildCost * Timers.delta() * getBuildPower(tile)); entity.deconstruct(unit, core, 2f / entity.buildCost * Timers.delta() * getBuildPower(tile));
}else{ }else{
entity.construct(unit, core, 1f / entity.buildCost * Timers.delta() * getBuildPower(tile)); entity.construct(unit, core, 1f / entity.buildCost * Timers.delta() * getBuildPower(tile));
@@ -232,6 +232,11 @@ public interface BuilderTrait extends Entity{
}else{ }else{
entity.progress = current.progress; entity.progress = current.progress;
} }
if(!current.initialized){
Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking));
current.initialized = true;
}
} }
/**Do not call directly.*/ /**Do not call directly.*/
@@ -352,9 +357,10 @@ public interface BuilderTrait extends Entity{
class BuildRequest{ class BuildRequest{
public final int x, y, rotation; public final int x, y, rotation;
public final Recipe recipe; public final Recipe recipe;
public final boolean remove; public final boolean breaking;
public float progress; public float progress;
public boolean initialized;
/**This creates a build request.*/ /**This creates a build request.*/
public BuildRequest(int x, int y, int rotation, Recipe recipe){ public BuildRequest(int x, int y, int rotation, Recipe recipe){
@@ -362,7 +368,7 @@ public interface BuilderTrait extends Entity{
this.y = y; this.y = y;
this.rotation = rotation; this.rotation = rotation;
this.recipe = recipe; this.recipe = recipe;
this.remove = false; this.breaking = false;
} }
/**This creates a remove request.*/ /**This creates a remove request.*/
@@ -371,7 +377,7 @@ public interface BuilderTrait extends Entity{
this.y = y; this.y = y;
this.rotation = -1; this.rotation = -1;
this.recipe = Recipe.getByResult(world.tile(x, y).block()); this.recipe = Recipe.getByResult(world.tile(x, y).block());
this.remove = true; this.breaking = true;
} }
} }
} }

View File

@@ -9,9 +9,10 @@ import io.anuke.ucore.core.Effects;
import io.anuke.ucore.entities.trait.SolidTrait; import io.anuke.ucore.entities.trait.SolidTrait;
public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{ public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{
@Remote(called = Loc.both, targets = Loc.both, forward = true) @Remote(called = Loc.both, targets = Loc.both, forward = true)
static void dropSelf(Player player){ static void dropSelf(Player player){
if(player.getCarrier() != null){ if(player != null && player.getCarrier() != null){
player.getCarrier().dropCarry(); player.getCarrier().dropCarry();
} }
} }
@@ -40,24 +41,16 @@ public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{
} }
} }
/** /**Returns the thing this carrier is carrying.*/
* Returns the thing this carrier is carrying.
*/
CarriableTrait getCarry(); CarriableTrait getCarry();
/** /**Sets the carrying unit. Internal use only! Use {@link #carry(CarriableTrait)} to set state.*/
* Sets the carrying unit. Internal use only! Use {@link #carry(CarriableTrait)} to set state.
*/
void setCarry(CarriableTrait unit); void setCarry(CarriableTrait unit);
/** /**Returns maximum mass this carrier can carry.*/
* Returns maximum mass this carrier can carry.
*/
float getCarryWeight(); float getCarryWeight();
/** /**Drops the unit that is being carried, if applicable.*/
* Drops the unit that is being carried, if applicable.
*/
default void dropCarry(){ default void dropCarry(){
carry(null); carry(null);
} }

View File

@@ -190,7 +190,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
} }
public void targetClosest(){ public void targetClosest(){
target = Units.getClosestTarget(team, x, y, getWeapon().getAmmo().getRange(), u -> type.targetAir || !u.isFlying()); target = Units.getClosestTarget(team, x, y, Math.max(getWeapon().getAmmo().getRange(), type.range), u -> type.targetAir || !u.isFlying());
} }
public TileEntity getClosestEnemyCore(){ public TileEntity getClosestEnemyCore(){

View File

@@ -76,7 +76,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
attack(150f); attack(150f);
if((Mathf.angNear(angleTo(target), rotation, 15f) || !getWeapon().getAmmo().bullet.keepVelocity) //bombers don't care about rotation if((Mathf.angNear(angleTo(target), rotation, 15f) || !getWeapon().getAmmo().bullet.keepVelocity) //bombers don't care about rotation
&& distanceTo(target) < getWeapon().getAmmo().getRange()){ && distanceTo(target) < Math.max(getWeapon().getAmmo().getRange(), type.range)){
AmmoType ammo = getWeapon().getAmmo(); AmmoType ammo = getWeapon().getAmmo();
Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.bullet.speed); Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.bullet.speed);

View File

@@ -29,7 +29,7 @@ public class UnitType extends UnlockableContent{
public float hitsize = 7f; public float hitsize = 7f;
public float hitsizeTile = 4f; public float hitsizeTile = 4f;
public float speed = 0.4f; public float speed = 0.4f;
public float range = 160; public float range = 0;
public float rotatespeed = 0.2f; public float rotatespeed = 0.2f;
public float baseRotateSpeed = 0.1f; public float baseRotateSpeed = 0.1f;
public float mass = 1f; public float mass = 1f;

View File

@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Queue; import com.badlogic.gdx.utils.Queue;
import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.traits.BuilderTrait; import io.anuke.mindustry.entities.traits.BuilderTrait;
@@ -12,7 +13,7 @@ import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.FlyingUnit; import io.anuke.mindustry.entities.units.FlyingUnit;
import io.anuke.mindustry.entities.units.UnitCommand; import io.anuke.mindustry.entities.units.UnitCommand;
import io.anuke.mindustry.entities.units.UnitState; import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.game.EventType.BlockBuildEvent; import io.anuke.mindustry.game.EventType.BuildSelectEvent;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
@@ -35,7 +36,8 @@ import java.io.DataInput;
import java.io.DataOutput; import java.io.DataOutput;
import java.io.IOException; import java.io.IOException;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.unitGroups;
import static io.anuke.mindustry.Vars.world;
public class Drone extends FlyingUnit implements BuilderTrait{ public class Drone extends FlyingUnit implements BuilderTrait{
protected static float discoverRange = 120f; protected static float discoverRange = 120f;
@@ -44,6 +46,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
protected Item targetItem; protected Item targetItem;
protected Tile mineTile; protected Tile mineTile;
protected Queue<BuildRequest> placeQueue = new ThreadQueue<>(); protected Queue<BuildRequest> placeQueue = new ThreadQueue<>();
protected boolean isBreaking;
public final UnitState public final UnitState
@@ -66,9 +69,13 @@ public class Drone extends FlyingUnit implements BuilderTrait{
if(core == null) return; if(core == null) return;
if(entity.progress() < 1f && entity.tile.block() instanceof BuildBlock){ //building is valid if((entity.progress() < 1f || entity.progress() > 0f) && entity.tile.block() instanceof BuildBlock){ //building is valid
if(!isBuilding() && distanceTo(target) < placeDistance * 0.9f){ //within distance, begin placing if(!isBuilding() && distanceTo(target) < placeDistance * 0.9f){ //within distance, begin placing
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.getRotation(), entity.recipe)); if(isBreaking){
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y));
}else{
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.getRotation(), entity.recipe));
}
} }
//if it's missing requirements, try and mine them //if it's missing requirements, try and mine them
@@ -234,27 +241,39 @@ public class Drone extends FlyingUnit implements BuilderTrait{
}; };
static{ static{
Events.on(BlockBuildEvent.class, event -> {
Events.on(BuildSelectEvent.class, event -> {
EntityGroup<BaseUnit> group = unitGroups[event.team.ordinal()]; EntityGroup<BaseUnit> group = unitGroups[event.team.ordinal()];
if(!(event.tile.entity instanceof BuildEntity)) return; if(!(event.builder instanceof Player) || !(event.tile.entity instanceof BuildEntity)) return;
BuildEntity entity = event.tile.entity(); BuildEntity entity = event.tile.entity();
for(BaseUnit unit : group.all()){ for(BaseUnit unit : group.all()){
if(unit instanceof Drone){ if(unit instanceof Drone){
((Drone) unit).notifyPlaced(entity); 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);
}
}
}
drone.notifyPlaced(entity, event.breaking);
} }
} }
}); });
} }
private void notifyPlaced(BuildEntity entity){ private void notifyPlaced(BuildEntity entity, boolean isBreaking){
float timeToBuild = entity.recipe.cost;
float dist = Math.min(entity.distanceTo(x, y) - placeDistance, 0); float dist = Math.min(entity.distanceTo(x, y) - placeDistance, 0);
if(dist / type.maxVelocity < timeToBuild * 0.9f){ if(!state.is(build) && dist / type.maxVelocity < entity.buildCost * 0.9f){
//Call.onDroneBeginBuild(this, entity.tile, entity.recipe);
target = entity; target = entity;
this.isBreaking = isBreaking;
setState(build); setState(build);
} }
} }

View File

@@ -1,6 +1,7 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.game;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.traits.BuilderTrait;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.function.Event; import io.anuke.ucore.function.Event;
@@ -76,14 +77,33 @@ public class EventType{
} }
} }
/**Called when block building begins. The tile's block will nearly always be a BuildBlock.*/ /**Called when block building begins by placing down the BuildBlock.
public static class BlockBuildEvent implements Event{ * The tile's block will nearly always be a BuildBlock.*/
public static class BlockBuildBeginEvent implements Event{
public final Tile tile; public final Tile tile;
public final Team team; public final Team team;
public final boolean breaking;
public BlockBuildEvent(Tile tile, Team team){ public BlockBuildBeginEvent(Tile tile, Team team, boolean breaking){
this.tile = tile; this.tile = tile;
this.team = team; this.team = team;
this.breaking = breaking;
}
}
/**Called when a player or drone begins building something.
* This does not necessarily happen when a new BuildBlock is created.*/
public static class BuildSelectEvent implements Event{
public final Tile tile;
public final Team team;
public final BuilderTrait builder;
public final boolean breaking;
public BuildSelectEvent(Tile tile, Team team, BuilderTrait builder, boolean breaking){
this.tile = tile;
this.team = team;
this.builder = builder;
this.breaking = breaking;
} }
} }

View File

@@ -256,9 +256,7 @@ public class Saves{
} }
public void delete(){ public void delete(){
if(!gwt){ //can't delete files SaveIO.fileFor(index).delete();
SaveIO.fileFor(index).delete();
}
saves.removeValue(this, true); saves.removeValue(this, true);
saveMap.remove(index); saveMap.remove(index);
if(this == current){ if(this == current){

View File

@@ -60,14 +60,15 @@ public class Palette{
bar = Color.SLATE, bar = Color.SLATE,
interact = Color.ORANGE, interact = Color.ORANGE,
accent = Color.valueOf("f4ba6e"), accent = Color.valueOf("f4ba6e"),
accentBack = new Color(accent.r * 0.8f, accent.g * 0.8f, accent.b * 0.8f, 1f), accentBack = Color.valueOf("d58c4b"),
place = Color.valueOf("6335f8"), place = Color.valueOf("6335f8"),
remove = Color.valueOf("e55454"), remove = Color.valueOf("e55454"),
removeBack = Color.valueOf("a73e3e"), removeBack = Color.valueOf("a73e3e"),
placeRotate = accent, placeRotate = accent,
breakInvalid = Color.valueOf("d44b3d"), breakInvalid = Color.valueOf("d44b3d"),
range = Color.valueOf("f4ba6e"), range = Color.valueOf("f4ba6e"),
power = Color.valueOf("fbd367"), power = Color.valueOf("fbad67"),
powerLight = Color.valueOf("fbd367"),
placing = Color.valueOf("616161"), placing = Color.valueOf("616161"),
lightTrail = Color.valueOf("ffe2a9"), lightTrail = Color.valueOf("ffe2a9"),

View File

@@ -222,7 +222,7 @@ public class DesktopInput extends InputHandler{
player.isShooting = true; player.isShooting = true;
} }
}else if(Inputs.keyTap(section, "deselect") && (recipe != null || mode != none || player.isBuilding()) && }else if(Inputs.keyTap(section, "deselect") && (recipe != null || mode != none || player.isBuilding()) &&
!(player.getCurrentRequest() != null && player.getCurrentRequest().remove && KeyBinds.get(section, "deselect") == KeyBinds.get(section, "break"))){ !(player.getCurrentRequest() != null && player.getCurrentRequest().breaking && KeyBinds.get(section, "deselect") == KeyBinds.get(section, "break"))){
if(recipe == null){ if(recipe == null){
player.clearBuilding(); player.clearBuilding();
} }

View File

@@ -14,6 +14,7 @@ import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.ValidateException; import io.anuke.mindustry.net.ValidateException;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.fragments.OverlayFragment; import io.anuke.mindustry.ui.fragments.OverlayFragment;
@@ -76,10 +77,11 @@ public abstract class InputHandler extends InputAdapter{
player.isTransferring = true; player.isTransferring = true;
ItemStack stack = player.inventory.getItem(); Item item = player.inventory.getItem().item;
int accepted = tile.block().acceptStack(stack.item, stack.amount, tile, player); int amount = player.inventory.getItem().amount;
int accepted = tile.block().acceptStack(item, amount, tile, player);
player.inventory.getItem().amount -= accepted;
boolean clear = stack.amount == accepted;
int sent = Mathf.clamp(accepted / 4, 1, 8); int sent = Mathf.clamp(accepted / 4, 1, 8);
int removed = accepted / sent; int removed = accepted / sent;
int[] remaining = {accepted, accepted}; int[] remaining = {accepted, accepted};
@@ -88,29 +90,24 @@ public abstract class InputHandler extends InputAdapter{
for(int i = 0; i < sent; i++){ for(int i = 0; i < sent; i++){
boolean end = i == sent - 1; boolean end = i == sent - 1;
Timers.run(i * 3, () -> { Timers.run(i * 3, () -> {
tile.block().getStackOffset(stack.item, tile, stackTrns); tile.block().getStackOffset(item, tile, stackTrns);
ItemTransfer.create(stack.item, ItemTransfer.create(item,
player.x + Angles.trnsx(player.rotation + 180f, backTrns), player.y + Angles.trnsy(player.rotation + 180f, backTrns), player.x + Angles.trnsx(player.rotation + 180f, backTrns), player.y + Angles.trnsy(player.rotation + 180f, backTrns),
new Translator(tile.drawx() + stackTrns.x, tile.drawy() + stackTrns.y), () -> { new Translator(tile.drawx() + stackTrns.x, tile.drawy() + stackTrns.y), () -> {
if(tile.block() != block || tile.entity == null) return; if(tile.block() != block || tile.entity == null) return;
tile.block().handleStack(stack.item, removed, tile, player); tile.block().handleStack(item, removed, tile, player);
remaining[1] -= removed; remaining[1] -= removed;
if(end && remaining[1] > 0){ if(end && remaining[1] > 0){
tile.block().handleStack(stack.item, remaining[1], tile, player); tile.block().handleStack(item, remaining[1], tile, player);
} }
}); });
stack.amount -= removed;
remaining[0] -= removed; remaining[0] -= removed;
if(end){ if(end){
stack.amount -= remaining[0];
if(clear){
player.inventory.clearItem();
}
player.isTransferring = false; player.isTransferring = false;
} }
}); });

View File

@@ -67,6 +67,7 @@ public abstract class SaveFileVersion{
if(tile.entity.liquids != null) tile.entity.liquids.write(stream); if(tile.entity.liquids != null) tile.entity.liquids.write(stream);
if(tile.entity.cons != null) tile.entity.cons.write(stream); if(tile.entity.cons != null) tile.entity.cons.write(stream);
tile.entity.writeConfig(stream);
tile.entity.write(stream); tile.entity.write(stream);
}else if(tile.block() == Blocks.air){ }else if(tile.block() == Blocks.air){
int consecutives = 0; int consecutives = 0;
@@ -152,6 +153,7 @@ public abstract class SaveFileVersion{
if(tile.entity.liquids != null) tile.entity.liquids.read(stream); if(tile.entity.liquids != null) tile.entity.liquids.read(stream);
if(tile.entity.cons != null) tile.entity.cons.read(stream); if(tile.entity.cons != null) tile.entity.cons.read(stream);
tile.entity.readConfig(stream);
tile.entity.read(stream); tile.entity.read(stream);
if(tile.block() == StorageBlocks.core){ if(tile.block() == StorageBlocks.core){

View File

@@ -2,12 +2,10 @@ package io.anuke.mindustry.io;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Base64Coder;
import com.badlogic.gdx.utils.IntArray; import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.IntMap;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.io.versions.Save16; import io.anuke.mindustry.io.versions.Save16;
import io.anuke.ucore.core.Settings;
import java.io.*; import java.io.*;
import java.util.zip.DeflaterOutputStream; import java.util.zip.DeflaterOutputStream;
@@ -33,40 +31,23 @@ public class SaveIO{
} }
public static void saveToSlot(int slot){ public static void saveToSlot(int slot){
if(gwt){ FileHandle file = fileFor(slot);
ByteArrayOutputStream stream = new ByteArrayOutputStream(); boolean exists = file.exists();
write(stream); if(exists) file.moveTo(file.sibling(file.name() + "-backup." + file.extension()));
Settings.putString("save-" + slot + "-data", new String(Base64Coder.encode(stream.toByteArray()))); try{
Settings.save(); write(fileFor(slot));
}else{ }catch(Exception e){
FileHandle file = fileFor(slot); if(exists) file.sibling(file.name() + "-backup." + file.extension()).moveTo(file);
boolean exists = file.exists(); throw new RuntimeException(e);
if(exists) file.moveTo(file.sibling(file.name() + "-backup." + file.extension()));
try{
write(fileFor(slot));
}catch(Exception e){
if(exists) file.sibling(file.name() + "-backup." + file.extension()).moveTo(file);
throw new RuntimeException(e);
}
} }
} }
public static void loadFromSlot(int slot){ public static void loadFromSlot(int slot){
if(gwt){ load(fileFor(slot));
load(getSlotStream(slot));
}else{
load(fileFor(slot));
}
} }
public static DataInputStream getSlotStream(int slot){ public static DataInputStream getSlotStream(int slot){
if(gwt){ return new DataInputStream(new InflaterInputStream(fileFor(slot).read()));
String string = Settings.getString("save-" + slot + "-data", "");
byte[] bytes = Base64Coder.decode(string);
return new DataInputStream(new ByteArrayInputStream(bytes));
}else{
return new DataInputStream(new InflaterInputStream(fileFor(slot).read()));
}
} }
public static boolean isSaveValid(int slot){ public static boolean isSaveValid(int slot){
@@ -165,6 +146,7 @@ public class SaveIO{
stream.close(); stream.close();
}catch(Exception e){ }catch(Exception e){
content.setTemporaryMapper(null);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

View File

@@ -1,7 +1,6 @@
package io.anuke.mindustry.io; package io.anuke.mindustry.io;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Base64Coder;
import io.anuke.annotations.Annotations.ReadClass; import io.anuke.annotations.Annotations.ReadClass;
import io.anuke.annotations.Annotations.WriteClass; import io.anuke.annotations.Annotations.WriteClass;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
@@ -17,7 +16,6 @@ import io.anuke.mindustry.entities.units.UnitCommand;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.net.Packets.AdminAction; import io.anuke.mindustry.net.Packets.AdminAction;
import io.anuke.mindustry.net.Packets.KickReason; import io.anuke.mindustry.net.Packets.KickReason;
import io.anuke.mindustry.net.TraceInfo;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
@@ -26,13 +24,14 @@ import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.Charset;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
/** Class for specifying read/write methods for code generation.*/ /** Class for specifying read/write methods for code generation.*/
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class TypeIO{ public class TypeIO{
private static final Charset charset = Charset.forName("UTF-8");
@WriteClass(Player.class) @WriteClass(Player.class)
public static void writePlayer(ByteBuffer buffer, Player player){ public static void writePlayer(ByteBuffer buffer, Player player){
@@ -164,9 +163,9 @@ public class TypeIO{
public static void writeRequests(ByteBuffer buffer, BuildRequest[] requests){ public static void writeRequests(ByteBuffer buffer, BuildRequest[] requests){
buffer.putShort((short)requests.length); buffer.putShort((short)requests.length);
for(BuildRequest request : requests){ for(BuildRequest request : requests){
buffer.put(request.remove ? (byte) 1 : 0); buffer.put(request.breaking ? (byte) 1 : 0);
buffer.putInt(world.toPacked(request.x, request.y)); buffer.putInt(world.toPacked(request.x, request.y));
if(!request.remove){ if(!request.breaking){
buffer.put(request.recipe.id); buffer.put(request.recipe.id);
buffer.put((byte) request.rotation); buffer.put((byte) request.rotation);
} }
@@ -330,7 +329,7 @@ public class TypeIO{
@WriteClass(String.class) @WriteClass(String.class)
public static void writeString(ByteBuffer buffer, String string){ public static void writeString(ByteBuffer buffer, String string){
if(string != null){ if(string != null){
byte[] bytes = string.getBytes(StandardCharsets.UTF_8); byte[] bytes = string.getBytes(charset);
buffer.putShort((short) bytes.length); buffer.putShort((short) bytes.length);
buffer.put(bytes); buffer.put(bytes);
}else{ }else{
@@ -344,7 +343,7 @@ public class TypeIO{
if(length != -1){ if(length != -1){
byte[] bytes = new byte[length]; byte[] bytes = new byte[length];
buffer.get(bytes); buffer.get(bytes);
return new String(bytes, StandardCharsets.UTF_8); return new String(bytes, charset);
}else{ }else{
return null; return null;
} }
@@ -363,45 +362,4 @@ public class TypeIO{
buffer.get(bytes); buffer.get(bytes);
return bytes; return bytes;
} }
@WriteClass(TraceInfo.class)
public static void writeTrace(ByteBuffer buffer, TraceInfo info){
buffer.putInt(info.playerid);
buffer.putShort((short) info.ip.getBytes().length);
buffer.put(info.ip.getBytes());
buffer.put(info.modclient ? (byte) 1 : 0);
buffer.put(info.android ? (byte) 1 : 0);
buffer.putInt(info.totalBlocksBroken);
buffer.putInt(info.structureBlocksBroken);
buffer.putInt(info.lastBlockBroken.id);
buffer.putInt(info.totalBlocksPlaced);
buffer.putInt(info.lastBlockPlaced.id);
buffer.put(Base64Coder.decode(info.uuid));
}
@ReadClass(TraceInfo.class)
public static TraceInfo readTrace(ByteBuffer buffer){
int id = buffer.getInt();
short iplen = buffer.getShort();
byte[] ipb = new byte[iplen];
buffer.get(ipb);
TraceInfo info = new TraceInfo(new String(ipb));
info.playerid = id;
info.modclient = buffer.get() == 1;
info.android = buffer.get() == 1;
info.totalBlocksBroken = buffer.getInt();
info.structureBlocksBroken = buffer.getInt();
info.lastBlockBroken = content.block(buffer.getInt());
info.totalBlocksPlaced = buffer.getInt();
info.lastBlockPlaced = content.block(buffer.getInt());
byte[] uuid = new byte[8];
buffer.get(uuid);
info.uuid = new String(Base64Coder.encode(uuid));
return info;
}
} }

View File

@@ -4,16 +4,16 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Base64Coder;
import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.io.MapIO; import io.anuke.mindustry.io.MapIO;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.function.Supplier; import io.anuke.ucore.function.Supplier;
import io.anuke.ucore.util.Log; import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.ThreadArray; import io.anuke.ucore.util.ThreadArray;
import java.io.*; import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -29,8 +29,6 @@ public class Maps implements Disposable{
private Array<Map> allMaps = new ThreadArray<>(); private Array<Map> allMaps = new ThreadArray<>();
/**Temporary array used for returning things.*/ /**Temporary array used for returning things.*/
private Array<Map> returnArray = new ThreadArray<>(); private Array<Map> returnArray = new ThreadArray<>();
/**Used for storing a list of custom map names for GWT.*/
private Array<String> customMapNames;
/**Returns a list of all maps, including custom ones.*/ /**Returns a list of all maps, including custom ones.*/
public Array<Map> all(){ public Array<Map> all(){
@@ -76,25 +74,14 @@ public class Maps implements Disposable{
/**Save a map. This updates all values and stored data necessary.*/ /**Save a map. This updates all values and stored data necessary.*/
public void saveMap(String name, MapTileData data, ObjectMap<String, String> tags){ public void saveMap(String name, MapTileData data, ObjectMap<String, String> tags){
try { try{
//create copy of tags to prevent mutation later //create copy of tags to prevent mutation later
ObjectMap<String, String> newTags = new ObjectMap<>(); ObjectMap<String, String> newTags = new ObjectMap<>();
newTags.putAll(tags); newTags.putAll(tags);
tags = newTags; tags = newTags;
if (!gwt) { FileHandle file = customMapDirectory.child(name + "." + mapExtension);
FileHandle file = customMapDirectory.child(name + "." + mapExtension); MapIO.writeMap(file.write(false), tags, data);
MapIO.writeMap(file.write(false), tags, data);
} else {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
MapIO.writeMap(stream, tags, data);
Settings.putString("map-data-" + name, new String(Base64Coder.encode(stream.toByteArray())));
if(!customMapNames.contains(name, false)){
customMapNames.add(name);
Settings.putObject("custom-maps", customMapNames);
}
Settings.save();
}
if(maps.containsKey(name)){ if(maps.containsKey(name)){
if(maps.get(name).texture != null) { if(maps.get(name).texture != null) {
@@ -105,7 +92,7 @@ public class Maps implements Disposable{
} }
Map map = new Map(name, new MapMeta(version, tags, data.width(), data.height(), null), true, getStreamFor(name)); Map map = new Map(name, new MapMeta(version, tags, data.width(), data.height(), null), true, getStreamFor(name));
if (!headless){ if(!headless){
map.texture = new Texture(MapIO.generatePixmap(data)); map.texture = new Texture(MapIO.generatePixmap(data));
} }
allMaps.add(map); allMaps.add(map);
@@ -126,14 +113,7 @@ public class Maps implements Disposable{
maps.remove(map.name); maps.remove(map.name);
allMaps.removeValue(map, true); allMaps.removeValue(map, true);
if (!gwt) { customMapDirectory.child(map.name + "." + mapExtension).delete();
customMapDirectory.child(map.name + "." + mapExtension).delete();
} else {
customMapNames.removeValue(map.name, false);
Settings.putString("map-data-" + map.name, "");
Settings.putObject("custom-maps", customMapNames);
Settings.save();
}
} }
private void loadMap(String name, Supplier<InputStream> supplier, boolean custom) throws IOException{ private void loadMap(String name, Supplier<InputStream> supplier, boolean custom) throws IOException{
@@ -151,43 +131,21 @@ public class Maps implements Disposable{
} }
private void loadCustomMaps(){ private void loadCustomMaps(){
if(!gwt){ for(FileHandle file : customMapDirectory.list()){
for(FileHandle file : customMapDirectory.list()){ try{
try{ if(file.extension().equalsIgnoreCase(mapExtension)){
if(file.extension().equalsIgnoreCase(mapExtension)){ loadMap(file.nameWithoutExtension(), file::read, true);
loadMap(file.nameWithoutExtension(), file::read, true);
}
}catch (Exception e){
Log.err("Failed to load custom map file '{0}'!", file);
Log.err(e);
}
}
}else{
customMapNames = Settings.getObject("custom-maps", Array.class, Array::new);
for(String name : customMapNames){
try{
String data = Settings.getString("map-data-" + name, "");
byte[] bytes = Base64Coder.decode(data);
loadMap(name, () -> new ByteArrayInputStream(bytes), true);
}catch (Exception e){
Log.err("Failed to load custom map '{0}'!", name);
Log.err(e);
} }
}catch (Exception e){
Log.err("Failed to load custom map file '{0}'!", file);
Log.err(e);
} }
} }
} }
/**Returns an input stream supplier for a given map name.*/ /**Returns an input stream supplier for a given map name.*/
private Supplier<InputStream> getStreamFor(String name){ private Supplier<InputStream> getStreamFor(String name){
if(!gwt){ return customMapDirectory.child(name + "." + mapExtension)::read;
return customMapDirectory.child(name + "." + mapExtension)::read;
}else{
String data = Settings.getString("map-data-" + name, "");
byte[] bytes = Base64Coder.decode(data);
return () -> new ByteArrayInputStream(bytes);
}
} }
@Override @Override

View File

@@ -52,7 +52,7 @@ public class BlockLocMission extends Mission{
float rot = players[0].angleTo(x * tilesize + block.offset(), y * tilesize + block.offset()); float rot = players[0].angleTo(x * tilesize + block.offset(), y * tilesize + block.offset());
float len = 12f; float len = 12f;
Draw.color(Palette.accent.r * 0.8f,Palette.accent.g * 0.8f,Palette.accent.b * 0.8f); Draw.color(Palette.accentBack);
Draw.rect("icon-arrow", players[0].x + Angles.trnsx(rot, len), players[0].y + Angles.trnsy(rot, len), rot); Draw.rect("icon-arrow", players[0].x + Angles.trnsx(rot, len), players[0].y + Angles.trnsy(rot, len), rot);
Draw.color(Palette.accent); Draw.color(Palette.accent);
Draw.rect("icon-arrow", players[0].x + Angles.trnsx(rot, len), players[0].y + Angles.trnsy(rot, len) + 1f, rot); Draw.rect("icon-arrow", players[0].x + Angles.trnsx(rot, len), players[0].y + Angles.trnsy(rot, len) + 1f, rot);

View File

@@ -2,6 +2,7 @@ package io.anuke.mindustry.net;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.annotations.Annotations.Serialize; import io.anuke.annotations.Annotations.Serialize;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
@@ -11,8 +12,6 @@ public class Administration{
/**All player info. Maps UUIDs to info. This persists throughout restarts.*/ /**All player info. Maps UUIDs to info. This persists throughout restarts.*/
private ObjectMap<String, PlayerInfo> playerInfo = new ObjectMap<>(); private ObjectMap<String, PlayerInfo> playerInfo = new ObjectMap<>();
/**Maps UUIDs to trace infos. This is wiped when a player logs off.*/
private ObjectMap<String, TraceInfo> traceInfo = new ObjectMap<>();
private Array<String> bannedIPs = new Array<>(); private Array<String> bannedIPs = new Array<>();
public Administration(){ public Administration(){
@@ -41,9 +40,7 @@ public class Administration{
Settings.save(); Settings.save();
} }
/** /**Call when a player joins to update their information here.*/
* Call when a player joins to update their information here.
*/
public void updatePlayerJoined(String id, String ip, String name){ public void updatePlayerJoined(String id, String ip, String name){
PlayerInfo info = getCreateInfo(id); PlayerInfo info = getCreateInfo(id);
info.lastName = name; info.lastName = name;
@@ -53,17 +50,8 @@ public class Administration{
if(!info.ips.contains(ip, false)) info.ips.add(ip); if(!info.ips.contains(ip, false)) info.ips.add(ip);
} }
/** public boolean banPlayer(String uuid){
* Returns trace info by UUID. return banPlayerID(uuid) || banPlayerIP(getInfo(uuid).lastIP);
*/
public TraceInfo getTraceByID(String uuid){
if(!traceInfo.containsKey(uuid)) traceInfo.put(uuid, new TraceInfo(uuid));
return traceInfo.get(uuid);
}
public void clearTraces(){
traceInfo.clear();
} }
/** /**
@@ -86,9 +74,7 @@ public class Administration{
return true; return true;
} }
/** /**Bans a player by UUID; returns whether this player was already banned.*/
* Bans a player by UUID; returns whether this player was already banned.
*/
public boolean banPlayerID(String id){ public boolean banPlayerID(String id){
if(playerInfo.containsKey(id) && playerInfo.get(id).banned) if(playerInfo.containsKey(id) && playerInfo.get(id).banned)
return false; return false;
@@ -215,11 +201,13 @@ public class Administration{
return info.admin && usip.equals(info.adminUsid); return info.admin && usip.equals(info.adminUsid);
} }
public Array<PlayerInfo> findByName(String name, boolean last){ /**Finds player info by IP, UUID and name.*/
Array<PlayerInfo> result = new Array<>(); public ObjectSet<PlayerInfo> findByName(String name){
ObjectSet<PlayerInfo> result = new ObjectSet<>();
for(PlayerInfo info : playerInfo.values()){ for(PlayerInfo info : playerInfo.values()){
if(info.lastName.toLowerCase().equals(name.toLowerCase()) || (last && info.names.contains(name, false))){ if(info.lastName.toLowerCase().equals(name.toLowerCase()) || (info.names.contains(name, false))
|| info.ips.contains(name, false) || info.id.equals(name)){
result.add(info); result.add(info);
} }
} }
@@ -287,8 +275,6 @@ public class Administration{
public String adminUsid; public String adminUsid;
public int timesKicked; public int timesKicked;
public int timesJoined; public int timesJoined;
public int totalBlockPlaced;
public int totalBlocksBroken;
public boolean banned, admin; public boolean banned, admin;
public long lastKicked; //last kicked timestamp public long lastKicked; //last kicked timestamp

View File

@@ -17,13 +17,14 @@ import io.anuke.mindustry.net.Streamable.StreamBuilder;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.BiConsumer; import io.anuke.ucore.function.BiConsumer;
import io.anuke.ucore.function.Consumer; import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log; import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Pooling; import io.anuke.ucore.util.Pooling;
import io.anuke.ucore.util.Threads;
import java.io.IOException; import java.io.IOException;
import static io.anuke.mindustry.Vars.headless; import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.ui;
public class Net{ public class Net{
private static boolean server; private static boolean server;
@@ -46,15 +47,43 @@ public class Net{
return serverProvider != null; return serverProvider != null;
} }
/** /**Display a network error. Call on the graphics thread.*/
* Display a network error. public static void showError(Throwable e){
*/
public static void showError(String text){
if(!headless){ if(!headless){
ui.showError(text); Threads.assertGraphics();
}else{
Log.err(text); Throwable t = e;
while(t.getCause() != null){
t = t.getCause();
}
String error = t.getMessage() == null ? "" : t.getMessage().toLowerCase();
String type = error.getClass().toString().toLowerCase();
if(error.equals("mismatch")){
error = Bundles.get("text.error.mismatch");
}else if(error.contains("port out of range") || error.contains("invalid argument") || (error.contains("invalid") && error.contains("address"))){
error = Bundles.get("text.error.invalidaddress");
}else if(error.contains("connection refused") || error.contains("route to host") || type.contains("unknownhost")){
error = Bundles.get("text.error.unreachable");
}else if(type.contains("timeout")){
error = Bundles.get("text.error.timeout");
}else if(error.equals("alreadyconnected")){
error = Bundles.get("text.error.alreadyconnected");
}else if(!error.isEmpty()){
error = Bundles.get("text.error.any");
}
ui.showText("", Bundles.format("text.connectfail", error));
ui.loadfrag.hide();
if(Net.client()){
netClient.disconnectQuietly();
}
} }
Log.err(e);
} }
/** /**
@@ -77,14 +106,18 @@ public class Net{
/** /**
* Connect to an address. * Connect to an address.
*/ */
public static void connect(String ip, int port) throws IOException{ public static void connect(String ip, int port, Runnable success){
lastIP = ip + ":" + port; try{
if(!active){ lastIP = ip + ":" + port;
clientProvider.connect(ip, port); if(!active){
active = true; clientProvider.connect(ip, port, success);
server = false; active = true;
}else{ server = false;
throw new IOException("Already connected!"); }else{
throw new IOException("alreadyconnected");
}
}catch(IOException e){
showError(e);
} }
} }
@@ -132,7 +165,7 @@ public class Net{
} }
/** /**
* Starts discovering servers on a different thread. Does not work with GWT. * Starts discovering servers on a different thread.
* Callback is run on the main libGDX thread. * Callback is run on the main libGDX thread.
*/ */
public static void discoverServers(Consumer<Host> cons, Runnable done){ public static void discoverServers(Consumer<Host> cons, Runnable done){
@@ -346,7 +379,7 @@ public class Net{
/**Client implementation.*/ /**Client implementation.*/
public interface ClientProvider{ public interface ClientProvider{
/**Connect to a server.*/ /**Connect to a server.*/
void connect(String ip, int port) throws IOException; void connect(String ip, int port, Runnable success) throws IOException;
/**Send an object to the server.*/ /**Send an object to the server.*/
void send(Object object, SendMode mode); void send(Object object, SendMode mode);

View File

@@ -6,6 +6,9 @@ public abstract class NetConnection{
public final int id; public final int id;
public final String address; public final String address;
public boolean modclient;
public boolean mobile;
public int lastSentSnapshotID = -1; public int lastSentSnapshotID = -1;
/**ID of last recieved client snapshot.*/ /**ID of last recieved client snapshot.*/

View File

@@ -73,6 +73,7 @@ public class NetworkIO{
if(tile.entity.liquids != null) tile.entity.liquids.write(stream); if(tile.entity.liquids != null) tile.entity.liquids.write(stream);
if(tile.entity.cons != null) tile.entity.cons.write(stream); if(tile.entity.cons != null) tile.entity.cons.write(stream);
tile.entity.writeConfig(stream);
tile.entity.write(stream); tile.entity.write(stream);
}else if(tile.block() == Blocks.air){ }else if(tile.block() == Blocks.air){
int consecutives = 0; int consecutives = 0;
@@ -229,6 +230,7 @@ public class NetworkIO{
if(tile.entity.liquids != null) tile.entity.liquids.read(stream); if(tile.entity.liquids != null) tile.entity.liquids.read(stream);
if(tile.entity.cons != null) tile.entity.cons.read(stream); if(tile.entity.cons != null) tile.entity.cons.read(stream);
tile.entity.readConfig(stream);
tile.entity.read(stream); tile.entity.read(stream);
}else if(wallid == 0){ }else if(wallid == 0){
int consecutives = stream.readUnsignedByte(); int consecutives = stream.readUnsignedByte();

View File

@@ -1,27 +0,0 @@
package io.anuke.mindustry.net;
import com.badlogic.gdx.utils.IntIntMap;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.world.Block;
public class TraceInfo{
public int playerid;
public String ip;
public boolean modclient;
public boolean android;
public IntIntMap fastShots = new IntIntMap();
public int totalBlocksBroken;
public int structureBlocksBroken;
public Block lastBlockBroken = Blocks.air;
public int totalBlocksPlaced;
public Block lastBlockPlaced = Blocks.air;
public String uuid;
public TraceInfo(String uuid){
this.uuid = uuid;
}
}

View File

@@ -13,6 +13,7 @@ public class BorderImage extends Image{
private float thickness = 3f; private float thickness = 3f;
public BorderImage(){ public BorderImage(){
} }
public BorderImage(Texture texture){ public BorderImage(Texture texture){

View File

@@ -3,6 +3,7 @@ package io.anuke.mindustry.ui;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.ItemStack;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.function.Supplier; import io.anuke.ucore.function.Supplier;
import io.anuke.ucore.scene.ui.Image; import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.layout.Stack; import io.anuke.ucore.scene.ui.layout.Stack;
@@ -14,7 +15,7 @@ public class ItemImage extends Stack{
public ItemImage(TextureRegion region, Supplier<CharSequence> text){ public ItemImage(TextureRegion region, Supplier<CharSequence> text){
Table t = new Table().left().bottom(); Table t = new Table().left().bottom();
t.label(text).color(Color.DARK_GRAY).padBottom(-20).get().setFontScale(Unit.dp.scl(0.5f)); t.label(text).color(Color.DARK_GRAY).padBottom(-Core.skin.font().getData().capHeight * 2).get().setFontScale(Unit.dp.scl(0.5f));
t.row(); t.row();
t.label(text).get().setFontScale(Unit.dp.scl(0.5f)); t.label(text).get().setFontScale(Unit.dp.scl(0.5f));
@@ -25,7 +26,7 @@ public class ItemImage extends Stack{
public ItemImage(ItemStack stack){ public ItemImage(ItemStack stack){
Table t = new Table().left().bottom(); Table t = new Table().left().bottom();
t.add(stack.amount + "").color(Color.DARK_GRAY).padBottom(-20).get().setFontScale(Unit.dp.scl(0.5f)); t.add(stack.amount + "").color(Color.DARK_GRAY).padBottom(-Core.skin.font().getData().capHeight * 2).get().setFontScale(Unit.dp.scl(0.5f));
t.row(); t.row();
t.add(stack.amount + "").get().setFontScale(Unit.dp.scl(0.5f)); t.add(stack.amount + "").get().setFontScale(Unit.dp.scl(0.5f));

View File

@@ -20,8 +20,6 @@ public class AdminsDialog extends FloatingDialog{
private void setup(){ private void setup(){
content().clear(); content().clear();
if(gwt) return;
float w = 400f, h = 80f; float w = 400f, h = 80f;
Table table = new Table(); Table table = new Table();

View File

@@ -21,8 +21,6 @@ public class BansDialog extends FloatingDialog{
private void setup(){ private void setup(){
content().clear(); content().clear();
if(gwt) return;
float w = 400f, h = 80f; float w = 400f, h = 80f;
Table table = new Table(); Table table = new Table();

View File

@@ -3,6 +3,7 @@ package io.anuke.mindustry.ui.dialogs;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Scaling;
import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.Difficulty;
import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.Map;
@@ -48,7 +49,7 @@ public class CustomGameDialog extends FloatingDialog{
modes.marginBottom(5); modes.marginBottom(5);
for(GameMode mode : GameMode.values()){ for(GameMode mode : GameMode.values()){
if(mode.hidden || (mode.isPvp && gwt)) continue; if(mode.hidden) continue;
modes.addButton("$mode." + mode.name() + ".name", "toggle", () -> state.mode = mode) modes.addButton("$mode." + mode.name() + ".name", "toggle", () -> state.mode = mode)
.update(b -> b.setChecked(state.mode == mode)).group(group).size(140f, 54f).padBottom(-5); .update(b -> b.setChecked(state.mode == mode)).group(group).size(140f, 54f).padBottom(-5);
@@ -106,6 +107,7 @@ public class CustomGameDialog extends FloatingDialog{
image.label((() -> Bundles.format("text.level.highscore", Settings.getInt("hiscore" + map.name, 0)))).pad(3f); image.label((() -> Bundles.format("text.level.highscore", Settings.getInt("hiscore" + map.name, 0)))).pad(3f);
BorderImage border = new BorderImage(map.texture, 3f); BorderImage border = new BorderImage(map.texture, 3f);
border.setScaling(Scaling.fit);
image.replaceImage(border); image.replaceImage(border);
image.clicked(() -> { image.clicked(() -> {

View File

@@ -21,15 +21,13 @@ import io.anuke.ucore.util.Pooling;
import java.util.Arrays; import java.util.Arrays;
import static io.anuke.mindustry.Vars.gwt;
public class FileChooser extends FloatingDialog{ public class FileChooser extends FloatingDialog{
public static Predicate<FileHandle> pngFilter = file -> file.extension().equalsIgnoreCase("png"); public static Predicate<FileHandle> pngFilter = file -> file.extension().equalsIgnoreCase("png");
public static Predicate<FileHandle> mapFilter = file -> file.extension().equalsIgnoreCase(Vars.mapExtension); public static Predicate<FileHandle> mapFilter = file -> file.extension().equalsIgnoreCase(Vars.mapExtension);
public static Predicate<FileHandle> jpegFilter = file -> file.extension().equalsIgnoreCase("png") || file.extension().equalsIgnoreCase("jpg") || file.extension().equalsIgnoreCase("jpeg"); public static Predicate<FileHandle> jpegFilter = file -> file.extension().equalsIgnoreCase("png") || file.extension().equalsIgnoreCase("jpg") || file.extension().equalsIgnoreCase("jpeg");
public static Predicate<FileHandle> defaultFilter = file -> true; public static Predicate<FileHandle> defaultFilter = file -> true;
private Table files; private Table files;
private FileHandle homeDirectory = gwt ? Gdx.files.internal("") : Gdx.files.absolute(OS.isMac ? OS.getProperty("user.home") + "/Downloads/" : private FileHandle homeDirectory = Gdx.files.absolute(OS.isMac ? OS.getProperty("user.home") + "/Downloads/" :
Gdx.files.getExternalStoragePath()); Gdx.files.getExternalStoragePath());
private FileHandle directory = homeDirectory; private FileHandle directory = homeDirectory;
private ScrollPane pane; private ScrollPane pane;
@@ -175,7 +173,7 @@ public class FileChooser extends FloatingDialog{
Arrays.sort(handles, (a, b) -> { Arrays.sort(handles, (a, b) -> {
if(a.isDirectory() && !b.isDirectory()) return -1; if(a.isDirectory() && !b.isDirectory()) return -1;
if(!a.isDirectory() && b.isDirectory()) return 1; if(!a.isDirectory() && b.isDirectory()) return 1;
return a.name().toUpperCase().compareTo(b.name().toUpperCase()); return String.CASE_INSENSITIVE_ORDER.compare(a.name(), b.name());
}); });
return handles; return handles;
} }

View File

@@ -18,7 +18,6 @@ import io.anuke.ucore.scene.ui.layout.Cell;
import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.utils.UIUtils; import io.anuke.ucore.scene.utils.UIUtils;
import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Strings; import io.anuke.ucore.util.Strings;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -248,16 +247,14 @@ public class JoinDialog extends FloatingDialog{
} }
void refreshLocal(){ void refreshLocal(){
if(!Vars.gwt){ totalHosts = 0;
totalHosts = 0;
local.clear(); local.clear();
local.background((Drawable)null); local.background((Drawable)null);
local.table("button", t -> { local.table("button", t -> {
t.label(() -> "[accent]" + Bundles.get("text.hosts.discovering") + Strings.animated(4, 10f, ".")).pad(10f); t.label(() -> "[accent]" + Bundles.get("text.hosts.discovering") + Strings.animated(4, 10f, ".")).pad(10f);
}).growX(); }).growX();
Net.discoverServers(this::addLocalHost, this::finishLocalHosts); Net.discoverServers(this::addLocalHost, this::finishLocalHosts);
}
} }
void finishLocalHosts(){ void finishLocalHosts(){
@@ -300,34 +297,11 @@ public class JoinDialog extends FloatingDialog{
}); });
Timers.runTask(2f, () -> { Timers.runTask(2f, () -> {
try{ Vars.netClient.beginConnecting();
Vars.netClient.beginConnecting(); Net.connect(ip, port, () -> {
Net.connect(ip, port);
hide(); hide();
add.hide(); add.hide();
}catch(Exception e){ });
Throwable t = e;
while(t.getCause() != null){
t = t.getCause();
}
//TODO localize
String error = t.getMessage() == null ? "" : t.getMessage().toLowerCase();
if(error.contains("connection refused")){
error = "connection refused";
}else if(error.contains("port out of range")){
error = "invalid port!";
}else if(error.contains("invalid argument")){
error = "invalid IP or port!";
}else if(t.getClass().toString().toLowerCase().contains("sockettimeout")){
error = "timed out!\nmake sure the host has port forwarding set up,\nand that the address is correct!";
}else{
error = Strings.parseException(e, false);
}
ui.showError(Bundles.format("text.connectfail", error));
ui.loadfrag.hide();
Log.err(e);
}
}); });
} }

View File

@@ -1,6 +1,5 @@
package io.anuke.mindustry.ui.dialogs; package io.anuke.mindustry.ui.dialogs;
import io.anuke.mindustry.core.Platform;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
import io.anuke.ucore.scene.ui.ButtonGroup; import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ScrollPane; import io.anuke.ucore.scene.ui.ScrollPane;
@@ -31,7 +30,7 @@ public class LanguageDialog extends FloatingDialog{
ButtonGroup<TextButton> group = new ButtonGroup<>(); ButtonGroup<TextButton> group = new ButtonGroup<>();
for(Locale loc : locales){ for(Locale loc : locales){
TextButton button = new TextButton(Platform.instance.getLocaleName(loc), "toggle"); TextButton button = new TextButton(loc.getDisplayName(loc), "toggle");
button.clicked(() -> { button.clicked(() -> {
if(getLocale().equals(loc)) return; if(getLocale().equals(loc)) return;
Settings.putString("locale", loc.toString()); Settings.putString("locale", loc.toString());

View File

@@ -86,28 +86,27 @@ public class LoadDialog extends FloatingDialog{
}); });
}).size(14 * 3).right(); }).size(14 * 3).right();
if(!gwt){ t.addImageButton("icon-save", "empty", 14 * 3, () -> {
t.addImageButton("icon-save", "empty", 14 * 3, () -> { if(!ios){
if(!ios){ Platform.instance.showFileChooser(Bundles.get("text.save.export"), "Mindustry Save", file -> {
Platform.instance.showFileChooser(Bundles.get("text.save.export"), "Mindustry Save", file -> {
try{
slot.exportFile(file);
setup();
}catch(IOException e){
ui.showError(Bundles.format("text.save.export.fail", Strings.parseException(e, false)));
}
}, false, saveExtension);
}else{
try{ try{
FileHandle file = Gdx.files.local("save-" + slot.getName() + "." + Vars.saveExtension);
slot.exportFile(file); slot.exportFile(file);
Platform.instance.shareFile(file); setup();
}catch(Exception e){ }catch(IOException e){
ui.showError(Bundles.format("text.save.export.fail", Strings.parseException(e, false))); ui.showError(Bundles.format("text.save.export.fail", Strings.parseException(e, false)));
} }
}, false, saveExtension);
}else{
try{
FileHandle file = Gdx.files.local("save-" + slot.getName() + "." + Vars.saveExtension);
slot.exportFile(file);
Platform.instance.shareFile(file);
}catch(Exception e){
ui.showError(Bundles.format("text.save.export.fail", Strings.parseException(e, false)));
} }
}).size(14 * 3).right(); }
} }).size(14 * 3).right();
}).padRight(-10).growX(); }).padRight(-10).growX();
@@ -153,7 +152,7 @@ public class LoadDialog extends FloatingDialog{
slots.row(); slots.row();
if(gwt || ios) return; if(ios) return;
slots.addImageTextButton("$text.save.import", "icon-add", "clear", 14 * 3, () -> { slots.addImageTextButton("$text.save.import", "icon-add", "clear", 14 * 3, () -> {
Platform.instance.showFileChooser(Bundles.get("text.save.import"), "Mindustry Save", file -> { Platform.instance.showFileChooser(Bundles.get("text.save.import"), "Mindustry Save", file -> {

View File

@@ -93,7 +93,7 @@ public class MapsDialog extends FloatingDialog{
button.row(); button.row();
button.addImage("white").growX().pad(4).color(Color.GRAY); button.addImage("white").growX().pad(4).color(Color.GRAY);
button.row(); button.row();
((Image) button.stack(new Image(map.texture), new BorderImage(map.texture)).size(mapsize - 20f).get().getChildren().first()).setScaling(Scaling.fit); button.stack(new Image(map.texture).setScaling(Scaling.fit), new BorderImage(map.texture).setScaling(Scaling.fit)).size(mapsize - 20f);
button.row(); button.row();
button.add(map.custom ? "$text.custom" : "$text.builtin").color(Color.GRAY).padTop(3); button.add(map.custom ? "$text.custom" : "$text.builtin").color(Color.GRAY).padTop(3);
@@ -114,7 +114,7 @@ public class MapsDialog extends FloatingDialog{
float mapsize = UIUtils.portrait() ? 160f : 300f; float mapsize = UIUtils.portrait() ? 160f : 300f;
Table table = dialog.content(); Table table = dialog.content();
((Image) table.stack(new Image(map.texture), new BorderImage(map.texture)).size(mapsize).get().getChildren().first()).setScaling(Scaling.fit); table.stack(new Image(map.texture).setScaling(Scaling.fit), new BorderImage(map.texture).setScaling(Scaling.fit)).size(mapsize);
table.table("clear", desc -> { table.table("clear", desc -> {
desc.top(); desc.top();

View File

@@ -61,25 +61,14 @@ public class PausedDialog extends FloatingDialog{
content().addButton("$text.settings", ui.settings::show); content().addButton("$text.settings", ui.settings::show);
content().row(); content().row();
content().addButton("$text.savegame", () -> { content().addButton("$text.savegame", save::show).disabled(s -> world.getSector() != null);
save.show();
}).disabled(s -> world.getSector() != null);
content().row(); content().row();
content().addButton("$text.loadgame", () -> { content().addButton("$text.loadgame", load::show).disabled(b -> Net.active());
load.show();
}).disabled(b -> Net.active());
content().row(); content().row();
content().addButton("$text.hostserver", () -> { content().addButton("$text.hostserver", ui.host::show).disabled(b -> Net.active());
if(!gwt){
ui.host.show();
}else{
ui.showInfo("$text.web.unsupported");
}
}).disabled(b -> Net.active());
content().row(); content().row();

Some files were not shown because too many files have changed in this diff Show More