Removed shadow/world padding
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 230 B |
Binary file not shown.
|
Before Width: | Height: | Size: 106 B After Width: | Height: | Size: 167 B |
@@ -263,7 +263,7 @@ text.mapeditor = Map Editor
|
||||
text.donate = Donate
|
||||
|
||||
text.connectfail = [crimson]Failed to connect to server\:\n\n[accent]{0}
|
||||
text.error.unreachable = Server unreachable.
|
||||
text.error.unreachable = Server unreachable.\nIs the address spelled correctly?
|
||||
text.error.invalidaddress = Invalid address.
|
||||
text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct!
|
||||
text.error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry!
|
||||
@@ -372,6 +372,7 @@ setting.musicvol.name = Music Volume
|
||||
setting.mutemusic.name = Mute Music
|
||||
setting.sfxvol.name = SFX Volume
|
||||
setting.mutesound.name = Mute Sound
|
||||
setting.crashreport.name = Send Anonymous Crash Reports
|
||||
text.keybind.title = Rebind Keys
|
||||
category.general.name = General
|
||||
category.view.name = View
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,13 +7,13 @@ text.link.dev-builds.description = Versiones de desarrollo inestable
|
||||
text.link.trello.description = Tablero de Trello oficial para las características planificadas
|
||||
text.link.itch.io.description = itch.io es la página donde podes descargar las versiones para PC y web
|
||||
text.link.google-play.description = Ficha en la Google Play Store
|
||||
text.link.wiki.description = wiki oficial de Mindustry
|
||||
text.link.wiki.description = Wiki oficial de Mindustry
|
||||
text.linkfail = ¡Error al abrir el enlace!\nLa URL ha sido copiada a su portapapeles.
|
||||
text.editor.web = ¡La versión web no es compatible con el editor!\nDescargue el juego para usarlo.
|
||||
text.editor.web = ¡La versión web no es compatible con el editor!\nDescarga el juego para usarlo.
|
||||
text.web.unsupported = ¡La versión web no soporta esta característica! Descarga el juego para poder usarla.
|
||||
text.gameover = Tu núcleo ha sido destruido.
|
||||
text.gameover.pvp = El equipo[accent] {0}[] ha ganado!
|
||||
text.sector.gameover = Este sector ha sido perdido. ¿Re-instaurar?
|
||||
text.gameover.pvp = ¡El equipo[accent] {0}[] ha ganado!
|
||||
text.sector.gameover = Este sector ha sido perdido. ¿Re-desplegar?
|
||||
text.sector.retry = Reintentar
|
||||
text.highscore = [accent]¡Nueva mejor puntuación!
|
||||
text.wave.lasted = Duraste hasta la ronda [accent]{0}[].
|
||||
@@ -22,35 +22,35 @@ text.level.delete.title = Confirmar Eliminación
|
||||
text.map.delete = ¿Estás seguro que quieres borrar el mapa "[accent]{0}[]"?
|
||||
text.level.select = Selección de nivel
|
||||
text.level.mode = Modo de juego:
|
||||
text.construction.desktop = Los controles de la versión de escritorio han cambiado.\nPara deseleccionar un bloque o dejar de construir, [accent]usa la barra espaciadora[].
|
||||
text.construction.desktop = Los controles de la versión de escritorio han cambiado.\nPara deseleccionar un bloque o dejar de construir, [accent]usa la space tab[].
|
||||
text.construction.title = Guía de Construcción de Bloques
|
||||
text.construction = Acaba de seleccionar el [accent]modo de construcción de bloques[].\n\nPara empezar a colocar, simplemente presione en una localización valida cerca de su nave.\nCuando haya terminado de seleccionar algunos bloques, presiona la casilla para confirmar, y su nave empezara a construirlos.\n\n- [accent]Remueve bloques[] de tu selección presionando en ellos.\n- [accent]Cambia tu selección de lugar[] manteniendo y arrastrando cualquier bloque en la selección.\n- [accent]Coloca bloques en línea[] presionando y manteniendo en un espacio vacío, y arrastrando hacia cualquier dirección.\n- [accent]Cancela la construcción o selección[] presionando la X abajo a la izquierda.
|
||||
text.deconstruction.title = Guía de Deconstrucción de Bloques
|
||||
text.deconstruction = Acaba de seleccionar el [accent]modo de deconstrucción de bloques[].\n\nPara empezar a destruir, simplemente presione en un bloque cercano a su nave.\nCuando haya terminado de seleccionar algunos bloques, presiona la casilla para confirmar, y su nave empezara a de-construirlos.\n\n- [accent]Remueve bloques[] de tu selección presionando en ellos.\n- [accent]Remueve bloques en un area[] presionando y manteniendo en un espacio vacío, y arrastrando hacia cualquier dirección.\n- [accent]Cancela la deconstrucción o selección[] presionando la X abajo a la izquierda.
|
||||
text.showagain = No mostrar devuelta en la próxima sesión
|
||||
text.deconstruction = Acaba de seleccionar el [accent]modo de deconstrucción de blocks[].\n\nPara empezar a destruir, simplemente presione en un bloque cercano a su nave.\nCuando haya terminado de seleccionar algunos bloques, presiona la casilla para confirmar, y su nave empezara a de-construirlos.\n\n- [accent]Remueve bloques[] de tu selección presionando en ellos.\n- [accent]Remueve bloques en un area[] presionando y manteniendo en un espacio vacío, y arrastrando hacia cualquier dirección.\n- [accent]Cancela la deconstrucción o selección[] presionando la X abajo a la izquierda.
|
||||
text.showagain = No mostrar otra vez en la próxima sesión
|
||||
text.coreattack = < ¡El núcleo está bajo ataque! >
|
||||
text.unlocks = Desbloqueos
|
||||
text.savegame = Guardar Partida
|
||||
text.loadgame = Cargar Partida
|
||||
text.joingame = Unirse a la Partida
|
||||
text.addplayers = Agregar/Remover Jugadores
|
||||
text.addplayers = Agregar/Quitar Jugadores
|
||||
text.customgame = Partida personalizada
|
||||
text.sectors = Sectores
|
||||
text.sector = Sector: [LIGHT_GRAY]{0}
|
||||
text.sector.time = Tiempo: [LIGHT_GRAY]{0}
|
||||
text.sector.deploy = Desplegar
|
||||
text.sector.abandon = Abandonar
|
||||
text.sector.abandon.confirm = ¿Definitivamente quieres abandonar todo el progreso hecho en este sector?\n¡Esto no se puede deshacer!
|
||||
text.sector.resume = Resumir
|
||||
text.sector.abandon.confirm = ¿Realmente quieres abandonar todo el progreso hecho en este sector?\n¡Esto no se puede deshacer!
|
||||
text.sector.resume = Continuar
|
||||
text.sector.locked = [scarlet][[Incompleto]
|
||||
text.sector.unexplored = [accent][[Inexplorado]
|
||||
text.missions = Missions:[LIGHT_GRAY] {0}
|
||||
text.sector.unexplored = [accent][[No explorado]
|
||||
text.missions = Misiones:[LIGHT_GRAY] {0}
|
||||
text.mission = Misión:[LIGHT_GRAY] {0}
|
||||
text.mission.main = Misión Principal:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Información de la Misión
|
||||
text.mission.complete = ¡Misión completada!
|
||||
text.mission.complete.body = El Sector {0},{1} ha sido conquistado.
|
||||
text.mission.wave = Sobrevive [accent]{0}[] hordas.
|
||||
text.mission.wave = Sobrevive [accent]{0}/{1}[] hordas\nHordas en {2}
|
||||
text.mission.wave.enemies = Sobrevive[accent] {0}/{1} []hordas\n{2} Enemigas
|
||||
text.mission.wave.enemy = Sobrevive[accent] {0}/{1} []hordas\n{2} Enemigas
|
||||
text.mission.wave.menu = Sobrevive[accent] {0} []hordas
|
||||
@@ -58,11 +58,11 @@ text.mission.battle = Destruye la base enemiga.
|
||||
text.mission.resource.menu = Obtener {0} x{1}
|
||||
text.mission.resource = Obtén {0} x{1}
|
||||
text.mission.block = Crear {0}
|
||||
text.mission.unit = Crear {0} Unit
|
||||
text.mission.command = Enviar Comando {0} A Las Unidades
|
||||
text.mission.unit = Crear {0}
|
||||
text.mission.command = Envía Comando {0} a las unidades
|
||||
text.mission.linknode = Conecta nodo de energía
|
||||
text.mission.display = [accent]Misión:\n[LIGHT_GRAY]{0}
|
||||
text.mission.mech = Cambiar a mech[accent] {0}[]
|
||||
text.mission.mech = Cambiar a mecanoide[accent] {0}[]
|
||||
text.mission.create = Crear[accent] {0}[]
|
||||
text.none = <no hay>
|
||||
text.close = Cerrar
|
||||
@@ -82,24 +82,24 @@ text.server.closing = [accent]Cerrando servidor...
|
||||
text.server.kicked.kick = ¡Has sido expulsado del servidor!
|
||||
text.server.kicked.serverClose = El servidor ha cerrado.
|
||||
text.server.kicked.sectorComplete = Sector completado.
|
||||
text.server.kicked.sectorComplete.text = Tu misión ha sido completada.\nEl servidor ahora continuara con el próximo sector.
|
||||
text.server.kicked.sectorComplete.text = Tu misión ha sido completada.\nEl servidor ahora continuará con el próximo sector.
|
||||
text.server.kicked.clientOutdated = ¡Cliente desactualizado! ¡Actualiza tu juego!
|
||||
text.server.kicked.serverOutdated = ¡Servidor desactualizado! ¡Pídele al anfitrión que lo actualice!
|
||||
text.server.kicked.banned = Has sido baneado del servidor.
|
||||
text.server.kicked.recentKick = Has sido expulsado recientemente.\nEspera para poder conectarte de nuevo.
|
||||
text.server.kicked.nameInUse = Ya hay alguien con ese nombre\nen el servidor.
|
||||
text.server.kicked.nameInUse = Ya hay alguien con ese\nnombre en el servidor.
|
||||
text.server.kicked.nameEmpty = Tu nombre debe por lo menos contener un carácter o número.
|
||||
text.server.kicked.idInUse = ¡Ya estás en el servidor! Conectarse con dos cuentas no está permitido.
|
||||
text.server.kicked.customClient = Este servidor no soporta versiones personalizadas. Descarga una versión oficial.
|
||||
text.host.info = El botón [accent]hostear[] hostea un servidor en el puerto [scarlet]6567[]. \nCualquier persona en la misma [LIGHT_GRAY]wifi o red local[] debería poder ver tu servidor en la lista de servidores.\n\nSi quieres que cualquier persona se pueda conectar de cualquier lugar por IP, la [accent]asignación de puertos[] es requerida.\n\n[LIGHT_GRAY]Nota: Si alguien experimenta problemas conectándose a tu partida LAN, asegúrate de permitir a Mindustry acceso a tu red local mediante la configuración de tu firewall.
|
||||
text.join.info = Aquí, puedes escribir la [accent]IP de un servidor[] para conectarte, o descubrir servidores de [accent]red local[] para conectarte.\nLAN y WAN es soportado para jugar en multijugador.\n\n[LIGHT_GRAY]Nota: No hay una lista automática global de servidores; si quieres conectarte por IP, tendrás que preguntarle al anfitrión por la IP.
|
||||
text.host.info = El botón [accent]host[] hostea un servidor en el puerto [scarlet]6567[]. \nCualquier persona en la misma [LIGHT_GRAY]wifi o red local[] debería poder ver tu servidor en la lista de servidores.\n\nSi quieres que cualquier persona se pueda conectar de cualquier lugar por IP, la [accent]asignación de puertos[] es requerida.\n\n[LIGHT_GRAY]Nota: Si alguien experimenta problemas conectándose a tu partida LAN, asegúrate de permitir a Mindustry acceso a tu red local mediante la configuración de tu firewall.
|
||||
text.join.info = Aquí, puedes escribir la [accent]IP de un server[] para conectarte, o descubrir servidores de [accent]red local[] para conectarte.\nLAN y WAN es soportado para jugar en multijugador.\n\n[LIGHT_GRAY]Nota: No hay una lista automática global de servidores; si quieres conectarte por IP, tendrás que preguntarle al anfitrión por la IP.
|
||||
text.hostserver = Hostear Servidor
|
||||
text.hostserver.mobile = Hostear\nJuego
|
||||
text.host = Hostear
|
||||
text.hosting = [accent]Abriendo servidor...
|
||||
text.hosts.refresh = Actualizar
|
||||
text.hosts.discovering = Descubrir partidas LAN
|
||||
text.server.refreshing = Actualizando servidor
|
||||
text.server.refreshing = Actualizando servidor...
|
||||
text.hosts.none = [lightgray]¡No se han encontrado partidas LAN!
|
||||
text.host.invalid = [scarlet]No se ha podido conectar al anfitrión
|
||||
text.trace = Rastrear Jugador
|
||||
@@ -108,29 +108,29 @@ text.trace.ip = IP: [accent]{0}
|
||||
text.trace.id = ID Única: [accent]{0}
|
||||
text.trace.android = Cliente de Android: [accent]{0}
|
||||
text.trace.modclient = Cliente Personalizado: [accent]{0}
|
||||
text.trace.totalblocksbroken = Total de bloques removidos: [accent]{0}
|
||||
text.trace.structureblocksbroken = Bloques de estructura removidos: [accent]{0}
|
||||
text.trace.lastblockbroken = Último bloque removido: [accent]{0}
|
||||
text.trace.totalblocksbroken = Total de bloques quitados: [accent]{0}
|
||||
text.trace.structureblocksbroken = Bloques de estructura quitados: [accent]{0}
|
||||
text.trace.lastblockbroken = Último bloque quitado: [accent]{0}
|
||||
text.trace.totalblocksplaced = Total de bloques colocados: [accent]{0}
|
||||
text.trace.lastblockplaced = Último bloque colocado: [accent]{0}
|
||||
text.invalidid = ¡ID de cliente invalida! Envía un informe del error.
|
||||
text.server.bans = Bans
|
||||
text.invalidid = ¡ID de cliente inválida! Envía un informe del error.
|
||||
text.server.bans = Baneos
|
||||
text.server.bans.none = ¡Ningún usuario ha sido baneado!
|
||||
text.server.admins = Admins
|
||||
text.server.admins.none = ¡Ningún admin ha sido encontrado!
|
||||
text.server.admins = Administradores
|
||||
text.server.admins.none = ¡Ningún administrador ha sido encontrado!
|
||||
text.server.add = Agregar Servidor
|
||||
text.server.delete = ¿Estás seguro que quieres borrar este servidor?
|
||||
text.server.delete = ¿Estás seguro de querer borrar este servidor?
|
||||
text.server.hostname = Anfitrión: {0}
|
||||
text.server.edit = Editar Servidor
|
||||
text.server.outdated = [crimson]¡Servidor desactualizado![]
|
||||
text.server.outdated.client = [crimson]¡Cliente desactualizado![]
|
||||
text.server.version = [lightgray]Versión: {0}
|
||||
text.server.custombuild = [yellow]Versión personalizada
|
||||
text.confirmban = ¿Estás seguro que quieres banear este jugador?
|
||||
text.confirmkick = ¿Estás seguro que quieres expulsar este jugador?
|
||||
text.confirmunban = ¿Estás seguro que quieres desbanear este jugador?
|
||||
text.confirmadmin = ¿Estás seguro que quieres hacer admin a este jugador?
|
||||
text.confirmunadmin = ¿Estás seguro que quieres quitar los permisos de admin a este jugador?
|
||||
text.confirmban = ¿Estás seguro de querer banear este jugador?
|
||||
text.confirmkick = ¿Estás seguro de querer expulsar este jugador?
|
||||
text.confirmunban = ¿Estás seguro de querer desbanear este jugador?
|
||||
text.confirmadmin = ¿Estás seguro de querer hacer administrador a este jugador?
|
||||
text.confirmunadmin = ¿Estás seguro de querer quitar los permisos de administrador a este jugador?
|
||||
text.joingame.title = Unirse a la partida
|
||||
text.joingame.ip = IP:
|
||||
text.disconnect = Desconectado.
|
||||
@@ -138,29 +138,29 @@ text.disconnect.data = ¡Se ha fallado la carga de datos del mundo!
|
||||
text.connecting = [accent]Conectando...
|
||||
text.connecting.data = [accent]Cargando datos del mundo...
|
||||
text.server.port = Puerto:
|
||||
text.server.addressinuse = ¡La dirección está en uso!
|
||||
text.server.addressinuse = ¡La dirección ya está en uso!
|
||||
text.server.invalidport = ¡El número de puerto es invalido!
|
||||
text.server.error = [crimson]Error hosteando el servidor: [accent]{0}
|
||||
text.save.old = Este punto de guardado es para una versión más antigua de este juego, y ya no puede ser usada.\n\n[LIGHT_GRAY]Guardados con retrocompatibilidad serán completamente implementados en la versión 4.0.
|
||||
text.server.error = [crimson]Error hosteando el servidor: error [accent]{0}
|
||||
text.save.old = Este punto de guardado es de una versión más antigua de este juego, y ya no puede ser usada.\n\n[LIGHT_GRAY]La retrocmpatibilidad de los puntos de guardado estará completamente implementada en la versión 4.0.
|
||||
text.save.new = Nuevo Punto de Guardado
|
||||
text.save.overwrite = ¿Estás seguro que quieres sobrescribir\neste punto de guardado?
|
||||
text.save.overwrite = ¿Estás seguro de querer sobrescribir\neste punto de guardado?
|
||||
text.overwrite = Sobrescribir
|
||||
text.save.none = ¡No se ha encontrado ningún punto de guardado!
|
||||
text.saveload = [accent]Guardando...
|
||||
text.savefail = ¡No se ha podido guardar la partida!
|
||||
text.save.delete.confirm = ¿Estás seguro que quieres borrar este punto de guardado?
|
||||
text.save.delete.confirm = ¿Estás seguro de querer borrar este punto de guardado?
|
||||
text.save.delete = Borrar
|
||||
text.save.export = Exportar Punto de Guardado
|
||||
text.save.import.invalid = [accent]¡Este punto de guardado es invalido!
|
||||
text.save.import.fail = [crimson]Se ha fallado la importación del punto de guardado: [accent]{0}
|
||||
text.save.export.fail = [crimson]Se ha fallado la exportación del punto de guardado: [accent]{0}
|
||||
text.save.import.invalid = [accent]¡Este punto de guardado es inválido!
|
||||
text.save.import.fail = [crimson]La importación del punto de guardado ha fallado: error [accent]{0}
|
||||
text.save.export.fail = [crimson]La exportación del punto de guardado ha fallado: error [accent]{0}
|
||||
text.save.import = Importar Punto de Guardado
|
||||
text.save.newslot = Nombre del Punto de Guardado:
|
||||
text.save.rename = Renombrar
|
||||
text.save.rename.text = Nuevo nombre:
|
||||
text.selectslot = Selecciona un Punto de Guardado.
|
||||
text.slot = [accent]Casilla {0}
|
||||
text.save.corrupted = [accent]¡El punto de guardado está corrupto o es invalido!\nSi acabas de actualizar el juego, esto debe ser probablemente un cambio en el formato de guardado y [scarlet]no[] un error.
|
||||
text.save.corrupted = [accent]¡El punto de guardado está corrupto o es inválido!\nSi acabas de actualizar el juego, esto debe ser probablemente un cambio en el formato de guardado y[scarlet] no[] un error.
|
||||
text.sector.corrupted = [accent]El punto de guardado de este sector fue encontrado, pero su carga ha fallado.\nUn nuevo punto ha sido creado.
|
||||
text.empty = <vacío>
|
||||
text.on = Encendido
|
||||
@@ -169,7 +169,7 @@ text.save.autosave = Autoguardado: {0}
|
||||
text.save.map = Mapa: {0}
|
||||
text.save.wave = Horda {0}
|
||||
text.save.difficulty = Dificultad: {0}
|
||||
text.save.date = Ultima vez guardado: {0}
|
||||
text.save.date = Última vez guardado: {0}
|
||||
text.save.playtime = Tiempo de juego: {0}
|
||||
text.confirm = Confirmar
|
||||
text.delete = Borrar
|
||||
@@ -182,9 +182,9 @@ text.back = Atras
|
||||
text.quit.confirm = ¿Estás seguro de querer salir de la partida?
|
||||
text.changelog.title = Registro de Parches
|
||||
text.changelog.loading = Consiguiendo el registro de parches...
|
||||
text.changelog.error.android = [accent]¡Nota que el registro de parches a veces no funciona en Android 4.4 o inferior!\nEsto es por un error de Android interno.
|
||||
text.changelog.error.ios = [accent]El registro de parches no es actualmente soportado por iOS.
|
||||
text.changelog.error = [scarlet]¡Error consiguiendo el registro de parches!\nChequeá tu conexión a Internet.
|
||||
text.changelog.error.android = [accent]¡Nota: el registro de parches a veces no funciona en Android 4.4 o inferior!\nEsto es por un error interno de Android.
|
||||
text.changelog.error.ios = [accent]El registro de parches no está actualmente soportado para iOS.
|
||||
text.changelog.error = [scarlet]¡Error consiguiendo el registro de parches!\Comprueba tu conexión a Internet.
|
||||
text.changelog.current = [yellow][[Versión actual]
|
||||
text.changelog.latest = [accent][[Última version]
|
||||
text.loading = [accent]Cargando...
|
||||
@@ -192,7 +192,7 @@ text.saving = [accent]Guardando...
|
||||
text.wave = [accent]Horda {0}
|
||||
text.wave.waiting = Horda en {0}
|
||||
text.waiting = Esperando...
|
||||
text.waiting.players = Esperando por jugafores...
|
||||
text.waiting.players = Esperando jugadores...
|
||||
text.wave.enemies = [LIGHT_GRAY]{0} Enemigos Restantes
|
||||
text.wave.enemy = [LIGHT_GRAY]{0} Enemigo Restante
|
||||
text.loadimage = Cargar Imagen
|
||||
@@ -200,11 +200,11 @@ text.saveimage = Guardar Imagen
|
||||
text.unknown = Desconocido
|
||||
text.custom = Personalizado
|
||||
text.builtin = Incorporado
|
||||
text.map.delete.confirm = ¿Estás seguro que quieres borrar este mapa? ¡Recuerda que está acción no puede ser descartada!
|
||||
text.map.delete.confirm = ¿Estás seguro de querer borrar este mapa? ¡Recuerda que está acción no puede sdeshacerse!
|
||||
text.map.random = [accent]Mapa Aleatorio
|
||||
text.map.nospawn = ¡Este mapa no tiene ningún núcleo en el cual pueda meter al jugador! Agrega un núcleo [ROYAL]azul[] al mapa con el editor.
|
||||
text.map.nospawn.pvp = ¡Este mapa no tiene ningún núcleo enemigo para que aparezca el jugador! Añade [SCARLET] red[] núcleos a este mapa en el editor.
|
||||
text.map.invalid = Error cargando el mapa: corrupto o archivo invalido.
|
||||
text.map.nospawn = ¡Este mapa no tiene ningún núcleo en el cual pueda aparecer el jugador! Agrega un núcleo[ROYAL] blue[] al mapa con el editor.
|
||||
text.map.nospawn.pvp = ¡Este mapa no tiene ningún núcleo enemigo para que aparezca el jugador! Añade un núcleo[SCARLET] red[] a este mapa en el editor.
|
||||
text.map.invalid = Error cargando el mapa: archivo corrupto o inválido.
|
||||
text.editor.brush = Pincel
|
||||
text.editor.slope = \\
|
||||
text.editor.openin = Abrir en el Editor
|
||||
@@ -216,15 +216,15 @@ text.editor.description = Descripción:
|
||||
text.editor.name = Nombre:
|
||||
text.editor.teams = Equipos
|
||||
text.editor.elevation = Elevación
|
||||
text.editor.errorimageload = Error cargando el archivo:\n[accent]{0}
|
||||
text.editor.errorimagesave = Error guardando el archivo:\n[accent]{0}
|
||||
text.editor.errorimageload = Error cargando el archivo:\n[accent] {0}
|
||||
text.editor.errorimagesave = Error guardando el archivo:\n[accent] {0}
|
||||
text.editor.generate = Generar
|
||||
text.editor.resize = Cambiar Tamaño
|
||||
text.editor.loadmap = Cargar Mapa
|
||||
text.editor.savemap = Guardar Mapa
|
||||
text.editor.saved = ¡Guardado!
|
||||
text.editor.save.noname = ¡Tu mapa no tiene un nombre! Pon uno en el menú 'Info del Mapa'.
|
||||
text.editor.save.overwrite = ¡Tu mapa sobrescribe uno ya incorporado! Elige un nombre diferente en el menu 'Info del Mapa'.
|
||||
text.editor.save.overwrite = ¡Tu mapa sobrescribe uno ya incorporado! Elige un nombre diferente en el menú 'Info del Mapa'.
|
||||
text.editor.import.exists = [scarlet]¡No se ha podido importar:[] un mapa incorporado con el nombre '{0}' ya existe!
|
||||
text.editor.import = Importar...
|
||||
text.editor.importmap = Importar Mapa
|
||||
@@ -240,14 +240,14 @@ text.editor.exportimage = Exportar Imagen del Terreno
|
||||
text.editor.exportimage.description = Exportar archivo de imagen del mapa
|
||||
text.editor.loadimage = Importar Terreno
|
||||
text.editor.saveimage = Exportar Terreno
|
||||
text.editor.unsaved = [scarlet]¡Tienes cambios sin guardar![]\n¿Estás seguro que quieres salir?
|
||||
text.editor.unsaved = [scarlet]¡Tienes cambios sin guardar![]\n¿Estás seguro de querer salir?
|
||||
text.editor.resizemap = Cambiar Tamaño del Mapa
|
||||
text.editor.mapname = Nombre del Mapa:
|
||||
text.editor.overwrite = [accent]¡Advertencia!\nEsto sobrescribe un mapa ya existente.
|
||||
text.editor.overwrite.confirm = [scarlet]¡Advertencia![] Un mapa con ese nombre ya existe. ¿Estás seguro que quieres sobrescribirlo?
|
||||
text.editor.overwrite.confirm = [scarlet]¡Advertencia![] Un mapa con ese nombre ya existe. ¿Estás seguro de querer sobrescribirlo?
|
||||
text.editor.selectmap = Selecciona un mapa para cargar:
|
||||
text.width = Ancho:
|
||||
text.height = Altura:
|
||||
text.height = Alto:
|
||||
text.menu = Menu
|
||||
text.play = Jugar
|
||||
text.load = Cargar
|
||||
@@ -264,7 +264,7 @@ text.donate = Donar
|
||||
text.connectfail = [crimson]Ha fallado la conexión con el servidor: [accent]{0}
|
||||
text.error.unreachable = Servidor inaccesible.
|
||||
text.error.invalidaddress = Dirección inválida.
|
||||
text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct!
|
||||
text.error.timedout = ¡Se acabó el tiempo!\n¡Asegúrate que el host ha hecho el port forwarding, y que la dirección es correcta!
|
||||
text.error.mismatch = Error de paquete:\nposible versión no válida del servidor/cliente.\nAsegúrate de que tú y el host tenéis la última versión de Mindustry.
|
||||
text.error.alreadyconnected = Ya estás conectado.
|
||||
text.error.mapnotfound = ¡Archivo de mapa no encontrado!
|
||||
@@ -277,17 +277,17 @@ text.settings.game = Juego
|
||||
text.settings.sound = Sonido
|
||||
text.settings.graphics = Gráficos
|
||||
text.settings.cleardata = Limpiar Datos del Juego...
|
||||
text.settings.clear.confirm = ¿Estas seguro de querer limpiar estos datos?\nEsta accion no puede deshacerse!
|
||||
text.settings.clearall.confirm = [scarlet]ADVERTENCIA![]\nEsto va a eliminar todos tus datos, incluyendo saves, mapas, desbloqueos y keybinds.\nUna vez presiones 'ok' el juego va a borrrar todos tus datos y a salir del juego automáticamente.
|
||||
text.settings.clear.confirm = ¿Estas seguro de querer limpiar estos datos?\n¡Esta acción no puede deshacerse!
|
||||
text.settings.clearall.confirm = [scarlet]ADVERTENCIA![]\nEsto va a eliminar todos tus datos, incluyendo guardados, mapas, desbloqueos y keybinds.\nUna vez presiones 'ok', el juego va a borrrar todos tus datos y saldrá del juego automáticamente.
|
||||
text.settings.clearsectors = Limpiar Sectores
|
||||
text.settings.clearunlocks = Limpiar Desbloqueos
|
||||
text.settings.clearall = Limpiar Todo
|
||||
text.paused = Pausado
|
||||
text.yes = Si
|
||||
text.yes = Sí
|
||||
text.no = No
|
||||
text.info.title = [accent]Información
|
||||
text.error.title = [crimson]Un error ha ocurrido
|
||||
text.error.crashtitle = Un error ha ocurrido
|
||||
text.error.title = [crimson]Un error ha ocurrido.
|
||||
text.error.crashtitle = Un error ha ocurrido.
|
||||
text.blocks.blockinfo = Información del Bloque
|
||||
text.blocks.powercapacity = Capacidad de Energía
|
||||
text.blocks.powershot = Energía/Disparo
|
||||
@@ -311,7 +311,7 @@ text.blocks.inputliquidaux = Líquido Auxiliar
|
||||
text.blocks.inputitem = Objeto de Entrada
|
||||
text.blocks.inputitems = Objetos de Entrada
|
||||
text.blocks.outputitem = Objeto de Salida
|
||||
text.blocks.drilltier = Taladrable
|
||||
text.blocks.drilltier = Taladrables
|
||||
text.blocks.drillspeed = Velocidad de Base del Taladro
|
||||
text.blocks.liquidoutput = Líquido de Salida
|
||||
text.blocks.liquidoutputspeed = Velocidad de Salida del Líquido
|
||||
@@ -326,7 +326,7 @@ text.blocks.inaccuracy = Imprecisión
|
||||
text.blocks.shots = Disparos
|
||||
text.blocks.reload = Recarga
|
||||
text.blocks.inputfuel = Combustible
|
||||
text.blocks.fuelburntime = Tiempo de Quema del Combustible
|
||||
text.blocks.fuelburntime = Tiempo de Quemado del Combustible
|
||||
text.blocks.inputcapacity = Capacidad de entrada
|
||||
text.blocks.outputcapacity = Capacidad de salida
|
||||
text.unit.blocks = bloques
|
||||
@@ -346,7 +346,7 @@ text.category.items = Objetos
|
||||
text.category.crafting = Fabricación
|
||||
text.category.shooting = Disparo
|
||||
setting.autotarget.name = Auto apuntado
|
||||
setting.fpscap.name = Max FPS
|
||||
setting.fpscap.name = Máx FPS
|
||||
setting.fpscap.none = Nada
|
||||
setting.fpscap.text = {0} FPS
|
||||
setting.difficulty.training = entrenamiento
|
||||
@@ -361,28 +361,28 @@ setting.sensitivity.name = Sensibilidad del Control
|
||||
setting.saveinterval.name = Intervalo del Auto-guardado
|
||||
setting.seconds = {0} Segundos
|
||||
setting.fullscreen.name = Pantalla Completa
|
||||
setting.multithread.name = Multihilo
|
||||
setting.multithread.name = Multiproceso
|
||||
setting.fps.name = Mostrar FPS
|
||||
setting.vsync.name = VSync
|
||||
setting.lasers.name = Mostrar Energía de los Lasers
|
||||
setting.lasers.name = Mostrar Energía de los Láseres
|
||||
setting.minimap.name = Mostrar Minimapa
|
||||
setting.musicvol.name = Volumen de la Musica
|
||||
setting.mutemusic.name = Mutear Musica
|
||||
setting.musicvol.name = Volumen de la Música
|
||||
setting.mutemusic.name = Silenciar Musica
|
||||
setting.sfxvol.name = Volumen de los efectos de sonido
|
||||
setting.mutesound.name = Mutear Sonido
|
||||
setting.mutesound.name = Silenciar Sonido
|
||||
text.keybind.title = Reasignar Teclas
|
||||
category.general.name = General
|
||||
category.view.name = Visión
|
||||
category.multiplayer.name = Multijugador
|
||||
command.attack = Atacar
|
||||
command.retreat = Retirada
|
||||
command.retreat = Retirarse
|
||||
command.patrol = Patrullar
|
||||
keybind.press = Presiona una tecla...
|
||||
keybind.press.axis = Pulsa un eje o botón...
|
||||
keybind.move_x.name = Mover x
|
||||
keybind.move_y.name = Mover y
|
||||
keybind.select.name = Seleccionar
|
||||
keybind.break.name = Remover
|
||||
keybind.break.name = Romper
|
||||
keybind.deselect.name = Deseleccionar
|
||||
keybind.shoot.name = Disparar
|
||||
keybind.zoom_hold.name = Mantener Zoom
|
||||
@@ -402,9 +402,9 @@ keybind.drop_unit.name = drop unit
|
||||
keybind.zoom_minimap.name = Zoom minimapa
|
||||
mode.text.help.title = Descripción de modos
|
||||
mode.waves.name = hordas
|
||||
mode.waves.description = el modo normal. con recursos limitados y entrada de hordas automática.
|
||||
mode.waves.description = El modo normal. con recursos limitados y entrada de hordas automática.
|
||||
mode.sandbox.name = sandbox
|
||||
mode.sandbox.description = recursos ilimitados y no hay temporizador para las hordas.
|
||||
mode.sandbox.description = Recursos ilimitados y sin temporizador para las hordas.
|
||||
mode.custom.warning = Ten en cuenta que los bloques no pueden usarse en partidas personalizadas hasta que se desbloqueen en sectores.\n\n[LIGHT_GRAY]Si no desbloqueaste ningún bloque, ningno aparecerá.
|
||||
mode.custom.warning.read = Solo para asegurar que lo has leído:\n[scarlet]¡LOS DESBLOQUEOS EN PARTIDAS PERSONALIZADAS NO ESTÁN DISPONIBLES EN LOS SECTORES U OTROS MODOS DE JUEGO!\n\n[LIGHT_GRAY](Ojalá esto no fuera necesario, pero parece que lo es)
|
||||
mode.freebuild.name = construcción libre
|
||||
@@ -451,33 +451,33 @@ liquid.lava.name = Lava
|
||||
liquid.oil.name = Petróleo
|
||||
liquid.cryofluid.name = Criogénico
|
||||
mech.alpha-mech.name = Alpha
|
||||
mech.alpha-mech.weapon = Heavy Repeater
|
||||
mech.alpha-mech.weapon = Repetidor Pesado
|
||||
mech.alpha-mech.ability = Drone Swarm
|
||||
mech.alpha-mech.description = The standard mech. Has decent speed and damage output; can create up to 3 drones for increased offensive capability.
|
||||
mech.alpha-mech.description = El mecanoide estándar. Tiene velocidad y daño decentes, puede crear hasta 3 drones para poder ofensivo incremenado.
|
||||
mech.delta-mech.name = Delta
|
||||
mech.delta-mech.weapon = Arc Generator
|
||||
mech.delta-mech.ability = Discharge
|
||||
mech.delta-mech.description = A fast, lightly-armored mech made for hit-and-run attacks. Does little damage against structures, but can kill large groups of enemy units very quickly with its arc lightning weapons.
|
||||
mech.delta-mech.weapon = Generador de arco
|
||||
mech.delta-mech.ability = Descarga
|
||||
mech.delta-mech.description = Un mecanoide rápido y ligeramente armado para ataques de ataque y retirada. Hace poco daño a estructuras, pero puede eliminar rápidamente a grandes grupos de unidades con sus armas de arco eléctrico.
|
||||
mech.tau-mech.name = Tau
|
||||
mech.tau-mech.weapon = Restruct Laser
|
||||
mech.tau-mech.weapon = Láser de reestructuración
|
||||
mech.tau-mech.ability = Repair Burst
|
||||
mech.tau-mech.description = The support mech. Heals allied blocks by shooting at them. Can extinguish fires and heal allies in a radius with its repair ability.
|
||||
mech.tau-mech.description = El mecanoide de soporte. Repara bloques aliados disparándolos. Puede extinguir el fuego y reparar aliados en un rango con su habilidad de reparación.
|
||||
mech.omega-mech.name = Omega
|
||||
mech.omega-mech.weapon = Swarm Missiles
|
||||
mech.omega-mech.ability = Armored Configuration
|
||||
mech.omega-mech.description = A bulky and well-armored mech, made for front-line assaults. Its armor ability can block up to 90% of incoming damage.
|
||||
mech.dart-ship.name = Dart
|
||||
mech.dart-ship.weapon = Repeater
|
||||
mech.omega-mech.description = Un mecanoide grande y bien armado, hecho para asaltos en primera línea. Su habilidad de armadura puede bloquear hasta el 90% del daño que recibe.
|
||||
mech.dart-ship.name = Dardo
|
||||
mech.dart-ship.weapon = Repetidor
|
||||
mech.dart-ship.description = La nave normal. Bastante ligera y rápida, pero tiene poca capacidad ofensiva y baja velocidad minado.
|
||||
mech.javelin-ship.name = Jabalina
|
||||
mech.javelin-ship.description = A hit-and-run strike ship. While initially slow, it can accelerate to great speeds and fly by enemy outposts, dealing large amounts of damage with its lightning ability and missiles.
|
||||
mech.javelin-ship.description = Una nave de ataque y retirada. Aunque inicialmente lento, puede acelerar a altas velocidades y volar sobre puestos enemigos, causando gran daño con su habilidad de rayos y misiles.
|
||||
mech.javelin-ship.weapon = Burst Missiles
|
||||
mech.javelin-ship.ability = Discharge Booster
|
||||
mech.trident-ship.name = Tridente
|
||||
mech.trident-ship.description = A heavy bomber. Reasonably well armored.
|
||||
mech.trident-ship.description = Un bombardero pesado. Razonablemente bien equipado.
|
||||
mech.trident-ship.weapon = Bomb Bay
|
||||
mech.glaive-ship.name = Glaive
|
||||
mech.glaive-ship.description = A large, well-armored gunship. Equipped with an incendiary repeater. Good acceleration and maximum speed.
|
||||
mech.glaive-ship.description = Una nave pistolera grande y bien armada. Equipada con un repetidor incendiario. Buena aceleración y velocidad máxima.
|
||||
mech.glaive-ship.weapon = Flame Repeater
|
||||
text.item.explosiveness = [LIGHT_GRAY]Explosividad: {0}
|
||||
text.item.flammability = [LIGHT_GRAY]Inflamabilidad: {0}
|
||||
@@ -557,14 +557,14 @@ block.pneumatic-drill.name = Taladro neumático
|
||||
block.laser-drill.name = Taladro Laser
|
||||
block.water-extractor.name = Extractor de Agua
|
||||
block.cultivator.name = Cultivador
|
||||
block.alpha-mech-pad.name = Alpha Mech Pad
|
||||
block.dart-ship-pad.name = Dart Ship Pad
|
||||
block.delta-mech-pad.name = Delta Mech Pad
|
||||
block.javelin-ship-pad.name = Javelin Ship Pad
|
||||
block.trident-ship-pad.name = Trident Ship Pad
|
||||
block.alpha-mech-pad.name = Pad de mecanoide Alpha
|
||||
block.dart-ship-pad.name = Pad de nave de dardos
|
||||
block.delta-mech-pad.name = Pad de mecanoide Delta
|
||||
block.javelin-ship-pad.name = Pad de nave Jabalina
|
||||
block.trident-ship-pad.name = Pad de nave Tridente
|
||||
block.glaive-ship-pad.name = Glaive Ship Pad
|
||||
block.omega-mech-pad.name = Omega Mech Pad
|
||||
block.tau-mech-pad.name = Tau Mech Pad
|
||||
block.omega-mech-pad.name = Pad de mecanoide Omega
|
||||
block.tau-mech-pad.name = Pad de mecanoide Tau
|
||||
block.conduit.name = Conducto
|
||||
block.mechanical-pump.name = Bomba Mecánica
|
||||
block.itemsource.name = Objeto Fuente
|
||||
@@ -587,12 +587,12 @@ block.solidifer.name = Solidificador
|
||||
block.solar-panel.name = Panel Solar
|
||||
block.solar-panel-large.name = Panel Solar Grande
|
||||
block.oil-extractor.name = Extractor de Petróleo
|
||||
block.spirit-factory.name = Spirit Drone Factory
|
||||
block.phantom-factory.name = Phantom Drone Factory
|
||||
block.spirit-factory.name = Fábrica de Drones Espíritu
|
||||
block.phantom-factory.name = Fábrica de Drones Fantasmales
|
||||
block.wraith-factory.name = Wraith Fighter Factory
|
||||
block.ghoul-factory.name = Ghoul Bomber Factory
|
||||
block.dagger-factory.name = Dagger Mech Factory
|
||||
block.titan-factory.name = Titan Mech Factory
|
||||
block.dagger-factory.name = Fábrica de Dagas
|
||||
block.titan-factory.name = Fábrica de Titanes
|
||||
block.fortress-factory.name = Fortress Mech Factory
|
||||
block.revenant-factory.name = Revenant Fighter Factory
|
||||
block.repair-point.name = Punto de Reparación
|
||||
@@ -610,7 +610,7 @@ block.blast-drill.name = Taladro Gigante
|
||||
block.thermal-pump.name = Bomba Térmica
|
||||
block.thermal-generator.name = Generador Térmico
|
||||
block.alloy-smelter.name = Alloy Smtler
|
||||
block.mend-projector.name = Mend Projector
|
||||
block.mend-projector.name = Proyector de reparación
|
||||
block.surge-wall.name = Surge Wall
|
||||
block.surge-wall-large.name = Large Surge Wall
|
||||
block.cyclone.name = Ciclón
|
||||
@@ -622,30 +622,30 @@ block.arc.name = Arc
|
||||
block.rtg-generator.name = Generador RTG
|
||||
block.spectre.name = Spectre
|
||||
block.meltdown.name = Meltdown
|
||||
block.container.name = Container
|
||||
block.container.name = Contenedor
|
||||
team.blue.name = azul
|
||||
team.red.name = rojo
|
||||
team.orange.name = naranja
|
||||
team.none.name = gris
|
||||
team.green.name = verde
|
||||
team.purple.name = púrpura
|
||||
unit.alpha-drone.name = Alpha Drone
|
||||
unit.spirit.name = Spirit Drone
|
||||
unit.alpha-drone.name = Dron Alpha
|
||||
unit.spirit.name = Dron Espíritu
|
||||
unit.spirit.description = El dron del comienzo. Aparece en el núcleo por defecto. Mina automáticamente minerales, recoge objetos y repara bloques.
|
||||
unit.phantom.name = Phantom Drone
|
||||
unit.phantom.name = Dron Fantasmal
|
||||
unit.phantom.description = Un dron avanzado. Mina automáticamente minerales, recoge objetos y repra bloques. Bastante más efectivo que un dron normal.
|
||||
unit.dagger.name = Daga
|
||||
unit.dagger.description = Una unidad de terreno. Útil con enjambres.
|
||||
unit.titan.name = Titán
|
||||
unit.titan.description = Una unidad blindada de terreno, avanzada. Ataca blancos de aire y de terreno.
|
||||
unit.ghoul.name = Ghoul Bomber
|
||||
unit.ghoul.description = A heavy carpet bomber. Uses blast compound or pyratite as ammo.
|
||||
unit.ghoul.description = Una unidad bombardera pesada. Usa compuesto explosivo o pirotita como munición.
|
||||
unit.wraith.name = Wraith Fighter
|
||||
unit.wraith.description = A fast, hit-and-run interceptor unit.
|
||||
unit.wraith.description = Una unidad interceptora rápida.
|
||||
unit.fortress.name = Fortress
|
||||
unit.fortress.description = A heavy artillery ground unit.
|
||||
unit.fortress.description = Una unidad terrestre pesada de artillería.
|
||||
unit.revenant.name = Revenant
|
||||
unit.revenant.description = A heavy laser platform.
|
||||
unit.revenant.description = Una plataforma láser pesada.
|
||||
tutorial.begin = Tu objetivo aquí es erradicar el[LIGHT_GRAY] enemy[].\n\nComienza[accent]minando copper[]. Toca una veta de cobre cerca de tu núcleo para hacer esto.
|
||||
tutorial.drill = Minar manualmente es ineficiente.\nLos [accent]taladros pueden minar automáticamente.\nColoca uno en una veta de cobre.
|
||||
tutorial.conveyor = Los [accent]Conveyors[] se usan para transportar objetos al núcleo.\nConstruye una línea de transportadores del taladro al núcleo.
|
||||
@@ -667,53 +667,53 @@ tutorial.daggerfactory = Construye una[accent] dagger mech factory[].\n\nEsto se
|
||||
tutorial.router = Las fábricas necesitan recursos para funcionar.\nCrea un enrutador para separar recursos del transportador.
|
||||
tutorial.dagger = Conecta nodos de energía a la fábrica.\nUna vez las necesidades se cumplan, una unidad será creada.\n\nCrea taladros, generadores y transportadores según necesites.
|
||||
tutorial.battle = El[LIGHT_GRAY] enemy[] ha revelado su núcleo.\nDestrúyelo con tu nave y tus unidades de combate.
|
||||
block.copper-wall.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.
|
||||
block.copper-wall-large.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.\nSpans multiple tiles.
|
||||
block.dense-alloy-wall.description = A standard defensive block.\nAdequate protection from enemies.
|
||||
block.dense-alloy-wall-large.description = A standard defensive block.\nAdequate protection from enemies.\nSpans multiple tiles.
|
||||
block.thorium-wall.description = A strong defensive block.\nGood protection from enemies.
|
||||
block.thorium-wall-large.description = A strong defensive block.\nGood protection from enemies.\nSpans multiple tiles.
|
||||
block.phase-wall.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful.
|
||||
block.phase-wall-large.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful.\nSpans multiple tiles.
|
||||
block.surge-wall.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.
|
||||
block.surge-wall-large.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.\nSpans multiple tiles.
|
||||
block.door.description = A small door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through.
|
||||
block.door-large.description = A large door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through.\nSpans multiple tiles.
|
||||
block.mend-projector.description = Periodically heals buildings in its vicinity.
|
||||
block.overdrive-projector.description = Increases the speed of nearby buildings like drills and conveyors.
|
||||
block.force-projector.description = Creates a hexagonal force field around itself, protecting buildings and units inside from damage through bullets.
|
||||
block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy.
|
||||
block.duo.description = A small, cheap turret.
|
||||
block.arc.description = A small turret which shoots electricity in a random arc towards the enemy.
|
||||
block.hail.description = A small artillery turret.
|
||||
block.lancer.description = A medium-sized turret which shoots charged electricity beams.
|
||||
block.wave.description = A medium-sized rapid-fire turret which shoots liquid bubbles.
|
||||
block.salvo.description = A medium-sized turret which fires shots in salvos.
|
||||
block.swarmer.description = A medium-sized turret which shoots burst missiles.
|
||||
block.ripple.description = A large artillery turret which fires several shots simultaneously.
|
||||
block.cyclone.description = A large rapid fire turret.
|
||||
block.fuse.description = A large turret which shoots powerful short-range beams.
|
||||
block.spectre.description = A large turret which shoots two powerful bullets at once.
|
||||
block.meltdown.description = A large turret which shoots powerful long-range beams.
|
||||
block.conveyor.description = Basic item transport block. Moved items forward and automatically deposits them into turrets or crafters. Rotatable.
|
||||
block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors.
|
||||
block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles.
|
||||
block.junction.description = Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations.
|
||||
block.mass-driver.description = Ultimate item transport block. Collects several items and then shoots them to another mass driver over a long range.
|
||||
block.smelter.description = Burns coal for smelting copper and lead into dense alloy.
|
||||
block.arc-smelter.description = Smelts copper and lead into dense alloy by using an external power source.
|
||||
block.copper-wall.description = Un bloque defensivo barato.\nÚtil para defneder e núcleo y las torres en las primeras hordas.
|
||||
block.copper-wall-large.description = Un bloque defensivo barato.\nÚtil para defneder e núcleo y las torres en las primeras hordas.\nOcupa múltiples casillas.
|
||||
block.dense-alloy-wall.description = Un bloque de defensa estándar.\nProtección adecuada contra enemigos.
|
||||
block.dense-alloy-wall-large.description = Un bloque de defensa estándar.\nProtección adecuada contra enemigos.\nOcupa múltiples casillas.
|
||||
block.thorium-wall.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos.
|
||||
block.thorium-wall-large.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos.\nOcupa múltiples casillas.
|
||||
block.phase-wall.description = No es tan fuerte como un muro de torio pero rebota balas al enemigo si no son demasiado fuertes.
|
||||
block.phase-wall-large.description = No es tan fuerte como un muro de torio pero rebota balas al enemigo si no son demasiado fuertes.\nOcupa múltiples casillas.
|
||||
block.surge-wall.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante.
|
||||
block.surge-wall-large.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante.\nOcupa múltiplies casillas.
|
||||
block.door.description = Una puerta pequeña que puede ser abierta y cerrada tocándola.\nSi está abirta, los enemigos pueden moverse y disparar a través de ella.\nOcupa múltiples casillas.
|
||||
block.door-large.description = Una puerta grande que puede ser abierta y cerrada tocándola.\nSi está abirta, los enemigos pueden moverse y disparar a través de ella.\nOcupa múltiples casillas.
|
||||
block.mend-projector.description = Regenera edificios cercanos periódcamente.
|
||||
block.overdrive-projector.description = Aumenta la velocidad de edificios cercanos como taladros y transportadores.
|
||||
block.force-projector.description = Crea un área de fuerza hexagonal alrededor de él, protegiendo edificios y unidades dentro de él del daño de las balas.
|
||||
block.shock-mine.description = Daña enemigos que pisan a mina. Casi invisible al enemigo.
|
||||
block.duo.description = Una torre pequeña y barata.
|
||||
block.arc.description = Una torre pequeña que disapra electricidad en un arco aleatorio al enemigo.
|
||||
block.hail.description = Una torre de artillería pequeña.
|
||||
block.lancer.description = Una torre de tamaño mediano que dispara rayos cargados eléctricamente.
|
||||
block.wave.description = Una torre de tamaño mediano que dispara burbujas de líquido.
|
||||
block.salvo.description = Una torre de tramaño mediano que dispara balas en salvos.
|
||||
block.swarmer.description = Una torre de tamaño mediano que dispara misiles en grupo.
|
||||
block.ripple.description = Una torre de artillería grande que dispara varios disparos simultáneamente.
|
||||
block.cyclone.description = Una torre de disparo rápido grande.
|
||||
block.fuse.description = Una torre grande que dispara rayos poderosos de corto alcance.
|
||||
block.spectre.description = Una torre grande que dispara dos balas poderosas de una vez.
|
||||
block.meltdown.description = Una torre grande que dispara rayos poderosos de largo alcance.
|
||||
block.conveyor.description = Bloque de transporte básico. Mueve objetos hacia adelante y los deposita automáticamente en torres o fábricas. Rotable.
|
||||
block.titanium-conveyor.description = Bloque de transporte avanzado. Mueve objetos más rápido que los transportadores estándar.
|
||||
block.phase-conveyor.description = Bloque de transporte avanzado. Usa energía para transportar objetos a otro transportador de fase conectado por varias casillas.
|
||||
block.junction.description = Actúa como puente para dos transportadores que se cruzan. Útil en situaciones con dos diferentes transportadores transportando diferentes materiales a diferentes lugares.
|
||||
block.mass-driver.description = El mejor bloque de transorte. Recoge varios objetos y los dispara a otro conductor de masa en un largo rango.
|
||||
block.smelter.description = Quema carbón para fundir cobre y plomo, produciendo así aleación densa.
|
||||
block.arc-smelter.description = Funde cobre y plomo en aleación densa usando una fuented de energía externa.
|
||||
block.silicon-smelter.description = Reduces sand with highly pure coke in order to produce silicon.
|
||||
block.plastanium-compressor.description = Produces plastanium from oil and titanium.
|
||||
block.plastanium-compressor.description = Produce plastanio con aceite y titanio.
|
||||
block.phase-weaver.description = Produces phase fabric from radioactive thorium and high amounts of sand.
|
||||
block.alloy-smelter.description = Produces surge alloy from titanium, lead, silicon and copper.
|
||||
block.pulverizer.description = Crushes stone into sand. Useful when there is a lack of natural sand.
|
||||
block.pyratite-mixer.description = Mixes coal, lead and sand into highly flammable pyratite.
|
||||
block.blast-mixer.description = Uses oil for transforming pyratite into the less flammable but more explosive blast compound.
|
||||
block.cryofluidmixer.description = Combines water and titanium into cryofluid which is much more efficient for cooling.
|
||||
block.solidifer.description = Cools lava to stone at a fast pace.
|
||||
block.melter.description = Heats up stone to very high temperatures to obtain lava.
|
||||
block.incinerator.description = Gets rid of any excess item or liquid.
|
||||
block.biomattercompressor.description = Compresses biomatter in order to retrieve oil.
|
||||
block.alloy-smelter.description = Produce "surge alloy" con titanio, plomo, silicona y cobre.
|
||||
block.pulverizer.description = Despedaza la piedra en arena. Útil cuando no hay arena natural.
|
||||
block.pyratite-mixer.description = Mezcla carbón, plomo y arena en pirotita altamente inflamable.
|
||||
block.blast-mixer.description = Usa aceite para transformar pirotita en un objeto menos inflamable pero más explosivo: compuesto explosivo.
|
||||
block.cryofluidmixer.description = Combina agua y titanio en líquido criogénico que es mucho más eficiente para enfriar.
|
||||
block.solidifer.description = Enfría la lava a piedra a una gran velocidad.
|
||||
block.melter.description = Calienta piedra a temperaturas muy altas para obtener lava.
|
||||
block.incinerator.description = Se deshace de cualquier líquido u objeto excesivo.
|
||||
block.biomattercompressor.description = Comprime biomateria para extraer aceite.
|
||||
block.separator.description = Expone piedra a la presión del agua para obtener diversos minerales contenidos en la piedra.
|
||||
block.centrifuge.description = Más eficiente que un separador, pero es más caro de construir y requiere energía.
|
||||
block.power-node.description = Transmite energía a nodos conectados, conecta hasta cuatro fuentes de energía, edificios que usan energía o nodos. El nodo obtendrá o transmitirá energía de cualquier bloque adyacente.
|
||||
@@ -733,47 +733,48 @@ block.vault.description = Almacena una gran cantidad de objetos. Úsalo para cre
|
||||
block.mechanical-drill.description = Un taladro barato. Cuando es colocado en casillas apropiadas, extrae objetos lentamente de forma indefinida.
|
||||
block.pneumatic-drill.description = Un taladro mejorado que es más rápido y puede obtener minerales más duros usando la presión.
|
||||
block.laser-drill.description = Permite obtener minerales incluso más rápido con la tecnología láser, pero requiere energía. Además, se puede obtener torio radioactivo con este taladro.
|
||||
block.blast-drill.description = The ultimate drill. Requires large amounts of power.
|
||||
block.blast-drill.description = El mejor taladro. Requiere grandes cantidades de energía.
|
||||
block.water-extractor.description = Extrae agua de la tierra. Úsalo cuando no haya lagos cercanos.
|
||||
block.cultivator.description = Cultiva la tierra para obtener biomateria.
|
||||
block.oil-extractor.description = Usa grandes cantidades de energía para extraer aceite de la arena. Úsalo cuando no hay fuentes directas de aceite cerca.
|
||||
block.dart-ship-pad.description = Leave your current vessel and change into a basic fighter aircraft.\nUse the pad by double tapping while standing on it.
|
||||
block.trident-ship-pad.description = Leave your current vessel and change into a reasonably well armored heavy bomber.\nUse the pad by double tapping while standing on it.
|
||||
block.javelin-ship-pad.description = Leave your current vessel and change into a strong and fast interceptor with lightning weapons.\nUse the pad by double tapping while standing on it.
|
||||
block.glaive-ship-pad.description = Leave your current vessel and change into a large, well-armored gunship.\nUse the pad by double tapping while standing on it.
|
||||
block.tau-mech-pad.description = Leave your current vessel and change into a support mech which can heal friendly buildings and units.\nUse the pad by double tapping while standing on it.
|
||||
block.dart-ship-pad.description = Deja tu nave actual y transfórmate en una unidad aérea básica.\nUsa el pad tocándolo dos veces mientras estás en él.
|
||||
block.trident-ship-pad.description = Deja tu nave actual y transfórmate en una unidad aérea bombardera pesada.\nUsa el pad tocándolo dos veces mientras estás en él.
|
||||
block.javelin-ship-pad.description = Deja tu nave actual y transfórmate en una unidad aérea fuerte y rápida interceptora con arma eléctrica.\nUsa el pad tocándolo dos veces mientras estás en él.
|
||||
block.glaive-ship-pad.description = Deja tu nave actual y transfórmate en una unidad aérea grande y bien armada nave pistolera.\nUsa el pad tocándolo dos veces mientras estás en él.
|
||||
block.tau-mech-pad.description = Deja tu nave actual y transfórmate en un mecanoide de soporte que puede reparar construcciones y tropas aliadas.\nUsa el pad tocándolo dos veces mientras estás en él.
|
||||
block.delta-mech-pad.description = Leave your current vessel and change into a fast, lightly-armored mech made for hit-and-run attacks.\nUse the pad by double tapping while standing on it.
|
||||
block.omega-mech-pad.description = Leave your current vessel and change into a bulky and well-armored mech, made for front-line assaults.\nUse the pad by double tapping while standing on it.
|
||||
Deja tu nave actual y transfórmate en un mecanoide rápido, con armas ligeras hecho para ataques de ataque y retirada.\nUsa el pad tocándolo dos veces mientras estás en él.
|
||||
block.omega-mech-pad.description = Deja tu nave actual y transfórmate en un mecanoide pesado y bien armado, hecho para asaltos en primera línea.\nUsa el pad tocándolo dos veces mientras estás en él.
|
||||
block.spirit-factory.description = Produce drones ligeros que obtienen minerales y reparan bloques.
|
||||
block.phantom-factory.description = Produces advanced drone units which are significantly more effective than a spirit drone.
|
||||
block.wraith-factory.description = Produces fast, hit-and-run interceptor units.
|
||||
block.ghoul-factory.description = Produces heavy carpet bombers.
|
||||
block.phantom-factory.description = Produce drones avanzados que son significativamente más eficientes que un dron espíritu.
|
||||
block.wraith-factory.description = Produce unidades aéreas rápidas e interceptoras.
|
||||
block.ghoul-factory.description = Produce unidadess bombarderas pesadas.
|
||||
block.dagger-factory.description = Produce unidades terrestres básicas.
|
||||
block.titan-factory.description = Produces advanced, armored ground units.
|
||||
block.fortress-factory.description = Produces heavy artillery ground units.
|
||||
block.revenant-factory.description = Produces heavy laser ground units.
|
||||
block.titan-factory.description = Produce unidades terrestres avanzadas.
|
||||
block.fortress-factory.description = Produce unidades terrestres de artillería pesada.
|
||||
block.revenant-factory.description = Produce unidades terrestres láser pesadas.
|
||||
block.repair-point.description = Repara la unidad dañada más cercana a su alrededor.
|
||||
block.command-center.description = Allows changing friendly AI behavior. Currently, attack, retreat and patrol commands are supported.
|
||||
block.conduit.description = Basic liquid transport block. Works like a conveyor, but with liquids. Best used with extractors, pumps or other conduits.
|
||||
block.pulse-conduit.description = Advanced liquid transport block. Transports liquids faster and stores more than standard conduits.
|
||||
block.phase-conduit.description = Advanced liquid transport block. Uses power to teleport liquids to a connected phase conduit over several tiles.
|
||||
block.liquid-router.description = Accepts liquids from one direction and outputs them to up to 3 other directions equally. Can also store a certain amount of liquid. Useful for splitting the liquids from one source to multiple targets.
|
||||
block.liquid-tank.description = Stores a large amount of liquids. Use it for creating buffers when there is a non-constant demand of materials or as a safeguard for cooling vital blocks.
|
||||
block.liquid-junction.description = Acts as a bridge for two crossing conduits. Useful in situations with two different conduits carrying different liquids to different locations.
|
||||
block.bridge-conduit.description = Advanced liquid transport block. Allows transporting liquids over up to 3 tiles of any terrain or building.
|
||||
block.mechanical-pump.description = A cheap pump with slow output, but no power consumption.
|
||||
block.rotary-pump.description = An advanced pump which doubles up speed by using power.
|
||||
block.thermal-pump.description = The ultimate pump. Three times as fast as a mechanical pump and the only pump which is able to retrieve lava.
|
||||
block.router.description = Accepts items from one direction and outputs them to up to 3 other directions equally. Useful for splitting the materials from one source to multiple targets.
|
||||
block.distributor.description = An advanced router which splits items to up to 7 other directions equally.
|
||||
block.bridge-conveyor.description = Advanced item transport block. Allows transporting items over up to 3 tiles of any terrain or building.
|
||||
block.alpha-mech-pad.description = When given enough power, rebuilds your ship into the[accent] Alpha[] mech.
|
||||
block.itemsource.description = Infinitely outputs items. Sandbox only.
|
||||
block.liquidsource.description = Infinitely outputs liquids. Sandbox only.
|
||||
block.itemvoid.description = Destroys any items which go into it without using power. Sandbox only.
|
||||
block.powerinfinite.description = Infinitely outputs power. Sandbox only.
|
||||
block.powervoid.description = Voids all power inputted into it. Sandbox only.
|
||||
liquid.water.description = Commonly used for cooling machines and waste processing.
|
||||
liquid.lava.description = Can be transformed into[LIGHT_GRAY] stone[], used for generating power or used as ammo for certain turrets.
|
||||
liquid.oil.description = Can be burnt, exploded or used as a coolant.
|
||||
liquid.cryofluid.description = The most efficient liquid for cooling things down.
|
||||
block.command-center.description = Permite cambiar el comportamiento de la IA aliada. Actualmente, atacar, retirarse y patrullar son los comandos soportados.
|
||||
block.conduit.description = Bloque de transporte de líquidos básico. Funciona como un transportador, pero con líquidos. Usado con bombas, extractores u otros conductos.
|
||||
block.pulse-conduit.description = Bloque de transporte de líquidos avanzado. Transporta líquidos más rápidamente y almacena más que los conductos estándar.
|
||||
block.phase-conduit.description = Bloque de transporte de líquidos avanzado. Usa energía para transportar líquidos a otro conducto de fase conectado por varias casillas.
|
||||
block.liquid-router.description = Acepta líquidos de una dirección y los deja en hasta 3 direcciones equitativamente. También puede amacenar cierta capacidad de líquido. Útil para dividir los líquidos de una fuente a varios objetivos.
|
||||
block.liquid-tank.description = Almacena una gran cantidad de líquidos. Úsalo para crear almacenes cuando no hay una demanda constante de materiales o para asegurarse de enfriar bloques vitales.
|
||||
block.liquid-junction.description = Actúa como un puente para dos condusctos que se cruzan. Útil en situaciones en las que hay dos conductos con líquidos diferentes a diferentes lugares.
|
||||
block.bridge-conduit.description = Bloque avanzado de transporte de líquidos. Permite transportar líquidos por encima hasta 3 casillas de cualquier terreno o construcción.
|
||||
block.mechanical-pump.description = Una bomba barata con extracción lenta, pero sin uso de energía.
|
||||
block.rotary-pump.description = Una bomba avanzada que duplica la velocidad usando energía.
|
||||
block.thermal-pump.description = La mejor bomba. Tres veces más rápido que la bomba mecánica, y la única bomba que puede extraer lava.
|
||||
block.router.description = Acepta objetos de una dirección y deja objetos equitativamente en hasta 3 direcciones diferentes. Útil para dividir los materiales de una fuente de recursos a múltiples objetivos.
|
||||
block.distributor.description = Un enrutador avanzado que distribuye objetos equitativamente en hasta otras 7 direcciones.
|
||||
block.bridge-conveyor.description = Bloque avanado de transporte. Puede transportar objetos por encima hasta 3 casillas de cualquier terreno o construcción.
|
||||
block.alpha-mech-pad.description = Cuando se le da suficiente energía, reconstruye tu nave en el mecanoide[accent] Alpha[].
|
||||
block.itemsource.description = Da objetos infinitos. Solo en sandbox.
|
||||
block.liquidsource.description = Da líquido infinito. Solo en sandbox.
|
||||
block.itemvoid.description = Destruye cuanquier objeto que va a él sin necesitar energía. Solo en sandbox.
|
||||
block.powerinfinite.description = Da energía infinita. Solo en sandbox.
|
||||
block.powervoid.description = Elimina toda la energía que se le da. Solo en sandbox.
|
||||
liquid.water.description = Usado comúnmente para enfriar máquinas y para procesar residuos.
|
||||
liquid.lava.description = Puede usarse para ser transformado en[LIGHT_GRAY] stone[], para generar energía o para munición de ciertas torres.
|
||||
liquid.oil.description = Puede ser quemado, explotado o como un enfriador.
|
||||
liquid.cryofluid.description = El líquido más eficiente pra enfriar las cosas.
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Mission Info
|
||||
text.mission.complete = Mission complete!
|
||||
text.mission.complete.body = Sector {0},{1} has been conquered.
|
||||
text.mission.wave = Survive [accent]{0}[] waves.
|
||||
text.mission.wave = Survive[accent] {0}/{1} []waves\nWave in {2}
|
||||
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
|
||||
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
|
||||
text.mission.wave.menu = Survive[accent] {0} []waves
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Mission Info
|
||||
text.mission.complete = Missione completata!
|
||||
text.mission.complete.body = Il settore {0},{1} è stato conquistato.
|
||||
text.mission.wave = Sopravvivi a [accent]{0}[] onda/e.
|
||||
text.mission.wave = Sopravvivi a [accent]{0}/{1][] onda/e.Onda in {2}
|
||||
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
|
||||
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
|
||||
text.mission.wave.menu = Survive[accent] {0} []waves
|
||||
@@ -13,22 +13,22 @@ text.editor.web = HTML5 버전은 에디터 기능을 지원하지 않습니다!
|
||||
text.web.unsupported = HTML5 버전은 이 기능을 지원하지 않습니다! 게임을 다운로드 한 뒤에 사용 해 주세요.
|
||||
text.gameover = 코어가 터졌습니다. 게임 오버!
|
||||
text.gameover.pvp = [accent]{0}[] 팀이 승리했습니다!
|
||||
text.sector.gameover = 이 구역을 공략하는데 실패했습니다. 다시 배치하시겠습니까?
|
||||
text.sector.retry = 다시할꺼임
|
||||
text.sector.gameover = 이 구역을 공략하는데 실패했습니다. 포기 하시겠습니까?
|
||||
text.sector.retry = 아니오
|
||||
text.highscore = [YELLOW]최고점수 달성!
|
||||
text.wave.lasted = [accent]{0}[] 까지 버티셨습니다.
|
||||
text.level.highscore = 최고 점수 : [accent]{0}
|
||||
text.level.delete.title = 삭제 확인
|
||||
text.map.delete = 정말로 "[accent]{0}[]" 맵을 삭제하시겠습니까?
|
||||
text.map.delete = 정말로 "[orange]{0}[]" 맵을 삭제하시겠습니까?
|
||||
text.level.select = 맵 선택
|
||||
text.level.mode = 게임모드 :
|
||||
text.construction.desktop = PC 에서의 조작 방법이 변경되었습니다.\n블록 선택을 해제하거나 건설을 중지하려면 [accent]스페이스 바[]를 누르세요.
|
||||
text.construction.title = 블록 배치 안내서
|
||||
text.construction = [accent]블록 배치 모드[]를 선택하셨습니다.\n\n블록을 설치하고 싶으면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 배치 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요. \n- [accent]블록을 넓게 배치[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록을 한줄로 배치[]하고 싶다면 배치하고 싶은 시작 영역을 한번 탭 하고 길게 누르면서 드래그 하면 됩니다. \n- [accent]블록 배치 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다.
|
||||
text.deconstruction.title = 블록 삭제 안내서
|
||||
text.deconstruction = [accent]블록 삭제 모드[]를 선택하셨습니다\n\n블록을 삭제하고 싶다면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 파괴 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요\n- [accent]블록을 넓은 범위로 삭제[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록 삭제 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다.
|
||||
text.deconstruction = [accent]블록 삭제 모드[]를 선택하셨습니다\n\n블록을 삭제하고 싶다면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 파괴 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요\n- [accent]블록을 넓은 범위로 삭제[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록 삭제 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다.
|
||||
text.showagain = 다음 세션에서 이 메세지를 표시하지 않습니다
|
||||
text.coreattack = < 코어가 공격받고 있습니다 ! >
|
||||
text.coreattack = < 코어가 공격받고 있습니다! >
|
||||
text.unlocks = 아이템들
|
||||
text.savegame = 게임 저장
|
||||
text.loadgame = 게임 불러오기
|
||||
@@ -50,20 +50,20 @@ text.mission.main = 주요 목표 : [LIGHT_GRAY]{0}
|
||||
text.mission.info = 미션 정보
|
||||
text.mission.complete = 미션 성공!
|
||||
text.mission.complete.body = 구역 {0},{1} 클리어.
|
||||
text.mission.wave = [accent]{0}[]단계가 될때까지 생존하세요.
|
||||
text.mission.wave.enemies = [accent] {0}/{1} []단계동안 생존하세요.\n{2}마리 남음
|
||||
text.mission.wave.enemy = [accent] {0}/{1} []단계동안 생존하세요.\n{2}마리 남음
|
||||
text.mission.wave = [accent]{0}/{1}[] 단계동안 생존하세요.남은 시간 {2}\n
|
||||
text.mission.wave.enemies = [accent] {0}/{1} []단계를 생존하세요.\n{2}마리 남음
|
||||
text.mission.wave.enemy = [accent] {0}/{1} []단계를 생존하세요.\n{2}마리 남음
|
||||
text.mission.wave.menu = [accent]{0}[] 단계
|
||||
text.mission.battle = 적 본부를 파괴하세요.
|
||||
text.mission.battle = 적 코어를 파괴하세요.
|
||||
text.mission.resource.menu = {0} {1}개 수집
|
||||
text.mission.resource = {0} 자원을 수집하세요 :\n[accent]{1}/{2}[]
|
||||
text.mission.block = 이것을 만드세요 :\n{0}
|
||||
text.mission.unit = 이 유닛을 만드세요 :\n{0}
|
||||
text.mission.command = 유닛에게 이 명령을 보내세요 :\n{0}
|
||||
text.mission.block = {0} 를 만드세요
|
||||
text.mission.unit = {0} 유닛을 만드세요
|
||||
text.mission.command = 유닛에게 {0} 명령을 보내세요
|
||||
text.mission.linknode = 전력 노드를 연결하세요.
|
||||
text.mission.display = [accent]미션 : \n[LIGHT_GRAY]{0}
|
||||
text.mission.mech = 이 기체로 바꾸세요 :\n[accent]{0}
|
||||
text.mission.create = 이 자원을 만드세요 :\n[accent]{0}
|
||||
text.mission.display = [accent]미션 :\n[LIGHT_GRAY]{0}
|
||||
text.mission.mech = [accent]{0}[] 기체로 바꾸세요
|
||||
text.mission.create = [accent]{0}[] 자원을 만드세요
|
||||
text.none = <없음>
|
||||
text.close = 닫기
|
||||
text.quit = 나가기
|
||||
@@ -91,12 +91,12 @@ text.server.kicked.nameInUse = 이 닉네임이 이미 서버에서 사용중입
|
||||
text.server.kicked.nameEmpty = 닉네임에는 반드시 영어 또는 숫자가 있어야 합니다.
|
||||
text.server.kicked.idInUse = 이미 서버에 접속중입니다! 다중 계정은 허용되지 않습니다.
|
||||
text.server.kicked.customClient = 이 서버는 직접 빌드한 버전을 지원하지 않습니다. 공식 버전을 사용하세요.
|
||||
text.host.info = [accent]호스트[] 버튼은 현재 네트워크의 [scarlet]6567[] 과 [scarlet]6568[] 포트를 사용합니다.\n[LIGHY_GRAY]같은 Wi-Fi 또는 로컬 네트워크[] 에서 서버 목록을 볼 수 있습니다.\n\n만약 플레이어들이 이 IP를 통해 어디에서나 연결할 수 있게 하고 싶다면, 공유기 설정에서 [accent]포트 포워딩[]을 해야 합니다.\n\n[LIGHT_GRAY]참고 : LAN 게임 연결에 문제가 있는 사람이 있다면, 방화벽 설정에서 Mindustry 가 로컬 네트워크에 액세스하도록 허용했는지 확인 해 주세요.
|
||||
text.host.info = [accent]호스트[] 버튼은 현재 네트워크의 [scarlet]6567[] 포트를 사용합니다.\n[LIGHY_GRAY]같은 Wi-Fi 또는 로컬 네트워크[] 에서 서버 목록을 볼 수 있습니다.\n\n만약 플레이어들이 이 IP를 통해 어디에서나 연결할 수 있게 하고 싶다면, 공유기 설정에서 [accent]포트 포워딩[]을 해야 합니다.\n\n[LIGHT_GRAY]참고 : LAN 게임 연결에 문제가 있는 사람이 있다면, 방화벽 설정에서 Mindustry 가 로컬 네트워크에 액세스하도록 허용했는지 확인 해 주세요.
|
||||
text.join.info = 여기서 [accent]서버 IP[]를 입력하여 다른 서버에 접속할 수 있습니다.\n또는 [accent]로컬 네트워크(LAN)[] 서버를 검색하여 접속할 수 있습니다.\nLAN 및 WAN 멀티 플레이어 모두 지원됩니다.\n\n[LIGHT_GRAY]참고:여기에서는 자동으로 글로벌 서버를 추가하지 않습니다. IP로 다른 사람의 서버에 접속할려면 서버장에게 IP를 요청해야 합니다.
|
||||
text.hostserver = 서버 열기
|
||||
text.hostserver.mobile = 게임\n호스트
|
||||
text.host = 호스트
|
||||
text.hosting = [accent]서버 여는중..
|
||||
text.hostserver.mobile = 서버\n열기
|
||||
text.host = 서버 열기
|
||||
text.hosting = [accent]서버 여는중...
|
||||
text.hosts.refresh = 새로고침
|
||||
text.hosts.discovering = LAN 게임 찾기
|
||||
text.server.refreshing = 서버 목록 새로고치는중...
|
||||
@@ -129,7 +129,7 @@ text.server.custombuild = [yellow]커스텀 서버
|
||||
text.confirmban = 이 플레이어를 차단하시겠습니까?
|
||||
text.confirmkick = 정말로 이 플레이어를 추방시키겠습니까?
|
||||
text.confirmunban = 이 플레이어를 차단해제 하시겠습니까?
|
||||
text.confirmadmin = 이 플레이어를 영자로 만들겠습니까?
|
||||
text.confirmadmin = 이 플레이어를 관리자로 만들겠습니까?
|
||||
text.confirmunadmin = 이 플레이어를 일반 유저로 만들겠습니까?
|
||||
text.joingame.title = 게임 참가
|
||||
text.joingame.ip = IP :
|
||||
@@ -140,7 +140,7 @@ text.connecting.data = [accent]맵 데이터 다운로드중...
|
||||
text.server.port = 포트 :
|
||||
text.server.addressinuse = 이 주소는 이미 사용중입니다!
|
||||
text.server.invalidport = 포트 번호가 잘못되었습니다.
|
||||
text.server.error = [crimson]{0}[accent]서버를 여는데 오류가 발생했습니다.[]
|
||||
text.server.error = [crimson]{0}[orange]서버를 여는데 오류가 발생했습니다.[]
|
||||
text.save.old = 이 저장파일은 이전 버전의 게임용이며, 지금은 사용할 수 없습니다. \n\n[LIGHT_GRAY]4.0 정식때 이전 게임버전에서 만든 저장파일과 호환됩니다.
|
||||
text.save.new = 새로 저장
|
||||
text.save.overwrite = 이 저장 슬롯을 덮어씌우겠습니까?
|
||||
@@ -151,17 +151,17 @@ text.savefail = 게임을 저장하지 못했습니다!
|
||||
text.save.delete.confirm = 이 저장파일을 삭제 하시겠습니까?
|
||||
text.save.delete = 삭제
|
||||
text.save.export = 저장파일 내보내기
|
||||
text.save.import.invalid = [accent]파일이 잘못되었습니다!
|
||||
text.save.import.fail = [crimson]저장파일을 불러오지 못함 : [accent]{0}
|
||||
text.save.export.fail = [crimson]저장파일을 내보내지 못함 : [accent]{0}
|
||||
text.save.import.invalid = [orange]파일이 잘못되었습니다!
|
||||
text.save.import.fail = [crimson]저장파일을 불러오지 못함 : [orange]{0}
|
||||
text.save.export.fail = [crimson]저장파일을 내보내지 못함 : [orange]{0}
|
||||
text.save.import = 저장파일 불러오기
|
||||
text.save.newslot = 저장 파일이름 :
|
||||
text.save.rename = 이름 변경
|
||||
text.save.rename.text = 새 이름 :
|
||||
text.selectslot = 저장슬롯을 선택하십시오.
|
||||
text.slot = [accent]{0}번째 슬롯
|
||||
text.save.corrupted = [accent]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[].
|
||||
text.sector.corrupted = [accent]저장 파일에서 구역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다.
|
||||
text.save.corrupted = [orange]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[].
|
||||
text.sector.corrupted = [orange]저장 파일에서 구역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다.
|
||||
text.empty = <비어있음>
|
||||
text.on = 켜기
|
||||
text.off = 끄기
|
||||
@@ -182,14 +182,14 @@ text.back = 뒤로가기
|
||||
text.quit.confirm = 정말로 종료하시겠습니까?
|
||||
text.changelog.title = 변경사항
|
||||
text.changelog.loading = 변경사항 가져오는중...
|
||||
text.changelog.error.android = [accent]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다.이것은 내부 Android 버그 때문입니다.
|
||||
text.changelog.error.ios = [accent]현재 iOS에서는 변경 사항을 지원하지 않습니다.
|
||||
text.changelog.error.android = [orange]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다. 이것은 내부 Android 버그 때문입니다.
|
||||
text.changelog.error.ios = [orange]현재 iOS에서는 변경 사항을 지원하지 않습니다.
|
||||
text.changelog.error = [scarlet]게임 변경사항을 가져오는 중 오류가 발생했습니다![]\n인터넷 연결을 확인하십시오.
|
||||
text.changelog.current = [accent][[현재 버전]
|
||||
text.changelog.latest = [accent][[최신 버전]
|
||||
text.changelog.current = [orange][[현재 버전]
|
||||
text.changelog.latest = [orange][[최신 버전]
|
||||
text.loading = [accent]불러오는중...
|
||||
text.saving = [accent]저장중...
|
||||
text.wave = [accent]{0}단계
|
||||
text.wave = [orange]{0}단계
|
||||
text.wave.waiting = 다음 단계 시작까지 {0}초
|
||||
text.waiting = [LIGHT_GRAY]대기중...
|
||||
text.waiting.players = 다른 플레이어를 기다리는 중..
|
||||
@@ -216,14 +216,14 @@ text.editor.description = 설명 :
|
||||
text.editor.name = 이름 :
|
||||
text.editor.teams = 팀
|
||||
text.editor.elevation = 지형 높이
|
||||
text.editor.errorimageload = [accent]{0}[] 파일을 불러오는데 오류가 발생했습니다.
|
||||
text.editor.errorimagesave = [accent]{0}[] 파일 저장중 오류가 발생했습니다.
|
||||
text.editor.errorimageload = [orange]{0}[] 파일을 불러오는데 오류가 발생했습니다.
|
||||
text.editor.errorimagesave = [orange]{0}[] 파일 저장중 오류가 발생했습니다.
|
||||
text.editor.generate = 생성
|
||||
text.editor.resize = 맵 크기조정
|
||||
text.editor.loadmap = 맵 불러오기
|
||||
text.editor.savemap = 맵 저장
|
||||
text.editor.saved = 저장됨!
|
||||
text.editor.save.noname = 지도에 이름이 없습니다! '맵 정보' 메뉴에서 설정하세요.
|
||||
text.editor.save.noname = 지도에 이름이 없습니다! 메뉴 -> '맵 정보' 에서 설정하세요.
|
||||
text.editor.save.overwrite = 이 맵의 이름은 기존에 있던 맵을 덮어씁니다! '맵 정보' 메뉴에서 다른 이름을 선택하세요.
|
||||
text.editor.import.exists = [scarlet]맵을 불러올 수 없음 : [] 기존에 있던 '{0}' 맵이 이미 존재합니다!
|
||||
text.editor.import = 가져오기
|
||||
@@ -261,7 +261,7 @@ text.tutorial = 게임 방법
|
||||
text.editor = 편집기
|
||||
text.mapeditor = 맵 편집기
|
||||
text.donate = 기부
|
||||
text.connectfail = [crimson]{0}[accent] 서버에 연결하지 못했습니다.[]
|
||||
text.connectfail = [crimson]{0}[orange] 서버에 연결하지 못했습니다.[]
|
||||
text.error.unreachable = 서버에 연결하지 못했습니다.
|
||||
text.error.invalidaddress = 잘못된 주소입니다.
|
||||
text.error.timedout = 시간 초과!\n서버에 포트 포워딩이 설정되어 있고 주소가 올바른지 확인하십시오.
|
||||
@@ -285,50 +285,50 @@ text.settings.clearall = 모두 초기화
|
||||
text.paused = 일시 정지
|
||||
text.yes = 예
|
||||
text.no = 아니오
|
||||
text.info.title = 정보
|
||||
text.info.title = [accent]정보
|
||||
text.error.title = [crimson]오류가 발생했습니다.
|
||||
text.error.crashtitle = 오류가 발생했습니다.
|
||||
text.blocks.blockinfo = 블록 정보
|
||||
text.blocks.powercapacity = 최대 전력 용량
|
||||
text.blocks.powershot = 1발당 전력 소모량
|
||||
text.blocks.targetsair = 공중공격 가능
|
||||
text.blocks.itemspeed = 유닛 이동 속도
|
||||
text.blocks.shootrange = 사거리
|
||||
text.blocks.size = 블록 크기
|
||||
text.blocks.liquidcapacity = 최대 액체 용량
|
||||
text.blocks.maxitemssecond = 최대 아이템 보관량
|
||||
text.blocks.powerrange = 전력 범위
|
||||
text.blocks.poweruse = 전력 사용
|
||||
text.blocks.powerdamage = 전력/데미지
|
||||
text.blocks.inputitemcapacity = 입력 아이템 용량
|
||||
text.blocks.outputitemcapacity = 출력 아이템 용량
|
||||
text.blocks.itemcapacity = 저장 용량
|
||||
text.blocks.basepowergeneration = 기지 전력 생성기
|
||||
text.blocks.powertransferspeed = 전력 전송량
|
||||
text.blocks.craftspeed = 생산 속도
|
||||
text.blocks.inputliquid = 사용되는 액체
|
||||
text.blocks.inputliquidaux = 보조 액체
|
||||
text.blocks.inputitem = 사용되는 아이템
|
||||
text.blocks.inputitems = 사용되는 아이템들
|
||||
text.blocks.outputitem = 출력 아이템
|
||||
text.blocks.drilltier = 드릴
|
||||
text.blocks.drillspeed = 기본 드릴 속도
|
||||
text.blocks.liquidoutput = 액체 출력
|
||||
text.blocks.liquidoutputspeed = 액체 출력속도
|
||||
text.blocks.liquiduse = 액체 사용량
|
||||
text.blocks.coolant = 냉각제
|
||||
text.blocks.coolantuse = 냉각수 사용
|
||||
text.blocks.inputliquidfuel = 연료 액
|
||||
text.blocks.liquidfueluse = 액체 연료 사용
|
||||
text.blocks.explosive = 이게 터지면 펑 터지면서 주변 블록에게 피해를 입힙니다!
|
||||
text.blocks.health = 체력
|
||||
text.blocks.inaccuracy = 오차각
|
||||
text.blocks.shots = 발포 횟수
|
||||
text.blocks.reload = 재장전
|
||||
text.blocks.inputfuel = 연료
|
||||
text.blocks.fuelburntime = 연료 연소 시간
|
||||
text.blocks.inputcapacity = 입력 용량
|
||||
text.blocks.outputcapacity = 출력 용량
|
||||
text.blocks.powercapacity = 최대 전력 용량
|
||||
text.blocks.powershot = 1발당 전력 소모량
|
||||
text.blocks.targetsair = 공중공격 가능
|
||||
text.blocks.itemspeed = 유닛 이동 속도
|
||||
text.blocks.shootrange = 사거리
|
||||
text.blocks.size = 블록 크기
|
||||
text.blocks.liquidcapacity = 최대 액체 용량
|
||||
text.blocks.maxitemssecond = 최대 아이템 보관량
|
||||
text.blocks.powerrange = 전력 범위
|
||||
text.blocks.poweruse = 전력 사용
|
||||
text.blocks.powerdamage = 전력/데미지
|
||||
text.blocks.inputitemcapacity = 입력 아이템 용량
|
||||
text.blocks.outputitemcapacity = 출력 아이템 용량
|
||||
text.blocks.itemcapacity = 저장 용량
|
||||
text.blocks.basepowergeneration = 기지 전력 생성기
|
||||
text.blocks.powertransferspeed = 전력 전송량
|
||||
text.blocks.craftspeed = 생산 속도
|
||||
text.blocks.inputliquid = 사용되는 액체
|
||||
text.blocks.inputliquidaux = 보조 액체
|
||||
text.blocks.inputitem = 사용되는 아이템
|
||||
text.blocks.inputitems = 사용되는 아이템들
|
||||
text.blocks.outputitem = 출력 아이템
|
||||
text.blocks.drilltier = 드릴
|
||||
text.blocks.drillspeed = 기본 드릴 속도
|
||||
text.blocks.liquidoutput = 액체 출력
|
||||
text.blocks.liquidoutputspeed = 액체 출력속도
|
||||
text.blocks.liquiduse = 액체 사용량
|
||||
text.blocks.coolant = 냉각제
|
||||
text.blocks.coolantuse = 냉각수 사용
|
||||
text.blocks.inputliquidfuel = 연료 액
|
||||
text.blocks.liquidfueluse = 액체 연료 사용
|
||||
text.blocks.explosive = 이 블록이 터지면 주변 블록과 같이 자폭을 합니다!!
|
||||
text.blocks.health = 체력
|
||||
text.blocks.inaccuracy = 오차각
|
||||
text.blocks.shots = 발포 횟수
|
||||
text.blocks.reload = 재장전
|
||||
text.blocks.inputfuel = 연료
|
||||
text.blocks.fuelburntime = 연료 연소 시간
|
||||
text.blocks.inputcapacity = 입력 용량
|
||||
text.blocks.outputcapacity = 출력 용량
|
||||
text.unit.blocks = 블록
|
||||
text.unit.powersecond = 전력/초
|
||||
text.unit.liquidsecond = 액체/초
|
||||
@@ -370,6 +370,7 @@ setting.musicvol.name = 음악 크기
|
||||
setting.mutemusic.name = 음소거
|
||||
setting.sfxvol.name = 효과음 크기
|
||||
setting.mutesound.name = 소리 끄기
|
||||
setting.crashreport.name = 오류 보고서 보내기
|
||||
text.keybind.title = 키 바인딩
|
||||
category.general.name = 일반
|
||||
category.view.name = 보기
|
||||
@@ -417,11 +418,11 @@ content.unit.name = 유닛
|
||||
content.recipe.name = 블록
|
||||
content.mech.name = 기체
|
||||
item.stone.name = 돌
|
||||
item.stone.description = 주로 용암을 사용하여 얻을 수 있습니다.
|
||||
item.stone.description = 주로 용암을 사용하여 얻을 수 있는 자원입니다.
|
||||
item.copper.name = 구리
|
||||
item.copper.description = 모든 유형의 블록에서 광범위하게 사용되는 자원입니다.
|
||||
item.lead.name = 납
|
||||
item.lead.description = 쉽게 구할 수 있는 자원.\n전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다.
|
||||
item.lead.description = 쉽게 구할 수 있으며, 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다.
|
||||
item.coal.name = 석탄
|
||||
item.coal.description = 쉽게 구할 수 있으며, 주로 제련소 등에서 연료로 사용됩니다.
|
||||
item.dense-alloy.name = 합금
|
||||
@@ -439,9 +440,9 @@ item.phase-fabric.description = 최첨단 전자 제품과 자기수리 기술
|
||||
item.surge-alloy.name = 설금
|
||||
item.surge-alloy.description = 주로 건물의 재료로 사용되는 자원입니다
|
||||
item.biomatter.name = 바이오메터
|
||||
item.biomatter.description = 이것은 유기농 덤불입니다!\n석유로 전환하거나 연료로 사용됩니다.
|
||||
item.biomatter.description = 이것은 유기농 덤불입니다!\n압축기에 넣어 석유로 바꿀 수 있습니다.
|
||||
item.sand.name = 모래
|
||||
item.sand.description = 합금이나 플렉스 등에서 제련시 광범위하게 사용되는 일반적인 재료입니다.
|
||||
item.sand.description = 합금이나 플럭스 등에서 제련시 광범위하게 사용되는 일반적인 재료입니다.
|
||||
item.blast-compound.name = 화합물
|
||||
item.blast-compound.description = 포탑 및 건설의 재료로 사용되는 휘발성 화합물.\n연료로도 사용할 수 있지만, 별로 추천하지는 않습니다.
|
||||
item.pyratite.name = 피라테
|
||||
@@ -482,7 +483,7 @@ mech.glaive-ship.weapon = 방화총
|
||||
text.item.explosiveness = [LIGHT_GRAY]폭발력 : {0}
|
||||
text.item.flammability = [LIGHT_GRAY]인화성 : {0}
|
||||
text.item.radioactivity = [LIGHT_GRAY]방사능 : {0}
|
||||
text.item.fluxiness = [LIGHT_GRAY]플렉스 파워 : {0}
|
||||
text.item.fluxiness = [LIGHT_GRAY]플럭스 파워 : {0}
|
||||
text.unit.health = [LIGHT_GRAY]체력 : {0}
|
||||
text.unit.speed = [LIGHT_GRAY]속도 : {0}
|
||||
text.mech.weapon = [LIGHT_GRAY]무기 : {0}
|
||||
@@ -496,7 +497,7 @@ text.liquid.viscosity = [LIGHT_GRAY]점도 : {0}
|
||||
text.liquid.temperature = [LIGHT_GRAY]온도 : {0}
|
||||
block.spawn.name = 적 스폰지점
|
||||
block.core.name = 코어
|
||||
block.metalfloor.name = 메탈 바닥
|
||||
block.metalfloor.name = 철판
|
||||
block.deepwater.name = 깊은물
|
||||
block.water.name = 물
|
||||
block.lava.name = 용암
|
||||
@@ -517,7 +518,7 @@ block.copper-wall-large.name = 큰 구리벽
|
||||
block.dense-alloy-wall.name = 합금 벽
|
||||
block.dense-alloy-wall-large.name = 큰 합금 벽
|
||||
block.phase-wall.name = 메타벽
|
||||
block.phase-wall-large.name = 메타벽
|
||||
block.phase-wall-large.name = 큰 메타벽
|
||||
block.thorium-wall.name = 토륨벽
|
||||
block.thorium-wall-large.name = 대형 토륨벽
|
||||
block.door.name = 문
|
||||
@@ -534,7 +535,7 @@ block.distributor.name = 대형 분배기
|
||||
block.sorter.name = 필터
|
||||
block.sorter.description = 아이템을 넣어서 필터에 설정된 아이템일 경우 바로 앞으로 통과하며, 그렇지 않을 경우 옆으로 통과합니다.
|
||||
block.overflow-gate.name = 오버플로 게이트
|
||||
block.overflow-gate.description = 정면 경로가 차단된 경우 왼쪽과 오른쪽으로만 출력하는 복합 분배기입니다.
|
||||
block.overflow-gate.description = 정면으로 가는 자원이 막히면 옆으로 출력하고, 그렇지 않으면 계속 정면으로 출력합니다.
|
||||
block.smelter.name = 제련소
|
||||
block.arc-smelter.name = 대형 제련소
|
||||
block.silicon-smelter.name = 실리콘 제련소
|
||||
@@ -623,7 +624,6 @@ block.rtg-generator.name = 토륨 발전소
|
||||
block.spectre.name = 스펙터
|
||||
block.meltdown.name = 멜트다운
|
||||
block.container.name = 컨테이너
|
||||
block.core.description = 게임에서 가장 중요한 건물.\n파괴되면 게임이 끝납니다.
|
||||
team.blue.name = 블루팀
|
||||
team.red.name = 레드팀
|
||||
team.orange.name = 오렌지팀
|
||||
@@ -637,6 +637,7 @@ unit.phantom.name = 팬텀 드론
|
||||
unit.phantom.description = 첨단 드론 유닛. 광석을 자동으로 채광하며, 아이템을 수집하고 블록을 수리합니다. 일반 드론보다 훨씬 효과적입니다.
|
||||
unit.dagger.name = 귀여운 디거
|
||||
unit.dagger.description = 밈의 대상으로 지정되어 이름이 바뀐 기본 지상 유닛입니다.
|
||||
## unit.dagger.description = 기본 지상 유닛입니다. 스웜과 같이 쓰면 유용합니다.
|
||||
unit.titan.name = 타이탄
|
||||
unit.titan.description = 고급 지상 유닛입니다. 합금을 탄약으로 사용하며 지상과 공중 둘다 공격할 수 있습니다.
|
||||
unit.ghoul.name = 구울 폭격기
|
||||
@@ -668,6 +669,7 @@ tutorial.daggerfactory = 이[accent] 귀여운 디거 기체 공장[]은\n\n공
|
||||
tutorial.router = 공장을 작동시키기 위해 자원이 필요합니다.\n컨베이어에 운반되고 있는 자원을 분할할 분배기를 만드세요.
|
||||
tutorial.dagger = 전력 노드를 공장에 연결하세요.\n일단 요구 사항이 충족되면 기체 생산을 시작합니다.\n\n필요에 따라 드릴 및 발전기, 컨베이어를 더 많이 만들 수 있습니다.
|
||||
tutorial.battle = [LIGHT_GRAY]적[]의 코어가 드러났습니다.\n당신의 부대와 귀여운 디거를 사용하여 파괴하세요.
|
||||
block.core.description = 게임에서 가장 중요한 건물.\n파괴되면 게임이 끝납니다.
|
||||
block.copper-wall.description = 구리로 만든 벽.
|
||||
block.copper-wall-large.description = 구리로 만든 큰 벽.
|
||||
block.dense-alloy-wall.description = 합금으로 만든 벽. 구리벽보다 체력이 높습니다.
|
||||
@@ -680,17 +682,17 @@ block.surge-wall.description = 데미지를 입으면 번개를 일으켜 대상
|
||||
block.surge-wall-large.description = 설금을 재료로 한 큰 벽.\n데미지를 입으면 번개를 일으켜 대상에게 피해를 입힙니다.
|
||||
block.door.description = 유닛이 지나갈 수 있도록 만든 문. 클릭하면 열고 닫습니다.
|
||||
block.door-large.description = 유닛이 자나갈 수 있도록 만든 큰 문. 클릭하면 열고 닫습니다.
|
||||
block.mend-projector.description = 주위 건물을 치료하는 건물.
|
||||
block.overdrive-projector.description = 범위 내 모든 행동의 속도를 높여주는 보조형 방어 건물.
|
||||
block.mend-projector.description = 주위 건물을 치료하는 건물입니다.
|
||||
block.overdrive-projector.description = 범위 내 모든 행동의 속도를 높여주는 보조형 방어 건물입니다.
|
||||
block.force-projector.description = 보호막을 생성하는 건물.\n기본적으로 전기만 있으면 작동하지만, 메타를 넣어 보호막의 범위를 크게 확장시킬 수 있습니다.
|
||||
block.shock-mine.description = 적이 이 블록을 지나가면 전격 공격을 하는 함정형 방어 건물.
|
||||
block.shock-mine.description = 적이 이 블록을 지나가면 전격 공격을 하는 함정형 방어 건물입니다.
|
||||
block.duo.description = 범용성을 가진 터렛.\n지상 및 공중공격을 하며, 초중반에 유용합니다.
|
||||
block.arc.description = 목표 방향으로 전격 공격을 하는 포탑입니다.
|
||||
block.hail.description = 장거리 지상 공격을 하는 터렛입니다.\n적이 오기 전에 쓸어버릴 수 있습니다.
|
||||
block.lancer.description = 중거리 레이져 포탑입니다.\n적을 관통하기 때문에 뭉쳐있는 적들에게 매우 효과적입니다.
|
||||
block.wave.description = 적이 있는 자리에 액체를 뿌립니다.\n이 포탑을 활용하여 액체를 뿌린 곳에 불을 붙이거나 적을 느리게 할 수 있습니다.
|
||||
block.salvo.description = 명중률이 높고, 3발씩 끊어 발사하는 포탑입니다.
|
||||
block.swarmer.description = 4발씩 끊어 발사하고, 유도 미사일을 가진 포탑입니다.
|
||||
block.swarmer.description = 4발씩 끊어서 유도체를 발사하는 포탑입니다
|
||||
block.ripple.description = 4개의 탄약으로 나눠 발사하여 명중률이 낮지만, 사거리가 매우 긴 포탑입니다.
|
||||
block.cyclone.description = 낮은 명중률과 높은 RPM 을 가진 포탑입니다.\n탄약이 남아있는 한 멈추지 않고 계속 연사합니다.
|
||||
block.fuse.description = 단거리에서 범위형 레이저를 발사하는 포탑입니다.
|
||||
@@ -701,21 +703,21 @@ block.titanium-conveyor.description = 빠른 속도로 자원을 수송할 수
|
||||
block.phase-conveyor.description = 자원을 순간이동 시켜 주는 컨베이어 입니다.
|
||||
block.junction.description = 컨베이어를 교차시켜 자원을 수송할 때 사용할 수 있는 블록입니다.
|
||||
block.mass-driver.description = 자원을 받아서 다른 물질 이동기로 전달할 수 있는 블록입니다.\n엄청난 사거리를 가지고 있으며, 주로 컨베이어가 접근할 수 없는 곳에 유용하게 사용됩니다.
|
||||
block.smelter.description = 합금을 제작할 수 있는 건물.
|
||||
block.smelter.description = 합금을 제작할 수 있는 건물입니다.
|
||||
block.arc-smelter.description = 합금을 제작할 수 있는 건물이지만, 이 건물은 석탄이 필요 없고 좀더 빠른 속도로 합금을 생산해낼 수 있습니다.
|
||||
block.silicon-smelter.description = 실리콘을 제작할 수 있는 건물.
|
||||
block.plastanium-compressor.description = 플라스터늄을 제조할 수 있는 건물.
|
||||
block.phase-weaver.description = 메타를 제작할 수 있는 건물.
|
||||
block.alloy-smelter.description = 설금을 제작할 수 있는 건물.
|
||||
block.pulverizer.description = 돌을 갈아서 모래로 만들 수 있는 건물.
|
||||
block.pyratite-mixer.description = 피라테를 제조할 수 있는 건물.
|
||||
block.blast-mixer.description = 화합물을 제조할 수 있는 건물.
|
||||
block.cryofluidmixer.description = 냉각수를 제작할 수 있는 건물.
|
||||
block.solidifer.description = 용암을 돌로 만들 수 있는 건물.
|
||||
block.melter.description = 돌로 용암을 만들 수 있는 건물.
|
||||
block.incinerator.description = 불필요한 아이템을 소각시켜 줄 수 있는 건물.
|
||||
block.biomattercompressor.description = 잔디밭에서 바이오메터를 추출할 수 있는 건물.
|
||||
block.separator.description = 돌을 분해하여 각종 자원으로 재활용 할 수 있게 해 주는 건물.
|
||||
block.silicon-smelter.description = 실리콘을 제작할 수 있는 건물입니다.
|
||||
block.plastanium-compressor.description = 플라스터늄을 제조할 수 있는 건물입니다.
|
||||
block.phase-weaver.description = 메타를 제작할 수 있는 건물입니다.
|
||||
block.alloy-smelter.description = 설금을 제작할 수 있는 건물입니다.
|
||||
block.pulverizer.description = 돌을 갈아서 모래로 만들 수 있는 건물입니다.
|
||||
block.pyratite-mixer.description = 피라테를 제조할 수 있는 건물입니다.
|
||||
block.blast-mixer.description = 화합물을 제조할 수 있는 건물입니다.
|
||||
block.cryofluidmixer.description = 냉각수를 제작할 수 있는 건물입니다.
|
||||
block.solidifer.description = 용암을 돌로 만들 수 있는 건물입니다.
|
||||
block.melter.description = 돌로 용암을 만들 수 있는 건물입니다.
|
||||
block.incinerator.description = 불필요한 아이템을 소각시켜 줄 수 있는 건물입니다.
|
||||
block.biomattercompressor.description = 잔디밭에서 바이오메터를 추출할 수 있는 건물입니다.
|
||||
block.separator.description = 돌을 분해하여 각종 자원으로 재활용 할 수 있게 해 주는 건물입니다.
|
||||
block.centrifuge.description = 돌을 분해하여 각종 자원으로 재활용 할 수 있게 해 주는 건물이지만, 이 건물은 좀 더 다양한 자원을 얻을 수 있게 해 줍니다.
|
||||
block.power-node.description = 생성된 전기를 다른 건물로 전달하기 위한 전력 노드입니다.
|
||||
block.power-node-large.description = 생성된 전기를 다른 건물로 전달하기 위한 건물이며, 일반 노드보다 더 많은 전력을 이동시킬 수 있습니다.
|
||||
@@ -729,31 +731,31 @@ block.solar-panel-large.description = 태양열을 받아 자기 스스로 전
|
||||
block.thorium-reactor.description = 토륨을 원료로 하는 토륨 원자로 입니다.\n많은 전력을 생산하지만 엄청난 열을 발생시키기 때문에, 많은 량의 물 또는 냉각수가 있어야 터지지 않고 작동합니다.
|
||||
block.rtg-generator.description = 냉각은 필요 없지만 토륨 원자로보다 적은량의 전력을 생산하는 방사선 동위원소 열전자 발전기.
|
||||
block.unloader.description = 해당 창고 및 코어에서 자원을 빼내는데 사용됩니다.
|
||||
block.container.description = 자원을 운반하기 위한 수송 블록입니다.
|
||||
block.vault.description = 아이템을 임시로 저장할 수 있는 대형 창고
|
||||
block.container.description = 아이템을 임시로 저장할 수 있는 소형 창고입니다.
|
||||
block.vault.description = 아이템을 임시로 저장할 수 있는 대형 창고입니다.
|
||||
block.mechanical-drill.description = 구리로 제작할 수 있는 기본 드릴입니다.
|
||||
block.pneumatic-drill.description = 돌, 티타늄을 채광할 수 있는 고급 드릴입니다.
|
||||
block.laser-drill.description = 토륨을 채광할 수 있는 최고급 드릴입니다.\n전력과 물을 공급하여 빠른 속도로 채광할 수 있습니다.
|
||||
block.blast-drill.description = 최상위 드릴입니다. 엄청난 양의 전력과 물을 소모하는 대신, 매우 빠른 속도로 채광합니다.
|
||||
block.water-extractor.description = 바닥에서 물을 추출하여 건물에 공급할 수 있는 건물.
|
||||
block.cultivator.description = 잔디에서 바이오메터를 추출할 수 있는 건물.
|
||||
block.oil-extractor.description = 기름을 추출 해 주는 건물.
|
||||
block.dart-ship-pad.description = 다트 비행선으로 바꿀 수 있는 패드.
|
||||
block.trident-ship-pad.description = 삼지창 비행선으로 바꿀 수 있는 패드.
|
||||
block.javelin-ship-pad.description = 자비린 비행선으로 바꿀 수 있는 패드.
|
||||
block.glaive-ship-pad.description = 글레브 비행선으로 바꿀 수 있는 패드.
|
||||
block.water-extractor.description = 바닥에서 물을 추출하여 건물에 공급할 수 있는 건물입니다.
|
||||
block.cultivator.description = 잔디에서 바이오메터를 추출할 수 있는 건물입니다.
|
||||
block.oil-extractor.description = 기름(타르)을 추출 해 주는 건물입니다.
|
||||
block.dart-ship-pad.description = 다트 비행선으로 바꿀 수 있는 패드입니다.
|
||||
block.trident-ship-pad.description = 삼지창 비행선으로 바꿀 수 있는 패드입니다.
|
||||
block.javelin-ship-pad.description = 자비린 비행선으로 바꿀 수 있는 패드입니다.
|
||||
block.glaive-ship-pad.description = 글레브 비행선으로 바꿀 수 있는 패드입니다.
|
||||
block.tau-mech-pad.description = 타우 기체로 바꿀 수 있는 패드
|
||||
block.delta-mech-pad.description = 델타 기체로 바꿀 수 있는 패드.
|
||||
block.delta-mech-pad.description = 델타 기체로 바꿀 수 있는 패드입니다.
|
||||
block.omega-mech-pad.description = 오메가 기체로 바꿀 수 있는 패드
|
||||
block.spirit-factory.description = 스피릿 유닛을 생산하는 공장.
|
||||
block.phantom-factory.description = 유닛 팬텀을 생산하는 공장.
|
||||
block.wraith-factory.description = 유닛 유령 전투기를 소환하는 공장.
|
||||
block.ghoul-factory.description = 구울 유닛을 생산하는 공장.
|
||||
block.dagger-factory.description = 귀여운 디거를 생산하는 공장.
|
||||
block.titan-factory.description = 타이탄 유닛을 생산할 수 있는 공장.
|
||||
block.fortress-factory.description = 포트리스를 생산하는 공장.
|
||||
block.revenant-factory.description = 레비던트 유닛을 생산할 수 있는 공장.
|
||||
block.repair-point.description = 근처 유닛들을 수리하는 건물.
|
||||
block.spirit-factory.description = 스피릿 유닛을 생산하는 공장입니다.
|
||||
block.phantom-factory.description = 유닛 팬텀을 생산하는 공장입니다.
|
||||
block.wraith-factory.description = 유닛 유령 전투기를 소환하는 공장입니다.
|
||||
block.ghoul-factory.description = 구울 유닛을 생산하는 공장입니다.
|
||||
block.dagger-factory.description = 귀여운 디거를 생산하는 공장입니다.
|
||||
block.titan-factory.description = 타이탄 유닛을 생산할 수 있는 공장입니다.
|
||||
block.fortress-factory.description = 포트리스를 생산하는 공장입니다.
|
||||
block.revenant-factory.description = 레비던트 유닛을 생산할 수 있는 공장입니다.
|
||||
block.repair-point.description = 근처 유닛들을 수리하는 건물입니다.
|
||||
block.command-center.description = 생산된 유닛들을 제어할 수 있는 건물.\n첫번째 버튼은 적 기지로 공격하며, 두번째는 대기 상태, 세번째는 기지 근처를 돌며 정찰합니다.
|
||||
block.conduit.description = 일반 파이프. 액체가 지나갈 수 있도록 해 줍니다.
|
||||
block.pulse-conduit.description = 티타늄으로 만들어 졌으며, 일반 파이프보다 액체 수용량이 높습니다.
|
||||
@@ -768,13 +770,13 @@ block.thermal-pump.description = 용암 위에서 사용할 수 있는 펌프입
|
||||
block.router.description = 한 방향에서 아이템을 받은 후 최대 3개의 다른 방향으로 동일하게 출력합니다.\n재료를 한곳에서 여러 대상으로 분할하여 운반하는데 유용합니다.
|
||||
block.distributor.description = 아이템을 최대 7개의 다른 방향으로 똑같이 분할하는 고급 분배기.
|
||||
block.bridge-conveyor.description = 고급 자원 수송 블록.\n지형이나 건물을 넘어 최대 3개 타일을 건너뛰고 자원을 운송할 수 있습니다.
|
||||
block.alpha-mech-pad.description = 알파 기체로 바꿀 수 있는 패드.
|
||||
block.itemsource.description = 자원을 선택하면 그 자원이 무한하게 튀어나오는 블록입니다.
|
||||
block.alpha-mech-pad.description = 알파 기체로 바꿀 수 있는 패드입니다.
|
||||
block.itemsource.description = 자원을 선택하면 그 자원이 무한하게 생성되는 블록입니다.
|
||||
block.liquidsource.description = 무한한 액체를 출력해냅니다.
|
||||
block.itemvoid.description = 아이템을 시공으로 빠트려 사라지게 만듭니다.
|
||||
block.powerinfinite.description = 무한한 전력을 출력해냅니다.
|
||||
block.powervoid.description = 무한한 아이템을 출력해냅니다.
|
||||
liquid.water.description = 유닛이 이 위를 지나가면 이동속도가 느려지고, 깊은 물에 빠지면 죽습니다.
|
||||
liquid.lava.description = 유닛이 이 위를 지나가면 이동속도가 매우 느려지고, 지속적으로 데미지를 입습니다.
|
||||
block.powerinfinite.description = 무한한 전력을 공급해주는 블록입니다.
|
||||
block.powervoid.description = 설정된 아이템을 계속해서 출력하는 블록입니다.
|
||||
liquid.water.description = 지상 유닛이 이 위를 지나가면 이동속도가 느려지고, 깊은 물에 빠지면 죽습니다.
|
||||
liquid.lava.description = 지상 유닛이 이 위를 지나가면 이동속도가 매우 느려지고, 지속적으로 데미지를 입습니다.
|
||||
liquid.oil.description = 일부 조합 블록에서 사용되는 자원입니다.
|
||||
liquid.cryofluid.description = 포탑 및 토륨 원자로에서 사용되는 자원입니다. 누출시 폭발 및 방화의 위험성이 있습니다.
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Mission Info
|
||||
text.mission.complete = Mission complete!
|
||||
text.mission.complete.body = Sector {0},{1} has been conquered.
|
||||
text.mission.wave = Survive [accent]{0}[] waves.
|
||||
text.mission.wave = Survive[accent] {0}/{1} []waves\nWave in {2}
|
||||
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
|
||||
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
|
||||
text.mission.wave.menu = Survive[accent] {0} []waves
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Mission Info
|
||||
text.mission.complete = Mission complete!
|
||||
text.mission.complete.body = Sector {0},{1} has been conquered.
|
||||
text.mission.wave = Sobrevive [accent]{0}[] Onda.
|
||||
text.mission.wave = Sobrevive [accent]{0}/{1}[] Onda\nOnda em {2}
|
||||
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
|
||||
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
|
||||
text.mission.wave.menu = Survive[accent] {0} []waves
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Главная мисия:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Информация о миссии
|
||||
text.mission.complete = Миссия выполнена!
|
||||
text.mission.complete.body = Сектор {0},{1} был завоёван.
|
||||
text.mission.wave = Пережить следующее количество волн: [accent]{0}[].
|
||||
text.mission.wave = Пережить следующее количество волн: [accent]{0}/{1}[]\nВолна в {2}
|
||||
text.mission.wave.enemies = Осталось волн:[accent] {0}/{1}[]\n{2} враг.
|
||||
text.mission.wave.enemy = Осталось волн:[accent] {0}/{1}[]\n{2} враг
|
||||
text.mission.wave.menu = Пережить[accent] {0} []волн
|
||||
@@ -407,7 +407,7 @@ mode.sandbox.name = Песочница
|
||||
mode.sandbox.description = Бесконечные ресурсы и нет таймера для волн, но можно самим вызвать волну.
|
||||
mode.custom.warning = [scarlet]РАЗБЛОКИРОВАННОЕ В ПОЛЬЗОВАТЕЛЬСКИХ ИГРАХ ИЛИ НА СЕРВЕРАХ НЕ СОХРАНЯЕТСЯ[]\n\nИграйте в секторах для разблокировки чего-либо
|
||||
mode.custom.warning.read = Внимательно прочитайте это!:\n[scarlet]РАЗБЛОКИРОВАННОЕ В ПОЛЬЗОВАТЕЛЬСКИХ ИГРАХ ИЛИ ДРУГИХ РЕЖИМАХ ИГРЫ НЕ РАСПРОСТРАНЯЕТСЯ НА СЕКТОРА ИЛИ ДРУГИЕ РЕЖИМЫ ИГРЫ!\n\n[LIGHT_GRAY](Я бы хотел, чтобы это не было необходимо, но, по-видимому, это так)
|
||||
mode.freebuild.name = Cвободная\nстройка
|
||||
mode.freebuild.name = Свободная\nстройка
|
||||
mode.freebuild.description = ограниченные ресурсы и нет таймера для волн.
|
||||
mode.pvp.name = Противо-\nстояние
|
||||
mode.pvp.description = боритесь против других игроков.
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Mission Info
|
||||
text.mission.complete = Gorev tamamlandi!
|
||||
text.mission.complete.body = Sektor {0},{1} ele gecirildi
|
||||
text.mission.wave = [accent]{0}[] Dalga hayatta kal
|
||||
text.mission.wave = [accent]{0}/{1}[] Dalga hayatta kal\n{2} Dalga
|
||||
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
|
||||
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
|
||||
text.mission.wave.menu = Survive[accent] {0} []waves
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Mission Info
|
||||
text.mission.complete = Mission complete!
|
||||
text.mission.complete.body = Sector {0},{1} has been conquered.
|
||||
text.mission.wave = Survive [accent]{0}[] waves.
|
||||
text.mission.wave = Survive[accent] {0}/{1} []waves\nWave in {2}
|
||||
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
|
||||
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
|
||||
text.mission.wave.menu = Survive[accent] {0} []waves
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Головна місія:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Інформація про місії
|
||||
text.mission.complete = Місія завершена!
|
||||
text.mission.complete.body = Сектор {0},{1} був завойований.
|
||||
text.mission.wave = Пережити наступну кількість хвиль:[accent]{0}[] .
|
||||
text.mission.wave = Пережити наступну кількість хвиль:[accent]{0}/{1}[]\nХвиля в {2}
|
||||
text.mission.wave.enemies = Пережити [accent] {0}/{1} []хвиль\n{2} Ворог.
|
||||
text.mission.wave.enemy = Пережити[accent] {0}/{1} []хвиль\n{2} Ворог
|
||||
text.mission.wave.menu = Пережити[accent] {0} []хвиль
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Mission Info
|
||||
text.mission.complete = 任务完成!
|
||||
text.mission.complete.body = 区域 {0},攻占了 {1} 个
|
||||
text.mission.wave = 存活了 [accent]{0}[] 波。
|
||||
text.mission.wave = 存活了 [accent]{0}/{1}[] 波。\nWave in {2}
|
||||
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
|
||||
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
|
||||
text.mission.wave.menu = Survive[accent] {0} []waves
|
||||
|
||||
@@ -50,7 +50,7 @@ text.mission.main = Main Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Mission Info
|
||||
text.mission.complete = Mission complete!
|
||||
text.mission.complete.body = Sector {0},{1} has been conquered.
|
||||
text.mission.wave = Survive [accent]{0}[] waves.
|
||||
text.mission.wave = Survive[accent] {0}/{1} []waves\nWave in {2}
|
||||
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
|
||||
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
|
||||
text.mission.wave.menu = Survive[accent] {0} []waves
|
||||
|
||||
Binary file not shown.
@@ -6,17 +6,15 @@ precision highp int;
|
||||
#define MAX_HITS 64
|
||||
#define HIT_RADIUS 12.0
|
||||
#define ALPHA 0.18
|
||||
#define thickness 1.0
|
||||
#define step 2.0
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
uniform vec4 u_color;
|
||||
uniform vec2 u_texsize;
|
||||
uniform float u_time;
|
||||
uniform float u_scaling;
|
||||
uniform float u_dp;
|
||||
uniform vec2 u_offset;
|
||||
uniform int u_hitamount;
|
||||
uniform vec3 u_hits[MAX_HITS];
|
||||
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texCoord;
|
||||
@@ -28,29 +26,19 @@ float round(float f){
|
||||
void main() {
|
||||
|
||||
vec2 T = v_texCoord.xy;
|
||||
|
||||
vec2 coords = (T * u_texsize) + u_offset;
|
||||
|
||||
T += vec2(sin(coords.y / 3.0 + u_time / 20.0) / 240.0, sin(coords.x / 3.0 + u_time / 20.0) / 240.0) * u_scaling;
|
||||
|
||||
float si = sin(u_time / 20.0) / 8.0;
|
||||
|
||||
vec4 color = texture2D(u_texture, T);
|
||||
|
||||
vec2 v = vec2(1.0/u_texsize.x, 1.0/u_texsize.y);
|
||||
|
||||
bool any = false;
|
||||
if(texture2D(u_texture, T).a < 0.1 &&
|
||||
(texture2D(u_texture, T + vec2(0, step) * v).a > 0.1 || texture2D(u_texture, T + vec2(0, -step) * v).a > 0.1 ||
|
||||
texture2D(u_texture, T + vec2(step, 0) * v).a > 0.1 || texture2D(u_texture, T + vec2(-step, 0) * v).a > 0.1)){
|
||||
|
||||
float thickness = 1.0;
|
||||
float step = 2.0;
|
||||
|
||||
if(texture2D(u_texture, T).a < 0.1 &&
|
||||
(texture2D(u_texture, T + vec2(0, step) * v).a > 0.1 || texture2D(u_texture, T + vec2(0, -step) * v).a > 0.1 ||
|
||||
texture2D(u_texture, T + vec2(step, 0) * v).a > 0.1 || texture2D(u_texture, T + vec2(-step, 0) * v).a > 0.1))
|
||||
any = true;
|
||||
|
||||
if(any){
|
||||
gl_FragColor = mix(u_color, vec4(1.0), si);
|
||||
gl_FragColor = mix(v_color, vec4(1.0), si);
|
||||
}else{
|
||||
|
||||
if(color.a > 0.1){
|
||||
@@ -59,18 +47,6 @@ void main() {
|
||||
}
|
||||
|
||||
color.a = ALPHA;
|
||||
|
||||
for(int i = 0; i < MAX_HITS; i ++){
|
||||
if(i >= u_hitamount) break;
|
||||
vec3 hit = u_hits[i];
|
||||
float rad = hit.z * HIT_RADIUS;
|
||||
float fin = 1.0 - hit.z;
|
||||
|
||||
if(abs(distance(vec2(hit.x, hit.y), coords - u_texsize/2.0) - rad) < 1.0){
|
||||
color = mix(color, mix(u_color, vec4(1.0), si), (1.0 * fin));
|
||||
color.a = ALPHA + 0.82 *fin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gl_FragColor = color;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 100 KiB |
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module>
|
||||
<source path="io/anuke/mindustry"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Content"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.type.ItemStack"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.Maps"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.SpawnGroup"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.core.GameState"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.SaveFileVersion"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.ucore.entities.impl.EffectEntity"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.effect"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.bullet.Bullet"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Team"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.missions.Mission"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.type.Item"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.meta.BlockBar"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.generation.WorldGenerator"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.StatusController"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.Sector"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.utils.Predicate"/>
|
||||
</module>
|
||||
@@ -94,6 +94,7 @@ public class Vars{
|
||||
public static float controllerMin = 0.25f;
|
||||
public static float baseControllerSpeed = 11f;
|
||||
public static boolean snapCamera = true;
|
||||
|
||||
public static ContentLoader content;
|
||||
public static GameState state;
|
||||
public static ThreadHandler threads;
|
||||
@@ -162,6 +163,7 @@ public class Vars{
|
||||
});
|
||||
}
|
||||
|
||||
state = new GameState();
|
||||
threads = new ThreadHandler();
|
||||
|
||||
mobile = Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS || testMobile;
|
||||
|
||||
@@ -71,6 +71,7 @@ public class BlockIndexer{
|
||||
flagMap[i][j] = new ObjectSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
typeMap.clear();
|
||||
ores = null;
|
||||
|
||||
@@ -246,7 +247,7 @@ public class BlockIndexer{
|
||||
for(int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++){
|
||||
for(int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){
|
||||
Tile result = world.tile(x, y);
|
||||
if(result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue;
|
||||
if( result == null || result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue;
|
||||
|
||||
itemSet.add(result.block().drops.item);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class Mechs implements ContentList{
|
||||
|
||||
alpha = new Mech("alpha-mech", false){
|
||||
int maxDrones = 3;
|
||||
float buildTime = 200f;
|
||||
float buildTime = 20f;
|
||||
|
||||
{
|
||||
drillPower = 1;
|
||||
@@ -53,14 +53,19 @@ public class Mechs implements ContentList{
|
||||
@Override
|
||||
public void updateAlt(Player player){
|
||||
|
||||
if(getDrones(player) < maxDrones && !TutorialSector.supressDrone() && player.timer.get(Player.timerAbility, buildTime)){
|
||||
if(!Net.client()) {
|
||||
AlphaDrone drone = (AlphaDrone) UnitTypes.alphaDrone.create(player.getTeam());
|
||||
drone.leader = player;
|
||||
drone.set(player.x, player.y);
|
||||
drone.add();
|
||||
if(player.isShooting && getDrones(player) < maxDrones && !TutorialSector.supressDrone()){
|
||||
player.timer.get(Player.timerAbility, buildTime);
|
||||
|
||||
if(player.timer.getTime(Player.timerAbility) > buildTime/2f){
|
||||
if(!Net.client()){
|
||||
AlphaDrone drone = (AlphaDrone) UnitTypes.alphaDrone.create(player.getTeam());
|
||||
drone.leader = player;
|
||||
drone.set(player.x, player.y);
|
||||
drone.add();
|
||||
|
||||
Effects.effect(UnitFx.unitLand, player);
|
||||
}
|
||||
}
|
||||
Effects.effect(UnitFx.unitLand, player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ public class Blocks extends BlockList implements ContentList{
|
||||
}};
|
||||
|
||||
ice = new Floor("ice"){{
|
||||
dragMultiplier = 0.3f;
|
||||
dragMultiplier = 0.2f;
|
||||
speedMultiplier = 0.4f;
|
||||
minimapColor = Color.valueOf("b8eef8");
|
||||
hasOres = true;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class LiquidBlocks extends BlockList implements ContentList{
|
||||
|
||||
thermalPump = new Pump("thermal-pump"){{
|
||||
shadow = "shadow-rounded-2";
|
||||
pumpAmount = 0.3f;
|
||||
pumpAmount = 0.275f;
|
||||
consumes.power(0.03f);
|
||||
liquidCapacity = 40f;
|
||||
hasPower = true;
|
||||
|
||||
@@ -20,9 +20,9 @@ public class PowerBlocks extends BlockList implements ContentList{
|
||||
}};
|
||||
|
||||
thermalGenerator = new LiquidHeatGenerator("thermal-generator"){{
|
||||
maxLiquidGenerate = 0.5f;
|
||||
maxLiquidGenerate = 4f;
|
||||
powerCapacity = 40f;
|
||||
powerPerLiquid = 1f;
|
||||
powerPerLiquid = 0.1f;
|
||||
generateEffect = BlockFx.redgeneratespark;
|
||||
size = 2;
|
||||
}};
|
||||
|
||||
@@ -179,12 +179,6 @@ public class Control extends Module{
|
||||
});
|
||||
|
||||
Events.on(WorldLoadEvent.class, event -> threads.runGraphics(() -> Events.fire(new WorldLoadGraphicsEvent())));
|
||||
|
||||
Events.on(TileChangeEvent.class, event -> {
|
||||
if(event.tile.getTeam() == players[0].getTeam() && Recipe.getByResult(event.tile.block()) != null){
|
||||
unlocks.handleContentUsed(Recipe.getByResult(event.tile.block()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addPlayer(int index){
|
||||
@@ -278,7 +272,7 @@ public class Control extends Module{
|
||||
outer:
|
||||
for(int i = 0; i < content.recipes().size; i ++){
|
||||
Recipe recipe = content.recipes().get(i);
|
||||
if(!recipe.hidden && recipe.requirements != null){
|
||||
if(!recipe.isHidden() && recipe.requirements != null){
|
||||
for(ItemStack stack : recipe.requirements){
|
||||
if(!entity.items.has(stack.item, Math.min((int) (stack.amount * unlockResourceScaling), 2000))) continue outer;
|
||||
}
|
||||
|
||||
@@ -10,9 +10,11 @@ import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.Teams;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Events;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
@@ -35,13 +37,31 @@ public class Logic extends Module{
|
||||
public boolean doUpdate = true;
|
||||
|
||||
public Logic(){
|
||||
state = new GameState();
|
||||
Events.on(TileChangeEvent.class, event -> {
|
||||
if(event.tile.getTeam() == defaultTeam && Recipe.getByResult(event.tile.block()) != null){
|
||||
handleContent(Recipe.getByResult(event.tile.block()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
EntityQuery.init();
|
||||
EntityQuery.collisions().setCollider(tilesize, world::solid);
|
||||
EntityQuery.collisions().setCollider(tilesize, (x, y) -> {
|
||||
Tile tile = world.tile(x, y);
|
||||
return tile != null && tile.solid();
|
||||
});
|
||||
}
|
||||
|
||||
/**Handles the event of content being used by either the player or some block.*/
|
||||
public void handleContent(UnlockableContent content){
|
||||
if(world.getSector() != null){
|
||||
world.getSector().currentMission().onContentUsed(content);
|
||||
}
|
||||
|
||||
if(!headless){
|
||||
control.unlocks.unlockContent(content);
|
||||
}
|
||||
}
|
||||
|
||||
public void play(){
|
||||
@@ -142,7 +162,8 @@ public class Logic extends Module{
|
||||
|
||||
world.sectors.completeSector(world.getSector().x, world.getSector().y);
|
||||
world.sectors.save();
|
||||
if(!headless){
|
||||
|
||||
if(!headless && !Net.client()){
|
||||
ui.missions.show(world.getSector());
|
||||
}
|
||||
|
||||
@@ -151,7 +172,6 @@ public class Logic extends Module{
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(threads.isEnabled() && !threads.isOnThread()) return;
|
||||
|
||||
if(Vars.control != null){
|
||||
control.runUpdateLogic();
|
||||
@@ -159,15 +179,10 @@ public class Logic extends Module{
|
||||
|
||||
if(!state.is(State.menu)){
|
||||
|
||||
if(!Net.client() && !world.isInvalidMap()){
|
||||
updateSectors();
|
||||
checkGameOver();
|
||||
}
|
||||
|
||||
if(!state.isPaused()){
|
||||
Timers.update();
|
||||
|
||||
if(!state.mode.disableWaveTimer && !state.mode.disableWaves){
|
||||
if(!state.mode.disableWaveTimer && !state.mode.disableWaves && !state.gameOver){
|
||||
state.wavetime -= Timers.delta();
|
||||
}
|
||||
|
||||
@@ -216,10 +231,11 @@ public class Logic extends Module{
|
||||
|
||||
world.pathfinder.update();
|
||||
}
|
||||
}
|
||||
|
||||
if(threads.isEnabled()){
|
||||
netServer.update();
|
||||
if(!Net.client() && !world.isInvalidMap()){
|
||||
updateSectors();
|
||||
checkGameOver();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,14 +165,17 @@ public class NetClient extends Module{
|
||||
public static void onKick(KickReason reason){
|
||||
netClient.disconnectQuietly();
|
||||
state.set(State.menu);
|
||||
if(!reason.quiet){
|
||||
if(reason.extraText() != null){
|
||||
ui.showText(reason.toString(), reason.extraText());
|
||||
}else{
|
||||
ui.showText("$text.disconnect", reason.toString());
|
||||
|
||||
threads.runGraphics(() -> {
|
||||
if(!reason.quiet){
|
||||
if(reason.extraText() != null){
|
||||
ui.showText(reason.toString(), reason.extraText());
|
||||
}else{
|
||||
ui.showText("$text.disconnect", reason.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
ui.loadfrag.hide();
|
||||
ui.loadfrag.hide();
|
||||
});
|
||||
}
|
||||
|
||||
@Remote(variants = Variant.both)
|
||||
@@ -396,11 +399,11 @@ public class NetClient extends Module{
|
||||
quiet = true;
|
||||
}
|
||||
|
||||
public synchronized void addRemovedEntity(int id){
|
||||
public void addRemovedEntity(int id){
|
||||
removed.add(id);
|
||||
}
|
||||
|
||||
public synchronized boolean isEntityUsed(int id){
|
||||
public boolean isEntityUsed(int id){
|
||||
return removed.contains(id);
|
||||
}
|
||||
|
||||
@@ -411,11 +414,9 @@ public class NetClient extends Module{
|
||||
|
||||
BuildRequest[] requests;
|
||||
|
||||
synchronized(player.getPlaceQueue()){
|
||||
requests = new BuildRequest[player.getPlaceQueue().size];
|
||||
for(int i = 0; i < requests.length; i++){
|
||||
requests[i] = player.getPlaceQueue().get(i);
|
||||
}
|
||||
requests = new BuildRequest[player.getPlaceQueue().size];
|
||||
for(int i = 0; i < requests.length; i++){
|
||||
requests[i] = player.getPlaceQueue().get(i);
|
||||
}
|
||||
|
||||
Call.onClientShapshot(lastSent++, TimeUtils.millis(), player.x, player.y,
|
||||
|
||||
@@ -416,7 +416,6 @@ public class NetServer extends Module{
|
||||
}
|
||||
|
||||
public void update(){
|
||||
if(threads.isEnabled() && !threads.isOnThread()) return;
|
||||
|
||||
if(!headless && !closing && Net.server() && state.is(State.menu)){
|
||||
closing = true;
|
||||
|
||||
@@ -248,11 +248,12 @@ public class Renderer extends RendererModule{
|
||||
overlays.drawBottom();
|
||||
drawAndInterpolate(playerGroup, p -> true, Player::drawBuildRequests);
|
||||
|
||||
Shaders.shield.color.set(Palette.accent);
|
||||
Graphics.beginShaders(Shaders.shield);
|
||||
EntityDraw.draw(shieldGroup);
|
||||
EntityDraw.drawWith(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawOver());
|
||||
Draw.color(Palette.accent);
|
||||
Graphics.endShaders();
|
||||
Draw.color();
|
||||
|
||||
overlays.drawTop();
|
||||
|
||||
|
||||
@@ -1,80 +1,35 @@
|
||||
package io.anuke.mindustry.core;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Log;
|
||||
import io.anuke.ucore.util.Threads;
|
||||
import io.anuke.ucore.util.Threads.ThreadInfoProvider;
|
||||
|
||||
import static io.anuke.mindustry.Vars.control;
|
||||
import static io.anuke.mindustry.Vars.logic;
|
||||
|
||||
public class ThreadHandler implements ThreadInfoProvider{
|
||||
private final Queue<Runnable> toRun = new Queue<>();
|
||||
private Thread thread, graphicsThread;
|
||||
private final Object updateLock = new Object();
|
||||
private float delta = 1f;
|
||||
private float smoothDelta = 1f;
|
||||
private long frame = 0, lastDeltaUpdate;
|
||||
private float framesSinceUpdate;
|
||||
private boolean enabled;
|
||||
private boolean rendered = true;
|
||||
private long lastFrameTime;
|
||||
|
||||
public ThreadHandler(){
|
||||
Threads.setThreadInfoProvider(this);
|
||||
graphicsThread = Thread.currentThread();
|
||||
|
||||
Timers.setDeltaProvider(() -> {
|
||||
float result = isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f;
|
||||
return Math.min(Float.isNaN(result) ? 1f : result, 15f);
|
||||
float result = Gdx.graphics.getDeltaTime() * 60f;
|
||||
return Math.min(Float.isNaN(result) || Float.isInfinite(result) ? 1f : result, 15f);
|
||||
});
|
||||
}
|
||||
|
||||
public void run(Runnable r){
|
||||
if(enabled){
|
||||
synchronized(toRun){
|
||||
toRun.addLast(r);
|
||||
}
|
||||
}else{
|
||||
r.run();
|
||||
}
|
||||
r.run();
|
||||
}
|
||||
|
||||
public void runGraphics(Runnable r){
|
||||
if(enabled){
|
||||
Gdx.app.postRunnable(r);
|
||||
}else{
|
||||
r.run();
|
||||
}
|
||||
r.run();
|
||||
}
|
||||
|
||||
public void runDelay(Runnable r){
|
||||
if(enabled){
|
||||
synchronized(toRun){
|
||||
toRun.addLast(r);
|
||||
}
|
||||
}else{
|
||||
Gdx.app.postRunnable(r);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTPS(){
|
||||
if(smoothDelta == 0f){
|
||||
return 60;
|
||||
}
|
||||
return (int) (60 / smoothDelta);
|
||||
Gdx.app.postRunnable(r);
|
||||
}
|
||||
|
||||
public long getFrameID(){
|
||||
return enabled ? frame : Gdx.graphics.getFrameId();
|
||||
}
|
||||
|
||||
public float getFramesSinceUpdate(){
|
||||
return framesSinceUpdate;
|
||||
return Gdx.graphics.getFrameId();
|
||||
}
|
||||
|
||||
public void handleBeginRender(){
|
||||
@@ -95,119 +50,16 @@ public class ThreadHandler implements ThreadInfoProvider{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!enabled) return;
|
||||
|
||||
framesSinceUpdate += Timers.delta();
|
||||
|
||||
synchronized(updateLock){
|
||||
rendered = true;
|
||||
updateLock.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled(){
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled){
|
||||
if(enabled){
|
||||
logic.doUpdate = false;
|
||||
Timers.runTask(2f, () -> {
|
||||
if(thread != null){
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
|
||||
thread = new Thread(this::runLogic);
|
||||
thread.setDaemon(true);
|
||||
thread.setName("Update Thread");
|
||||
thread.start();
|
||||
Log.info("Starting logic thread.");
|
||||
|
||||
this.enabled = true;
|
||||
});
|
||||
}else{
|
||||
this.enabled = false;
|
||||
if(thread != null){
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
Timers.runTask(2f, () -> {
|
||||
logic.doUpdate = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public boolean doInterpolate(){
|
||||
return enabled && Gdx.graphics.getFramesPerSecond() - getTPS() > 20 && getTPS() < 30;
|
||||
}
|
||||
|
||||
public boolean isOnThread(){
|
||||
return Thread.currentThread() == thread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnLogicThread() {
|
||||
return !enabled || Thread.currentThread() == thread;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnGraphicsThread() {
|
||||
return !enabled || Thread.currentThread() == graphicsThread;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void runLogic(){
|
||||
try{
|
||||
while(true){
|
||||
long time = TimeUtils.nanoTime();
|
||||
|
||||
while(true){
|
||||
Runnable r;
|
||||
synchronized(toRun){
|
||||
if(toRun.size > 0){
|
||||
r = toRun.removeFirst();
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r.run();
|
||||
}
|
||||
|
||||
logic.doUpdate = true;
|
||||
logic.update();
|
||||
logic.doUpdate = false;
|
||||
|
||||
long elapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time));
|
||||
long target = (long) ((1000) / 60f);
|
||||
|
||||
if(elapsed < target){
|
||||
Thread.sleep(target - elapsed);
|
||||
}
|
||||
|
||||
synchronized(updateLock){
|
||||
while(!rendered){
|
||||
updateLock.wait();
|
||||
}
|
||||
rendered = false;
|
||||
}
|
||||
|
||||
long actuallyElapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time));
|
||||
delta = Math.max(actuallyElapsed, target) / 1000f * 60f;
|
||||
|
||||
if(TimeUtils.timeSinceMillis(lastDeltaUpdate) > 1000){
|
||||
lastDeltaUpdate = TimeUtils.millis();
|
||||
smoothDelta = delta;
|
||||
}
|
||||
|
||||
frame++;
|
||||
framesSinceUpdate = 0;
|
||||
}
|
||||
}catch(InterruptedException ex){
|
||||
Log.info("Stopping logic thread.");
|
||||
}catch(Throwable ex){
|
||||
control.setError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.anuke.ucore.scene.ui.TextField.TextFieldFilter;
|
||||
import io.anuke.ucore.scene.ui.TooltipManager;
|
||||
import io.anuke.ucore.scene.ui.layout.Table;
|
||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||
import io.anuke.ucore.util.Threads;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
import static io.anuke.ucore.scene.actions.Actions.*;
|
||||
@@ -154,6 +155,7 @@ public class UI extends SceneModule{
|
||||
load = new LoadDialog();
|
||||
levels = new CustomGameDialog();
|
||||
language = new LanguageDialog();
|
||||
unlocks = new UnlocksDialog();
|
||||
settings = new SettingsMenuDialog();
|
||||
host = new HostDialog();
|
||||
paused = new PausedDialog();
|
||||
@@ -164,7 +166,6 @@ public class UI extends SceneModule{
|
||||
traces = new TraceDialog();
|
||||
maps = new MapsDialog();
|
||||
localplayers = new LocalPlayerDialog();
|
||||
unlocks = new UnlocksDialog();
|
||||
content = new ContentInfoDialog();
|
||||
sectors = new SectorsDialog();
|
||||
missions = new MissionDialog();
|
||||
@@ -239,6 +240,8 @@ public class UI extends SceneModule{
|
||||
}
|
||||
|
||||
public void showInfoFade(String info){
|
||||
Threads.assertGraphics();
|
||||
|
||||
Table table = new Table();
|
||||
table.setFillParent(true);
|
||||
table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor());
|
||||
@@ -247,6 +250,8 @@ public class UI extends SceneModule{
|
||||
}
|
||||
|
||||
public void showInfo(String info){
|
||||
Threads.assertGraphics();
|
||||
|
||||
new Dialog("$text.info.title", "dialog"){{
|
||||
getCell(content()).growX();
|
||||
content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center);
|
||||
@@ -255,6 +260,8 @@ public class UI extends SceneModule{
|
||||
}
|
||||
|
||||
public void showInfo(String info, Runnable clicked){
|
||||
Threads.assertGraphics();
|
||||
|
||||
new Dialog("$text.info.title", "dialog"){{
|
||||
getCell(content()).growX();
|
||||
content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center);
|
||||
|
||||
@@ -70,7 +70,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
public TargetTrait moveTarget;
|
||||
|
||||
private float walktime;
|
||||
private Queue<BuildRequest> placeQueue = new ThreadQueue<>();
|
||||
private Queue<BuildRequest> placeQueue = new Queue<>();
|
||||
private Tile mining;
|
||||
private CarriableTrait carrying;
|
||||
private Trail trail = new Trail(12);
|
||||
@@ -323,7 +323,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
}
|
||||
|
||||
if(floor.isLiquid){
|
||||
Draw.tint(Color.WHITE, floor.liquidColor, Mathf.clamp(drownTime));
|
||||
Draw.tint(Color.WHITE, floor.liquidColor, drownTime);
|
||||
}else{
|
||||
Draw.tint(Color.WHITE);
|
||||
}
|
||||
@@ -421,55 +421,53 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
|
||||
/**Draw all current build requests. Does not draw the beam effect, only the positions.*/
|
||||
public void drawBuildRequests(){
|
||||
synchronized(getPlaceQueue()){
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(getCurrentRequest() == request) continue;
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(getCurrentRequest() == request) continue;
|
||||
|
||||
if(request.breaking){
|
||||
Block block = world.tile(request.x, request.y).target().block();
|
||||
if(request.breaking){
|
||||
Block block = world.tile(request.x, request.y).target().block();
|
||||
|
||||
//draw removal request
|
||||
Lines.stroke(2f);
|
||||
//draw removal request
|
||||
Lines.stroke(2f);
|
||||
|
||||
Draw.color(Palette.removeBack);
|
||||
Draw.color(Palette.removeBack);
|
||||
|
||||
float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1;
|
||||
float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1;
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + block.offset(),
|
||||
request.y * tilesize + block.offset() - 1,
|
||||
rad);
|
||||
Lines.square(
|
||||
request.x * tilesize + block.offset(),
|
||||
request.y * tilesize + block.offset() - 1,
|
||||
rad);
|
||||
|
||||
Draw.color(Palette.remove);
|
||||
Draw.color(Palette.remove);
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + block.offset(),
|
||||
request.y * tilesize + block.offset(),
|
||||
rad);
|
||||
}else{
|
||||
//draw place request
|
||||
Lines.stroke(2f);
|
||||
Lines.square(
|
||||
request.x * tilesize + block.offset(),
|
||||
request.y * tilesize + block.offset(),
|
||||
rad);
|
||||
}else{
|
||||
//draw place request
|
||||
Lines.stroke(2f);
|
||||
|
||||
Draw.color(Palette.accentBack);
|
||||
Draw.color(Palette.accentBack);
|
||||
|
||||
float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f;
|
||||
float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f;
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset() - 1,
|
||||
rad);
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset() - 1,
|
||||
rad);
|
||||
|
||||
Draw.color(Palette.accent);
|
||||
Draw.color(Palette.accent);
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset(),
|
||||
rad);
|
||||
}
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset(),
|
||||
rad);
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
//endregion
|
||||
@@ -512,14 +510,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
achievedFlight = true;
|
||||
}
|
||||
|
||||
if(boostHeat <= liftoffBoost + 0.05f && achievedFlight){
|
||||
if(boostHeat <= liftoffBoost + 0.05f && achievedFlight && !mech.flying){
|
||||
if(tile != null){
|
||||
if(mech.shake > 1f){
|
||||
Effects.shake(mech.shake, mech.shake, this);
|
||||
}
|
||||
Effects.effect(UnitFx.unitLand, tile.floor().minimapColor, x, y, tile.floor().isLiquid ? 1f : 0.5f);
|
||||
}
|
||||
if(!mech.flying) mech.onLand(this);
|
||||
mech.onLand(this);
|
||||
achievedFlight = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -259,27 +259,25 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
synchronized(Tile.tileSetLock){
|
||||
//TODO better smoke effect, this one is awful
|
||||
if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) &&
|
||||
Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){
|
||||
//TODO better smoke effect, this one is awful
|
||||
if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) &&
|
||||
Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){
|
||||
|
||||
Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4));
|
||||
}
|
||||
Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4));
|
||||
}
|
||||
|
||||
timeScaleDuration -= Timers.delta();
|
||||
if(timeScaleDuration <= 0f || !tile.block().canOverdrive){
|
||||
timeScale = 1f;
|
||||
}
|
||||
timeScaleDuration -= Timers.delta();
|
||||
if(timeScaleDuration <= 0f || !tile.block().canOverdrive){
|
||||
timeScale = 1f;
|
||||
}
|
||||
|
||||
if(health <= 0){
|
||||
onDeath();
|
||||
}
|
||||
Block previous = tile.block();
|
||||
tile.block().update(tile);
|
||||
if(tile.block() == previous && cons != null){
|
||||
cons.update(this);
|
||||
}
|
||||
if(health <= 0){
|
||||
onDeath();
|
||||
}
|
||||
Block previous = tile.block();
|
||||
tile.block().update(tile);
|
||||
if(tile.block() == previous && cons != null){
|
||||
cons.update(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
|
||||
drownTime = Mathf.clamp(drownTime);
|
||||
|
||||
if(drownTime >= 0.999f){
|
||||
if(drownTime >= 0.999f && !Net.client()){
|
||||
damage(health + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -88,14 +88,13 @@ public interface BuilderTrait extends Entity{
|
||||
}
|
||||
|
||||
default void readBuilding(DataInput input, boolean applyChanges) throws IOException{
|
||||
synchronized(getPlaceQueue()){
|
||||
if(applyChanges) getPlaceQueue().clear();
|
||||
if(applyChanges) getPlaceQueue().clear();
|
||||
|
||||
byte type = input.readByte();
|
||||
if(type != -1){
|
||||
int position = input.readInt();
|
||||
float progress = input.readFloat();
|
||||
BuildRequest request;
|
||||
byte type = input.readByte();
|
||||
if(type != -1){
|
||||
int position = input.readInt();
|
||||
float progress = input.readFloat();
|
||||
BuildRequest request;
|
||||
|
||||
if(type == 1){ //remove
|
||||
request = new BuildRequest(Pos.x(position), Pos.y(position));
|
||||
@@ -105,13 +104,12 @@ public interface BuilderTrait extends Entity{
|
||||
request = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.recipe(recipe));
|
||||
}
|
||||
|
||||
request.progress = progress;
|
||||
request.progress = progress;
|
||||
|
||||
if(applyChanges){
|
||||
getPlaceQueue().addLast(request);
|
||||
}else if(isBuilding()){
|
||||
getCurrentRequest().progress = progress;
|
||||
}
|
||||
if(applyChanges){
|
||||
getPlaceQueue().addLast(request);
|
||||
}else if(isBuilding()){
|
||||
getCurrentRequest().progress = progress;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,13 +124,11 @@ public interface BuilderTrait extends Entity{
|
||||
* Otherwise, a new place request is added to the queue.
|
||||
*/
|
||||
default void replaceBuilding(int x, int y, int rotation, Recipe recipe){
|
||||
synchronized(getPlaceQueue()){
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(request.x == x && request.y == y){
|
||||
clearBuilding();
|
||||
addBuildRequest(request);
|
||||
return;
|
||||
}
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(request.x == x && request.y == y){
|
||||
clearBuilding();
|
||||
addBuildRequest(request);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,18 +142,16 @@ public interface BuilderTrait extends Entity{
|
||||
|
||||
/**Add another build requests to the tail of the queue, if it doesn't exist there yet.*/
|
||||
default void addBuildRequest(BuildRequest place){
|
||||
synchronized(getPlaceQueue()){
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(request.x == place.x && request.y == place.y){
|
||||
return;
|
||||
}
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(request.x == place.x && request.y == place.y){
|
||||
return;
|
||||
}
|
||||
Tile tile = world.tile(place.x, place.y);
|
||||
if(tile != null && tile.entity instanceof BuildEntity){
|
||||
place.progress = tile.<BuildEntity>entity().progress;
|
||||
}
|
||||
getPlaceQueue().addLast(place);
|
||||
}
|
||||
Tile tile = world.tile(place.x, place.y);
|
||||
if(tile != null && tile.entity instanceof BuildEntity){
|
||||
place.progress = tile.<BuildEntity>entity().progress;
|
||||
}
|
||||
getPlaceQueue().addLast(place);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,9 +159,7 @@ public interface BuilderTrait extends Entity{
|
||||
* May return null.
|
||||
*/
|
||||
default BuildRequest getCurrentRequest(){
|
||||
synchronized(getPlaceQueue()){
|
||||
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
|
||||
}
|
||||
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,18 +271,15 @@ public interface BuilderTrait extends Entity{
|
||||
/**Draw placement effects for an entity. This includes mining*/
|
||||
default void drawBuilding(Unit unit){
|
||||
BuildRequest request;
|
||||
|
||||
synchronized(getPlaceQueue()){
|
||||
if(!isBuilding()){
|
||||
if(getMineTile() != null){
|
||||
drawMining(unit);
|
||||
}
|
||||
return;
|
||||
if(!isBuilding()){
|
||||
if(getMineTile() != null){
|
||||
drawMining(unit);
|
||||
}
|
||||
|
||||
request = getCurrentRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
request = getCurrentRequest();
|
||||
|
||||
Tile tile = world.tile(request.x, request.y);
|
||||
|
||||
if(unit.distanceTo(tile) > placeDistance){
|
||||
|
||||
@@ -28,10 +28,7 @@ import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Timer;
|
||||
import io.anuke.ucore.util.*;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -316,8 +313,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
||||
if(target != null) behavior();
|
||||
|
||||
if(!isWave && !isFlying()){
|
||||
x = Mathf.clamp(x, 0, world.width() * tilesize);
|
||||
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
||||
x = Mathf.clamp(x, tilesize/2f, world.width() * tilesize - tilesize/2f);
|
||||
y = Mathf.clamp(y, tilesize/2f, world.height() * tilesize - tilesize/2f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
package io.anuke.mindustry.entities.units.types;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.annotations.Annotations.Loc;
|
||||
import io.anuke.annotations.Annotations.Remote;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.content.fx.UnitFx;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.Predict;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.entities.traits.TargetTrait;
|
||||
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||
import io.anuke.mindustry.entities.units.FlyingUnit;
|
||||
import io.anuke.mindustry.entities.units.UnitCommand;
|
||||
import io.anuke.mindustry.entities.units.UnitState;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.AmmoType;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import java.io.DataInput;
|
||||
@@ -22,7 +28,8 @@ import static io.anuke.mindustry.Vars.players;
|
||||
public class AlphaDrone extends FlyingUnit {
|
||||
static final float followDistance = 80f;
|
||||
|
||||
public Unit leader;
|
||||
public Player leader;
|
||||
|
||||
public final UnitState attack = new UnitState() {
|
||||
@Override
|
||||
public void update() {
|
||||
@@ -32,15 +39,18 @@ public class AlphaDrone extends FlyingUnit {
|
||||
}
|
||||
TargetTrait last = target;
|
||||
target = leader;
|
||||
|
||||
if(last == null){
|
||||
circle(50f);
|
||||
circle(leader.isShooting ? 60f : 0f);
|
||||
}
|
||||
|
||||
target = last;
|
||||
if(distanceTo(leader) < followDistance){
|
||||
targetClosest();
|
||||
}else{
|
||||
target = null;
|
||||
}
|
||||
|
||||
if(target != null){
|
||||
attack(50f);
|
||||
|
||||
@@ -51,9 +61,20 @@ public class AlphaDrone extends FlyingUnit {
|
||||
getWeapon().update(AlphaDrone.this, to.x, to.y);
|
||||
}
|
||||
}
|
||||
|
||||
if(!leader.isShooting && distanceTo(leader) < 8f){
|
||||
Call.onAlphaDroneFade(AlphaDrone.this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Remote(called = Loc.server)
|
||||
public static void onAlphaDroneFade(BaseUnit drone){
|
||||
if(drone == null) return;
|
||||
drone.remove();
|
||||
Effects.effect(UnitFx.pickup, drone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(UnitCommand command){
|
||||
//nuh
|
||||
|
||||
@@ -40,12 +40,11 @@ import static io.anuke.mindustry.Vars.unitGroups;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class Drone extends FlyingUnit implements BuilderTrait{
|
||||
protected static float discoverRange = 120f;
|
||||
protected static int timerRepairEffect = timerIndex++;
|
||||
|
||||
protected Item targetItem;
|
||||
protected Tile mineTile;
|
||||
protected Queue<BuildRequest> placeQueue = new ThreadQueue<>();
|
||||
protected Queue<BuildRequest> placeQueue = new Queue<>();
|
||||
protected boolean isBreaking;
|
||||
|
||||
public final UnitState
|
||||
@@ -250,14 +249,12 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
||||
for(BaseUnit unit : group.all()){
|
||||
if(unit instanceof Drone){
|
||||
Drone drone = (Drone)unit;
|
||||
synchronized(drone.getPlaceQueue()){
|
||||
if(drone.isBuilding()){
|
||||
//stop building if opposite building begins.
|
||||
BuildRequest req = drone.getCurrentRequest();
|
||||
if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){
|
||||
drone.clearBuilding();
|
||||
drone.setState(drone.repair);
|
||||
}
|
||||
if(drone.isBuilding()){
|
||||
//stop building if opposite building begins.
|
||||
BuildRequest req = drone.getCurrentRequest();
|
||||
if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){
|
||||
drone.clearBuilding();
|
||||
drone.setState(drone.repair);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,6 +316,10 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
||||
TileEntity entity = (TileEntity) target;
|
||||
entity.health += type.healSpeed * Timers.delta();
|
||||
entity.health = Mathf.clamp(entity.health, 0, entity.tile.block().health);
|
||||
|
||||
if(timer.get(timerRepairEffect, 30)){
|
||||
Effects.effect(BlockFx.healBlockFull, Palette.heal, entity.x, entity.y, entity.tile.block().size);
|
||||
}
|
||||
}
|
||||
|
||||
updateBuilding(this);
|
||||
|
||||
@@ -19,14 +19,6 @@ public class Unlocks{
|
||||
Settings.setSerializer(ContentType.class, (stream, t) -> stream.writeInt(t.ordinal()), stream -> ContentType.values()[stream.readInt()]);
|
||||
}
|
||||
|
||||
/**Handles the event of content being used by either the player or some block.*/
|
||||
public void handleContentUsed(UnlockableContent content){
|
||||
if(world.getSector() != null){
|
||||
world.getSector().currentMission().onContentUsed(content);
|
||||
}
|
||||
unlockContent(content);
|
||||
}
|
||||
|
||||
/** Returns whether or not this piece of content is unlocked yet.*/
|
||||
public boolean isUnlocked(UnlockableContent content){
|
||||
return rootSet().isUnlocked(content) || currentSet().isUnlocked(content);
|
||||
|
||||
@@ -106,32 +106,29 @@ public class BlockRenderer{
|
||||
for(int x = minx; x <= maxx; x++){
|
||||
for(int y = miny; y <= maxy; y++){
|
||||
boolean expanded = (Math.abs(x - avgx) > rangex || Math.abs(y - avgy) > rangey);
|
||||
Tile tile = world.rawTile(x, y);
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
Tile tile = world.rawTile(x, y);
|
||||
if(tile != null){
|
||||
Block block = tile.block();
|
||||
Team team = tile.getTeam();
|
||||
|
||||
if(tile != null){
|
||||
Block block = tile.block();
|
||||
Team team = tile.getTeam();
|
||||
if(!expanded && block != Blocks.air && world.isAccessible(x, y)){
|
||||
tile.block().drawShadow(tile);
|
||||
}
|
||||
|
||||
if(!expanded && block != Blocks.air && world.isAccessible(x, y)){
|
||||
tile.block().drawShadow(tile);
|
||||
if(block != Blocks.air){
|
||||
if(!expanded){
|
||||
addRequest(tile, Layer.block);
|
||||
teamChecks.add(team.ordinal());
|
||||
}
|
||||
|
||||
if(block != Blocks.air){
|
||||
if(!expanded){
|
||||
addRequest(tile, Layer.block);
|
||||
teamChecks.add(team.ordinal());
|
||||
if(block.expanded || !expanded){
|
||||
if(block.layer != null && block.isLayer(tile)){
|
||||
addRequest(tile, block.layer);
|
||||
}
|
||||
|
||||
if(block.expanded || !expanded){
|
||||
if(block.layer != null && block.isLayer(tile)){
|
||||
addRequest(tile, block.layer);
|
||||
}
|
||||
|
||||
if(block.layer2 != null && block.isLayer2(tile)){
|
||||
addRequest(tile, block.layer2);
|
||||
}
|
||||
if(block.layer2 != null && block.isLayer2(tile)){
|
||||
addRequest(tile, block.layer2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,16 +168,14 @@ public class BlockRenderer{
|
||||
layerBegins(req.layer);
|
||||
}
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
Block block = req.tile.block();
|
||||
Block block = req.tile.block();
|
||||
|
||||
if(req.layer == Layer.block){
|
||||
block.draw(req.tile);
|
||||
}else if(req.layer == block.layer){
|
||||
block.drawLayer(req.tile);
|
||||
}else if(req.layer == block.layer2){
|
||||
block.drawLayer2(req.tile);
|
||||
}
|
||||
if(req.layer == Layer.block){
|
||||
block.draw(req.tile);
|
||||
}else if(req.layer == block.layer){
|
||||
block.drawLayer(req.tile);
|
||||
}else if(req.layer == block.layer2){
|
||||
block.drawLayer2(req.tile);
|
||||
}
|
||||
|
||||
lastLayer = req.layer;
|
||||
@@ -199,17 +194,16 @@ public class BlockRenderer{
|
||||
BlockRequest req = requests.get(index);
|
||||
if(req.tile.getTeam() != team) continue;
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
Block block = req.tile.block();
|
||||
Block block = req.tile.block();
|
||||
|
||||
if(req.layer == Layer.block){
|
||||
block.draw(req.tile);
|
||||
}else if(req.layer == block.layer){
|
||||
block.drawLayer(req.tile);
|
||||
}else if(req.layer == block.layer2){
|
||||
block.drawLayer2(req.tile);
|
||||
}
|
||||
if(req.layer == Layer.block){
|
||||
block.draw(req.tile);
|
||||
}else if(req.layer == block.layer){
|
||||
block.drawLayer(req.tile);
|
||||
}else if(req.layer == block.layer2){
|
||||
block.drawLayer2(req.tile);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,20 +74,18 @@ public class MinimapRenderer implements Disposable{
|
||||
dx = Mathf.clamp(dx, sz, world.width() - sz);
|
||||
dy = Mathf.clamp(dy, sz, world.height() - sz);
|
||||
|
||||
synchronized(units){
|
||||
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
|
||||
Graphics.beginClip(x, y, w, h);
|
||||
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
|
||||
Graphics.beginClip(x, y, w, h);
|
||||
|
||||
for(Unit unit : units){
|
||||
float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h;
|
||||
Draw.color(unit.getTeam().color);
|
||||
Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2));
|
||||
}
|
||||
|
||||
Draw.color();
|
||||
|
||||
Graphics.endClip();
|
||||
for(Unit unit : units){
|
||||
float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h;
|
||||
Draw.color(unit.getTeam().color);
|
||||
Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2));
|
||||
}
|
||||
|
||||
Draw.color();
|
||||
|
||||
Graphics.endClip();
|
||||
}
|
||||
|
||||
public TextureRegion getRegion(){
|
||||
@@ -128,11 +126,9 @@ public class MinimapRenderer implements Disposable{
|
||||
dx = Mathf.clamp(dx, sz, world.width() - sz);
|
||||
dy = Mathf.clamp(dy, sz, world.height() - sz);
|
||||
|
||||
synchronized(units){
|
||||
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
|
||||
units.clear();
|
||||
Units.getNearby(rect, units::add);
|
||||
}
|
||||
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
|
||||
units.clear();
|
||||
Units.getNearby(rect, units::add);
|
||||
}
|
||||
|
||||
private int colorFor(Tile tile){
|
||||
|
||||
@@ -53,10 +53,7 @@ public class OverlayRenderer{
|
||||
//draw config selected block
|
||||
if(input.frag.config.isShown()){
|
||||
Tile tile = input.frag.config.getSelectedTile();
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
tile.block().drawConfigure(tile);
|
||||
}
|
||||
tile.block().drawConfigure(tile);
|
||||
}
|
||||
|
||||
input.drawTop();
|
||||
@@ -113,53 +110,52 @@ public class OverlayRenderer{
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
Block block = target.block();
|
||||
TileEntity entity = target.entity;
|
||||
Block block = target.block();
|
||||
TileEntity entity = target.entity;
|
||||
|
||||
if(entity != null){
|
||||
int[] values = {0, 0};
|
||||
boolean[] doDraw = {false};
|
||||
if(entity != null){
|
||||
int[] values = {0, 0};
|
||||
boolean[] doDraw = {false};
|
||||
|
||||
Runnable drawbars = () -> {
|
||||
for(BlockBar bar : block.bars.list()){
|
||||
float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1]));
|
||||
Runnable drawbars = () -> {
|
||||
for(BlockBar bar : block.bars.list()){
|
||||
float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1]));
|
||||
|
||||
float value = bar.value.get(target);
|
||||
float value = bar.value.get(target);
|
||||
|
||||
if(MathUtils.isEqual(value, -1f)) continue;
|
||||
if(MathUtils.isEqual(value, -1f)) continue;
|
||||
|
||||
if(doDraw[0]){
|
||||
drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value);
|
||||
}
|
||||
|
||||
if(bar.top)
|
||||
values[0]++;
|
||||
else
|
||||
values[1]++;
|
||||
if(doDraw[0]){
|
||||
drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value);
|
||||
}
|
||||
};
|
||||
|
||||
drawbars.run();
|
||||
|
||||
if(values[0] > 0){
|
||||
drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]);
|
||||
if(bar.top)
|
||||
values[0]++;
|
||||
else
|
||||
values[1]++;
|
||||
}
|
||||
};
|
||||
|
||||
if(values[1] > 0){
|
||||
drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]);
|
||||
}
|
||||
drawbars.run();
|
||||
|
||||
doDraw[0] = true;
|
||||
values[0] = 0;
|
||||
values[1] = 1;
|
||||
|
||||
drawbars.run();
|
||||
if(values[0] > 0){
|
||||
drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]);
|
||||
}
|
||||
|
||||
if(values[1] > 0){
|
||||
drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]);
|
||||
}
|
||||
|
||||
target.block().drawSelect(target);
|
||||
doDraw[0] = true;
|
||||
values[0] = 0;
|
||||
values[1] = 1;
|
||||
|
||||
drawbars.run();
|
||||
}
|
||||
|
||||
|
||||
target.block().drawSelect(target);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.anuke.mindustry.graphics;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import io.anuke.ucore.core.Core;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
@@ -168,9 +167,7 @@ public class Shaders{
|
||||
}
|
||||
|
||||
public static class Shield extends Shader{
|
||||
public static final int MAX_HITS = 3 * 64;
|
||||
public Color color = new Color();
|
||||
public FloatArray hits = new FloatArray();
|
||||
//public Color color = new Color();
|
||||
|
||||
public Shield(){
|
||||
super("shield", "default");
|
||||
@@ -179,12 +176,9 @@ public class Shaders{
|
||||
@Override
|
||||
public void apply(){
|
||||
float scaling = Core.cameraScale / 4f / Core.camera.zoom;
|
||||
if(hits.size > 0){
|
||||
shader.setUniform3fv("u_hits[0]", hits.items, 0, Math.min(hits.size, MAX_HITS));
|
||||
shader.setUniformi("u_hitamount", Math.min(hits.size, MAX_HITS) / 3);
|
||||
}
|
||||
|
||||
shader.setUniformf("u_dp", Unit.dp.scl(1f));
|
||||
shader.setUniformf("u_color", color);
|
||||
//shader.setUniformf("u_color", color);
|
||||
shader.setUniformf("u_time", Timers.time() / Unit.dp.scl(1f));
|
||||
shader.setUniformf("u_scaling", scaling);
|
||||
shader.setUniformf("u_offset",
|
||||
|
||||
@@ -22,7 +22,7 @@ public class Trail{
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public synchronized void update(float curx, float cury){
|
||||
public void update(float curx, float cury){
|
||||
if(Vector2.dst(curx, cury, lastX, lastY) >= maxJump){
|
||||
points.clear();
|
||||
}
|
||||
@@ -39,11 +39,11 @@ public class Trail{
|
||||
lastY = cury;
|
||||
}
|
||||
|
||||
public synchronized void clear(){
|
||||
public void clear(){
|
||||
points.clear();
|
||||
}
|
||||
|
||||
public synchronized void draw(Color color, float stroke){
|
||||
public void draw(Color color, float stroke){
|
||||
Draw.color(color);
|
||||
|
||||
for(int i = 0; i < points.size - 2; i += 2){
|
||||
|
||||
@@ -430,7 +430,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
@Override
|
||||
public boolean touchDown(int screenX, int screenY, int pointer, int button){
|
||||
if(state.is(State.menu)) return false;
|
||||
if(state.is(State.menu) || player.isDead()) return false;
|
||||
|
||||
//get tile on cursor
|
||||
Tile cursor = tileAt(screenX, screenY);
|
||||
@@ -519,7 +519,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
@Override
|
||||
public boolean longPress(float x, float y){
|
||||
if(state.is(State.menu) || mode == none) return false;
|
||||
if(state.is(State.menu) || mode == none || player.isDead()) return false;
|
||||
|
||||
//get tile on cursor
|
||||
Tile cursor = tileAt(x, y);
|
||||
@@ -535,7 +535,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
if(mode == breaking){
|
||||
Effects.effect(Fx.tapBlock, cursor.worldx(), cursor.worldy(), 1f);
|
||||
}else{
|
||||
}else if(recipe != null){
|
||||
Effects.effect(Fx.tapBlock, cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe.result.size);
|
||||
}
|
||||
|
||||
@@ -595,7 +595,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(state.is(State.menu)){
|
||||
if(state.is(State.menu) || player.isDead()){
|
||||
selection.clear();
|
||||
removals.clear();
|
||||
mode = none;
|
||||
|
||||
@@ -47,23 +47,15 @@ public class MapIO{
|
||||
data.position(0, 0);
|
||||
|
||||
TileDataMarker marker = data.newDataMarker();
|
||||
Color color = new Color();
|
||||
|
||||
for(int y = 0; y < data.height(); y++){
|
||||
for(int x = 0; x < data.width(); x++){
|
||||
data.read(marker);
|
||||
byte elev = y >= data.height() - 1 ? 0 : data.read(x, y + 1, DataPosition.elevation);
|
||||
Block floor = content.block(marker.floor);
|
||||
Block wall = content.block(marker.wall);
|
||||
int wallc = ColorMapper.getBlockColor(wall);
|
||||
if(wallc == 0 && (wall.update || wall.solid || wall.breakable)) wallc = Team.all[marker.team].intColor;
|
||||
wallc = wallc == 0 ? ColorMapper.getBlockColor(floor) : wallc;
|
||||
if(marker.elevation > 0){
|
||||
float scaling = 1f + marker.elevation / 8f;
|
||||
color.set(wallc);
|
||||
color.mul(scaling, scaling, scaling, 1f);
|
||||
wallc = Color.rgba8888(color);
|
||||
}
|
||||
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, wallc);
|
||||
int color = ColorMapper.colorFor(floor, wall, Team.all[marker.team], marker.elevation + 1, elev > marker.elevation ? (byte)(1 << 6) : (byte)0);
|
||||
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.maps;
|
||||
|
||||
import com.badlogic.gdx.utils.IntIntMap;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
|
||||
public class MapMeta{
|
||||
public final int version;
|
||||
@@ -18,15 +19,19 @@ public class MapMeta{
|
||||
}
|
||||
|
||||
public String author(){
|
||||
return tags.get("author", "unknown");
|
||||
return tag("author");
|
||||
}
|
||||
|
||||
public String description(){
|
||||
return tags.get("description", "unknown");
|
||||
return tag("description");
|
||||
}
|
||||
|
||||
public String name(){
|
||||
return tags.get("name", "unknown");
|
||||
return tag("name");
|
||||
}
|
||||
|
||||
public String tag(String name){
|
||||
return tags.containsKey(name) && !tags.get(name).trim().isEmpty() ? tags.get(name): Bundles.get("text.unknown");
|
||||
}
|
||||
|
||||
public boolean hasOreGen(){
|
||||
|
||||
@@ -23,10 +23,10 @@ public class SectorPresets{
|
||||
|
||||
public SectorPresets(){
|
||||
|
||||
//base tutorial mission (disabled)
|
||||
/*add(new SectorPreset(0, 0,
|
||||
//base tutorial mission
|
||||
add(new SectorPreset(0, 0,
|
||||
TutorialSector.getMissions(),
|
||||
Array.with(Items.copper, Items.coal, Items.lead)));*/
|
||||
Array.with(Items.copper, Items.coal, Items.lead)));
|
||||
|
||||
//command center mission
|
||||
add(new SectorPreset(0, 1,
|
||||
@@ -56,7 +56,8 @@ public class SectorPresets{
|
||||
Missions.blockRecipe(ProductionBlocks.waterExtractor),
|
||||
new ContentMission(Items.biomatter),
|
||||
Missions.blockRecipe(CraftingBlocks.biomatterCompressor),
|
||||
new ContentMission(Liquids.oil)
|
||||
new ContentMission(Liquids.oil),
|
||||
new BattleMission()
|
||||
),
|
||||
Array.with(Items.copper, Items.lead, Items.coal, Items.titanium)));
|
||||
}
|
||||
@@ -69,6 +70,8 @@ public class SectorPresets{
|
||||
return presets.get(x, y);
|
||||
}
|
||||
|
||||
public GridMap<SectorPreset> getPresets() { return presets; }
|
||||
|
||||
private void add(SectorPreset preset){
|
||||
presets.put(preset.x, preset.y, preset);
|
||||
orePresets.put(preset.x, preset.y, preset.ores);
|
||||
|
||||
@@ -41,7 +41,7 @@ public class Sectors{
|
||||
private final AsyncExecutor executor = new AsyncExecutor(6);
|
||||
|
||||
public void playSector(Sector sector){
|
||||
if(sector.hasSave() && SaveIO.breakingVersions.contains(sector.getSave().getBuild())){
|
||||
if(!headless && sector.hasSave() && SaveIO.breakingVersions.contains(sector.getSave().getBuild())){
|
||||
sector.getSave().delete();
|
||||
ui.showInfo("$text.save.old");
|
||||
}
|
||||
@@ -88,8 +88,6 @@ public class Sectors{
|
||||
|
||||
public Difficulty getDifficulty(Sector sector){
|
||||
if(sector.difficulty == 0){
|
||||
//yes, this means hard tutorial difficulty
|
||||
//(((have fun)))
|
||||
return Difficulty.hard;
|
||||
}else if(sector.difficulty < 4){
|
||||
return Difficulty.normal;
|
||||
@@ -158,7 +156,7 @@ public class Sectors{
|
||||
}
|
||||
grid.clear();
|
||||
|
||||
Array<Sector> out = Settings.getObject("sectors", Array.class, Array::new);
|
||||
Array<Sector> out = Settings.getObject("sector-data-2", Array.class, Array::new);
|
||||
|
||||
for(Sector sector : out){
|
||||
|
||||
@@ -187,7 +185,7 @@ public class Sectors{
|
||||
}
|
||||
}
|
||||
|
||||
Settings.putObject("sectors", out);
|
||||
Settings.putObject("sector-data-2", out);
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@@ -229,7 +227,7 @@ public class Sectors{
|
||||
private void generate(Sector sector){
|
||||
|
||||
//50% chance to get a wave mission
|
||||
if(Mathf.randomSeed(sector.getSeed() + 6) < 0.5){
|
||||
if(Mathf.randomSeed(sector.getSeed() + 7) < 0.5){
|
||||
//recipe mission (maybe)
|
||||
addRecipeMission(sector, 3);
|
||||
sector.missions.add(new WaveMission(sector.difficulty*5 + Mathf.randomSeed(sector.getSeed(), 1, 4)*5));
|
||||
|
||||
@@ -2,12 +2,15 @@ package io.anuke.mindustry.maps;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.content.UnitTypes;
|
||||
import io.anuke.mindustry.content.blocks.*;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
import io.anuke.mindustry.maps.missions.*;
|
||||
import io.anuke.mindustry.content.blocks.CraftingBlocks;
|
||||
import io.anuke.mindustry.content.blocks.ProductionBlocks;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.content.blocks.UnitBlocks;
|
||||
import io.anuke.mindustry.maps.missions.BlockMission;
|
||||
import io.anuke.mindustry.maps.missions.ItemMission;
|
||||
import io.anuke.mindustry.maps.missions.Mission;
|
||||
import io.anuke.mindustry.maps.missions.WaveMission;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -16,7 +19,7 @@ public class TutorialSector{
|
||||
private static int droneIndex;
|
||||
|
||||
public static Array<Mission> getMissions(){
|
||||
|
||||
/*
|
||||
Array<Mission> missions = Array.with(
|
||||
new ItemMission(Items.copper, 60).setMessage("$tutorial.begin"),
|
||||
|
||||
@@ -30,7 +33,8 @@ public class TutorialSector{
|
||||
//TODO fill turret with items mission
|
||||
//new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drillturret"),
|
||||
|
||||
new WaveMission(2).setMessage("$tutorial.waves"),
|
||||
// Create a wave mission which spawns the core at 60, 60 rather than in the center of the map
|
||||
new WaveMission(2, 60, 60).setMessage("$tutorial.waves"),
|
||||
|
||||
new ItemMission(Items.lead, 150).setMessage("$tutorial.lead"),
|
||||
new ItemMission(Items.copper, 250).setMessage("$tutorial.morecopper"),
|
||||
@@ -82,9 +86,21 @@ public class TutorialSector{
|
||||
droneIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return missions;
|
||||
return Array.with(
|
||||
//intentionally unlocalized
|
||||
new ItemMission(Items.copper, 50).setMessage("An updated tutorial will return next build.\nFor now, you'll have to deal with... this."),
|
||||
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill),
|
||||
|
||||
new ItemMission(Items.copper, 100),
|
||||
new ItemMission(Items.lead, 50),
|
||||
|
||||
new BlockMission(CraftingBlocks.smelter),
|
||||
new ItemMission(Items.densealloy, 10),
|
||||
new WaveMission(5)
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean supressDrone(){
|
||||
|
||||
@@ -57,6 +57,7 @@ public class FortressGenerator{
|
||||
|
||||
void gen(){
|
||||
gen.setBlock(enemyX, enemyY, StorageBlocks.core, team);
|
||||
gen.random.nextBoolean();
|
||||
|
||||
float difficultyScl = Mathf.clamp(gen.sector.difficulty / 20f + gen.random.range(0.25f), 0f, 0.9999f);
|
||||
float dscl2 = Mathf.clamp(0.5f + gen.sector.difficulty / 20f + gen.random.range(0.1f), 0f, 1.5f);
|
||||
|
||||
@@ -312,7 +312,7 @@ public class WorldGenerator{
|
||||
+ sim3.octaveNoise2D(detailed ? 12 : 9, 0.6, 1f / 1100f, x - 120, y);
|
||||
double lake = sim2.octaveNoise2D(1, 1, 1f / 110f, x, y);
|
||||
|
||||
elevation -= lake/3f;
|
||||
elevation -= Math.pow(lake + 0.15, 5);
|
||||
|
||||
int lerpDst = 20;
|
||||
lerpDst *= lerpDst;
|
||||
@@ -330,9 +330,9 @@ public class WorldGenerator{
|
||||
}
|
||||
}
|
||||
|
||||
if(elevation < 0.7 || lake > 0.96){
|
||||
if(elevation < 0.7){
|
||||
floor = Blocks.deepwater;
|
||||
}else if(elevation < 0.79 || lake > 0.948){
|
||||
}else if(elevation < 0.79){
|
||||
floor = Blocks.water;
|
||||
}else if(elevation < 0.85){
|
||||
floor = Blocks.sand;
|
||||
|
||||
@@ -12,8 +12,24 @@ import io.anuke.ucore.util.Bundles;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class BattleMission extends Mission{
|
||||
public class BattleMission extends MissionWithStartingCore{
|
||||
final int spacing = 30;
|
||||
public static final int defaultXCorePos = 50;
|
||||
public static final int defaultYCorePos = 50;
|
||||
|
||||
/** Creates a battle mission with the player core being at (@defaultXCorePos, @defaultYCorePos) */
|
||||
public BattleMission(){
|
||||
this(defaultXCorePos, defaultYCorePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a wave survival with the player core being at a custom location.
|
||||
* @param xCorePos The X coordinate of the custom core position.
|
||||
* @param yCorePos The Y coordinate of the custom core position.
|
||||
*/
|
||||
public BattleMission(int xCorePos, int yCorePos){
|
||||
super(xCorePos, yCorePos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon(){
|
||||
@@ -37,7 +53,7 @@ public class BattleMission extends Mission{
|
||||
|
||||
@Override
|
||||
public void generate(Generation gen){
|
||||
generateCoreAt(gen, 50, 50, defaultTeam);
|
||||
generateCoreAtFirstSpawnPoint(gen, defaultTeam);
|
||||
|
||||
if(state.teams.get(defaultTeam).cores.size == 0){
|
||||
return;
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.mindustry.Vars;
|
||||
|
||||
/**A mission that just displays some text.*/
|
||||
public class MessageMission extends ActionMission{
|
||||
|
||||
public MessageMission(String text){
|
||||
super(() -> {
|
||||
if(!Vars.headless){
|
||||
Vars.ui.showInfo(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -100,10 +100,4 @@ public abstract class Mission{
|
||||
}
|
||||
|
||||
public void generate(Generation gen){}
|
||||
|
||||
public void generateCoreAt(Generation gen, int coreX, int coreY, Team team){
|
||||
gen.tiles[coreX][coreY].setBlock(StorageBlocks.core);
|
||||
gen.tiles[coreX][coreY].setTeam(team);
|
||||
state.teams.get(team).cores.add(gen.tiles[coreX][coreY]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
|
||||
public abstract class MissionWithStartingCore extends Mission{
|
||||
/** Stores a custom starting location for the core, or null if the default calculation (map center) shall be used. */
|
||||
private final GridPoint2 customStartingPoint;
|
||||
|
||||
/** Default constructor. Missions created this way will have a player starting core in the center of the map. */
|
||||
MissionWithStartingCore(){
|
||||
this.customStartingPoint = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mission with a core on a non-default location.
|
||||
* @param xCorePos The x coordinate of the custom core position.
|
||||
* @param yCorePos The y coordinate of the custom core position.
|
||||
*/
|
||||
MissionWithStartingCore(int xCorePos, int yCorePos){
|
||||
this.customStartingPoint = new GridPoint2(xCorePos, yCorePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a player core based on generation parameters.
|
||||
* @param gen The generation parameters which provide the map size.
|
||||
* @param team The team to generate the core for.
|
||||
*/
|
||||
public void generateCoreAtFirstSpawnPoint(Generation gen, Team team){
|
||||
Array<GridPoint2> spawnPoints = getSpawnPoints(gen);
|
||||
if(spawnPoints == null || spawnPoints.size == 0){
|
||||
throw new IllegalArgumentException("A MissionWithStartingCore subclass did not provide a spawn point in getSpawnPoints(). However, at least one point must always be provided.");
|
||||
}
|
||||
|
||||
Tile startingCoreTile = gen.tiles[spawnPoints.first().x][spawnPoints.first().y];
|
||||
startingCoreTile.setBlock(StorageBlocks.core);
|
||||
startingCoreTile.setTeam(team);
|
||||
state.teams.get(team).cores.add(startingCoreTile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the spawn point in the center of the map or at a custom location which was provided through the constructor.
|
||||
* @param gen The generation parameters which provide the map size.
|
||||
* @return The center of the map or a custom location.
|
||||
* @implNote Must return an array with at least one entry.
|
||||
*/
|
||||
@Override
|
||||
public Array<GridPoint2> getSpawnPoints(Generation gen){
|
||||
if(this.customStartingPoint == null){
|
||||
return Array.with(new GridPoint2(gen.width / 2, gen.height / 2));
|
||||
}else{
|
||||
return Array.with(this.customStartingPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
@@ -9,16 +8,31 @@ import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.Waves;
|
||||
import io.anuke.mindustry.maps.Sector;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
import static io.anuke.mindustry.Vars.waveTeam;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class WaveMission extends Mission{
|
||||
public class WaveMission extends MissionWithStartingCore{
|
||||
private final int target;
|
||||
|
||||
/**
|
||||
* Creates a wave survival mission with the player core being in the center of the map.
|
||||
* @param target The number of waves to be survived.
|
||||
*/
|
||||
public WaveMission(int target){
|
||||
super();
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a wave survival with the player core being at a custom location.
|
||||
* @param target The number of waves to be survived.
|
||||
* @param xCorePos The X coordinate of the custom core position.
|
||||
* @param yCorePos The Y coordinate of the custom core position.
|
||||
*/
|
||||
public WaveMission(int target, int xCorePos, int yCorePos){
|
||||
super(xCorePos, yCorePos);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@@ -29,8 +43,7 @@ public class WaveMission extends Mission{
|
||||
|
||||
@Override
|
||||
public void generate(Generation gen){
|
||||
int coreX = gen.width/2, coreY = gen.height/2;
|
||||
generateCoreAt(gen, coreX, coreY, Team.blue);
|
||||
generateCoreAtFirstSpawnPoint(gen, Team.blue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +62,7 @@ public class WaveMission extends Mission{
|
||||
public String displayString(){
|
||||
return state.wave > target ?
|
||||
Bundles.format(
|
||||
Vars.unitGroups[Vars.waveTeam.ordinal()].size() > 1 ?
|
||||
Vars.unitGroups[Vars.waveTeam.ordinal()].size() > 1 && !Net.client() ?
|
||||
"text.mission.wave.enemies" :
|
||||
"text.mission.wave.enemy", target, target, Vars.unitGroups[Vars.waveTeam.ordinal()].size()) :
|
||||
Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60));
|
||||
@@ -71,9 +84,4 @@ public class WaveMission extends Mission{
|
||||
public boolean isComplete(){
|
||||
return state.wave > target && Vars.unitGroups[Vars.waveTeam.ordinal()].size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array<GridPoint2> getSpawnPoints(Generation gen){
|
||||
return Array.with(new GridPoint2(gen.width/2, gen.height/2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class Net{
|
||||
}
|
||||
|
||||
String error = t.getMessage() == null ? "" : t.getMessage().toLowerCase();
|
||||
String type = error.getClass().toString().toLowerCase();
|
||||
String type = t.getClass().toString().toLowerCase();
|
||||
|
||||
if(error.equals("mismatch")){
|
||||
error = Bundles.get("text.error.mismatch");
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
package io.anuke.mindustry.ui;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture.TextureFilter;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.ucore.core.Core;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.scene.Element;
|
||||
import io.anuke.ucore.scene.event.InputEvent;
|
||||
import io.anuke.ucore.scene.event.InputListener;
|
||||
import io.anuke.ucore.scene.style.TextureRegionDrawable;
|
||||
import io.anuke.ucore.scene.ui.Image;
|
||||
import io.anuke.ucore.scene.ui.layout.Table;
|
||||
|
||||
import static io.anuke.mindustry.Vars.renderer;
|
||||
import static io.anuke.mindustry.Vars.showFog;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Minimap extends Table{
|
||||
|
||||
@@ -25,14 +21,15 @@ public class Minimap extends Table{
|
||||
margin(5);
|
||||
marginBottom(10);
|
||||
|
||||
Image image = new Image(new TextureRegionDrawable(new TextureRegion())){
|
||||
TextureRegion r = new TextureRegion();
|
||||
|
||||
Element elem = new Element(){
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha){
|
||||
public void draw(){
|
||||
if(renderer.minimap.getRegion() == null) return;
|
||||
|
||||
TextureRegionDrawable draw = (TextureRegionDrawable) getDrawable();
|
||||
draw.getRegion().setRegion(renderer.minimap.getRegion());
|
||||
super.draw(batch, parentAlpha);
|
||||
Draw.crect(renderer.minimap.getRegion(), x, y, width, height);
|
||||
|
||||
if(renderer.minimap.getTexture() != null){
|
||||
renderer.minimap.drawEntities(x, y, width, height);
|
||||
}
|
||||
@@ -40,7 +37,7 @@ public class Minimap extends Table{
|
||||
if(showFog){
|
||||
renderer.fog.getTexture().setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
|
||||
|
||||
TextureRegion r = draw.getRegion();
|
||||
r.setRegion(renderer.minimap.getRegion());
|
||||
float pad = renderer.fog.getPadding();
|
||||
|
||||
float px = r.getU() * world.width() + pad;
|
||||
@@ -55,7 +52,7 @@ public class Minimap extends Table{
|
||||
r.setV2(1f - py2 / (world.height() + pad*2f));
|
||||
|
||||
Graphics.shader(Shaders.fog);
|
||||
super.draw(batch, parentAlpha);
|
||||
Draw.crect(r, x, y, width, height);
|
||||
Graphics.shader();
|
||||
|
||||
renderer.fog.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
|
||||
@@ -70,7 +67,7 @@ public class Minimap extends Table{
|
||||
}
|
||||
});
|
||||
|
||||
image.update(() -> {
|
||||
elem.update(() -> {
|
||||
|
||||
Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true);
|
||||
if(e != null && e.isDescendantOf(this)){
|
||||
@@ -79,6 +76,7 @@ public class Minimap extends Table{
|
||||
Core.scene.setScrollFocus(null);
|
||||
}
|
||||
});
|
||||
add(image).size(140f, 140f);
|
||||
|
||||
add(elem).size(140f, 140f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ public class PausedDialog extends FloatingDialog{
|
||||
hide();
|
||||
});
|
||||
|
||||
content().row();
|
||||
content().addButton("$text.unlocks", ui.unlocks::show);
|
||||
|
||||
content().row();
|
||||
content().addButton("$text.settings", ui.settings::show);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class SectorsDialog extends FloatingDialog{
|
||||
margin(0);
|
||||
getTitleTable().clear();
|
||||
clear();
|
||||
stack(content(), buttons(), container).grow();
|
||||
stack(content(), container, buttons()).grow();
|
||||
|
||||
shown(this::setup);
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class SectorsDialog extends FloatingDialog{
|
||||
class SectorView extends Element{
|
||||
float lastX, lastY;
|
||||
boolean clicked = false;
|
||||
float panX = 0, panY = -sectorSize/2f;
|
||||
float panX = sectorSize/2f, panY = sectorSize/2f;
|
||||
|
||||
SectorView(){
|
||||
addListener(new InputListener(){
|
||||
|
||||
@@ -130,13 +130,16 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
sound.volumePrefs();
|
||||
|
||||
game.screenshakePref();
|
||||
//game.checkPref("smoothcam", true);
|
||||
game.checkPref("effects", true);
|
||||
if(mobile){
|
||||
game.checkPref("autotarget", true);
|
||||
}
|
||||
//game.sliderPref("sensitivity", 100, 10, 300, i -> i + "%");
|
||||
game.sliderPref("saveinterval", 60, 10, 5 * 120, i -> Bundles.format("setting.seconds", i));
|
||||
game.sliderPref("saveinterval", 120, 10, 5 * 120, i -> Bundles.format("setting.seconds", i));
|
||||
|
||||
if(!mobile){
|
||||
game.checkPref("crashreport", true);
|
||||
}
|
||||
|
||||
game.pref(new Setting(){
|
||||
@Override
|
||||
public void add(SettingsTable table){
|
||||
@@ -187,12 +190,6 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
});
|
||||
|
||||
graphics.sliderPref("fpscap", 125, 5, 125, 5, s -> (s > 120 ? Bundles.get("setting.fpscap.none") : Bundles.format("setting.fpscap.text", s)));
|
||||
graphics.checkPref("multithread", mobile, threads::setEnabled);
|
||||
|
||||
if(Settings.getBool("multithread")){
|
||||
threads.setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
if(!mobile){
|
||||
graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b));
|
||||
|
||||
@@ -107,7 +107,7 @@ public class HudFragment extends Fragment{
|
||||
|
||||
Stack stack = new Stack();
|
||||
TextButton waves = new TextButton("");
|
||||
Table btable = new Table().margin(14);
|
||||
Table btable = new Table().margin(0);
|
||||
|
||||
stack.add(waves);
|
||||
stack.add(btable);
|
||||
@@ -126,7 +126,6 @@ public class HudFragment extends Fragment{
|
||||
IntFormat tps = new IntFormat("text.tps");
|
||||
IntFormat ping = new IntFormat("text.ping");
|
||||
t.label(() -> fps.get(Gdx.graphics.getFramesPerSecond())).padRight(10);
|
||||
t.label(() -> tps.get(threads.getTPS())).visible(() -> threads.isEnabled());
|
||||
t.row();
|
||||
if(Net.hasClient()){
|
||||
t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2);
|
||||
@@ -375,7 +374,7 @@ public class HudFragment extends Fragment{
|
||||
(!state.mode.disableWaveTimer ?
|
||||
Bundles.format("text.wave.waiting", (int)(state.wavetime/60)) :
|
||||
Bundles.get("text.waiting"))) :
|
||||
Bundles.format("text.mission.display", world.getSector().currentMission().displayString())).growX();
|
||||
Bundles.format("text.mission.display", world.getSector().currentMission().displayString())).growX().pad(8f);
|
||||
|
||||
table.clicked(() -> {
|
||||
if(world.getSector() != null && world.getSector().currentMission().hasMessage()){
|
||||
|
||||
@@ -230,7 +230,7 @@ public class Block extends BaseBlock {
|
||||
/**Call when some content is produced. This unlocks the content if it is applicable.*/
|
||||
public void useContent(Tile tile, UnlockableContent content){
|
||||
if(!headless && tile.getTeam() == players[0].getTeam()){
|
||||
control.unlocks.handleContentUsed(content);
|
||||
logic.handleContent(content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,7 @@ public class ColorMapper implements ContentList{
|
||||
private static ObjectIntMap<Block> colorMap = new ObjectIntMap<>();
|
||||
private static ThreadLocal<Color> tmpColors = new ThreadLocal<>();
|
||||
|
||||
public static Block getByColor(int color){
|
||||
return blockMap.get(color);
|
||||
}
|
||||
|
||||
public static int getBlockColor(Block block){
|
||||
private static int getBlockColor(Block block){
|
||||
return colorMap.get(block, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
|
||||
public class Tile implements PosTrait, TargetTrait{
|
||||
public static final Object tileSetLock = new Object();
|
||||
/**
|
||||
* The coordinates of the core tile this is linked to, in the form of two bytes packed into one.
|
||||
* This is relative to the block it is linked to; negate coords to find the link.
|
||||
@@ -130,8 +129,9 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
return wall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Team getTeam(){
|
||||
return Team.all[team];
|
||||
return Team.all[target().team];
|
||||
}
|
||||
|
||||
public void setTeam(Team team){
|
||||
@@ -143,33 +143,27 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
}
|
||||
|
||||
public void setBlock(Block type, int rotation){
|
||||
synchronized(tileSetLock){
|
||||
preChanged();
|
||||
if(rotation < 0) rotation = (-rotation + 2);
|
||||
this.wall = type;
|
||||
this.link = 0;
|
||||
setRotation((byte) (rotation % 4));
|
||||
changed();
|
||||
}
|
||||
preChanged();
|
||||
if(rotation < 0) rotation = (-rotation + 2);
|
||||
this.wall = type;
|
||||
this.link = 0;
|
||||
setRotation((byte) (rotation % 4));
|
||||
changed();
|
||||
}
|
||||
|
||||
public void setBlock(Block type, Team team){
|
||||
synchronized(tileSetLock){
|
||||
preChanged();
|
||||
this.wall = type;
|
||||
this.team = (byte)team.ordinal();
|
||||
this.link = 0;
|
||||
changed();
|
||||
}
|
||||
preChanged();
|
||||
this.wall = type;
|
||||
this.team = (byte)team.ordinal();
|
||||
this.link = 0;
|
||||
changed();
|
||||
}
|
||||
|
||||
public void setBlock(Block type){
|
||||
synchronized(tileSetLock){
|
||||
preChanged();
|
||||
this.wall = type;
|
||||
this.link = 0;
|
||||
changed();
|
||||
}
|
||||
preChanged();
|
||||
this.wall = type;
|
||||
this.link = 0;
|
||||
changed();
|
||||
}
|
||||
|
||||
public void setFloor(Floor type){
|
||||
@@ -266,7 +260,7 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
* Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock.
|
||||
* This array contains all linked tiles, including this tile itself.
|
||||
*/
|
||||
public synchronized Array<Tile> getLinkedTiles(Array<Tile> tmpArray){
|
||||
public Array<Tile> getLinkedTiles(Array<Tile> tmpArray){
|
||||
Block block = block();
|
||||
tmpArray.clear();
|
||||
if(block.isMultiblock()){
|
||||
@@ -288,7 +282,7 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
* Returns the list of all tiles linked to this multiblock if it were this block, or an empty array if it's not a multiblock.
|
||||
* This array contains all linked tiles, including this tile itself.
|
||||
*/
|
||||
public synchronized Array<Tile> getLinkedTilesAs(Block block, Array<Tile> tmpArray){
|
||||
public Array<Tile> getLinkedTilesAs(Block block, Array<Tile> tmpArray){
|
||||
tmpArray.clear();
|
||||
if(block.isMultiblock()){
|
||||
int offsetx = -(block.size - 1) / 2;
|
||||
@@ -390,52 +384,47 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
}
|
||||
|
||||
private void preChanged(){
|
||||
synchronized(tileSetLock){
|
||||
block().removed(this);
|
||||
if(entity != null){
|
||||
entity.removeFromProximity();
|
||||
}
|
||||
team = 0;
|
||||
block().removed(this);
|
||||
if(entity != null){
|
||||
entity.removeFromProximity();
|
||||
}
|
||||
team = 0;
|
||||
}
|
||||
|
||||
private void changed(){
|
||||
|
||||
synchronized(tileSetLock){
|
||||
if(entity != null){
|
||||
entity.remove();
|
||||
entity = null;
|
||||
}
|
||||
|
||||
Block block = block();
|
||||
|
||||
if(block.hasEntity()){
|
||||
entity = block.newEntity().init(this, block.update);
|
||||
entity.cons = new ConsumeModule();
|
||||
if(block.hasItems) entity.items = new ItemModule();
|
||||
if(block.hasLiquids) entity.liquids = new LiquidModule();
|
||||
if(block.hasPower){
|
||||
entity.power = new PowerModule();
|
||||
entity.power.graph.add(this);
|
||||
}
|
||||
|
||||
if(!world.isGenerating()){
|
||||
entity.updateProximity();
|
||||
}
|
||||
}else if(!(block instanceof BlockPart) && !world.isGenerating()){
|
||||
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
|
||||
for(GridPoint2 p : Geometry.d4){
|
||||
Tile tile = world.tile(x + p.x, y + p.y);
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
tile.block().onProximityUpdate(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateOcclusion();
|
||||
if(entity != null){
|
||||
entity.remove();
|
||||
entity = null;
|
||||
}
|
||||
|
||||
Block block = block();
|
||||
|
||||
if(block.hasEntity()){
|
||||
entity = block.newEntity().init(this, block.update);
|
||||
entity.cons = new ConsumeModule();
|
||||
if(block.hasItems) entity.items = new ItemModule();
|
||||
if(block.hasLiquids) entity.liquids = new LiquidModule();
|
||||
if(block.hasPower){
|
||||
entity.power = new PowerModule();
|
||||
entity.power.graph.add(this);
|
||||
}
|
||||
|
||||
if(!world.isGenerating()){
|
||||
entity.updateProximity();
|
||||
}
|
||||
}else if(!(block instanceof BlockPart) && !world.isGenerating()){
|
||||
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
|
||||
for(GridPoint2 p : Geometry.d4){
|
||||
Tile tile = world.tile(x + p.x, y + p.y);
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
tile.block().onProximityUpdate(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateOcclusion();
|
||||
|
||||
world.notifyChanged(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter;
|
||||
import io.anuke.mindustry.world.meta.BlockStat;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
@@ -15,9 +16,7 @@ import static io.anuke.mindustry.Vars.tilesize;
|
||||
public abstract class ItemLiquidGenerator extends ItemGenerator{
|
||||
protected float minLiquidEfficiency = 0.2f;
|
||||
protected float powerPerLiquid = 0.13f;
|
||||
/**
|
||||
* Maximum liquid used per frame.
|
||||
*/
|
||||
/**Maximum liquid used per frame.*/
|
||||
protected float maxLiquidGenerate = 0.4f;
|
||||
|
||||
public ItemLiquidGenerator(String name){
|
||||
@@ -28,6 +27,12 @@ public abstract class ItemLiquidGenerator extends ItemGenerator{
|
||||
consumes.add(new ConsumeLiquidFilter(liquid -> getLiquidEfficiency(liquid) >= minLiquidEfficiency, 0.001f, true)).update(false).optional(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
super.init();
|
||||
stats.remove(BlockStat.liquidFuelUse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Tile tile){
|
||||
ItemGeneratorEntity entity = tile.entity();
|
||||
|
||||
@@ -13,19 +13,21 @@ import io.anuke.ucore.util.Mathf;
|
||||
|
||||
public abstract class LiquidGenerator extends PowerGenerator{
|
||||
protected float minEfficiency = 0.2f;
|
||||
protected float powerPerLiquid = 0.13f;
|
||||
/**
|
||||
* Maximum liquid used per frame.
|
||||
*/
|
||||
protected float maxLiquidGenerate = 0.4f;
|
||||
protected float powerPerLiquid;
|
||||
/**Maximum liquid used per frame.*/
|
||||
protected float maxLiquidGenerate;
|
||||
protected Effect generateEffect = BlockFx.generatespark;
|
||||
|
||||
public LiquidGenerator(String name){
|
||||
super(name);
|
||||
liquidCapacity = 30f;
|
||||
hasLiquids = true;
|
||||
}
|
||||
|
||||
consumes.add(new ConsumeLiquidFilter(liquid -> getEfficiency(liquid) >= minEfficiency, 0.001f)).update(false);
|
||||
@Override
|
||||
public void setStats(){
|
||||
consumes.add(new ConsumeLiquidFilter(liquid -> getEfficiency(liquid) >= minEfficiency, maxLiquidGenerate)).update(false);
|
||||
super.setStats();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,7 @@ public class LiquidHeatGenerator extends LiquidGenerator{
|
||||
public void setStats(){
|
||||
super.setStats();
|
||||
|
||||
stats.add(BlockStat.basePowerGeneration, maxLiquidGenerate * powerPerLiquid * 60f * 0.4f, StatUnit.powerSecond);
|
||||
stats.add(BlockStat.basePowerGeneration, maxLiquidGenerate * powerPerLiquid * 60f, StatUnit.powerSecond);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.badlogic.gdx.utils.IntSet;
|
||||
import com.badlogic.gdx.utils.ObjectSet;
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
|
||||
import static io.anuke.mindustry.Vars.threads;
|
||||
|
||||
@@ -37,63 +38,38 @@ public class PowerGraph{
|
||||
|
||||
lastFrameUpdated = threads.getFrameID();
|
||||
|
||||
boolean charge = false;
|
||||
|
||||
float totalInput = 0f;
|
||||
float bufferInput = 0f;
|
||||
|
||||
for(Tile producer : producers){
|
||||
if (producer.block().consumesPower) {
|
||||
bufferInput += producer.entity.power.amount;
|
||||
} else {
|
||||
totalInput += producer.entity.power.amount;
|
||||
}
|
||||
totalInput += producer.entity.power.amount;
|
||||
}
|
||||
|
||||
float maxOutput = 0f;
|
||||
float bufferOutput = 0f;
|
||||
for(Tile consumer : consumers){
|
||||
if (consumer.block().outputsPower) {
|
||||
bufferOutput += consumer.block().powerCapacity - consumer.entity.power.amount;
|
||||
} else {
|
||||
maxOutput += consumer.block().powerCapacity - consumer.entity.power.amount;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxOutput < totalInput) {
|
||||
charge = true;
|
||||
}
|
||||
|
||||
if (totalInput + bufferInput <= 0.0001f || maxOutput + bufferOutput <= 0.0001f) {
|
||||
return;
|
||||
}
|
||||
|
||||
float bufferUsed = 0;
|
||||
if (charge) {
|
||||
bufferUsed = Math.min((totalInput - maxOutput) / bufferOutput, 1f);
|
||||
} else {
|
||||
bufferUsed = Math.min((maxOutput - totalInput) / bufferInput, 1f);
|
||||
}
|
||||
|
||||
float inputUsed = charge ? Math.min((maxOutput + bufferOutput) / totalInput, 1f) : 1f;
|
||||
for(Tile producer : producers){
|
||||
if (producer.block().consumesPower) {
|
||||
if (!charge) {
|
||||
producer.entity.power.amount -= producer.entity.power.amount * bufferUsed;
|
||||
}
|
||||
float accumulator = producer.entity.power.amount;
|
||||
|
||||
if(accumulator <= 0.0001f) continue;
|
||||
|
||||
float toEach = accumulator / consumers.size;
|
||||
float outputs = 0f;
|
||||
|
||||
for(Tile tile : consumers){
|
||||
outputs += Math.min(tile.block().powerCapacity - tile.entity.power.amount, toEach) / toEach;
|
||||
}
|
||||
|
||||
float finalEach = toEach / outputs * Timers.delta();
|
||||
float buffer = 0f;
|
||||
|
||||
if(Float.isNaN(finalEach) || Float.isInfinite(finalEach)){
|
||||
continue;
|
||||
}
|
||||
producer.entity.power.amount -= producer.entity.power.amount * inputUsed;
|
||||
}
|
||||
|
||||
float outputSatisfied = charge ? 1f : Math.min((totalInput + bufferInput) / maxOutput, 1f);
|
||||
for(Tile consumer : consumers){
|
||||
if (consumer.block().outputsPower) {
|
||||
if (charge) {
|
||||
consumer.entity.power.amount += (consumer.block().powerCapacity - consumer.entity.power.amount) * bufferUsed;
|
||||
}
|
||||
continue;
|
||||
for(Tile tile : consumers){
|
||||
float used = Math.min(tile.block().powerCapacity - tile.entity.power.amount, finalEach) * accumulator / totalInput;
|
||||
buffer += used;
|
||||
tile.entity.power.amount += used;
|
||||
}
|
||||
consumer.entity.power.amount += (consumer.block().powerCapacity - consumer.entity.power.amount) * outputSatisfied;
|
||||
|
||||
producer.entity.power.amount -= buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public class MechPad extends Block{
|
||||
|
||||
if(checkValidTap(tile, player)){
|
||||
Call.onMechFactoryTap(player, tile);
|
||||
}else if(player.isLocal && mobile){
|
||||
}else if(player.isLocal && mobile && !player.isDead()){
|
||||
player.moveTarget = tile.entity;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user