diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 4c8606ea07..a948e0b3bb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -17,7 +17,9 @@ assignees: '' **Link(s) to mod(s) used**: *The mod repositories or zip files that are related to the issue, if applicable.* -**Save file**: *The (zipped) save file you were playing on when the bug happened. THIS IS REQUIRED FOR ANY ISSUE HAPPENING IN-GAME, REGARDLESS OF WHETHER YOU THINK IT HAPPENS EVERYWHERE. DO NOT DELETE OR OMIT THIS LINE UNLESS YOU ARE SURE THAT THE ISSUE DOES NOT HAPPEN IN-GAME.* +**Save file**: *The (zipped) save file you were playing on when the bug happened. THIS IS REQUIRED FOR ANY ISSUE HAPPENING IN-GAME OR IN MULTIPLAYER, REGARDLESS OF WHETHER YOU THINK IT HAPPENS EVERYWHERE. DO NOT DELETE OR OMIT THIS LINE UNLESS YOU ARE SURE THAT THE ISSUE DOES NOT HAPPEN IN-GAME.* + +If you remove the line above without reading it properly and understanding what it means, I will reap your soul. Even if you're playing on someone's server, you can still save the game to a slot. **Crash report**: *The contents of relevant crash report files. REQUIRED if you are reporting a crash.* diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index bc993bae07..e98615e268 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -15,9 +15,11 @@ jobs: uses: actions/setup-java@v1 with: java-version: 14 + - name: Set env + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - name: Create artifacts run: | - ./gradlew desktop:dist server:dist core:javadoc -Pbuildversion=${GITHUB_REF:1} + ./gradlew desktop:dist server:dist core:javadoc -Pbuildversion=${RELEASE_VERSION:1} - name: Update docs run: | cd ../ @@ -27,24 +29,24 @@ jobs: cp -a Mindustry/core/build/docs/javadoc/. docs/ cd docs git add . - git commit -m "Update ${GITHUB_REF:1}" + git commit -m "Update ${RELEASE_VERSION:1}" git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/MindustryGame/docs cd ../Mindustry - name: Add Arc release run: | git clone --depth=1 --branch=master https://github.com/Anuken/Arc ../Arc cd ../Arc - git tag ${GITHUB_REF} - git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/Anuken/Arc ${GITHUB_REF}; + git tag ${RELEASE_VERSION} + git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/Anuken/Arc ${RELEASE_VERSION}; cd ../Mindustry - name: Update F-Droid build string run: | git clone --depth=1 --branch=master https://github.com/Anuken/MindustryBuilds ../MindustryBuilds cd ../MindustryBuilds - echo "Updating version to ${GITHUB_REF:1}" - echo versionName=6-fdroid-${GITHUB_REF:1}$'\n'versionCode=${GITHUB_REF:1} > version_fdroid.txt + echo "Updating version to ${RELEASE_VERSION:1}" + echo versionName=6-fdroid-${RELEASE_VERSION:1}$'\n'versionCode=${RELEASE_VERSION:1} > version_fdroid.txt git add . - git commit -m "Updating to build ${GITHUB_REF:1}" + git commit -m "Updating to build ${RELEASE_VERSION:1}" cd ../Mindustry - name: Upload client artifacts uses: svenstaro/upload-release-action@v2 diff --git a/README.md b/README.md index 882d0b15ae..97aece9742 100644 --- a/README.md +++ b/README.md @@ -61,5 +61,5 @@ Post feature requests and feedback [here](https://github.com/Anuken/Mindustry-Su ## Downloads -| [![](https://static.itch.io/images/badge.svg)](https://anuke.itch.io/mindustry) | [![](https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png)](https://play.google.com/store/apps/details?id=io.anuke.mindustry) | [![](https://fdroid.gitlab.io/artwork/badge/get-it-on.png)](https://f-droid.org/packages/io.anuke.mindustry) | [![](https://flathub.org/assets/badges/flathub-badge-en.svg)](https://flathub.org/apps/details/com.github.Anuken.Mindustry) | +| [![](https://static.itch.io/images/badge.svg)](https://anuke.itch.io/mindustry) | [![](https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png)](https://play.google.com/store/apps/details?id=io.anuke.mindustry) | [![](https://fdroid.gitlab.io/artwork/badge/get-it-on.png)](https://f-droid.org/packages/io.anuke.mindustry) | [![](https://flathub.org/assets/badges/flathub-badge-en.svg)](https://flathub.org/apps/details/com.github.Anuken.Mindustry) |--- |--- |--- |--- | diff --git a/build.gradle b/build.gradle index 5adc73c9ee..79290c6ac8 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ allprojects{ ext{ versionNumber = '6' - if(!project.hasProperty("versionModifier")) versionModifier = 'beta' + if(!project.hasProperty("versionModifier")) versionModifier = 'release' if(!project.hasProperty("versionType")) versionType = 'official' appName = 'Mindustry' steamworksVersion = '891ed912791e01fe9ee6237a6497e5212b85c256' diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index a5303bc3d6..4854fcd313 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -99,7 +99,7 @@ preparingconfig = Preparing Config preparingcontent = Preparing Content uploadingcontent = Uploading Content uploadingpreviewfile = Uploading Preview File -committingchanges = Comitting Changes +committingchanges = Committing Changes done = Done feature.unsupported = Your device does not support this feature. @@ -1460,7 +1460,7 @@ unit.reign.description = Fires a barrage of massive piercing bullets at all near unit.nova.description = Fires laser bolts that damage enemies and repair allied structures. Capable of flight. unit.pulsar.description = Fires arcs of electricity that damage enemies and repair allied structures. Capable of flight. unit.quasar.description = Fires piercing laser beams that damage enemies and repair allied structures. Capable of flight. Shielded. -unit.vela.description = Fires a massive continuous laser beam that damages enemies, causes fires and repair allied structures. Capable of flight. +unit.vela.description = Fires a massive continuous laser beam that damages enemies, causes fires and repairs allied structures. Capable of flight. unit.corvus.description = Fires a massive laser blast that damages enemies and repairs allied structures. Can step over most terrain. unit.crawler.description = Runs toward enemies and self-destructs, causing a large explosion. unit.atrax.description = Fires debilitating orbs of slag at ground targets. Can step over most terrain. diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties index dad6c44fa3..4c0ded36a7 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -7,9 +7,9 @@ link.reddit.description = El subreddit de Mindustry link.github.description = Código fuente del juego link.changelog.description = Lista de actualizaciones link.dev-builds.description = Versiones en desarrollo inestables -link.trello.description = Tablero de Trello oficial para las características planificadas -link.itch.io.description = itch.io es la página donde podes descargar las versiones para PC y Servidor -link.google-play.description = Ficha en la Google Play Store +link.trello.description = Tablón de Trello oficial para las características planificadas +link.itch.io.description = Página de itch.io, donde puedes descargar las versiones para PC +link.google-play.description = Ver en Google Play Store link.f-droid.description = Página de F-Droid del juego link.wiki.description = Wiki oficial de Mindustry link.suggestions.description = Sugerir nuevas funciones @@ -17,13 +17,13 @@ linkfail = ¡Error al abrir el enlace!\nLa URL ha sido copiada a su portapapeles screenshot = Captura de pantalla guardada en {0} screenshot.invalid = Mapa demasiado grande, no hay suficiente memoria para la captura de pantalla. gameover = Tu núcleo ha sido destruido. +gameover.disconnect = Desconectado gameover.pvp = ¡El equipo[accent] {0}[] ha ganado! +gameover.waiting = [accent]Esperando el próximo mapa... highscore = [accent]¡Nuevo récord de puntuación! -copied = Copiado. - -indev.popup = [accent]v6[] esta actualmente en [accent]alpha[].\n[lightgray]Esto significa que:[]\n[scarlet]- El modo de campaña no esta totalmente acabado[]\n-Falta contenido dentro del juego\n - Mucha de la [scarlet]AI de enemigos[] no funciona totalmente\n- Algunas unidades todavia no estan acabadas\n- Todo lo que ves es probable que sea cambiado o removido.\n\nReporta bugs o crasheos en [accent]Github[]. -indev.notready = Esta parte del juego no esta lista todavia. - +copied = Copiado +indev.notready = Esta parte del juego no esta lista aún. +indev.campaign = [accent]Has llegado al final de la campaña![]\n\nEsto es todo lo lejos que puedes llegar por ahora.\nLos viajes interplanetarios se añadirán en futuras actualizaciones. load.sound = Sonidos load.map = Mapas @@ -34,31 +34,32 @@ load.mod = Mods load.scripts = Scripts be.update = Una nueva e innovadora versión disponible: -be.update.confirm = Descargar y reiniciar ahora? +be.update.confirm = ¿Descargar y reiniciar ahora? be.updating = Actualizando... be.ignore = Ignorar be.noupdates = No se encontraron actualizaciones. be.check = Revisando actualizaciones -schematic = Esquema -schematic.add = Guardar esquema... -schematics = Esquemas -schematic.replace = Un esquema con ese nombre ya existe. ¿Deseas remplazarlo? -schematic.exists = Un esquema con ese nombre ya existe. -schematic.import = Importar esquema... +schematic = Plantilla +schematic.add = Guardar plantilla... +schematics = Plantillas +schematic.replace = Ya existe una plantilla con ese nombre. ¿Deseas remplazarla? +schematic.exists = Ya existe una plantilla con ese nombre. +schematic.import = Importar plantilla... schematic.exportfile = Exportar archivo schematic.importfile = Importar archivo schematic.browseworkshop = Buscar en el Steam Workshop schematic.copy = Copiar al portapapeles. schematic.copy.import = Importar desde el portapapeles. schematic.shareworkshop = Compartir en el Steam Workshop -schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Girar esquemático -schematic.saved = Esquemático guardado. -schematic.delete.confirm = Esto esquemático será completamente borrado. -schematic.rename = Renombrar esquemático +schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Girar plantilla +schematic.saved = Plantilla guardada. +schematic.delete.confirm = Esta plantilla será completamente borrada. +schematic.rename = Renombrar plantilla schematic.info = {0}x{1}, {2} bloques -schematic.disabled = [scarlet]Schematics disabled[]\nYou are not allowed to use schematics on this [accent]map[] or [accent]server. +schematic.disabled = [scarlet]Plantillas desactivadas.[]\nNo puedes usar plantillas en este [accent]mapa[] o [accent]servidor. +stats = Estadísticas stat.wave = Oleadas Derrotadas:[accent] {0} stat.enemiesDestroyed = Enemigos Destruidos:[accent] {0} stat.built = Estructuras Construidas:[accent] {0} @@ -68,14 +69,14 @@ stat.delivered = Recursos Lanzados: stat.playtime = Tiempo jugado:[accent] {0} stat.rank = Rango final: [accent]{0} -globalitems = [accent]Global Items -map.delete = ¿Estás seguro que quieres borrar el mapa "[accent]{0}[]"? +globalitems = [accent]Recursos Totales +map.delete = ¿Estás seguro de que quieres borrar el mapa "[accent]{0}[]"? level.highscore = Puntuación más alta: [accent]{0} level.select = Selección de nivel level.mode = Modo de juego: coreattack = < ¡El núcleo está bajo ataque! > nearpoint = [[ [scarlet]ABANDONA EL PUNTO DE APARICIÓN INMEDIATAMENTE[] ]\nAniquilación inminente -database = Base de datos del núcleo +database = Base de datos savegame = Guardar Partida loadgame = Cargar Partida joingame = Unirse a la Partida @@ -87,12 +88,12 @@ position = Posición close = Cerrar website = Sitio web quit = Salir -save.quit = Guardar & Salir +save.quit = Guardar y Salir maps = Mapas maps.browse = Navegar por los Mapas continue = Continuar maps.none = [lightgray]¡No se han encontrado mapas! -invalid = Invalido +invalid = No es válido pickcolor = Escoge Color preparingconfig = Preparando Configuración preparingcontent = Preparando Contenido @@ -100,110 +101,116 @@ uploadingcontent = Subiendo Contenido uploadingpreviewfile = Subiendo Archivo de Vista Previa committingchanges = Confirmando Cambios done = Hecho -feature.unsupported = Tu dispositivo no soporta esta función. +feature.unsupported = Tu dispositivo no es compatible con esta función. mods.alphainfo = Ten en cuenta que los mods estan en versión Alpha, y[scarlet] pueden tener varios problemas[].\nReporta cualquier error que encuentres en la página de GitHub de Mindustry o Discord. mods = Mods -mods.none = [lightgray]No se encontraron Mods! +mods.none = [lightgray]¡No se encontraron Mods! mods.guide = Guía de Modding mods.report = Reportar Error mods.openfolder = Abrir carpeta de mods mods.reload = Recargar -mods.reloadexit = El juego se va a cerrar para recargar los mods. +mods.reloadexit = A continuación se cerrará el juego para recargar los mods. mod.display = [gray]Mod:[orange] {0} mod.enabled = [lightgray]Activado mod.disabled = [scarlet]Desactivado mod.disable = Desactivar mod.content = Contenido: -mod.delete.error = Fallo al elminar el mod. Quizás el archivo esta en uso. -mod.requiresversion = [scarlet]Requiere mínima versión del juego: [accent]{0} +mod.delete.error = No se pudo elminar el mod. Tal vez esté en uso por el juego. +mod.requiresversion = [scarlet]Requiere como mínimo la versión del juego: [accent]{0} mod.outdated = [scarlet]No es compatible con la V6 (no minGameVersion: 105) mod.missingdependencies = [scarlet]Dependencias faltantes: {0} -mod.erroredcontent = [scarlet]Errores de contenido -mod.errors = Ocurrieron fallos al cargar el contenido. -mod.noerrorplay = [scarlet]Tienes mods con fallos.[]Deshabilita las modificaciones afectadas o arregla los errores antes de jugar. +mod.erroredcontent = [scarlet]Contenido erróneo +mod.errors = Ha ocurrido un fallo al cargar el contenido. +mod.noerrorplay = [scarlet]Se están ejecutando algunos mods con fallos.[]Deshabilítalos o arregla los errores antes de jugar. mod.nowdisabled = [scarlet]Al/Los Mod/s '{0}'le esta/n faltando dependencias:[accent] {1}\n[lightgray]Estos mods necesitan descargarse primero.\nEste mod será automaticamente desactivado. mod.enable = Activar mod.requiresrestart = El juego se cerrará para aplicar los mods. -mod.reloadrequired = [scarlet]Se requiere actualizar +mod.reloadrequired = [scarlet]Se requiere volver a cargar mod.import = Importar mod - mod.import.file = Importar archivo mod.import.github = Importar Mod de Github -mod.jarwarn = [scarlet]Los mods JAR pueden ser inseguros.[]\nAsegúrate de que los descargaste de una fuente segura! - +mod.jarwarn = [scarlet]Los mods JAR pueden no ser seguros.[]\n¡Asegúrate de haberlos descargado de una fuente en la que confíes! mod.item.remove = Este objeto es parte del[accent] '{0}'[] mod. Para eliminarlo, desinstala ese mod. mod.remove.confirm = Este mod va a ser eliminado.\n¿Quieres continuar? mod.author = [lightgray]Autor:[] {0} -mod.missing = Esta partida guardada usa mods que has actualizado recientemente o que ya no has instalado. Se puede corromper la partida guardada. ¿Estás seguro de que quieres cargarla?\n[lightgray]Mods:\n{0} +mod.missing = Esta partida guardada usa mods que has actualizado recientemente o que no tienes instalados. Se puede corromper la partida guardada. ¿Quieres cargarla a pesar de ello?\n[lightgray]Mods:\n{0} mod.preview.missing = Antes de publicar este mod en el Steam Workshop, debe añadir una imagen de vista previa.\nAñada una imagen con nombre[accent] preview.png[] en la carpeta del mod e intente nuevamente. mod.folder.missing = Solo los mods en forma de carpeta se pueden publicar en el Steam Workshop.\nPara convertir cualquier mod en una carpeta, simplemente descomprima su archivo a una carpeta y elimine el zip anterior, luego reinicie su juego o vuelva a cargar sus mods. -mod.scripts.disable = Tu dispositivo no soporta los mods con scripts. Debes deshabilitar esos mods para jugar. +mod.scripts.disable = Tu dispositivo no es compatible con mods con scripts. Debes deshabilitar esos mods para jugar. -about.button = Acerca de +about.button = Acerca del juego name = Nombre: noname = Elige un[accent] nombre de jugador[] primero. planetmap = Mapa del planeta launchcore = Lanzar núcleo filename = Nombre del archivo: -unlocked = ¡Nuevo Bloque Desbloqueado! +unlocked = ¡Nuevo contenido en la Base de Datos! +available = ¡Nueva investigación disponible! completed = [accent]Completado -techtree = Árbol de Tecnologías -research.list = [lightgray]investigación: -research = Investigación +techtree = Tecnologías +research.legacy = Se han encontrado datos guardados de investigaciones tecnológicas realizadas en la versión [accent]5.0[].\n¿Quieres [accent]cargar estos datos[], o [accent]descartarlos[] para reiniciar los descubrimientos tecnológicos del nuevo modo Campaña? (Recomendado) +research.load = Cargar +research.discard = Descartar +research.list = [lightgray]Investigaciones: +research = Investigaciones researched = [lightgray]{0} investigado. research.progress = {0}% completado -players = {0} jugadores online -players.single = {0} jugador online -players.search = buscar +players = {0} jugadores +players.single = {0} jugador +players.search = Buscar players.notfound = [gray]No se encontraron jugadores server.closing = [accent]Cerrando servidor... -server.kicked.kick = ¡Has sido expulsado del servidor! -server.kicked.whitelist = No estas en la lista blanca de aqui. -server.kicked.serverClose = El servidor ha cerrado. -server.kicked.vote = Te han expulsado por votación. Adiós! -server.kicked.clientOutdated = ¡Cliente desactualizado! ¡Actualiza tu juego! +server.kicked.kick = ¡Te han echado del servidor! +server.kicked.whitelist = No estás en la lista blanca de este servidor. +server.kicked.serverClose = El servidor se ha cerrado. +server.kicked.vote = Has sido expulsado por votación. ¡Adiós! +server.kicked.clientOutdated = ¡Cliente desactualizado! ¡Actualiza el juego! server.kicked.serverOutdated = ¡Servidor desactualizado! ¡Pídele al anfitrión que lo actualice! -server.kicked.banned = Has sido expulsado del servidor. +server.kicked.banned = Has sido baneado en este servidor. server.kicked.typeMismatch = Este servidor no es compatible con su tipo de compilación. -server.kicked.playerLimit = Este servidor está lleno. Espera un espacio vacío. +server.kicked.playerLimit = Este servidor está lleno. Aunque siempre puedes esperar a que alguien deje un hueco... server.kicked.recentKick = Has sido expulsado recientemente.\nEspera para poder conectarte de nuevo. server.kicked.nameInUse = Ya hay alguien con ese\nnombre en el servidor. -server.kicked.nameEmpty = Tu nombre debe por lo menos contener un carácter o número. -server.kicked.idInUse = ¡Ya estás en el servidor! Conectarse con dos cuentas no está permitido. +server.kicked.nameEmpty = Tu nombre debe contener al menos un carácter o número. +server.kicked.idInUse = ¡Ya estás en el servidor! No está permitido conectarse con dos cuentas. server.kicked.customClient = Este servidor no soporta versiones personalizadas. Descarga una versión oficial. server.kicked.gameover = ¡Fin del juego! server.kicked.serverRestarting = Se esta reiniciando el servidor. server.versions = Tu versión:[accent] {0}[]\nVersión del servidor:[accent] {1}[] -host.info = El botón [accent]host[] crea un servidor en el puerto [scarlet]6567[]. \nCualquier persona en la misma [lightgray]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[lightgray]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. -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[lightgray]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. +host.info = El botón [accent]host[] crea un servidor en el puerto [scarlet]6567[]. \nCualquier persona en la misma [lightgray]wifi []o [lightgray]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 mediante IP, se requiere [accent]asignación de puertos[].\n\n[lightgray]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. +join.info = Aquí, puedes escribir la [accent]IP de un servidor[] para conectarte, o descubrir servidores en tu [accent]red local[] para conectarte.\nTambién se puede jugar multijugador en redes LAN y WAN.\n\n[lightgray]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. hostserver = Crear Servidor invitefriends = Invitar Amigos -hostserver.mobile = Crear\nJuego +hostserver.mobile = Crear\nPartida host = Servidor hosting = [accent]Abriendo servidor... hosts.refresh = Actualizar -hosts.discovering = Descubrir partidas LAN -hosts.discovering.any = Descubrir juegos +hosts.discovering = Buscando partidas en LAN... +hosts.discovering.any = Buscando partidas server.refreshing = Actualizando servidor... -hosts.none = [lightgray]¡No se han encontrado partidas LAN! -host.invalid = [scarlet]No se ha podido conectar al anfitrión. +hosts.none = [lightgray]No se han encontrado partidas en LAN +host.invalid = [scarlet]No se pudo conectar con el anfitrión servers.local = Servidores Locales servers.remote = Servidores Remotos servers.global = Servidores Globales +ervers.showhidden = Mostrar servidores ocultos +server.shown = Visibles +server.hidden = Ocultos + trace = Rastrear Jugador trace.playername = Nombre de jugador: [accent]{0} trace.ip = IP: [accent]{0} trace.id = ID Única: [accent]{0} -trace.mobile = Cliente de movíl: [accent]{0} +trace.mobile = Cliente de móvil: [accent]{0} trace.modclient = Cliente Personalizado: [accent]{0} -invalidid = ¡ID de cliente inválida! Envía un informe del error. +invalidid = ¡ID de cliente inválida! Por favor, envía un informe del error. server.bans = Expulsiones -server.bans.none = ¡Ningún usuario ha sido expulsado! +server.bans.none = No se ha baneado a ningún usuario aún server.admins = Administradores -server.admins.none = ¡Ningún administrador ha sido encontrado! +server.admins.none = ¡No hay ningún administrador! server.add = Agregar Servidor server.delete = ¿Estás seguro de querer borrar este servidor? server.edit = Editar Servidor @@ -211,26 +218,27 @@ server.outdated = [crimson]¡Servidor desactualizado![] server.outdated.client = [crimson]¡Cliente desactualizado![] server.version = [lightgray]Versión: {0} server.custombuild = [accent]Versión personalizada -confirmban = ¿Estás seguro de querer banear este jugador? +confirmban = ¿Quieres banear a este jugador? confirmkick = ¿Estás seguro de querer expulsar este jugador? -confirmvotekick = ¿Estás seguro de querer hechar por votación a este jugador? -confirmunban = ¿Estás seguro de querer desbanear este jugador? -confirmadmin = ¿Estás seguro de querer hacer administrador a este jugador? -confirmunadmin = ¿Estás seguro de querer quitar los permisos de administrador a este jugador? +confirmvotekick = ¿Estás de acuerdo en expulsar este jugador? +confirmunban = ¿Quieres desbanear a este jugador? +confirmadmin = ¿Quieres hacer administrador a este jugador? +confirmunadmin = ¿Quieres quitar los permisos de administrador a este jugador? joingame.title = Unirse a la partida joingame.ip = IP: disconnect = Desconectado. disconnect.error = Error en la conexión. disconnect.closed = Conexión cerrada. -disconnect.timeout = Desconectado. -disconnect.data = ¡Se ha fallado la carga de datos del mundo! +disconnect.timeout = Tiempo de espera agotado. +disconnect.data = ¡Hubo un fallo con la carga de datos! cantconnect = No es posible unirse a la partida ([accent]{0}[]). connecting = [accent]Conectando... +reconnecting = [accent]Reconectado... connecting.data = [accent]Cargando datos del mundo... server.port = Puerto: server.addressinuse = ¡La dirección ya está en uso! -server.invalidport = ¡El número de puerto es invalido! -server.error = [crimson]Error creando el servidor: error [accent]{0} +server.invalidport = ¡El número de puerto no es valido! +server.error = [crimson]Error al crear el servidor: error [accent]{0} save.new = Nuevo Punto de Guardado save.overwrite = ¿Estás seguro de querer sobrescribir\neste punto de guardado? overwrite = Sobrescribir @@ -247,19 +255,19 @@ save.newslot = Nombre del Punto de Guardado: save.rename = Renombrar save.rename.text = Nuevo nombre: selectslot = Selecciona un Punto de Guardado. -slot = [accent]Casilla {0} +slot = [accent]Hueco {0} editmessage = Editar mensaje -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. +save.corrupted = [accent]¡El punto de guardado está corrupto o es inválido!\nSi acabas de actualizar el juego, probablemente se deba a un cambio en el formato de guardado y[scarlet] no[] un a error. empty = -on = Encendido -off = Apagado +on = ON +off = OFF save.autosave = Autoguardado: {0} save.map = Mapa: {0} save.wave = Oleada {0} -save.mode = ModoJuego: {0} +save.mode = Modo de Juego: {0} save.date = Última vez guardado: {0} save.playtime = Tiempo de juego: {0} -warning = Aviso. +warning = Aviso confirm = Confirmar delete = Borrar view.workshop = Ver en el Steam Workshop @@ -271,34 +279,38 @@ cancel = Cancelar openlink = Abrir Enlace copylink = Copiar Enlace back = Atrás +crash.export = Exportar Registros de errores +crash.none = No se encontraron Registros de errores. +crash.exported = Registros de errores exportados. data.export = Exportar Datos data.import = Importar Datos data.openfolder = Abrir Carpeta de Datos data.exported = Datos exportados. data.invalid = Esta data del juego no es valida. data.import.confirm = Importando los datos externos borrará[scarlet] todo[] tu progreso.\n[accent]Esto no se puede rehacer![]\n\nUna vez que los datos hayan sido importados, el juego saldrá automaticamente. -quit.confirm = ¿Estás seguro de querer salir de la partida? +quit.confirm = ¿Quieres salir de la partida? quit.confirm.tutorial = ¿Estás seguro de que sabes qué estas haciendo?\nSe puede hacer el tutorial de nuevo en[accent] Ajustes->Juego->Volver a hacer tutorial.[] loading = [accent]Cargando... reloading = [accent]Recargando mods... saving = [accent]Guardando... - -respawn = [accent][[{0}][] para respawnear en el nucleo - +respawn = [accent][[{0}][] para reaparecer en el núcleo cancelbuilding = [accent][[{0}][] para limpiar el plan selectschematic = [accent][[{0}][] para seleccionar+copiar pausebuilding = [accent][[{0}][] para pausar la construcción -resumebuilding = [scarlet][[{0}][] para resumir la construcción +resumebuilding = [scarlet][[{0}][] para reanudar la construcción +showui = Interfaz oculta.\nPulsa [accent][[{0}][] para volver a mostrar la Interfaz. wave = [accent]Oleada {0} -wave.cap = [accent]Wave {0}/{1} +wave.cap = [accent]Oleada {0}/{1} wave.waiting = Oleada en {0} wave.waveInProgress = [lightgray]Oleada en progreso waiting = Esperando... waiting.players = Esperando jugadores... wave.enemies = [lightgray]{0} Enemigos Restantes +wave.enemycores = [accent]{0}[lightgray] Núcleos enemigos +wave.enemycore = [accent]{0}[lightgray] Núcleo enemigo wave.enemy = [lightgray]{0} Enemigo Restante -wave.guardianwarn = Guardian approaching in [accent]{0}[] waves. -wave.guardianwarn.one = Guardian approaching in [accent]{0}[] wave. +wave.guardianwarn = El Guardián llegará en [accent]{0}[] oleadas. +wave.guardianwarn.one = El Guardián se aproxima... [accent]{0}[] oleada restante. loadimage = Cargar Imagen saveimage = Guardar Imagen unknown = Desconocido @@ -306,9 +318,9 @@ custom = Personalizado builtin = Incorporado map.delete.confirm = ¿Estás seguro de querer borrar este mapa? ¡Recuerda que está acción no se puede deshacer! map.random = [accent]Mapa Aleatorio -map.nospawn = ¡Este mapa no tiene ningún núcleo en el cual pueda aparecer el jugador! Agrega un núcleo[accent] orange[] [white]al mapa con el editor. -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. -map.nospawn.attack = ¡Este mapa no tiene núcleos para que el jugador ataque! Añade núcleos[scarlet] red[] a este mapa en el editor. +map.nospawn = ¡Este mapa no tiene ningún núcleo en que pueda aparecer el jugador! Agrega un núcleo[accent] naranja[] al mapa con el editor. +map.nospawn.pvp = ¡Este mapa no tiene ningún núcleo enemigo para que aparezca el jugador! Añade un núcleo[scarlet] "de otro color"[] a este mapa en el editor. +map.nospawn.attack = ¡Este mapa no tiene núcleos a los que los jugadores deban atacar! Añade núcleos[scarlet] rojos[] a este mapa en el editor. map.invalid = Error cargando el mapa: archivo corrupto o inválido. workshop.update = Actualizar artículo workshop.error = Error al obtener detalles del Steam Workshop: {0} @@ -319,7 +331,7 @@ changelog = Lista de cambios (optional): eula = EULA de Steam missing = Este artículo ha sido movido o eliminado.\n[lightgray]La lista del taller ahora se ha desvinculado automáticamente. publishing = [accent]Publicando... -publish.confirm = ¿Estás seguro de que quieres publicar esto?\n\n[lightgray]¡Asegúrese de aceptar primero el EULA del taller, o sus artículos no aparecerán! +publish.confirm = ¿Estás seguro de que quieres publicar esto?\n\n[lightgray]¡Asegúrese de aceptar primero el EULA del Steam Workshop, o sus artículos no aparecerán! publish.error = Error publicando el artículo: {0} steam.error = Error al inicializar los servicios de Steam.\nError: {0} @@ -337,7 +349,7 @@ editor.generation = Generación: editor.ingame = Editar dentro del juego editor.publish.workshop = Publicar en el Steam Workshop editor.newmap = Nuevo Mapa -editor.center = Center +editor.center = Centrar workshop = Steam Workshop waves.title = Oleadas waves.remove = Borrar @@ -356,11 +368,10 @@ waves.invalid = Oleadas inválidaas en el portapapeles. waves.copied = Oleadas copiadas. waves.none = No hay enemigos definidos.\nNótese que las listas de oleadas vacías se sustituirán por la lista por defecto. - -wavemode.counts = Cuentas -wavemode.totals = Totales -wavemode.health = Salud - +#Estos están en minúscula intencionadamente. +wavemode.counts = limitadas +wavemode.totals = totales +wavemode.health = por salud editor.default = [lightgray] details = Detalles... @@ -386,7 +397,7 @@ editor.savemap = Guardar Mapa editor.saved = ¡Guardado! editor.save.noname = ¡Tu mapa no tiene un nombre! Pon uno en el menú 'Info del Mapa'. editor.save.overwrite = ¡Tu mapa sobrescribe uno ya incorporado! Elige un nombre diferente en el menú 'Info del Mapa'. -editor.import.exists = [scarlet]¡No se ha podido importar:[] un mapa incorporado con el nombre '{0}' ya existe! +editor.import.exists = [scarlet]¡No se ha podido importar:[] ya existe un mapa incorporado con el nombre '{0}'! editor.import = Importar... editor.importmap = Importar Mapa editor.importmap.description = Importar un mapa ya existente @@ -413,41 +424,41 @@ toolmode.replace = Sustituir toolmode.replace.description = Solo dibuja en bloques sólidos. toolmode.replaceall = Sustituir Todo toolmode.replaceall.description = Sustituye todos los bloques del mapa. -toolmode.orthogonal = Ortogonal +toolmode.orthogonal = Perpendicular toolmode.orthogonal.description = Solo dibuja líneas ortogonales. toolmode.square = Cuadrado toolmode.square.description = Pincel cuadrado. toolmode.eraseores = Borrar Vetas toolmode.eraseores.description = Solo borra vetas. -toolmode.fillteams = Llenar Equipos -toolmode.fillteams.description = Llena equipos en vez de bloques. +toolmode.fillteams = Rellenar Equipos +toolmode.fillteams.description = Rellena equipos en lugar de bloques. toolmode.drawteams = Dibujar Equipos -toolmode.drawteams.description = Dibuja equipos en vez de bloques. +toolmode.drawteams.description = Dibuja equipos en lugar de bloques. filters.empty = [lightgray]¡No hay filtros! Añade uno con el botón de abajo. filter.distort = Distorsionar filter.noise = Ruido -filter.enemyspawn = Elegir punto de aparición enemigo -filter.spawnpath = Path To Spawn +filter.enemyspawn = Punto de aparición enemigo +filter.spawnpath = Ruta hasta el punto de aterrizaje filter.corespawn = Elegir Núcleo -filter.median = Median -filter.oremedian = Veta Median -filter.blend = Mezcla +filter.median = Calcular probabilidades de generación +filter.oremedian = Probabilidad de vetas +filter.blend = Mezclar filter.defaultores = Vetas por defecto -filter.ore = Vetas -filter.rivernoise = Ruido de rio +filter.ore = Vetas de Minerales +filter.rivernoise = Añadir Río filter.mirror = Espejo filter.clear = Despejar filter.option.ignore = Ignorar filter.scatter = Dispersar filter.terrain = Terreno filter.option.scale = Escala -filter.option.chance = Chance +filter.option.chance = Probabilidad filter.option.mag = Magnitud filter.option.threshold = Umbral filter.option.circle-scale = Escala del círculo -filter.option.octaves = Octaves -filter.option.falloff = Caída +filter.option.octaves = Continuidad +filter.option.falloff = Aterrizaje filter.option.angle = Ángulo filter.option.amount = Cantidad filter.option.block = Bloque @@ -456,7 +467,7 @@ filter.option.flooronto = Suelo objetivo filter.option.target = Target filter.option.wall = Muro filter.option.ore = Veta -filter.option.floor2 = Piso secundario +filter.option.floor2 = Terreno secundario filter.option.threshold2 = Umbral secundario filter.option.radius = Radio filter.option.percentile = Porcentaje @@ -470,12 +481,14 @@ load = Cargar save = Guardar fps = FPS: {0} ping = Ping: {0} ms -language.restart = Por favor reinicia el juego para que los cambios del idioma tengan efecto. +memory = Mem: {0}mb +memory2 = Mem:\n {0}mb +\n {1}mb +language.restart = Reinicia el juego para que los cambios en el idioma tengan efecto. settings = Ajustes tutorial = Tutorial -tutorial.retake = Volver a hacer tutorial +tutorial.retake = Volver a jugar el tutorial editor = Editor -mapeditor = Editor de Mapa +mapeditor = Editor de Mapas abandon = Abandonar abandon.text = Esta zona y sus recursos se perderán ante el enemigo. @@ -483,27 +496,24 @@ locked = Bloqueado complete = [lightgray]Completado: requirement.wave = Alcanzar la oleada {0} en {1} requirement.core = Destruir el núcleo enemigo en {0} -requirement.research = Research {0} -requirement.capture = Capture {0} +requirement.research = Investigar {0} +requirement.capture = Capturar {0} bestwave = [lightgray]Récord: {0} -launch.text = Launch -research.multiplayer = Only the host can research items. +launch.text = Lanzar +research.multiplayer = Solo el anfitrión de la partida puede \nrealizar investigaciones tecnologías. +map.multiplayer = Solo el anfitrión de la partida puede ver los sectores del mapa. uncover = Descubrir configure = Configurar carga inicial -loadout = Loadout -resources = Resources + +loadout = Carga Inicial +resources = Recursos bannedblocks = Bloques prohibidos addall = Añadir todo -launch.destination = Destination: {0} +launch.from = Lanzando desde: [accent]{0} +launch.destination = Destino: {0} configure.invalid = La cantidad debe estar entre 0 y {0}. -zone.unlocked = [lightgray]{0} desbloqueado. -zone.requirement.complete = Oleada {0} alcanzada:\nrequerimientos de la zona {1} cumplidos. -zone.resources = Recursos Detectados: -zone.objective = [lightgray]Objetivo: [accent]{0} -zone.objective.survival = Sobrevivir -zone.objective.attack = Destruir Núcleo Enemigo add = Añadir... -boss.health = Salud del Jefe +boss.health = Guardián connectfail = [crimson]Ha fallado la conexión con el servidor: [accent]{0} error.unreachable = Servidor inaccesible. @@ -514,29 +524,52 @@ error.alreadyconnected = Ya estás conectado. error.mapnotfound = ¡Archivo de mapa no encontrado! error.io = Error I/O de conexión. error.any = Error de red desconocido. -error.bloom = Error al cargar el bloom.\nPuede que tu dispositivo no soporte esta característica. +error.bloom = Error al cargar el efecto de bloom.\nPuede que tu dispositivo no sea compatible con esta característica. weather.rain.name = Lluvia weather.snow.name = Nieve weather.sandstorm.name = Tormenta de arena weather.sporestorm.name = Tormenta de esporas - weather.fog.name = Niebla sectors.unexplored = [lightgray]No explorado sectors.resources = Recursos: sectors.production = Producción: +sectors.export = Exportado: +sectors.time = Tiempo: +sectors.threat = Amenaza: +sectors.wave = Oleada: sectors.stored = Almacenado: sectors.resume = Reanudar sectors.launch = Lanzar sectors.select = Elegir -sectors.nonelaunch = [lightgray]ninguno (sun) -sectors.rename = Rename Sector -sector.missingresources = [scarlet]Insuficientes recursos +sectors.nonelaunch = [lightgray]Ninguno (Sol) +sectors.rename = Renombrar sector +sectors.enemybase = [scarlet]Base enemiga +sectors.vulnerable = [scarlet]Vulnerable +sectors.underattack = [scarlet]¡Bajo ataque! [accent]{0}% dañado +sectors.survives = [accent]Sobrevive {0} oleadas +sectors.go = Ir +sector.curcapture = Sector Capturado +sector.curlost = Sector Perdido +sector.missingresources = [scarlet]Recursos Insuficientes +sector.attacked = Sector [accent]{0}[white] bajo ataque[]! +sector.lost = ¡Sector [accent]{0}[white] perdido[]! +#nota: el espacio en blanco en la línea siguiente es intencionado +sector.captured = ¡Sector [accent]{0}[white] capturado[]! + +threat.low = Baja +threat.medium = Media +threat.high = Alta +threat.extreme = Extrema +threat.eradication = Exterminio + +planets = Planetas planet.serpulo.name = Serpulo planet.sun.name = Sol +sector.impact0078.name = Impacto 0078 sector.groundZero.name = Zona de impacto sector.craters.name = Los Cráteres sector.frozenForest.name = Bosque Congelado @@ -548,19 +581,27 @@ sector.overgrowth.name = Crecimiento excesivo sector.tarFields.name = Campos de alquitrán sector.saltFlats.name = Llanuras de sal sector.fungalPass.name = Paso de hongos +sector.biomassFacility.name = Centro de Sintetización de Biomasa +sector.windsweptIslands.name = Islas Windswept +sector.extractionOutpost.name = Puesto de avanzada de Extracción +sector.planetaryTerminal.name = Terminal de Lanzamiento Interplanetario - -sector.groundZero.description = La ubicación óptima para empezar una vez más. Baja amenaza enemiga. Pocos recursos.\nReúna la mayor cantidad de plomo y cobre posible.\nSiga adelante. -sector.frozenForest.description = Incluso aquí, más cerca de las montañas, las esporas se han extendido. Las gélidas temperaturas no pueden contenerlos para siempre.\n\nComienza la aventura hacia el poder. Construye generadores de combustión. Aprenda a usar reparadores. -sector.saltFlats.description = En las afueras del desierto se encuentran las Salinas. Se pueden encontrar pocos recursos en esta ubicación.\n\nEl enemigo ha erigido un complejo de almacenamiento de recursos aquí. Erradicar su núcleo. No dejes nada en pie. -sector.craters.description = El agua se ha acumulado en este cráter, reliquia de las viejas guerras. Recupere el área. Recoge arena. Fundir metavidrio. Bombee agua para enfriar torretas y taladros. -sector.ruinousShores.description = Más allá de los páramos, está la costa. Una vez, esta ubicación albergó una serie de defensa costera. No queda mucho. Solo las estructuras de defensa más básicas han quedado ilesas, todo lo demás reducido a chatarra.\nContinúe la expansión hacia afuera. Redescubra la tecnología. -sector.stainedMountains.description = Más tierra adentro se encuentran las montañas, pero no contaminadas por esporas.\nExtraiga el abundante titanio de esta zona. Aprenda como usarlo.\n\nLa presencia enemiga es mayor aquí. No les des tiempo para enviar sus unidades más fuertes. -sector.overgrowth.description = Esta área está cubierta de maleza, más cerca de la fuente de las esporas.\nEl enemigo ha establecido un puesto de avanzada aquí. Construye unidades Titán. Destruyelo. Recupera lo que se perdió. -sector.tarFields.description = Las afueras de una zona de producción de petróleo, entre la montaña y el desierto. Una de las pocas áreas con reservas de alquitrán utilizables.\nAunque está abandonada, esta zona tiene algunas fuerzas enemigas peligrosas cerca. No los subestimes.\n\n[lightgray]Investigue la tecnología de procesamiento de aceite si es posible. -sector.desolateRift.description = Una zona extremadamente peligrosa. Recursos abundantes, pero poco espacio. Alto riesgo de destrucción. Vete lo antes posible. No se deje engañar por el gran intervalo entre los ataques enemigos. -sector.nuclearComplex.description = Antigua instalación de producción y procesamiento de torio, reducida a ruinas.\n[lightgray] Investiga el torio y sus múltiples usos.\n\nEl enemigo está presente aquí en gran número, constantemente en busca de atacantes. -sector.fungalPass.description = Un área de transición entre montañas altas y tierras bajas plagadas de esporas. Aquí se encuentra una pequeña base de reconocimiento enemiga.\nDestroy it.\nUsa unidades Dagger y Crawler. Saca los dos núcleos de funcionamiento! +sector.groundZero.description = La ubicación adecuada para empezar una vez más. Baja amenaza enemiga. Pocos recursos.\nReúna la mayor cantidad de plomo y cobre posible y sigue adelante. +sector.frozenForest.description = Incluso aquí, más cerca de las montañas, las esporas se han extendido. Las gélidas temperaturas no las contendrán para siempre.\n\nAprende a usar la energía. Construye generadores de combustión. Aprende a usar reparadores. +sector.saltFlats.description = En las afueras del desierto se encuentran las Salinas. No hay muchos recursos en esta ubicación.\n\nEl enemigo ha creado un complejo de almacenamiento de recursos aquí. Erradica su núcleo. No dejes nada en pie. +sector.craters.description = El agua se ha acumulado en este cráter, reliquia de las viejas guerras. Recupera la zona. Recoge arena. Funde Metacristal. Bombea agua para enfriar torretas y taladros. +sector.ruinousShores.description = Más allá de los páramos, se encuentra la costa. Una vez, esta ubicación albergó una serie de defensa costera. No queda mucho. Solo las estructuras de defensa más básicas han quedado ilesas, todo lo demás está reducido a chatarra.\nContinúa la expansión. Redescubre la tecnología. +sector.stainedMountains.description = Más adentro se encuentran las montañas, aún intactas por las esporas.\nExtrae el abundante titanio de esta zona. Aprende a usarlo.\n\nLa presencia enemiga es mayor aquí. No les des tiempo para enviar sus unidades más fuertes. +sector.overgrowth.description = El área está cubierta de maleza, más cerca de la fuente de las esporas.\nEl enemigo ha establecido un puesto de avanzada aquí. Construye unidades Titán. Destruyelo. Recupera lo que se perdió. +sector.tarFields.description = Las afueras de una zona de producción de petróleo, entre la montaña y el desierto. Una de las pocas áreas con reservas de alquitrán utilizables.\nAunque está abandonada, esta zona tiene algunas fuerzas enemigas peligrosas cerca. No los subestimes.\n\n[lightgray]Investiga la tecnología de procesamiento de petróleo si es posible. +sector.desolateRift.description = Una zona extremadamente peligrosa. Recursos abundantes, pero poco espacio. Alto riesgo de destrucción. Abandona el lugar lo antes posible. No te dejes engañar por el intervalo entre los ataques enemigos. +sector.nuclearComplex.description = Antigua instalación de producción y procesamiento de torio, reducida a ruinas.\n[lightgray] Investiga el torio y sus múltiples usos.\n\nEl enemigo está presente aquí,superando en número a sus atacantes. +sector.fungalPass.description = Un área de transición entre montañas y las tierras bajas, plagadas de esporas. Aquí se encuentra una pequeña base de reconocimiento enemiga.\nDestrúyela.\nUsa unidades Dagger y Crawler. Acaba con los dos núcleos. +sector.biomassFacility.description = El origen de las esporas. Este es el centro en el que se investigaron, y donde fueron incialmente producidas.\nDescubre la tecnología restante que contiene. Cultiva esporas para producir combustible y plásticos.\n\n[lightgray]Nada en el ecosistema local pudo combatir semejante organismo tan invasivo, originado en este lugar. +sector.windsweptIslands.description = Tras la costa, se encuentra esta remota cadena de islas. Las grabaciones muestran que aquí existieron estructuras relacionadas con la producción de [accent]Plastanio[].\n\nDefiéndete de las unidades navales enemigas. Establece una base en las islas. Investiga estas fábricas. +sector.extractionOutpost.description = Una base remota, construida por el enemigo con el objetivo de lanzar recursos a otros sectores.\n\nLa tecnología de transporte de recursos entre sectores es esencial para conquistar a gran escala. Destruye la base. Investiga sus Plataformas de Lanzamiento. +sector.impact0078.description = Aquí yacen las ruinas de la primera estación de transporte interestelar en estar operativa del sistema.\n\nRecupera todo lo posible de los escombros. Investiga cualquier tecnología intacta. +sector.planetaryTerminal.description = El objetivo final.\n\nÉsta base costera alberga una estructura capaz de lanzar Núcleos a planeteas locales. Está extremadamente bien protegida.\n\nProduce unidades navales. Acaba con el enemigo lo antes posible. Analiza la estructura de lanzamiento. settings.language = Idioma settings.data = Datos del Juego @@ -571,35 +612,32 @@ settings.controls = Controles settings.game = Juego settings.sound = Sonido settings.graphics = Gráficos -settings.cleardata = Limpiar Datos del Juego... -settings.clear.confirm = ¿Estas seguro de querer limpiar estos datos?\n¡Esta acción no puede deshacerse! -settings.clearall.confirm = [scarlet]ADVERTENCIA![]\nEsto va a eliminar todos tus datos, incluyendo guardados, mapas, desbloqueos y atajos de teclado.\nUna vez presiones 'ok', el juego va a borrrar todos tus datos y saldrá del juego automáticamente. - -settings.clearsaves.confirm = Estas seguro de que quieres borrar tus partidas guardadas? +settings.cleardata = Eliminando Datos del Juego... +settings.clear.confirm = ¿Quieres eliminar estos datos?\n¡Esta acción no se puede deshacer! +settings.clearall.confirm = [scarlet]¡ADVERTENCIA![]\nEsto va a eliminar todos tus datos, incluyendo guardados, mapas, desbloqueos y atajos de teclado.\nUna vez presiones 'ok', el juego borrrará todos tus datos y se cerrará automáticamente. +settings.clearsaves.confirm = ¿Quieres borrar tus partidas guardadas? settings.clearsaves = Limpiar partidas guardadas -settings.clearresearch = Borrar descubrimientos -settings.clearresearch.confirm = Estas seguro? -settings.clearcampaignsaves = Borrar Guardados de campaña -settings.clearcampaignsaves.confirm = Estas seguro de que quieres borrar tus partidas guardadas en el modo campaña? - +settings.clearresearch = Borrar Investigaciones Tecnológicas +settings.clearresearch.confirm = ¿Quieres eliminar todo el progreso de las Investigaciones Tecnológicas del modo Campaña? +settings.clearcampaignsaves = Borrar datos de campaña +settings.clearcampaignsaves.confirm = ¿Quieres borrar tus partidas guardadas en el modo campaña? paused = [accent] < Pausado > -clear = Limpiar +clear = Vaciar banned = [scarlet]Baneado -unplaceable.sectorcaptured = [scarlet]Necesita que el sector esté capturado. yes = Sí no = No -info.title = [accent]Información -error.title = [crimson]Un error ha ocurrido. -error.crashtitle = Un error ha ocurrido. - -unit.nobuild = [scarlet]La unidad no puede construir -lastaccessed = [lightgray]Anteriormente usado: {0} +info.title = Información +error.title = [crimson]Ha ocurrido un error. +error.crashtitle = Ha ocurrido un error. +unit.nobuild = [scarlet]Esta unidad no puede construir +lastaccessed = [lightgray]Último usado: {0} block.unknown = [lightgray]??? +stat.description = Objetivo stat.input = Entrada stat.output = Salida stat.booster = Potenciador -stat.tiles = Tiles requeridos +stat.tiles = Terreno requerido stat.affinities = Afinidades stat.powercapacity = Capacidad de Energía stat.powershot = Energía/Disparo @@ -608,26 +646,28 @@ stat.targetsair = Apunta al Aire stat.targetsground = Apunta a Tierra stat.itemsmoved = Velocidad de movimiento stat.launchtime = Tiempo entre lanzamientos -stat.shootrange = Rango de Disparo +stat.shootrange = Alcance stat.size = Tamaño -stat.displaysize = Tamaño mostrado +stat.displaysize = Tamaño de Pantalla stat.liquidcapacity = Capacidad de Líquidos stat.powerrange = Rango de Energía -stat.linkrange = Rango de conexión -stat.instructions = Instructions -stat.powerconnections = Conexiones maximas +stat.linkrange = Alcance de conexión +stat.instructions = Instrucciones +stat.powerconnections = Conexiones máximas stat.poweruse = Consumo de Energía stat.powerdamage = Energía/Daño stat.itemcapacity = Capacidad de Objetos -stat.memorycapacity = Memory Capacity -stat.basepowergeneration = Generación de energía base +stat.memorycapacity = Capacidad de memoria +stat.basepowergeneration = Generación de energía stat.productiontime = Tiempo de producción stat.repairtime = Tiempo para Reparar Bloque Completamente +stat.weapons = Armas +stat.bullet = Proyectil stat.speedincrease = Aumento de Velocidad -stat.range = Rango +stat.range = Alcance stat.drilltier = Taladrables -stat.drillspeed = Velocidad Base del Taladro -stat.boosteffect = Efecto del Potenciador +stat.drillspeed = Velocidad del Taladro +stat.boosteffect = Efecto de Potenciador stat.maxunits = Máximo de Unidades Activas stat.health = Vida stat.buildtime = Tiempo de construcción @@ -635,37 +675,39 @@ stat.maxconsecutive = Máximo consecutivo stat.buildcost = Coste de construcción stat.inaccuracy = Imprecisión stat.shots = Disparos -stat.reload = Recarga +stat.reload = Disparos/segundo stat.ammo = Munición -stat.shieldhealth = Salud del escudo -stat.cooldowntime = Tiempo de enfriamiento -stat.explosiveness = Explosiveness -stat.basedeflectchance = Probabilidad de desvío base -stat.lightningchance = Probabilidad de rayo +stat.shieldhealth = Escudo +stat.cooldowntime = Enfriamiento +stat.explosiveness = Explosividad +stat.basedeflectchance = Probabilidad de desvío +stat.lightningchance = Probabilidad de descarga stat.lightningdamage = Daño por rayo stat.flammability = Inflamabilidad -stat.radioactivity = Radiactividad -stat.heatcapacity = HeatCapacity +stat.radioactivity = Radioactividad +stat.heatcapacity = Resistencia temperatura stat.viscosity = Viscosidad stat.temperature = Temperatura stat.speed = Velocidad stat.buildspeed = Velocidad de construcción -stat.minespeed = Velocidad de la mina -stat.minetier = Nivel de mina -stat.payloadcapacity = Capacidad de carga útil +stat.minespeed = Velocidad de extracción +stat.minetier = Nivel de taladro +stat.payloadcapacity = Capacidad de carga stat.commandlimit = Límite de comando stat.abilities = Habilidades +stat.canboost = Tiene Propulsores +stat.flying = Aéreo -skill.forcefield = Campo de fuerza -skill.repairfield = Campo de reparación -skill.statusfield = Campo de estado -skill.unitspawn = {0} Fábrica -skill.shieldregenfield = Campo de regeneración del escudo +ability.forcefield = Zona de Escudo +ability.repairfield = Zona de Reparación +ability.statusfield = Zona de Estado +ability.unitspawn = {0} Fábrica de Drones +ability.shieldregenfield = Zona de Regeneración de Escudos +ability.movelightning = Movimiento Relámpago -bar.drilltierreq = Se requiere un mejor taladro. +bar.drilltierreq = Se requiere un taladro mejor. bar.noresources = Recursos faltantes -bar.corereq = Se requiere de un núcleo base - +bar.corereq = Necesitas un núcleo base bar.drillspeed = Velocidad del Taladro: {0}/s bar.pumpspeed = Velocidad de bombeado: {0}/s bar.efficiency = Eficiencia: {0}% @@ -673,7 +715,7 @@ bar.powerbalance = Energía: {0} bar.powerstored = Almacenados: {0}/{1} bar.poweramount = Energía: {0} bar.poweroutput = Salida de Energía: {0} -bar.powerlines = Connections: {0}/{1} +bar.powerlines = Conexiones: {0}/{1} bar.items = Objetos: {0} bar.capacity = Capacidad: {0} bar.unitcap = {0} {1}/{2} @@ -685,24 +727,26 @@ bar.progress = Progreso de construcción bar.input = Entrada bar.output = Salida -units.processorcontrol = [lightgray]Processor Controlled +units.processorcontrol = [lightgray]Procesador Controlado -bullet.damage = [stat]{0}[lightgray] daño +bullet.damage = [stat]{0}[lightgray] Daño bullet.splashdamage = [stat]{0}[lightgray] daño de área ~[stat] {1}[lightgray] casillas bullet.incendiary = [stat]Incendiaria +bullet.sapping = [stat]Oxidante bullet.homing = [stat]Rastreadora bullet.shock = [stat]Electrizante -bullet.frag = [stat]Explosiva -bullet.knockback = [stat]{0}[lightgray]Retroceso -bullet.pierce = [stat]{0}[lightgray]x pierce -bullet.infinitepierce = [stat]pierce +bullet.frag = [stat]De fragmentación +bullet.knockback = [stat]{0}[lightgray] Empuje +bullet.pierce = [stat]{0}[lightgray]x penetración +bullet.infinitepierce = [stat]Penetrante +bullet.healpercent = [stat]{0}[lightgray]% reparación bullet.freezing = [stat]Congelación -bullet.tarred = [stat]Relantizado +bullet.tarred = [stat]Ralentizado bullet.multiplier = [stat]{0}[lightgray]x multiplicador de munición -bullet.reload = [stat]{0}[lightgray]x recarga +bullet.reload = [stat]{0}[lightgray]x cadencia de fuego unit.blocks = bloques -unit.blockssquared = blocks² +unit.blockssquared = bloques² unit.powersecond = unidades de energía/segundo unit.liquidsecond = unidades de líquido/segundo unit.itemssecond = objetos/segundo @@ -715,88 +759,83 @@ unit.persecond = /seg unit.perminute = /min unit.timesspeed = x velocidad unit.percent = % - -unit.shieldhealth = Vida del escudo - +unit.shieldhealth = Escudo unit.items = objetos unit.thousands = k unit.millions = M unit.billions = b +category.purpose = Objetivo category.general = General category.power = Energía category.liquids = Líquidos category.items = Objetos category.crafting = Fabricación -category.function = Function +category.function = Función category.optional = Mejoras Opcionales -setting.landscape.name = Bloquear modo paisaje +setting.landscape.name = Bloquear modo horizontal setting.shadows.name = Sombras setting.blockreplace.name = Sugerir bloques al construir setting.linear.name = Filtrado Lineal -setting.hints.name = Pistas - -setting.flow.name = Mostrar tasa de flujo de recursos[scarlet] (experimental) +setting.hints.name = Consejos +setting.flow.name = Mostrar tasa de flujo de recursos +setting.backgroundpause.name = Pausar en segundo plano setting.buildautopause.name = Auto-pausar construcción - -setting.animatedwater.name = Agua Animada -setting.animatedshields.name = Escudos Animados +setting.animatedwater.name = Animaciones de Terreno +setting.animatedshields.name = Animación de Escudos setting.antialias.name = Antialias[lightgray] (necesita un reinicio)[] -setting.playerindicators.name = Indicadores de jugadores -setting.indicators.name = Indicadores de Aliados -setting.autotarget.name = Auto apuntado +setting.playerindicators.name = Indicadores de Jugadores +setting.indicators.name = Indicadores de Enemigos +setting.autotarget.name = Auto-Apuntado setting.keyboard.name = Controles de Ratón+Teclado -setting.touchscreen.name = Controles táctiles -setting.fpscap.name = Máx FPS +setting.touchscreen.name = Controles Táctiles +setting.fpscap.name = Máximos FPS setting.fpscap.none = Nada setting.fpscap.text = {0} FPS -setting.uiscale.name = Escala de UI[lightgray] (necesita reiniciar)[] -setting.swapdiagonal.name = Siempre Colocar Diagonalmente -setting.difficulty.training = entrenamiento -setting.difficulty.easy = fácil -setting.difficulty.normal = normal -setting.difficulty.hard = difícil -setting.difficulty.insane = locura +setting.uiscale.name = Escala de Interfaz[lightgray] (necesita reiniciar)[] +setting.swapdiagonal.name = Siempre Construir Diagonalmente +setting.difficulty.training = Entrenamiento +setting.difficulty.easy = Fácil +setting.difficulty.normal = Normal +setting.difficulty.hard = Difícil +setting.difficulty.insane = Demencial setting.difficulty.name = Dificultad: -setting.screenshake.name = Movimiento de la Pantalla -setting.effects.name = Mostrar Efectos +setting.screenshake.name = Vibración de pantalla +setting.effects.name = Mostrar efectos setting.destroyedblocks.name = Mostrar bloques destruidos setting.blockstatus.name = Mostrar estado de los bloques -setting.conveyorpathfinding.name = Colocación del transportador en búsqueda de caminos -setting.sensitivity.name = Sensibilidad del Control +setting.conveyorpathfinding.name = Construcción de transportadores Inteligente +setting.sensitivity.name = Sensibilidad del Mando setting.saveinterval.name = Intervalo del Autoguardado -setting.seconds = {0} Segundos -setting.blockselecttimeout.name = Tiempo de espera de selección de bloque +setting.seconds = {0} segundos setting.milliseconds = {0} milisegundos setting.fullscreen.name = Pantalla Completa setting.borderlesswindow.name = Ventana sin Bordes[lightgray] (podría requerir un reinicio) -setting.fps.name = Mostrar FPS -setting.smoothcamera.name = Cámara suave - - -setting.vsync.name = Vsync (Limita los fps a los Hz de tu pantalla) -setting.pixelate.name = Pixelar [lightgray](podría reducir el rendimiento) +setting.fps.name = Mostrar FPS y Ping +setting.smoothcamera.name = Movimiento de cámara suave +setting.vsync.name = VSync (Limita los fps a los Hz de tu pantalla) +setting.pixelate.name = Pixelar setting.minimap.name = Mostrar Minimapa setting.coreitems.name = Mostrar elementos en el nucleo (WIP) -setting.position.name = Mostrar posición del jugador. +setting.position.name = Mostrar indicadores de posición de jugadores. setting.musicvol.name = Volumen de la Música -setting.atmosphere.name = Mostrar atmosfera del planeta +setting.atmosphere.name = Mostrar Atmósfera del planeta setting.ambientvol.name = Volumen del Ambiente setting.mutemusic.name = Silenciar Musica setting.sfxvol.name = Volumen de los efectos de sonido setting.mutesound.name = Silenciar Sonido setting.crashreport.name = Enviar informes de fallos anónimos -setting.savecreate.name = Crear puntos de guardado automáticamente -setting.publichost.name = Visibilidad del juego público +setting.savecreate.name = Autoguardar la Partida +setting.publichost.name = Visibilidad de la Partida setting.playerlimit.name = Limite de Jugadores setting.chatopacity.name = Opacidad del Chat -setting.lasersopacity.name = Opacidad de los rayos láser -setting.bridgeopacity.name = Opacidad de Puentes +setting.lasersopacity.name = Opacidad del Laser de Nodos de Energía +setting.bridgeopacity.name = Opacidad de Puentes Transportadores setting.playerchat.name = Mostrar el chat de burbuja -public.confirm = ¿Quieres hacer público tu juego?\n[lightgray]Esto se puede cambiar más tarde en Configuración->Juego->Visibilidad pública del juego. -public.beta = Recuerda que en las versiones beta del juego no puedes crear partidas públicas. -uiscale.reset = La escala de la interfaz ha sido modificada con éxito.\nPulsa "OK" para conservar esta escala.\n[scarlet]Deshaciendo los cambios y saliendo al menu en [accent] {0}[]segundos... -uiscale.cancel = Cancelar & Salir -setting.bloom.name = Brillo +public.confirm = ¿Quieres hacer pública tu partida?\n[lightgray]Esto se puede cambiar más tarde en "Configuración->Juego->Visibilidad pública de la partida". +public.beta = Recuerda que no puedes crear partidas públicas en las versiones beta del juego. +uiscale.reset = La escala de la interfaz ha sido modificada.\nPulsa "OK" para conservar esta escala.\n[scarlet]Se desharán los cambios automáticamente en [accent] {0}[] segundos... +uiscale.cancel = Cancelar y Salir +setting.bloom.name = Desenfoque de movimiento keybind.title = Cambiar accesos de teclado keybinds.mobile = [scarlet]Los accesos del teclado aquí mostrados no estan disponible en Móviles o Tablets. Solo aceptan movimiento básico. category.general.name = General @@ -807,72 +846,72 @@ command.attack = Atacar command.rally = Patrullar command.retreat = Retirarse command.idle = Esperar -placement.blockselectkeys = \n[lightgray]LLaves: [{0}, +placement.blockselectkeys = \n[lightgray]Códigos: [{0}, keybind.respawn.name = Reaparecer keybind.control.name = Controlar unidad keybind.clear_building.name = Eliminar construcción -keybind.press = Presiona una tecla... +keybind.press = Pulsa una tecla... keybind.press.axis = Pulsa un eje o botón... keybind.screenshot.name = Captura de pantalla de Mapa -keybind.toggle_power_lines.name = Activar láser de potencia -keybind.toggle_block_status.name = Cambiar estado de los bloques +keybind.toggle_power_lines.name = Ocultar Láser de Red Eléctrica +keybind.toggle_block_status.name = Alternar estado de los bloques keybind.move_x.name = Mover x keybind.move_y.name = Mover y -keybind.mouse_move.name = Seguír al ratón - -keybind.pan.name = Vista panorámica -keybind.boost.name = Impulsar - +keybind.mouse_move.name = Seguir al Cursor del Ratón +keybind.pan.name = Desplazar la cámara +keybind.boost.name = Acelerar keybind.schematic_select.name = Seleccionar región -keybind.schematic_menu.name = Menu de esquemas -keybind.schematic_flip_x.name = Girar esquemático desde X -keybind.schematic_flip_y.name = Girar esquemático desde Y +keybind.schematic_menu.name = Menu de Plantillas +keybind.schematic_flip_x.name = Invertir Plantilla desde X +keybind.schematic_flip_y.name = Invertir Plantilla desde Y keybind.category_prev.name = Categoría anterior keybind.category_next.name = Siguiente categoría -keybind.block_select_left.name = Seleccionar bloque a la izquierda -keybind.block_select_right.name = Seleccionar bloque a la derecha -keybind.block_select_up.name = Seleccionar bloque hacia arriba -keybind.block_select_down.name = Seleccionar bloque hacia abajo -keybind.block_select_01.name = Seleccionar categoría / bloque 1 -keybind.block_select_02.name = Seleccionar categoría / bloque 2 -keybind.block_select_03.name = Seleccionar categoría / bloque 3 -keybind.block_select_04.name = Seleccionar categoría / bloque 4 -keybind.block_select_05.name = Seleccionar categoría / bloque 5 -keybind.block_select_06.name = Seleccionar categoría / bloque 6 -keybind.block_select_07.name = Seleccionar categoría / bloque 7 -keybind.block_select_08.name = Seleccionar categoría / bloque 8 -keybind.block_select_09.name = Seleccionar categoría / bloque 9 -keybind.block_select_10.name = Seleccionar categoría / bloque 10 -keybind.fullscreen.name = Intercambiar con Pantalla Completa +keybind.block_select_left.name = Seleccionar bloque - Izquierda +keybind.block_select_right.name = Seleccionar bloque - Derecha +keybind.block_select_up.name = Seleccionar bloque - Arriba +keybind.block_select_down.name = Seleccionar bloque - Abajo +keybind.block_select_01.name = Seleccionar Categoría/Bloque 1 +keybind.block_select_02.name = Seleccionar Categoría/Bloque 2 +keybind.block_select_03.name = Seleccionar Categoría/Bloque 3 +keybind.block_select_04.name = Seleccionar Categoría/Bloque 4 +keybind.block_select_05.name = Seleccionar Categoría/Bloque 5 +keybind.block_select_06.name = Seleccionar Categoría/Bloque 6 +keybind.block_select_07.name = Seleccionar Categoría/Bloque 7 +keybind.block_select_08.name = Seleccionar Categoría/Bloque 8 +keybind.block_select_09.name = Seleccionar Categoría/Bloque 9 +keybind.block_select_10.name = Seleccionar Categoría/Bloque 10 +keybind.fullscreen.name = Cambiar a Pantalla Completa keybind.select.name = Seleccionar keybind.diagonal_placement.name = Construcción Diagonal keybind.pick.name = Elegir bloque keybind.break_block.name = Destruir Bloque keybind.deselect.name = Deseleccionar -keybind.pickupCargo.name = Pickup Cargo -keybind.dropCargo.name = Drop Cargo -keybind.command.name = Command +keybind.pickupCargo.name = Recoger carga +keybind.dropCargo.name = Soltar carga +keybind.command.name = Ordenar keybind.shoot.name = Disparar keybind.zoom.name = Zoom keybind.menu.name = Menú keybind.pause.name = Pausa -keybind.pause_building.name = Pausar/Resumir construcción +keybind.pause_building.name = Pausar/Reanudar construcción keybind.minimap.name = Minimapa +keybind.planet_map.name = Mapa del Planeta +keybind.research.name = Investigaciones keybind.chat.name = Chat keybind.player_list.name = Lista de jugadores keybind.console.name = Consola keybind.rotate.name = Rotar keybind.rotateplaced.name = Rotar existente (mantener) -keybind.toggle_menus.name = Alternar menús -keybind.chat_history_prev.name = Historial de chat anterior -keybind.chat_history_next.name = Historial de chat siguiente -keybind.chat_scroll.name = Desplazamiento de chat -keybind.drop_unit.name = Caida de la unidad +keybind.toggle_menus.name = Ocultar menús +keybind.chat_history_prev.name = Historial de chat - Anterior +keybind.chat_history_next.name = Historial de chat - Siguiente +keybind.chat_scroll.name = Desplazar el chat +keybind.drop_unit.name = Soltar unidad keybind.zoom_minimap.name = Zoom del minimapa mode.help.title = Descripción de modos mode.survival.name = Supervivencia mode.survival.description = El modo normal. Recursos limitados y oleadas automáticas. -mode.sandbox.name = Arenero +mode.sandbox.name = Modo Libre mode.sandbox.description = Recursos ilimitados y sin temporizador para las oleadas. mode.editor.name = Editor mode.pvp.name = JcJ @@ -881,14 +920,14 @@ mode.attack.name = Ataque mode.attack.description = No hay oleadas, el objetivo es destruir la base enemiga. mode.custom = Normas personalizadas -rules.infiniteresources = Recursos Infinitos -rules.reactorexplosions = Reactor Explosions -rules.schematic = Schematics Allowed -rules.wavetimer = Temportzador de Oleadas +rules.infiniteresources = Recursos infinitos +rules.reactorexplosions = Los reactores pueden explotar +rules.schematic = Permitir Plantillas +rules.wavetimer = Temporizador de Oleadas rules.waves = Oleadas -rules.attack = Modo de Ataque -rules.buildai = Construccion de la IA -rules.enemyCheat = Recursos infinitos de la IA +rules.attack = Ataque +rules.buildai = La IA enemiga puede construir +rules.enemyCheat = La IA enemiga tiene recursos infinitos rules.blockhealthmultiplier = Multiplicador de salud de bloque rules.blockdamagemultiplier = Multiplicador de daño de bloque rules.unitbuildspeedmultiplier = Multiplicador de velocidad de creación de unidades @@ -898,7 +937,7 @@ rules.enemycorebuildradius = Radio de No-Construcción del Núcleo Enemigo:[ligh rules.wavespacing = Tiempo entre oleadas:[lightgray] (seg) rules.buildcostmultiplier = Multiplicador de coste de construcción rules.buildspeedmultiplier = Multiplicador de velocidad de construcción -rules.deconstructrefundmultiplier = Multiplicador de Devolución de Desconstrucción +rules.deconstructrefundmultiplier = Multiplicador de devolución de desconstrucción rules.waitForWaveToEnd = Las oleadas esperan a los enemigos rules.dropzoneradius = Radio de zona de caída:[lightgray] (casillas) rules.unitammo = Las unidades necesitan munición @@ -907,7 +946,6 @@ rules.title.resourcesbuilding = Recursos y Construcción rules.title.enemy = Enemigos rules.title.unit = Unidades rules.title.experimental = Experimental - rules.title.environment = Entorno rules.lighting = Iluminación rules.enemyLights = Luces enemigas @@ -918,11 +956,11 @@ rules.weather = Clima rules.weather.frequency = Frequencia: rules.weather.duration = Duracion: - content.item.name = Objetos content.liquid.name = Líquidos content.unit.name = Unidades content.block.name = Bloques +content.sector.name = Sectores item.copper.name = Cobre item.lead.name = Plomo @@ -943,23 +981,22 @@ item.scrap.name = Chatarra liquid.water.name = Agua liquid.slag.name = Fundido liquid.oil.name = Petróleo -liquid.cryofluid.name = Criogénico - - -unit.dagger.name = Daga -unit.mace.name = Mazo -unit.fortress.name = Fortaleza +liquid.cryofluid.name = Líquido criogénico +#Names of Units and Turrets look better untranslated, since they are propper/own names +unit.dagger.name = Dagger +unit.mace.name = Mace +unit.fortress.name = Fortress unit.nova.name = Nova unit.pulsar.name = Pulsar unit.quasar.name = Quasar -unit.crawler.name = Oruga +unit.crawler.name = Crawler unit.atrax.name = Atrax unit.spiroct.name = Spiroct unit.arkyid.name = Arkyid -unit.toxopid.name = Toxopodo -unit.flare.name = Bengala -unit.horizon.name = Horizonte -unit.zenith.name = Cenit +unit.toxopid.name = Toxopid +unit.flare.name = Flare +unit.horizon.name = Horizon +unit.zenith.name = Zenith unit.antumbra.name = Antumbra unit.eclipse.name = Eclipse unit.mono.name = Mono @@ -975,22 +1012,20 @@ unit.omura.name = Omura unit.alpha.name = Alpha unit.beta.name = Beta unit.gamma.name = Gamma -unit.scepter.name = Cetro +unit.scepter.name = Scepter unit.reign.name = Reign unit.vela.name = Vela -unit.corvus.name = Corvo +unit.corvus.name = Corvus block.resupply-point.name = Punto de reabastecimiento - -block.parallax.name = Paralaje -block.cliff.name = Acantilado - -block.sand-boulder.name = Piedra de Arena +block.parallax.name = Parallax +block.cliff.name = Cliff +block.sand-boulder.name = Roca de arena +block.basalt-boulder.name = Roca de basalto block.grass.name = Hierba -block.slag.name = Escoria -block.space.name = Space +block.slag.name = Magma +block.space.name = Espacio block.salt.name = Sal - block.salt-wall.name = Muro de sal block.pebbles.name = Guijarros block.tendrils.name = Zarcillos @@ -999,20 +1034,17 @@ block.spore-pine.name = Pino de esporas block.spore-wall.name = Muro de esporas block.boulder.name = Roca block.snow-boulder.name = Roca de nieve - block.snow-pine.name = Pino de nieve block.shale.name = Pizarra -block.shale-boulder.name = Piedra de Pizarra +block.shale-boulder.name = Piedra de pizarra block.moss.name = Musgo block.shrubs.name = Arbustos block.spore-moss.name = Musgo de esporas - block.shale-wall.name = Muro de pizarra - -block.scrap-wall.name = Muro de Chatarra -block.scrap-wall-large.name = Muro de Chatarra grande -block.scrap-wall-huge.name = Muro de Chatarra muy grande -block.scrap-wall-gigantic.name = Muro de Chatarra gigante +block.scrap-wall.name = Muro de chatarra +block.scrap-wall-large.name = Muro de chatarra grande +block.scrap-wall-huge.name = Muro de chatarra muy grande +block.scrap-wall-gigantic.name = Muro de chatarra gigante block.thruster.name = Propulsor block.kiln.name = Horno block.graphite-press.name = Prensa de grafito @@ -1024,26 +1056,26 @@ block.core-foundation.name = Núcleo: Fundación block.core-nucleus.name = Núcleo: Núcleo block.deepwater.name = Aguas profundas block.water.name = Agua -block.tainted-water.name = Agua Contaminada -block.darksand-tainted-water.name = Agua Contaminada con Arena Oscura +block.tainted-water.name = Agua contaminada +block.darksand-tainted-water.name = Agua contaminada con arena oscura block.tar.name = Alquitrán block.stone.name = Piedra block.sand.name = Arena -block.darksand.name = Arena Oscura +block.darksand.name = Arena oscura block.ice.name = Hielo block.snow.name = Nieve block.craters.name = Cráteres -block.sand-water.name = Agua con Arena -block.darksand-water.name = Agua con Arena Oscura +block.sand-water.name = Agua con arena +block.darksand-water.name = Agua con arena oscura block.char.name = Carbonizado block.dacite.name = Dacita -block.dacite-wall.name = Pared de Dacita -block.dacite-boulder.name = Dacite Boulder -block.ice-snow.name = Hielo Nieve +block.dacite-wall.name = Pared de dacita +block.dacite-boulder.name = Roca de dacita +block.ice-snow.name = Hielo-Nieve block.stone-wall.name = Pared de piedra block.ice-wall.name = Pared de hielo block.snow-wall.name = Pared de nieve -block.dune-wall.name = Pared de duna +block.dune-wall.name = Pared de arena block.pine.name = Pino block.dirt.name = Tierra block.dirt-wall.name = Pared de tierra @@ -1078,16 +1110,15 @@ block.thorium-wall.name = Pared de Torio block.thorium-wall-large.name = Muro de Torio grande block.door.name = Puerta block.door-large.name = Puerta Grande -block.duo.name = Dúo -block.scorch.name = Quemador -block.scatter.name = Dispersor -block.hail.name = Granizo -block.lancer.name = Lancero +block.duo.name = Duo +block.scorch.name = Scorch +block.scatter.name = Scatter +block.hail.name = Hail +block.lancer.name = Lancer block.conveyor.name = Cinta Transportadora block.titanium-conveyor.name = Cinta Transportadora de Titanio -block.plastanium-conveyor.name = Cinta Transportadora de Titanio +block.plastanium-conveyor.name = Cinta Transportadora de Plastanio block.armored-conveyor.name = Cinta Transportadora Acorazada -block.armored-conveyor.description = Mueve items a la misma veolcidad que una cinta de titanio, pero tiene mas defensa. No acepta entradas por los lados a menos que sean lineas transportadoras. block.junction.name = Cruce block.router.name = Enrutador block.distributor.name = Distribuidor @@ -1095,7 +1126,6 @@ block.sorter.name = Clasificador block.inverted-sorter.name = Clasificador Invertido block.message.name = Mensaje block.illuminator.name = Iluminador -block.illuminator.description = Una fuente de luz pequeña, compacta y configurable. Requiere poder para funcionar. block.overflow-gate.name = Compuerta de Desborde block.underflow-gate.name = Compuerta de Subdesbordamiento block.silicon-smelter.name = Horno para Silicio @@ -1131,12 +1161,12 @@ block.liquid-void.name = Vacío de líquidos block.power-void.name = Vacío de energía block.power-source.name = Energía Infinita block.unloader.name = Descargador -block.vault.name = Bóveda -block.wave.name = Ola +block.vault.name = Almacén +block.wave.name = Wave block.tsunami.name = Tsunami -block.swarmer.name = Enjambre -block.salvo.name = Salva -block.ripple.name = Onda +block.swarmer.name = Swarmer +block.salvo.name = Salvo +block.ripple.name = Ripple block.phase-conveyor.name = Cinta Transportadora de Fase block.bridge-conveyor.name = Puente de Cinta Transportadora block.plastanium-compressor.name = Compresor de Plastanio @@ -1145,9 +1175,9 @@ block.blast-mixer.name = Mezclador de Explosivos block.solar-panel.name = Panel Solar block.solar-panel-large.name = Panel Solar Grande block.oil-extractor.name = Extractor de Petróleo -block.repair-point.name = Punto de Reparación +block.repair-point.name = Punto de Reparación de Unidades block.pulse-conduit.name = Conducto de Pulso -block.plated-conduit.name = Conducto Chapado +block.plated-conduit.name = Conducto Acorazado block.phase-conduit.name = Conducto de Fase block.liquid-router.name = Enrutador de Líquidos block.liquid-tank.name = Tanque de Líquidos @@ -1161,103 +1191,125 @@ block.thermal-pump.name = Bomba Térmica block.thermal-generator.name = Generador Térmico block.alloy-smelter.name = Fundidor de Materia block.mender.name = Reparador -block.mend-projector.name = Proyector de reparación +block.mend-projector.name = Proyector de Reparación block.surge-wall.name = Muro de Sobretensión block.surge-wall-large.name = Muro de Sobretensión grande -block.cyclone.name = Ciclón -block.fuse.name = Fusible +block.cyclone.name = Cyclone +block.fuse.name = Fuse block.shock-mine.name = Mina electrizante -block.overdrive-projector.name = Proyector de sobremarcha -block.force-projector.name = Proyector de fuerza -block.arc.name = Arco +block.overdrive-projector.name = Proyector de Aceleración +block.force-projector.name = Proyector de Escudo +block.arc.name = Arc block.rtg-generator.name = Generador RTG -block.spectre.name = Espectro -block.meltdown.name = Fusión de Reactor +block.spectre.name = Spectre +block.meltdown.name = Meltdown block.foreshadow.name = Foreshadow block.container.name = Contenedor block.launch-pad.name = Pad de Lanzamiento block.launch-pad-large.name = Pad de Lanzamiento Grande -block.segment.name = Segmento +block.segment.name = Segment block.command-center.name = Centro de comando - block.ground-factory.name = Fábrica terrestre block.air-factory.name = Fábrica aérea - block.naval-factory.name = Fábrica naval block.additive-reconstructor.name = Reconstructor aditivo block.multiplicative-reconstructor.name = Reconstructor multiplicativo block.exponential-reconstructor.name = Reconstructor exponencial block.tetrative-reconstructor.name = Reconstructor tetrativo - -block.payload-conveyor.name = Transportador masivo -block.payload-router.name = Enrutador de carga útil +block.payload-conveyor.name = Transportador de carga +block.payload-router.name = Enrutador de carga block.disassembler.name = Desensamblador block.silicon-crucible.name = Crisol de silicio -block.overdrive-dome.name = Cupula de sobremarcha +block.overdrive-dome.name = Campo de Aceleración +#experimental, puede ser eliminado +block.block-forge.name = Fundidor de Bloques +block.block-loader.name = Cargador de Bloques +block.block-unloader.name = Descargador de Bloques +block.interplanetary-accelerator.name = Acelerador Interplanetario block.switch.name = Interruptor block.micro-processor.name = Micro Processador block.logic-processor.name = Procesador lógico block.hyper-processor.name = Hiperprocesador block.logic-display.name = Pantalla lógica -block.large-logic-display.name = Gran pantalla lógica -block.memory-cell.name = Celda de memoria -block.memory-bank.name = Banco de memoria +block.large-logic-display.name = Pantalla lógica grande +block.memory-cell.name = Unidad de memoria +block.memory-bank.name = Servidor de memoria - -team.blue.name = Azul +team.blue.name = azul team.crux.name = rojo team.sharded.name = naranja -team.orange.name = Naranja +team.orange.name = naranja +team.derelict.name = abandonado +team.green.name = verde +team.purple.name = morado -team.derelict.name = derelicto +hint.skip = Omitir +hint.desktopMove = Usa [accent][[WASD][] para moverte. +hint.zoom = Puedes usar la [accent]Rueda del ratón[] para controlar el zoom. +hint.mine = Acércate a \uf8c4 una veta de cobre [accent]tócala[]\n para extraer cobre manualmente. +hint.desktopShoot = [accent][[Left-click][] para disparar. +hint.depositItems = Deposita objetos arrastrándolos desde tu nave hasta el núcleo. +hint.respawn = Para sacar otra nave, pulsa [accent][[V][]. +hint.respawn.mobile = Has pasado a controlar una unidad/estructura. Para volver a manejar la nave, [accent]toca el icono arriba a la izquierda.[] +hint.desktopPause = Pulsa [accent][[Space][] para pausar y reanudar la partida. +hint.placeDrill = Selecciona la pestaña de \ue85e [accent]Taladros[] en el menú abajo a la derecha, luego escoge un \uf870 [accent]Taladro[] y haz clic sobre una veta de cobre para colocarlo. +hint.placeDrill.mobile = Selecciona la pestaña de \ue85e [accent]Taladros[] en el menú abajo a la derecha, luego escoge un \uf870 [accent]Taladro[] y toca sobre una veta de cobre para colocarlo.\n\nPulsa el botón con la \ue800 [accent]"V"[] abajo a la derecha para confirmar. +hint.placeConveyor = Las cintas transportadoras pueden sacar objetos de los taladros, y moverlos hasta otros bloques. Selecciona un \uf896 [accent]Transportador[] de la pestaña \ue814 [accent]Distribución[].\n\nHaz clic y arrastra para crear una cadena con múltiples transportadores.\nUsa la [accent]Rueda del ratón[] para rotarlo. +hint.placeConveyor.mobile = Las cintas transportadoras pueden mover objetos de los taladros hasta otros bloques. Selecciona un \uf896 [accent]Transportador[] de la pestaña \ue814 [accent]Distribución[].\n\nMantén el dedo un segundo y arrastra para crear múltiples cintas transportadoras. +hint.placeTurret = Construye \uf861 [accent]Torretas[] para defender tu base de los enemigos.\n\nLas torretas necesitan munición - en este caso, \uf838cobre.\nUsa cintas transportadoras y taladros para abastecerlas con cobre. +hint.breaking = Pulsa [accent]Clic-derecho[] y arrastra para destruir bloques. +hint.breaking.mobile = Activa el botón con el \ue817 [accent]martillo[] situado abajo a la derecha y selecciona bloque para eliminarlos.\n\nMantén el dedo un segundo y arrastra para eliminar bloques directamente en esa selección. +hint.research = Usa el botón \ue875 [accent]Investigación[] para acceder al menú de descubrimientos tecnológicos. +hint.research.mobile = Usa el botón \ue875 [accent]Investigación[] para acceder al menú de descubrimientos tecnológicos. +hint.unitControl = Mantén [accent][[L-ctrl][] y [accent]haz clic[] sobre unidades o torretas aliadas para controlarlas manualmente. +hint.unitControl.mobile = [accent][Toca dos veces rápidamente[] una unidad o torreta aliada para controlarla manualmente. +hint.launch = Cuando tengas sufientes recursos, puedes [accent]Lanzar el Núcleo[] escogiendo como objetivo sectores cercanos en el \ue827 [accent]Mapa[] abajo a la derecha. +hint.launch.mobile = Cuando tengas sufientes recursos, puedes [accent]Lanzar el Núcleo[] escogiendo como objetivo sectores cercanos en el \ue827 [accent]Mapa[], disponible desde el \ue88c [accent]Menú de pausa[]. +hint.schematicSelect = Mantén [accent][[F][] y arrastra para crear una selección de bloques que puedes copiar y pegar.\n\nUsa [accent][[Clic central][] para seleccionar un tipo de bloque. +hint.conveyorPathfind = Mantener [accent][[L-Ctrl][] mientras arrastras cintas transportadoras generará automáticamente una ruta. +hint.conveyorPathfind.mobile = Activa el\ue844 [accent]modo diagonal[] y arrastra cintas transportadoras para generar una ruta inteligente. +hint.boost = Mantén [accent][[L-Shift][] para sobrevolar obstáculos con tu unidad actual.\n\nSólo algunas unidades terrestres disponen de estos propulsores. +hint.command = Pulsa [accent][[G][] para comandar unidades aliadas cercanas. +hint.command.mobile = [accent][[Toca dos veces][] tu unidad para comandar unidades aliadas cercanas. +hint.payloadPickup = Pulsa [accent][[[] para recoger bloques pequeños o unidades. +hint.payloadPickup.mobile = [accent]Mantén[] sobre un bloque pequeño o unidad para recogerlo. +hint.payloadDrop = Pulsa [accent]][] para soltar la carga. +hint.payloadDrop.mobile = [accent]Mantén[] sobre un lugar vacío para soltar la carga. +hint.waveFire = Cuando las torretas [accent]Wave[] usan agua como munición, apagarán fuego e incendios cercanos automáticamente. +hint.generator = Los \uf879[accent]Generadores de combustión[] querman carbón para transmitir energía a bloques adyacentes.\n\nEl alcance de transmisión de energía se puede extender usando \uf87f[accent]Nodos de energía[]. +hint.guardian = Los [accent]Guardianes[] poseen una robusta armadura. Municiones débiles como el [accent]Cobre[] o el [accent]Plomo[] no son [scarlet]effectivas[] contra él.\n\nUsa torretas de mayor categoría o por ejemplo, munición de \uf835[accent]Grafito[] \uf861Duo/\uf859 en torretas Salvo para derribar a los Guardianes. -team.green.name = Verde -team.purple.name = Púrpura +item.copper.description = Un útil material de estructura. Usado en todo tipo de bloques. +item.copper.details = Cobre. Metal anormalmente abundante en Serpulo. Estructuralmente débil a menos que sea reforzado. +item.lead.description = Un material básico. Usado en electrónicos y transferencia de líquidos. +item.lead.details = Denso. Inerte. Extensamente usado en baterías.\nNota: Suele ser tóxico para la mayoría de formas de vida biológicas. Aunque ya no quedan muchas de esas por aquí. +item.metaglass.description = Usado en almacenamiento y distribución de líquidos. +item.graphite.description = Carbón mineralizado, usado como munición y en componentes eléctricos. +item.sand.description = Es usada sobre todo para producir otros minerales refinados. +item.coal.description = Se usa como combustible y también en la producción de materiales refinados. +item.coal.details = Parece ser materia vegetal fosilizada, formada hace mucho tiempo. +item.titanium.description = Usado en transporte de liquidos, taladros y aeronaves. +item.thorium.description = Usado en estructuras robustas y como combustible nuclear. +item.scrap.description = Usado en fundidores y pulverizadores para refinarlo en otros materiales. +item.scrap.details = Restos de antiguas estructuras y unidades caídas. +item.silicon.description = Usado en paneles solares, electrónicos complejos y munición inteligente. +item.plastanium.description = Usado en unidades avanzadas, aislamiento y munición de fragmentación. +item.phase-fabric.description = Usado en electrónicos avanzados y estructuras autoreparadoras. +item.surge-alloy.description = Usado en armamento avanzado y estructuras de defensa reactiva. +item.spore-pod.description = Se puede usar como combustible, o para obtener petróleo y explosivos. +item.spore-pod.details = Esporas. Es algo parecido a una forma de vida sintética. Emiten gases tóxicos para el resto de vida biológica. Extremadamente invasivo. Altamente inflamable bajo determinadas condiciones. +item.blast-compound.description = Usado en bombas y munición explosiva. +item.pyratite.description = Usado en armas incendiarias y generadores de combustión. -tutorial.next = [lightgray] -tutorial.intro = Has entrado en el[scarlet]Tutorial de Mindustry.[]\nComienza[accent]minando cobre[]. Toca en una veta de cobre cercana al núcleo para hacer esto.\n\n[accent]{0}/{1} cobre -tutorial.intro.mobile = Has entrado en el[scarlet] Tutorial de Mindustry.[]\nArrastra la pantalla para moverte.\n[accent]Pellizca con 2 dedos [] para alejar y acercar la vista.\nComienza por[accent] minar cobre[]. Muevete cerca de el, luego toca una veta de mineral de cobre cerca de su núcleo para hacer esto.\n\n[accent]{0}/{1} cobre -tutorial.drill = Minar manualmente es ineficiente.\nLos [accent]taladros pueden minar automáticamente.\nColoca uno en una veta de cobre. -tutorial.drill.mobile = Minar manualmente no es muy eficiente.\nLos [accent]Taladros[] pueden minar automáticamente.\nToca la sección de taladros el la esquina de abajo a la derecha.\nSelecciona el[accent]taladro mecánico[].\nColócalo en una veta de cobre tocándola, después pulsa el [accent]botón de confirmación de debajo para confirmar tu selección.\nPulsa el[accent]botón "X" para cancelar la construcción. -tutorial.blockinfo = Cada bloque tiene diferentes estadísticas. Cada taladro solo puede minar ciertos minerales.\nPara comprobar la información y estadísticas de un bloque,[accent] toca el botón "?" mientras lo tienes seleccionado en el menú de construcción.[]\n\n[accent]Accede a las estadísticas del Taladro Mecánico ahora.[] -tutorial.conveyor = Las [accent]Cintas Transportadoras[] se usan para transportar recursos al núcleo.\nConstruye una línea de transportadores del taladro al núcleo. -tutorial.conveyor.mobile = Las [accent]Cintas Transportadoras[] se usan para transportar recursos al núcleo.\nConstruye una línea de transportadores del taladro al núcleo.\n[accent] Construye una línea manteniendo el dedo unos segundos[] y arrastrando hacia una dirección.\n\n[accet]{0}/{1} cintas colocadas en línea\n[ccent]]0/1 recursos transportados. -tutorial.turret = Debes construir estructuras defensivas para repeler al [lightgray]enemigo[].\nConstruye una torreta dúo cerca de tu base. -tutorial.drillturret = Los dúos requieren[accent] munición de cobre[]para disparar.\nColoca un taladro junto a la torre para darle cobre. \nTambien puedes hacer una línea de transportadores desde el taladro hasta el dúo. -tutorial.pause = Durante la batalla, puedes[accent]pausar el juego.[]\nPuedes dejar estructuras en cola mientras pausas.\n\n[accent]Pulsa Espacio para pausar. -tutorial.pause.mobile = Durante la batalla, puedes[accent] pausar el juego.[]\nPuedes dejar estructuras en cola mientras pausas.\n\n[accent]Pulsa este boton de arriba a la izquierda para pausar. -tutorial.unpause = Ahora toca Espacio otra vez para dejar de pausar. -tutorial.unpause.mobile = Ahora tócalo otra vez para dejar de pausar. -tutorial.breaking = Muchas veces hace falta destruir bloques.\n[accent]Mantén el botón derecho[] para destruir todos los bloques en una selección.[]\n\n[accent]Destruye todos los bloques de chatarra de la izquierda de tu núcleo usando selección de área. -tutorial.breaking.mobile = Muchas veces hace falta destruir bloques.\n[accent]Selecciona el modo de desonstrucción[], después toca un bloque para comenzar a romperlo.\nDestruye un área manteniendo tu dedo algunos segundos[] y arrastrando hacia una dirección.\nUsa el botón de confirmación para confirmar la destrucción.\n\n[accent]Destruye todos los bloques de chatarra de la izquierda de tu núcleo usando la selección de área.[] -tutorial.withdraw = En algunas situaciones, es necesario coger recursos directamente de bloques.\nPara hacer esto, [accent]toca un bloque[] con recursos en él, después [accent]toca el recurso[] en el inventario.\nSe pueden sacar múltiples recursos [accent]tocando y manteniendo[].\n\n[accent]Saca algo de cobre del núcleo.[] -tutorial.deposit = Deposita recursos en bloques arrastrándolos de tu nave al bloque de destino.\n\n[accent]Deposita tu cobre otra vez al núcleo.[] -tutorial.waves = El[lightgray] enemigo[] se acerca.\n\nDefiende tu núcleo por 2 oleadas. Construye más torretas y taladros. Mina más cobre. -tutorial.waves.mobile = El[lightgray] enemigo[] se acerca.\n\nDefiende tu núcleo por 2 oleadas. Tu nave disparará automáticamente a los enemigos.\nConstruye más torretas y taladros. Mina más cobre. -tutorial.launch = Una vez llegues a cierta oleada, podrás[accent]lanzar el núcleo[], dejando atrás tus defensas y los recursos en tu núcleo.[]\nEstos recursos pueden ser usados para investigar nueva tecnología.\n\n[accent]Pulsa el botón de lanzamiento. - -item.copper.description = Un útil material de estructura. Usado extensivamente en todo tipo de bloques. -item.lead.description = Un material básico. Usado extensivamente en electrónicos y bloques de transferencia de líquidos. -item.metaglass.description = Un compuesto muy duro de cristal. Usado extensivamente para almacenamiento y distribución de líquidos. -item.graphite.description = Carbón mineralizado, usasdo para munición y aislamiento eléctrico. -item.sand.description = Un material común que es usado extensivamente en la fundición, para aleaciones y como fundente. -item.coal.description = Un combustible común y preparado para ser quemado. -item.titanium.description = Un metal raro muy ligero usado extensivamente en transportación de liquidos, taladros y aeronaves. -item.thorium.description = Un metal radiactivo, muy denso y usado en soporte de estructuras y combustible nuclear. -item.scrap.description = Restos de estructuras y unidades antiguas. Contiene pequeñas cantidades de muchos metales diferentes. -item.silicon.description = Un semiconductor muy útil, se usa para paneles solares y muchos electrónicos complejos. -item.plastanium.description = Un material dúctil y ligero usado en aeronaves y proyectiles de fragmentación. -item.phase-fabric.description = Una sustancia casi sin peso usada en electrónica avanzada y en tecnología autoreparadora. -item.surge-alloy.description = Una aleación avanzada con propiedades eléctricas únicas. -item.spore-pod.description = Utilizado para ser convertido en petróleo, explosivos y combustible. -item.blast-compound.description = Un compuesto volátil usado en bombas y explosivos. Aunque se puede quemar como combustible, esto no es recomendable. -item.pyratite.description = Una sustancia extremadamente inflamable usada en armas incendiarias. liquid.water.description = Usada comúnmente para enfriar máquinas y para procesar residuos. -liquid.slag.description = Diferentes tipos de metales fundidos mezclados. Puede ser separado en sus minerales constituyentes, o expulsado a unidades enemigas como arma. -liquid.oil.description = Puede ser quemado, explotado o como un enfriador. -liquid.cryofluid.description = El líquido más eficiente pra enfriar las cosas. +liquid.slag.description = Diferentes tipos de metales fundidos mezclados. Puede ser separado en sus minerales constituyentes, o disparado a unidades enemigas como arma. +liquid.oil.description = Se utiliza en producción de materiales avanzados, y en munición incendiaria. +liquid.cryofluid.description = Usado como refrigerante para reactores, torretas, y fábricas. +block.resupply-point.description = Reabastece unidades cercanas con munición de cobre. No es compatible con unidades que requieren energía. +block.armored-conveyor.description = Mueve objetos. No acepta objetos si entran por los lados. +block.illuminator.description = Emite luz. block.message.description = Almacena un mensaje. Puedes usarlo para comunicarte con aliados o dejar recordatorios. block.graphite-press.description = Comprime carbón en piezas de grafito puro. block.multi-press.description = Una versión mejorada de la prensa de grafito. Utiliza agua y energía para procesar carbón rápida y eficientemente. @@ -1275,12 +1327,12 @@ block.spore-press.description = Comprime esporas en petróleo. block.pulverizer.description = Despedaza la piedra en arena. Útil cuando no hay arena natural. block.coal-centrifuge.description = Solidifica petróleo en piezas de carbón. block.incinerator.description = Se deshace de cualquier líquido o material producido en exceso. -block.power-void.description = Elimina toda la energía que se le da. Solo en disponible en el modo Sandbox. -block.power-source.description = Da energía infinita. Solo disponible en el modo Sandbox. -block.item-source.description = Hace aparecer minerales de forma infinita. Solo disponible en el modo Sandbox. -block.item-void.description = Destruye cuanquier objeto que entra en él. Solo disponible en el modo Sandbox. -block.liquid-source.description = Da líquido infinito. Solo disponible en el modo Sandbox. -block.liquid-void.description = Elimina cualquier liquido que entra en él. Solo disponible en el modo Sandbox. +block.power-void.description = Elimina toda la energía que se le da. Solo en disponible en el modo Libre. +block.power-source.description = Da energía infinita. Solo disponible en el modo Libre. +block.item-source.description = Hace aparecer minerales de forma infinita. Solo disponible en el modo Libre. +block.item-void.description = Destruye cuanquier objeto que entra en él. Solo disponible en el modo Libre. +block.liquid-source.description = Da líquido infinito. Solo disponible en el modo Libre. +block.liquid-void.description = Elimina cualquier liquido que entra en él. Solo disponible en el modo Libre. block.copper-wall.description = Un bloque defensivo barato.\nÚtil para defender el núcleo y las torres en las primeras oleadas. block.copper-wall-large.description = Un bloque defensivo barato.\nÚtil para defender el núcleo y las torres en las primeras oleadas.\nOcupa múltiples casillas. block.titanium-wall.description = Un bloque defensivo moderadamente fuerte.\nProporciona protección moderada contra los enemigos. @@ -1302,71 +1354,134 @@ block.force-projector.description = Crea un área de fuerza hexagonal alrededor block.shock-mine.description = Daña enemigos que pisan a mina. Casi invisible al enemigo. 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.plastanium-conveyor.description = Mueve ítems por lotes.\nAcepta ítems por detrás, y los descarga en tres direcciones hacia el frente, como un enrutador. +block.plastanium-conveyor.description = Mueve objetos por lotes.\nAcepta objetos por detrás, y los descarga en tres direcciones hacia el frente, como un enrutador. 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.bridge-conveyor.description = Bloque avanzado de transporte. Puede transportar objetos por encima hasta 3 casillas de cualquier terreno o construcción. block.phase-conveyor.description = Bloque de transporte avanzado. Usa energía para transportar objetos a otro transportador de fase conectado a través de varias casillas. block.sorter.description = Clasifica objetos. Si un objeto es igual al seleccionado, pasará al frente. Si no, el objeto saldrá por la izquierda y la derecha. block.inverted-sorter.description = Procesa elementos como un clasificador estándar, pero en su lugar pasa elementos seleccionados a los lados. block.router.description = Acepta objetos de una dirección luego los deja equitativamente en hasta 3 direcciones diferentes. Útil para dividir los materiales de una fuente de recursos a múltiples objetivos. \n\n[scarlet]Nunca usar como entrada de producción porque puede tapar con los objetos de salida.[] +block.router.details = Un mal necesario... No se recomienda usarlo junto a estructuras de producción ya que puede atascar una cadena de transporte. block.distributor.description = Un enrutador avanzado que distribuye objetos equitativamente en hasta otras 7 direcciones. block.overflow-gate.description = Un enrutador que solo saca por la izquierda y la derecha si la cinta del frente está llena. block.underflow-gate.description = El opuesto de la compuerda de desborde. Solo dispensa hacia el frente si los lados están bloqueados. block.mass-driver.description = El mejor bloque de transorte. Recoge varios objetos y los dispara a otro conductor de masa en un largo rango. Requiere energía para operar. block.mechanical-pump.description = Una bomba de agua barata algo lenta, pero funciona sin energía. -block.rotary-pump.description = Una bomba de agua algo mas avanzada. Bombea más líquido, pero requiere energía. -block.thermal-pump.description = La mejor bomba. Utiliza energía. +block.rotary-pump.description = Una bomba algo mas avanzada. Bombea más líquido, pero requiere energía. +block.thermal-pump.description = La mejor bomba de líquidos. Utiliza energía. 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.plated-conduit.description = Mueve líquidos a la misma velocidad que los conductos de pulso, pero posee más armadura. No acepta líquidos de los lados por otra cosa que no sean conductos.\nGotea menos. block.liquid-router.description = Acepta líquidos de una dirección y los deja en hasta 3 direcciones equitativamente. También puede almacenar 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.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.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. -block.power-node-large.description = Tiene un radio más amplio que el nodo de energía y conecta hasta seis fuentes de energía, edificios que usan energía o nodos. -block.surge-tower.description = Un nodo con un gran alcance con menos conexiones disponibles. +block.bridge-conduit.description = Bloque avanzado de transporte de líquidos. Permite transportar líquidos por encima de hasta 3 casillas de cualquier terreno o construcción. +block.phase-conduit.description = Bloque de transporte de líquidos avanzado. Usa energía para transportar líquidos a otro conducto de fase conectado a través de varias casillas. +block.power-node.description = Transmite energía a nodos conectados, conecta hasta diez fuentes de energía, edificios que usan energía o nodos. El nodo obtendrá o transmitirá energía de cualquier bloque adyacente. +block.power-node-large.description = Tiene un radio más amplio que el nodo de energía y conecta hasta diez fuentes de energía, edificios que usan energía o nodos. +block.surge-tower.description = Un nodo con un gran alcance, pero sólo dos conexiones disponibles. block.diode.description = La energía de la batería puede fluir a través de este bloque en una sola dirección, pero solo si el otro lado tiene menos energía almacenada. block.battery.description = Guarda energía cuando hay abundancia y proporciona energía cuando hay escasez de energía mientras la batería tenga energía. block.battery-large.description = Almacena mucha más energía que una batería normal. -block.combustion-generator.description = Genera energía quemando aceite o materiales inflamables. +block.combustion-generator.description = Genera energía quemando materiales inflamables o petróleo. block.thermal-generator.description = Genera una gran cantidad de energía con la lava. block.steam-generator.description = Más eficiente que un generador de combustión, pero requiere agua adicional. -block.differential-generator.description = Genera grandes cantidades de energía. Utiliza la diferencia de temperatura entre el fluído criogenico y la quema de piratita. +block.differential-generator.description = Genera grandes cantidades de energía. Utiliza la diferencia de temperatura entre el fluído criogenico y la quema de pirotita. block.rtg-generator.description = Un generador radioisótropo termoeléctrico que no necesita enfriamiento, pero proporciona menos energía que un reactor de torio. -block.solar-panel.description = Proporciona una pequeña cantidad de energía procedente del sol. -block.solar-panel-large.description = Genera un mucho mejor suministro de energía que un panel solar estándar, pero también es mucho más caro de construir. +block.solar-panel.description = Proporciona una pequeña cantidad de energía. +block.solar-panel-large.description = Genera un mayor suministro de energía que un panel solar estándar, pero también es mucho más caro de construir. block.thorium-reactor.description = Genera grandes cantidades de energía del torio altamente radioactivo. Necesita enfriamiento constante. Explotará violentamente si no se le aporta suficiente enfriamiento. block.impact-reactor.description = Un generador avanzado, capaz de crear cantidades masivas de energía a máxima eficiencia. Requiere una cantidad significante de energía para impulsar el comienzo del proceso. block.mechanical-drill.description = Un taladro barato. Cuando es colocado en casillas apropiadas, extrae objetos lentamente de forma indefinida. Solo es capaz de minar recursos básicos. block.pneumatic-drill.description = Un taladro mejorado, es capaz de minar titanio. Más rápido que un taladro mécanico. -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.laser-drill.description = Su tecnología láser le permite obtener minerales incluso más rápido, pero requiere energía. Además, se puede obtener torio radioactivo con este taladro. block.blast-drill.description = El mejor taladro. Requiere grandes cantidades de energía y refrigeración. block.water-extractor.description = Extrae agua de la tierra. Úsalo cuando no haya lagos cercanos. block.cultivator.description = Cultiva concentraciones de esporas en la atmosfera a vainas. +block.cultivator.details = Tecnología recuperada. Usada para producir cantidades masivas de biomasa. Parecido al primer incubador de esporas, que ahora cubren Serpulo. block.oil-extractor.description = Usa grandes cantidades de energía, arena y agua para obtener petróleo. Úsalo cuando no hay fuentes directas de petróleo cerca. -block.core-shard.description = La primera iteración de la cápsula del núcleo. Una vez destruido, todo el contacto con la región es perdido. No permitas que esto ocurra. -block.core-foundation.description = La segunda versión del núcleo. Mejor blindado. Almacena más recursos. -block.core-nucleus.description = La tercera y última iteración de la cápsula del núcleo. Muy bien blindado. Almacena cantidades masivas dde recursos. -block.vault.description = Almacena una gran cantidad de objetos. Úsalo para crear almacenes cuando no hay una demanda constante de materales. Un [lightgray] unloader[] puede usarse para obtener objetos del almacén. -block.container.description = Almacena una pequeña cantidad de objetos. Úsalo para crear almacenes cuando no hay una demanda constante de materales. Un [lightgray] unloader[] puede usarse para obtener objetos del contenedor. +block.core-shard.description = El núcleo de la base. Compacto. Puede auto-replicarse. Equipado con propulsores de uso único. +block.core-shard.details = La primera iteración. Si es destruido, todo contacto con el sector está perdido. No designado para viajes interplanetarios. +block.core-foundation.description = El núcleo de la base. Mejor blindado. Almacena más recursos que el modelo Fragmento. +block.core-foundation.details = La segunda iteración. +block.core-nucleus.description = El núcleo de la base. Extremadamente bien armado. Almacena cantidades masivas de recursos. +block.core-nucleus.details = La tercera y última iteración. +block.vault.description = Almacena una gran cantidad de objetos. Úsalo para crear almacenes cuando no hay una demanda constante de materales. Un [lightgray] descargador[] puede usarse para obtener los objetos almacenados. +block.container.description = Almacena una pequeña cantidad de objetos. Úsalo para crear almacenes cuando no hay una demanda constante de materales. Un [lightgray] descargador[] puede usarse para obtener objetos del contenedor. block.unloader.description = Descarga objetos de un contenedor, almacén o el núcleo a un transportador o directamente a un bloque adyacente. El tipo de objeto descargado puede ser cambiado tocando el descagador. -block.launch-pad.description = Lanza paquetes de recursos sin necesitar lanzar con el núcleo. -block.launch-pad-large.description = Una versión mejorada del pad de lanzamiento. Almacena más recursos y los lanza más frecuentemente. +block.launch-pad.description = Lanza paquetes de recursos a los sectores seleccionados. block.duo.description = Una torre pequeña y barata. Útil contra enemigos terrestres no demasiado fuertes. -block.scatter.description = Una torreta antiaérea de tamaño medio. Dispara fuego anti-aéreo de plomo o chatarra a las unidades enemigas. +block.scatter.description = Una torreta antiaérea de tamaño medio. Dispara proyectiles de plomo o chatarra a las unidades enemigas. block.scorch.description = Quema a cualquier enemigo terrestre cercano a él. Altamente efectivo a corto alcance. block.hail.description = Una torre de artillería pequeña de largo alcance. block.wave.description = Una torre de tamaño mediano. Dispara chorros de líquido a enemigos. Apaga el fuego en su rango de acción si recibe agua. block.lancer.description = Una torre láser anti-terrestre de tamaño mediano. Dispara y carga poderosos rayos de energía. block.arc.description = Una pequeña torre eléctrica de rango corto. Dispara arcos de electricidad a los enemigos. block.swarmer.description = Una torre de tamaño mediano que dispara misiles. Ataca a aire y tierra. Dispara misiles teledirigidos. -block.salvo.description = Una versión más grande y avanzada dela torre dúo. Dispara salvas rápidas al enemigo +block.salvo.description = Una versión más grande y avanzada de la torre dúo. Dispara ráfagas a enemigos terrestres y aéreos. block.fuse.description = Una torre grande de energía de corto alcance. Dispara tres rayos perforantes a enemigos cercanos. -block.ripple.description = Una extramadamente poderosa torre. Dispara conjuntos de balas a los enemigos en grandes distancias. -block.cyclone.description = Una torre grande anti-aérea y anti-terrestre. Dispara conjuntos explosivos de Flak a enemigos cercanos. +block.ripple.description = Una torre extramadamente poderosa. Dispara conjuntos de balas a los enemigos desde grandes distancias. +block.cyclone.description = Una torre grande anti-aérea y anti-terrestre. Dispara conjuntos fragmentados explosivos a enemigos cercanos. block.spectre.description = Un cañon masivo de dos barriles. Dispara balas perforantes a objetivos de aire y tierra. -block.meltdown.description = Un cañon láser masivo. Carga y dispara un rayo láser constante a enemigos cercanos. Requiere enfriamiento para operar. -block.repair-point.description = Repara la unidad dañada más cercana a su alrededor. -block.segment.description = Daña y destruye proyectiles enemigos. No apunta a láseres. +block.meltdown.description = Un cañon láser masivo. Carga y dispara un rayo láser continuo a enemigos cercanos. Requiere enfriamiento para operar. +block.foreshadow.description = Dispara un rayo de un solo objetivo a grandes distancias. +block.repair-point.description = Repara constantemente la unidad dañada más cercana dentro de su área. +block.segment.description = Daña y destruye proyectiles que se acerquen. No afecta a los láseres. +block.parallax.description = Dispara un rayo tractor que atrae enemigos aéreos, dañándolos en el proceso. +block.tsunami.description = Dispara poderosos torrentes de líquido a los enemigos. También apaga fuegos automáticamente si se lo abastece con agua. +block.silicon-crucible.description = Refina silicio a partir de arena y carbón, usando pirotita como una fuente de calor adicional. Es más eficiente en lugares cálidos. +block.disassembler.description = Separa magma cantidades moderadas de componentes minerales exóticos con baja eficiencia. Puede producir Torio. +block.overdrive-dome.description = Incrementa la velocidad de estructuras cercanas. Requiere Tejido de Fase, y Silicio para operar. +block.payload-conveyor.description = Mueve tanto grandes cargas, como unidades recién ensambladas de sus fábricas. +block.payload-router.description = Divide las cargas entrantes en 3 direcciones de salida. +block.command-center.description = Controla el comportamiento de las unidades con diferentes órdenes. +block.ground-factory.description = Produce unidades terrestres. Las unidades resultantes se pueden usar directamente, o se pueden llevar a reconstructores para mejorarlas. +block.air-factory.description = Produce unidades aéreas. Las unidades resultantes se pueden usar directamente, o se pueden llevar a reconstructores para mejorarlas. +block.naval-factory.description = Produce unidades navales. Las unidades resultantes se pueden usar directamente, o se pueden llevar a reconstructores para mejorarlas. +block.additive-reconstructor.description = Mejora unidades a segunda categoría. +block.multiplicative-reconstructor.description = Mejora unidades a tercera categoría. +block.exponential-reconstructor.description = Mejora unidades a cuarta categoría. +block.tetrative-reconstructor.description = Mejora unidades a la quinta y última categoría. +block.switch.description = Un interruptor alternable. Su estado puede ser detectado y controlado por procesadores lógicos. +block.micro-processor.description = Ejecuta una secuencia de instrucciones lógicas en bucle. Se puede usar para controlar unidades y estructuras. +block.logic-processor.description = Ejecuta una secuencia de instrucciones lógicas en bucle. Se puede usar para controlar unidades y estructuras. Es más rápido que el microprocesador. +block.hyper-processor.description = Ejecuta una secuencia de instrucciones lógicas en bucle. Se puede usar para controlar unidades y estructuras. Es más rápido que el procesador lógico. +block.memory-cell.description = Almacena información para los procesadores lógicos. +block.memory-bank.description = Almacena información para los procesadores lógicos. Alta capacidad. +block.logic-display.description = Muestra gráficos arbitrarios desde un procesador lógico. +block.large-logic-display.description = También muestra gráficos arbitrarios desde un procesador lógico. +block.interplanetary-accelerator.description = Una torre de proyección electromagnética masiva. Puede acelerar los núcleos hasta la velocidad necesaria para su desplegación interplanetaria. + +unit.dagger.description = Dispara proyectiles básicos a enemigos cercanos. +unit.mace.description = Lanza torrentes de llamas a enemigos cercanos. +unit.fortress.description = Utiliza artillería de largo alcance contra enemigos terrestres. +unit.scepter.description = Bombardea enemigos cercanos con proyectiles cargados. +unit.reign.description = Bombardea enemigos con proyectiles penetrantes. +unit.nova.description = Dispara rayos láser que dañan enemigos y reparan estructuras aliadas. Puede volar. +unit.pulsar.description = Dispara arcos eléctricos que dañan enemigos y reparan estructuras aliadas. Puede volar. +unit.quasar.description = Dispara rayos láser perforantes que dañan enemigos, pueden provocar incendios y reparan estructuras aliadas. Puede volar. Posee escudo. +unit.vela.description = Dispara un rayo láser continuo que daña enemigos, provoca incendios y reparan estructuras aliadas. Puede volar. +unit.corvus.description = Dispara poderosos láseres que dañan enemigos, y reparan estructuras aliadas. Puede pisar sobre la mayoría de terreno. +unit.crawler.description = Corre hacia enemigos y se autodestruye, provocando una gran explosión. +unit.atrax.description = Dispara orbes de magma debilitantes a enemigos terrestres. Puede pisar sobre la mayoría de terreno. +unit.spiroct.description = Dispara láseres que debilitan al enemigo, reparándose en el proceso. Puede pisar sobre la mayoría de terreno. +unit.arkyid.description = Dispara grandes rayos láser que debilitan al enemigo, repairing itself in the process. Puede pisar sobre la mayoría de terreno. +unit.toxopid.description = Dispara grandes fragmentos electrizados y láseres perforantes. Puede pisar sobre la mayoría de terreno. +unit.flare.description = Dispara proyectiles básicos a enemigos cercanos. +unit.horizon.description = Suelta fragmentos explosivos sobre objetivos terrestres. +unit.zenith.description = Dispara ráfagas de misiles a enemigos cercanos. +unit.antumbra.description = Dispara un enjambre de balas a cualquer enemigo cercano. +unit.eclipse.description = Dispara dos láseres perforantes y un enjambre de balas de fragmentación. +unit.mono.description = Extrae cobre y plomo, y los deposita en el núcleo. +unit.poly.description = Recosntruye automáticamente estructuras dañadas y asiste a otros unidades en la construcción. +unit.mega.description = Repara automáticamente estructuras dañadas. Puede llevar estructuras y unidades terrestres pequeñas. +unit.quad.description = Suelta grandes bombas sobre objetivos terrestres, repara estructuras aliadas y daña enemigos. Puede cargar con unidades terrestres de tamaño medio. +unit.oct.description = Protege aliados con su escudo. Puede cargar con la mayoría de unidades terrestres. +unit.risso.description = Dispara un enjambre de misiles y proyectiles a enemigos cercanos. +unit.minke.description = Dispara proyectiles variados a enemigos terrestres. +unit.bryde.description = Dispara misiles de largo alcance a enemigos. +unit.sei.description = Dispara un enjambre de misiles y proyectiles perforantes a enemigos. +unit.omura.description = Dispara rayos contínuos perforantes. Construye unidades Flare. +unit.alpha.description = Defiende el núcleo Fragmento de los enemigos. Construye estructuras. +unit.beta.description = Defiende el núcleo Foundation de los enemigos. Construye estructuras. +unit.gamma.description = Defiende el núcleo Nucleus de los enemigos. Construye estructuras. diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index 922c854e69..65f26e9b78 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -22,6 +22,7 @@ highscore = [accent]Nowy rekord! copied = Skopiowano. indev.popup = [accent]Wersja v6[] jest obecnie w [accent]alphie[].\n[lightgray]Oznacza to, że:[]\n[scarlet]- Kampania nie jest skończona[]\n- Brakuje zawartości\n - Większość [scarlet]SI jednostek[] nie działa poprawnie\n- Wiele jednostek jest niedokończonych\n- Wszystko to, co widzisz, może ulec zmianie lub usunięciu.\n\nZgłaszaj błędy i awarie na [accent]Githubie[]. indev.notready = Ta część gry nie jest jeszcze ukończona +indev.campaign = [accent]Udało ci się zakończyć kampanie![]\n\nZawartość kończy się na tym. Podróż międzyplanetarna zostanie dodana w przyszłych aktualizacjach. load.sound = Dźwięki load.map = Mapy @@ -189,6 +190,10 @@ servers.local = Serwery Lokalne servers.remote = Serwery Zdalne servers.global = Serwery Publiczne +servers.showhidden = Pokaż Ukryte Serwery +server.shown = Pokazane +server.hidden = Ukryte + trace = Zlokalizuj Gracza trace.playername = Nazwa gracza: [accent]{0} trace.ip = IP: [accent]{0} @@ -495,7 +500,7 @@ zone.objective = [lightgray]Cel: [accent]{0} zone.objective.survival = Przeżyj zone.objective.attack = Zniszcz Rdzeń Wroga add = Dodaj... -boss.health = Zdrowie Bossa +boss.health = Zdrowie Strażnika connectfail = [crimson]Nie można połączyć się z serwerem:\n\n[accent]{0} error.unreachable = Serwer niedostępny.\nCzy adres jest wpisany poprawnie? @@ -523,10 +528,12 @@ sectors.launch = Wystrzel sectors.select = Wybierz sectors.nonelaunch = [lightgray]żaden (słońce) sectors.rename = Zmień Nazwę Sektora -sector.missingresources = [scarlet]Insufficient Core Resources +sector.missingresources = [scarlet]Niewystarczające Zasoby Rdzenia +sector.attacked = Sektor [accent]{0}[white] jest atakowany! +sector.lost = Sektor [accent]{0}[white] został stracony! planet.serpulo.name = Serpulo -planet.sun.name = Sun +planet.sun.name = Słońce sector.groundZero.name = Punkt Zerowy sector.craters.name = Kratery @@ -539,6 +546,10 @@ sector.overgrowth.name = Przerośnięty Las sector.tarFields.name = Pola Smołowe sector.saltFlats.name = Solne Równiny sector.fungalPass.name = Grzybowa Przełęcz +sector.biomassFacility.name = Obiekt Syntezy Biomasy +sector.windsweptIslands.name = Wyspy Wiatru +sector.extractionOutpost.name = Placówka Ekstrakcji +sector.planetaryTerminal.name = Planetarny Terminal Startowy sector.groundZero.description = Optymalna lokalizacja, aby rozpocząć jeszcze raz. Niskie zagrożenie. Niewiele zasobów.\nZbierz jak najwięcej miedzi i ołowiu, tyle ile jest możliwe.\nPrzejdź do następnej strefy jak najszybciej. sector.frozenForest.description = Nawet tutaj, bliżej gór, zarodniki rozprzestrzeniły się. Niskie temperatury nie mogą ich zatrzymać na zawsze.\n\nRozpocznij przedsięwzięcie od prądu. Buduj generatory spalinowe. Naucz się korzystać z naprawiaczy. @@ -551,6 +562,11 @@ sector.tarFields.description = Obrzeża strefy produkcji ropy, między górami a sector.desolateRift.description = Strefa wyjątkowo niebezpieczna. Obfita w zasoby ale mało miejsca. Wysokie ryzyko zniszczenia. Opuść tę strefe jak najszybciej. Nie daj się zwieść długiemu odstępowi między atakami wroga. sector.nuclearComplex.description = Dawny zakład produkcji i przetwarzania toru, zredukowny do ruin.\n[lightgray]Zbadaj tor i jego zastosowania.\n\nWróg jest tutaj obecny w dużej ilości, nieustannie poszukuje napastników. sector.fungalPass.description = Przejściowy obszar pomiędzy wysokimi górami a nisko znajdującymi się, ogarniętymi przez zarodniki równinami. Znajduje się tu mała postawiona przez wrogów baza zwiadowcza.\nZniszcz ją.\nUżyj jednostek Nóż i Pełzak. Zniszcz oba rdzenie. +sector.biomassFacility.description = Miejsce powstania zarodników. Tutał były badane i początkowo produkowane.\nZbadaj zawartą w nim technologię. Hoduj zarodniki dla paliwa i tworzyw sztucznych.\n\n[lightgray]Po upadku tej placówki zarodniki zostały uwolnione. Nic w lokalnym ekosystemie nie mogło konkurować z tak inwazyjnym organizmem. +sector.windsweptIslands.description = Dalej za linią brzegową znajduje się ten odległy łańcuch wysp. Zapisy wyakzują ze były tu struktury produkujące [accent]Plastan[].\n\nOdeprzyj morskie jednostki wroga. Załóż bazę na wyspach. Odkryj te fabryki. +sector.extractionOutpost.description = Odległa placówka zbudowana przez wroga w celu wystrzeliwania zasobów do innych sektorów.\n\nDo dalszych podbojów niezbędna jest międzysektorowa technologia transportu. Zniszcz bazę. Zbadaj ich Wyrzutnie. +sector.impact0078.description = Tutaj leżą pozostałości międzygwiezdnego statku transportowego, który jako pierwszy wszedł do tego układu.\n\nWydobądź jak najwięcej z wraku. Zbadaj każdą nienaruszoną technologię. +sector.planetaryTerminal.description = Ostatni cel.\n\nTa baza przybrzeżna zawiera strukturę zdolną do wyrzucania rdzeni na lokalne planety. Jest wyjątkowo dobrze strzeżona.\n\nProdukuj jednostki morskie. Jak najszybciej wyeliminuj wroga. Zbadaj tą strukturę. settings.language = Język settings.data = Dane Gry @@ -573,14 +589,14 @@ settings.clearcampaignsaves.confirm = Jesteś pewny że chcesz usunąć wszystki paused = [accent]< Wstrzymano > clear = Wyczyść banned = [scarlet]Zbanowano -unplaceable.sectorcaptured = [scarlet]Requires captured sector + unplaceable.sectorcaptured = [scarlet]Wymaga podbitego sektora. yes = Tak no = Nie info.title = Informacje error.title = [crimson]Wystąpił błąd error.crashtitle = Wystąpił błąd unit.nobuild = [scarlet]Jednostka nie może budować -lastaccessed = [lightgray]Last Accessed: {0} +lastaccessed = [lightgray]Osatino wpłynął: {0} block.unknown = [lightgray]??? stat.input = Wejście @@ -600,7 +616,7 @@ stat.size = Rozmiar stat.displaysize = Wielkość Wyświetlania stat.liquidcapacity = Pojemność cieczy stat.powerrange = Zakres mocy -stat.linkrange = Link Range +stat.linkrange = Odległość połączeń stat.instructions = Instrukcje stat.powerconnections = Maksymalna ilość połączeń stat.poweruse = Zużycie prądu @@ -642,16 +658,19 @@ stat.minetier = Stopień Wydobycia stat.payloadcapacity = Ładowność stat.commandlimit = Limit Jednostek Zarządanych stat.abilities = Umiejętności +stat.canboost = Może przyspieszyć +stat.flying = Latanie ability.forcefield = Pole Mocy ability.repairfield = Pole Naprawy ability.statusfield = Pole Statusu -ability.unitspawn = {0} Fabryka +ability.unitspawn = Fabryka jednostek {0} ability.shieldregenfield = Strefa Tarczy Regenerującej +ability.movelightning = Pioruny Poruszania bar.drilltierreq = Wymagane Lepsze Wiertło -bar.noresources = Missing Resources -bar.corereq = Core Base Required +bar.noresources = Brak Zasobów +bar.corereq = Wymagany Rdzeń bar.drillspeed = Prędkość wiertła: {0}/s bar.pumpspeed = Prędkość pompy: {0}/s bar.efficiency = Efektywność: {0}% @@ -659,7 +678,7 @@ bar.powerbalance = Moc: {0} bar.powerstored = Zmagazynowano: {0}/{1} bar.poweramount = Moc: {0} bar.poweroutput = Wyjście mocy: {0} -bar.powerlines = Connections: {0}/{1} +bar.powerlines = Połączenia: {0}/{1} bar.items = Przedmiotów: {0} bar.capacity = Pojemność: {0} bar.unitcap = {0} {1}/{2} @@ -671,7 +690,7 @@ bar.progress = Postęp Budowy bar.input = Wejście bar.output = Wyjście -units.processorcontrol = [lightgray]Procesor Kontrolowany +units.processorcontrol = [lightgray]Kontrolowany Procesorem bullet.damage = [stat]{0}[lightgray] Obrażenia bullet.splashdamage = [stat]{0}[lightgray] Obrażenia obszarowe ~[stat] {1}[lightgray] kratki @@ -899,6 +918,7 @@ content.item.name = Przedmioty content.liquid.name = Płyny content.unit.name = Jednostki content.block.name = Klocki +content.sector.name = Sektory item.copper.name = Miedź item.lead.name = Ołów @@ -963,21 +983,21 @@ block.grass.name = Trawa block.slag.name = Żużel block.space.name = Space block.salt.name = Sól -block.salt-wall.name = Salt Wall +block.salt-wall.name = Solna Ściana block.pebbles.name = Kamyki block.tendrils.name = Wić -block.sand-wall.name = Sand Wall +block.sand-wall.name = Piaskowa Ściana block.spore-pine.name = Sosna Zarodnikowa -block.spore-wall.name = Spore Wall -block.boulder.name = Boulder -block.snow-boulder.name = Snow Boulder +block.spore-wall.name = Zarodinkowa Ściana +block.boulder.name = Głaz +block.snow-boulder.name = Śnieżny Głaz block.snow-pine.name = Sosna śniegowa block.shale.name = Łupek block.shale-boulder.name = Głaz Łupkowy block.moss.name = Mech block.shrubs.name = Krzewy block.spore-moss.name = Mech Zarodnikowy -block.shale-wall.name = Shale Wall +block.shale-wall.name = Ściana Z Łupku block.scrap-wall.name = Ściana ze Złomu block.scrap-wall-large.name = Duża Ściana ze Złomu block.scrap-wall-huge.name = Ogromna Ściana ze Złomu @@ -1160,6 +1180,10 @@ block.payload-router.name = Rozdzielacz Ładunku block.disassembler.name = Rozkładacz block.silicon-crucible.name = Tygiel Krzemu block.overdrive-dome.name = Kopuła Pola Overdrive +block.block-forge.name = Piec Bloków +block.block-loader.name = Ładownik Bloków +block.block-unloader.name = Opróżniacz Bloków +block.interplanetary-accelerator.name = Przspieszacz Międzyplanetarny block.switch.name = Przełącznik block.micro-processor.name = Micro Procesor @@ -1178,27 +1202,41 @@ team.derelict.name = szary team.green.name = zielony team.purple.name = fioletowy -tutorial.next = [lightgray] -tutorial.intro = Wszedłeś do[scarlet] Samouczka Mindustry.[]\nUżyj [accent][[WASD][], aby poruszyć się.\n[accent]Przytrzymaj [[Ctrl] podczas przewijania[], aby przybliżyć i oddalić widok.\nZacznij od[accent] wydobycia miedzi[]. W tym celu przybliż się, a następnie dotknij żyły rudy miedzi w pobliżu rdzenia.\n\n[accent]{0}/{1} miedź -tutorial.intro.mobile = Wszedłeś do[scarlet] Samouczka Mindustry.[]\nPrzesuń palcem po ekranie, aby poruszyć się.\n[accent]Użyj dwóch palcy[], aby przybliżyć i oddalić widok.\nZacznij od[accent] wydobycia miedzi[]. W tym celu przybliż się, a następnie dotknij żyły rudy miedzi w pobliżu rdzenia.\n\n[accent]{0}/{1} miedź -tutorial.drill = Wydobywanie ręczne nie jest efektywne.\n[accent]Wiertła []mogą kopać automatycznie.\nKliknij zakładkę wiertła w prawym dolnym rogu.\nWybierz[accent] wiertło mechaniczne[]. Umieść go na złożu miedzi, klikając.\n[accent]Kliknij prawym przyciskiem myszy[], aby przestać budować. -tutorial.drill.mobile = Wydobywanie ręczne jest nieefektywne.\n[accent]Wiertła []mogą kopać automatycznie.\nDotknij zakładkę wiertła w prawym dolnym rogu.\nWybierz[accent] wiertło mechaniczne[].\nUmieść go na złożu miedzi poprzez Stuknięcie, potem wciśnij[accent] ptaszek[] na dole by potwierdzić wybór.\nNaciśnij przycisk[accent] X[] by anulować budowe. -tutorial.blockinfo = Każdy blok ma inne statystyki. Każde wiertło może kopać tylko wybrane rudy.\nBy sprawdzić informacje i statystyki bloku,[accent] kliknij przycisk "?" podczas jego wyboru w menu budowy.[]\n\n[accent]Sprawdź teraz statystyki mechanicznego wiertła.[] -tutorial.conveyor = [accent]Przenośnik[] jest używany do transportowania przedmiotów do rdzenia.\nStwórz linie przenośników z wierteł do rdzenia.\n[accent]Przytrzymaj przycisk myszy by położyć w linii.[]\nPrzytrzymaj[accent] CTRL[] podczas wybierania linii, by budować po skosie.\n\n[accent]{0}/{1} Przenośniki położone w linii\n[accent]0/1 Przedmioty dostarczone -tutorial.conveyor.mobile = [accent]Przenośnik[] jest używany do transportowania przedmiotów do rdzenia.\nStwórz linie przenośników z wierteł do rdzenia.\n[accent] Zbuduj w linii poprzez przytrzymanie palcem przez moment[] i przesunięcie w którymś kierunku.\n\n[accent]{0}/{1} Przenośniki położone w linii\n[accent]0/1 Przedmioty dostarczone -tutorial.turret = Kiedy przedmiot dociera do rdzenia, może zostać użyty do budowy.\nPamiętaj że nie każdy przedmiot może zostać użyty do budowy.\nprzedmioty które nie są używane do budowy, takie jak[accent] Węgiel[] lub[accent] złom[], nie moga zostać wprowadzone do rdzenia.\nStruktury obronne muszą zostać zbudowane by odeprzeć[lightgray] wroga[].\nZbuduj[accent] podwójne działko[] niedaleko swojej bazy. -tutorial.drillturret = Podwójne działka wymagają[accent] miedzianej amunicji []do strzelania.\nPołóż wiertło obok działka.\nPoprowadź przenośniki do działek by zaopatrzyć je w miedź.\n\n[accent]Amunicja dostarczona: 0/1 -tutorial.pause = Podczas gry, możesz[accent] zatrzymać grę.[]\nMożesz ustalić kolejkę budowy podczas pauzy.\n\n[accent]Naciśnij spacje by zapauzować. -tutorial.pause.mobile = Podczas gry, możesz[accent] zatrzymać grę.[]\nMożesz ustalić kolejkę budowy podczas pauzy.\n\n[accent]Nacniśnij przycisk w lewym górnym rogu by zapauzować. -tutorial.unpause = Teraz znowu naciśnij spacje by odpauzować. -tutorial.unpause.mobile = Naciśnij go znowu by odpauzować. -tutorial.breaking = Bloki często wymagają rozbiórki.\n[accent]Przytrzymaj prawy przcisk myszy[] by niszczyć wszystkie wybrane bloki.[]\n\n[accent]Zniszcz wszystkie bloki złomu na lewo od twojego rdzenia używając selekcji obszarowej. -tutorial.breaking.mobile = Bloki często wymagają rozbiórki.\n[accent]Wybierz tryb dekonstrukcji[], a następnie dotknij blok by zacząć go niszczyć.\nZdekonstruuj obszarowo poprzez przytrzymanie palcem przez moment[] i przesunięcie go w jakimś kierunku.\nNaciśnij przycisk ptaszka by potwierdzić rozbiórkę.\n\n[accent]Zniszcz wszystkie bloki złomu na lewo od twojego rdzenia używając selekcji obszarowej. -tutorial.withdraw = Czasami, konieczne jest wyjmowanie przedmiotów prosto z bloków.\nBy tego dokonać, [accent]kliknij blok[] z przedmiotami w nim, potem [accent]kliknij przedmiot[] w inwentarzu.\nMożesz zebrać wiele przedmiotów naraz poprzez [accent]kliknięcie i przytrzymanie[].\n\n[accent]Zabierz trochę miedzi z rdzenia.[] -tutorial.deposit = Włóż przedmioty do bloków poprzez przeciągnięcie z twojego statku do danego bloku.\n\n[accent]Włóż miedź z powrotem do rdzenia .[] -tutorial.waves = [lightgray] Wrogowie[] nadchodzą.\n\nBroń swój rdzeń przez 2 fale.[accent] Kliknij[] by strzelać.\nZbuduj wiecej działek i wierteł. Wydobądź więcej miedzi. -tutorial.waves.mobile = [lightgray] Wrogowie[] nadchodzą.\n\nBroń swój rdzeń przez 2 fale. Twój statek będzie automatycznie atakował wrogów.\nZbuduj wiecej działek i wierteł. Wydobądź więcej miedzi. -tutorial.launch = Kiedy dotrzesz do określonej fali, masz możliwość[accent] wystrzelenia rdzenia[], pozostawiając struktury obronne za sobą i[accent] otrzymując wszystkie surowce znajdujące się w rdzeniu.[]\nSurowce te mogą potem zostać użyte do odkrywania nowych technologii.\n\n[accent]Naciśnij przycisk Wystrzału. +hint.skip = Pomiń +hint.desktopMove = Użyj [accent][[WASD][] by się poruszać. +hint.zoom = [accent]Przewiń[] by przybliżać lub oddlać obraz. +hint.mine = Zbliż się do \uf8c4 rudy miedzi i [accent]kliknij[] by kopać manualnie. +hint.desktopShoot = Kliknij [accent][[Lewy przycisk myszy][] by strzelać. +hint.depositItems = By przenosić przedmoty, przeciągij je ze swojego statku do rdzenia. +hint.respawn = By się odrodzić jako statek, kliknij [accent][[V][]. +hint.respawn.mobile = Przełączyłeś się na inną jednoskę/strukturę. By odrodzić się jako statek, [accent]kliknij w awatar w górnym lewym rogu.[] +hint.desktopPause = Naciśnij [accent][[Spację][] by zatrzymać lub wznowić grę. +hint.placeDrill = Wybierz \ue85e [accent]Wiertło[] w menu w prawym dolnym rogu, i wybierz wtedy \uf870 [accent]Wiertło[] i kliknij na miedzi by je postawić. +hint.placeDrill.mobile = Wybierz zakładkę z \ue85e[accent]Wiertłem[] w menu w prawym dolnym rogu, i wtedy wybierz \uf870 [accent]Wietło[] i kliknij na miedzi by je postawić.\n\nNaciśnij \ue800 [accent]znak potwierdzenia[] w dolnym prawym rogu by potwierdzić. +hint.placeConveyor = Przenośniki mogą przenosić przedmioty z wierteł. Wybierz \uf896 [accent]Przenośnik[] z zakładki \ue814 [accent]Dystrybucja[].\n\nKliknij i przeciągnij by położyć wiele przeciągników.\n[accent]Przewiń[] by obrócić. +hint.placeConveyor.mobile = Przenośniki mogą przenosić przedmioty z wierteł. Wybierz \uf896 [accent]Przenośnik[] z zakładki \ue814 [accent]Dystrybucja[].\n\nPrzytrzymaj palcem i przeciągij by położyć wiele przeciągników. +hint.placeTurret = Postaw \uf861 [accent]Działka[] by bronić się przed wrogami.\n\nDziałka potzebują amunicji - w tym wypadku, \uf838copper.\nUżyj przenośników i wierteł by je naładować. +hint.breaking = Użyj [accent]Prawego przycisku myszy[] i przeciągnij by zniszczyć bloki. +hint.breaking.mobile = Aktywuj \ue817 [accent]ikonę młota[] w dolnym prawym rogu by zniszczyć bloki.\n\nPrzytrymaj swój palec i przeciągij by wybrać wiele bloków do zniszczenia. +hint.research = Klikij przycisk \ue875 [accent]Badań[] by odkrwyać nowe technologie. +hint.research.mobile = Użyj przycisku \ue875 [accent]Badań[] w \ue88c [accent]Menu[] by odkrwyać nowe technologie. +hint.unitControl = Przytrzymaj [accent][[Lewy CTRL][] i [accent]kliknij[] to control by kontrolować sojusznicze jednostki i działka. +hint.unitControl.mobile = [accent][Kliknij dwukrotnie[] by kontrolować sojusznicze jednostki i działka. +hint.launch = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrzelić[] wybierając \ue827 [accent]Mape[] w dolnym prawym rogu. +hint.launch.mobile = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrzelić[] do pobliskich sektorów klikając w \ue827 [accent]Mape[] w \ue88c [accent]Menu[]. +hint.schematicSelect = Przytrzymaj [accent][[F][] by kopiować i wkleić bloki.\n\n[accent][[Środkowy przycisk myszy][] kopiuje pojedyńczy blok. +hint.conveyorPathfind = Przeciągij i przytrzymaj [accent][[Lewy CTRL][] w trakcie budowania przenośników by wygenerować ścieżkę. +hint.conveyorPathfind.mobile = Włącz \ue844 [accent]tryb ukośny[] i przeciągnij w trakcie budowania przenośników by wygenerować ścieżkę. +hint.boost = Przytrzymaj [accent][[Lewy Shift][] by przelecieć ponad przeszkody.\n\nNie wszystkie jednostki tak mogą. +hint.command = Kliknij [accent][[G][] by ukształtować formacje z pobliskich jednostek. +hint.command.mobile = [accent][[Podwójne kliknięcie][] kształtuje formacje z pobliskich jednostek. +hint.payloadPickup = Kliknij [accent][[[] by podnieść małe bloki lub jednostki. +hint.payloadPickup.mobile = [accent]Kliknij i przytrzymaj[] mały blok by go podnieść. +hint.payloadDrop = Kliknij [accent]][] by opuścić podniesoiny towar. +hint.payloadDrop.mobile = [accent]Kliknij i przytrzymaj[] w puste miejsce by opuścić podniesoiny towar. +hint.waveFire = [accent]Strumień[] wypełniony wodą będzie gasić pobiskie pożary. +hint.generator = \uf879 [accent]Generatory Spalinowe[] spalają węgiel i przekuzują moc do pobliskich bloków.\n\nMożesz powiększyć odległość transmitowanej mocy używająć \uf87f [accent]Węzeły Prądu[]. +hint.guardian = Jednostki [accent]Strażnicze[] są uzbrojone. Słaba amunicja - taka jak [accent]Miedź[] oraz [accent]Ołów[] [scarlet]nie jest efektywna[].\n\nUżyj lepszych działek takich jak \uf835 [accent]Naładowane Grafitem[] \uf861Duo/\uf859Salwa by pozbyć się strażników. item.copper.description = Przydatny materiał budowlany. Szeroko używany w prawie każdej konstrukcji. item.lead.description = Podstawowy materiał. Używany w przesyle przemiotów i płynów. Nie jest on przypadkiem szkodliwy? @@ -1356,7 +1394,7 @@ block.memory-cell.description = Przechowuje informacje dla procesora. block.memory-bank.description = Przechowuje informacje dla procesora. Duża pojemność. block.logic-display.description = Wyświetla obraz z procesora. block.large-logic-display.description = Wyświetla obraz z procesora. -block.interplanetary-accelerator.description = Masywna elektromagnetyczna wierza. Przyspiesza rdzeń do prędkości ucieczki by wylądować na innych planetach. +block.interplanetary-accelerator.description = Masywna elektromagnetyczna wieża. Przyspiesza rdzeń do prędkości ucieczki by wylądować na innych planetach. unit.dagger.description = Strzela standardowymi pociskami w najbliższych wrogów. @@ -1387,8 +1425,8 @@ unit.oct.description = Broni wszystkie jednostki tarczą regeneracyjną. Może p unit.risso.description = Strzela sporą ilością pocisków i rakiet w najbliższych przeciwników. unit.minke.description = Strzela granatami i standardowymi pociskami w najbliższych przeciwników. unit.bryde.description = Strzela granatami i rakietami na dużą odległość we wrogów. -unit.sei.description = Strzela dużą ilością rakiet oraz przebijających zbroje pocisków we wrogów -unit.omura.description = Strzela przebijającym superszybkim pociskiem we wrogów ze sporej odległości. Produkuje Błyski (jednostki) +unit.sei.description = Strzela dużą ilością rakiet oraz przebijających zbroje pocisków we wrogów. +unit.omura.description = Strzela przebijającym superszybkim pociskiem we wrogów ze sporej odległości. Produkuje Błyski (jednostki). unit.alpha.description = Chroni Rdzeń: Odłamek przed wrogami. Buduje struktury. unit.beta.description = Chroni Rdzeń: Podstawa przed wrogami. Buduje struktury. unit.gamma.description = Chroni Rdzeń: Jądro przed wrogami. Buduje struktury. diff --git a/core/assets/bundles/bundle_zh_CN.properties b/core/assets/bundles/bundle_zh_CN.properties index 9b0f278d9c..428de78f53 100644 --- a/core/assets/bundles/bundle_zh_CN.properties +++ b/core/assets/bundles/bundle_zh_CN.properties @@ -17,11 +17,14 @@ linkfail = 打开链接失败!\n网址已复制到您的剪贴板。 screenshot = 屏幕截图已保存到 {0} screenshot.invalid = 地图太大,可能没有足够的内存用于截图。 gameover = 游戏结束 +gameover.disconnect = 断开连接 gameover.pvp = [accent] {0}[]队获胜! +gameover.waiting = [accent]正在等待下一张地图... highscore = [accent]新纪录! -copied = 已复制。 +copied = 已复制 indev.popup = [accent]6.0[]仍在[accent]测试版[].\n[lightgray]这意味着:[]\n[scarlet]- 战役玩法完全没有完成[]\n- 很多内容还没有做完\n - 大多[scarlet]单位AI[]无法正确地运行\n- 单位系统完全没有完成\n- 一切您所看到的内容都可能会移除或调整。\n\n在[accent]Github[]提交错误报告。\n[#66ccff]来自译者WinterUnderTheSnow的忠告:不建议新玩家游玩还在测试阶段的6.0!建议您先从[orange]v104.6[#66ccff]或[orange]v104.10[#66ccff]开始游玩! indev.notready = 这部分玩法还未开发完成。 +indev.campaign = [accent]您已经到达战役模式的结尾![]\n\n这是内容所能做到的。 未来的更新中将添加行星际旅行。 load.sound = 音乐加载中 load.map = 地图加载中 @@ -57,6 +60,7 @@ schematic.rename = 重命名蓝图 schematic.info = {0}x{1},{2} 个方块 schematic.disabled = [scarlet]蓝图已禁用![]\n您不能在此[accent]地图[]或[accent]服务器[]上使用蓝图. +stats = 统计资料 stat.wave = 防守波数:[accent]{0} stat.enemiesDestroyed = 消灭敌人:[accent]{0} stat.built = 建造建筑:[accent]{0} @@ -189,6 +193,10 @@ servers.local = 本地服务器 servers.remote = 远程服务器 servers.global = 全球服务器 +servers.showhidden = 显示隐藏的服务器 +server.shown = 显示 +server.hidden = 隐藏 + trace = 跟踪玩家 trace.playername = 玩家名称:[accent]{0} trace.ip = IP 地址:[accent]{0} @@ -267,6 +275,9 @@ cancel = 取消 openlink = 打开链接 copylink = 复制链接 back = 返回 +crash.export = 导出崩溃日志 +crash.none = 找不到崩溃日志。 +crash.exported = 崩溃日志已导出。 data.export = 导出数据 data.import = 导入数据 data.openfolder = 打开数据文件夹 @@ -283,6 +294,7 @@ cancelbuilding = [accent][[{0}][]来清除规划 selectschematic = [accent][[{0}][]来选择复制 pausebuilding = [accent][[{0}][]来暂停建造 resumebuilding = [scarlet][[{0}][]来恢复建造 +showui = UI已隐藏\n按[accent][[{0}][]显示UI wave = [accent]第{0}波 wave.cap = [accent]Wave {0}/{1} wave.waiting = [lightgray]下一波倒计时:{0}秒 @@ -290,6 +302,8 @@ wave.waveInProgress = [lightgray]波次袭来 waiting = [lightgray]等待中… waiting.players = 等待玩家中… wave.enemies = [lightgray]剩余 {0} 个敌人 +wave.enemycores = [accent]{0}[lightgray] 敌人核心(多个) +wave.enemycore = [accent]{0}[lightgray] 敌人核心 wave.enemy = [lightgray]剩余 {0} 个敌人 wave.guardianwarn = Boss 将在[accent]{0}[]波后到来。 wave.guardianwarn.one = Boss 将在[accent]{0}[]波后到来。 @@ -350,6 +364,7 @@ waves.invalid = 剪贴板中的波次信息无效。 waves.copied = 波次信息已复制。 waves.none = 没有定义敌人。\n请注意,这将自动替换为默认的敌人列表。 +#these are intentionally in lower case wavemode.counts = 数目 wavemode.totals = 总和 wavemode.health = 生命值 @@ -462,6 +477,8 @@ load = 载入游戏 save = 保存 fps = 帧数:{0} ping = 延迟:{0}毫秒 +memory = 内存: {0}mb +memory2 = 内存:\n {0}mb +\n {1}mb language.restart = 为了使语言设置生效请重启游戏。 settings = 设置 tutorial = 教程 @@ -476,24 +493,21 @@ complete = [lightgray]完成: requirement.wave = {1}中的第{0}波次 requirement.core = 在{0}中摧毁敌方核心 requirement.research = 研究 {0} +requirement.produce = 生产 {0} requirement.capture = 占领 {0} -bestwave = [lightgray]最高波次:{0} launch.text = 发射 research.multiplayer = 仅有服主可研究物品。 +map.multiplayer = 仅有服主可查看区域。 uncover = 解锁 configure = 设定装运的数量 + loadout = 装运 resources = 资源 bannedblocks = 禁用建筑 addall = 添加所有 +launch.from = 发射地: [accent]{0} launch.destination = 目的地: {0} configure.invalid = 数量必须是0到{0}之间的数字。 -zone.unlocked = [lightgray]{0} 已解锁。 -zone.requirement.complete = 完成{0}。\n已达成解锁{1}的要求。 -zone.resources = 地图中的资源: -zone.objective = [lightgray]目标:[accent]{0} -zone.objective.survival = 生存 -zone.objective.attack = 摧毁敌方核心 add = 添加… boss.health = Boss 生命值 @@ -517,17 +531,41 @@ weather.fog.name = 雾 sectors.unexplored = [lightgray]未探索 sectors.resources = 资源: sectors.production = 产出: +sectors.export = 输出: +sectors.time = 时间: +sectors.threat = 威胁 +sectors.wave = 进攻波: sectors.stored = 贮存: sectors.resume = 继续 sectors.launch = 发射 sectors.select = 选择 sectors.nonelaunch = [lightgray]无 (太阳) sectors.rename = 重命名区块 +sectors.enemybase = [scarlet]敌人基地 +sectors.vulnerable = [scarlet]脆弱的 +sectors.underattack = [scarlet]遭到攻击![accent]{0}% 被摧毁 +sectors.survives = [accent]存活{0}波 +sectors.go = 进入 +sector.curcapture = 区域已占领 +sector.curlost = 区域丢失 sector.missingresources = [scarlet]核心资源不足 +sector.attacked = 区域[accent]{0}[white]受到攻击! +sector.lost = 区域[accent]{0}[white]已丢失! +#note: the missing space in the line below is intentional +sector.captured = 区域[accent]{0}[white]已占领! + +threat.low = 低 +threat.medium = 中 +threat.high = 高 +threat.extreme = 极高 +threat.eradication = 根除 + +planets = 行星 planet.serpulo.name = 塞普罗 planet.sun.name = 太阳 +sector.impact0078.name = 影响0078 sector.groundZero.name = 零号地区 sector.craters.name = 陨石带 sector.frozenForest.name = 冰冻森林 @@ -539,6 +577,10 @@ sector.overgrowth.name = 增生区 sector.tarFields.name = 油田 sector.saltFlats.name = 盐碱荒滩 sector.fungalPass.name = 真菌通道 +sector.biomassFacility.name = 生物质合成设施 +sector.windsweptIslands.name = 风吹群岛 +sector.extractionOutpost.name = 萃取前哨 +sector.planetaryTerminal.name = 行星发射终端 sector.groundZero.description = 踏上旅程的最佳位置。这儿的敌人威胁很小,但资源也少。\n收集尽可能多的铅和铜。\n出发吧! sector.frozenForest.description = 即使是靠近山脉的这里,孢子也已经扩散。他们不能长期停留在寒冷的温度中。\n\n开始运用电力。建造火力发电机并学会使用修理者。 @@ -573,7 +615,6 @@ settings.clearcampaignsaves.confirm = 您确定要清除战役进度? paused = [accent]< 暂停 > clear = 清除 banned = [scarlet]已禁止 -unplaceable.sectorcaptured = [scarlet]需要占领区块 yes = 是 no = 否 info.title = [accent]详情 @@ -583,6 +624,7 @@ unit.nobuild = [scarlet]单位未能建造 lastaccessed = [lightgray]上次操作: {0} block.unknown = [lightgray]??? +stat.description = 介绍 stat.input = 输入 stat.output = 输出 stat.booster = 增强物品/液体 @@ -610,6 +652,8 @@ stat.memorycapacity = 内存容量 stat.basepowergeneration = 基础能源输出 stat.productiontime = 生产时间 stat.repairtime = 建筑完全修复时间 +stat.weapons = 武器 +stat.bullet = 子弹 stat.speedincrease = 提速 stat.range = 范围 stat.drilltier = 可钻探矿物 @@ -642,12 +686,15 @@ stat.minetier = 采矿等级 stat.payloadcapacity = 载货容量 stat.commandlimit = 指挥上限 stat.abilities = 能力 +stat.canboost = 助推器 +stat.flying = 飞行 ability.forcefield = 力墙场 ability.repairfield = 修复场 ability.statusfield = 状态场 ability.unitspawn = {0} 工厂 ability.shieldregenfield = 护盾再生场 +ability.movelightning = 闪电移动 bar.drilltierreq = 需要更好的钻头 bar.noresources = 缺失资源 @@ -676,12 +723,14 @@ units.processorcontrol = [lightgray]由处理器控制 bullet.damage = [stat]{0}[lightgray] 伤害 bullet.splashdamage = [stat]{0}[lightgray] 范围伤害 ~[stat] {1}[lightgray] 格 bullet.incendiary = [stat] 燃烧 +bullet.sapping = [stat]sapping bullet.homing = [stat] 追踪 bullet.shock = [stat] 电击 bullet.frag = [stat] 分裂 bullet.knockback = [stat]{0}[lightgray] 击退 bullet.pierce = [stat]{0}[lightgray]x 穿透 bullet.infinitepierce = [stat]pierce +bullet.healpercent = [stat]{0}[lightgray]% 修复 bullet.freezing = [stat] 冰冻 bullet.tarred = [stat] 减速 bullet.multiplier = [stat]{0}[lightgray]x 装弹数量 @@ -706,6 +755,7 @@ unit.items = 物品 unit.thousands = K unit.millions = M unit.billions = B +category.purpose = 介绍 category.general = 普通 category.power = 能量 category.liquids = 液体 @@ -719,6 +769,7 @@ setting.blockreplace.name = 自动推荐合适的建筑 setting.linear.name = 抗锯齿 setting.hints.name = 提示 setting.flow.name = 显示资源传送速度[scarlet] (实验性) +setting.backgroundpause.name = 在背景中暂停 setting.buildautopause.name = 自动暂停建造 setting.animatedwater.name = 流动的水 setting.animatedshields.name = 动态画面 @@ -747,7 +798,6 @@ setting.conveyorpathfinding.name = 传送带自动寻路 setting.sensitivity.name = 控制器灵敏度 setting.saveinterval.name = 自动保存间隔 setting.seconds = {0} 秒 -setting.blockselecttimeout.name = 建筑选择超时 setting.milliseconds = {0} 毫秒 setting.fullscreen.name = 全屏 setting.borderlesswindow.name = 无边界窗口[lightgray](可能需要重启) @@ -836,6 +886,8 @@ keybind.menu.name = 菜单 keybind.pause.name = 暂停 keybind.pause_building.name = 暂停/继续建造 keybind.minimap.name = 小地图 +keybind.planet_map.name = 行星地图 +keybind.research.name = 研究 keybind.chat.name = 聊天 keybind.player_list.name = 玩家列表 keybind.console.name = 控制台 @@ -899,6 +951,7 @@ content.item.name = 物品 content.liquid.name = 液体 content.unit.name = 部队 content.block.name = 块 +content.sector.name = 区域 item.copper.name = 铜 item.lead.name = 铅 @@ -959,6 +1012,7 @@ block.resupply-point.name = 补给点 block.parallax.name = 差扰光束 block.cliff.name = 悬崖 block.sand-boulder.name = 砂岩 +block.basalt-boulder.name = 玄武岩巨石 block.grass.name = 草地 block.slag.name = 矿渣 block.space.name = 太空 @@ -1056,7 +1110,6 @@ block.conveyor.name = 传送带 block.titanium-conveyor.name = 钛传送带 block.plastanium-conveyor.name = 塑钢传送带 block.armored-conveyor.name = 装甲传送带 -block.armored-conveyor.description = 运送物品,与钛传送带一样的速度,但有更强的装甲。除其他传送带,不接受任何边上的输入。 block.junction.name = 连接器 block.router.name = 路由器 block.distributor.name = 分配器 @@ -1064,7 +1117,6 @@ block.sorter.name = 分类器 block.inverted-sorter.name = 反向分类器 block.message.name = 信息板 block.illuminator.name = 照明器 -block.illuminator.description = 小型、紧凑、可配置的光源。需要能量运行。 block.overflow-gate.name = 溢流门 block.underflow-gate.name = 反向溢流门 block.silicon-smelter.name = 硅冶炼厂 @@ -1160,6 +1212,11 @@ block.payload-router.name = 载荷路由器 block.disassembler.name = 解离机 block.silicon-crucible.name = 热能坩埚 block.overdrive-dome.name = 超速穹顶投射器 +#experimental, may be removed +block.block-forge.name = 方块熔炉 +block.block-loader.name = 方块装载机 +block.block-unloader.name = 方块卸载机 +block.interplanetary-accelerator.name = 行星际加速器 block.switch.name = 开关 block.micro-processor.name = 微型处理器 @@ -1178,30 +1235,45 @@ team.derelict.name = 灰 team.green.name = 绿 team.purple.name = 紫 -tutorial.next = [lightgray]<点击以继续> -tutorial.intro = 您已进入[scarlet] Mindustry 教程[]。[]\n使用[accent][[WASD][]键移动机甲和视角。\n[accent]按住[[Ctrl]并转动鼠标滚轮[]缩放视野。\n让我们从[accent]采集铜矿[]开始。先移动到铜矿旁边,然后点按矿脉附近散落的矿物。\n\n[accent]{0}/{1} 铜 -tutorial.intro.mobile = 您已进入[scarlet] Mindustry 教程[]。\n在屏幕上滑动来继续。\n[accent]双指捏合[] 来缩小和放大。\n让我们从[accent]采集铜矿[]开始。先移动到铜矿旁边,然后点按矿脉附近散落的矿物。\n\n[accent]铜 {0}/{1} -tutorial.drill = 手动采矿效率不高。\n[accent]钻头[]可以自动采矿。\n让我们在在铜矿上放一个。\n点击右下角的钻头菜单。\n选择[accent]机械钻头[]。\n单击将其放置在铜矿上。\n[accent]右键单击[]来停止。 -tutorial.drill.mobile = 手动采矿效率不高。\n[accent]钻头[]可以自动采矿。\n点右下角的钻头菜单。\n选择[accent]机械钻头[]。\n点一下将其放在铜矿上,点[accent]对号[]来确定。\n点[accent]叉号[]来取消。 -tutorial.blockinfo = 每种钻头都有其独特的数据。每个钻头只能开采部分矿石。\n若要查看建筑的详细信息,[accent]在菜单中点击问号。[]\n\n[accent]现在查看机械钻头的数据吧。[] -tutorial.conveyor = [accent]传送带[]可以把物资传送到核心。\n请在钻头到核心间建造一条传送带。 -tutorial.conveyor.mobile = [accent]传送带[]可以把物资传送到核心。\n请在钻头到核心间建造一条传送带。\n[accent]长按数秒[]并向一个方向拖动来直线放置。\n\n[accent]{0}/{1} 条传送带\n[accent]0/1 物品 -tutorial.turret = 必须建造防御建筑来击退[lightgray]敌人[]。\n请在核心附近造一个双管炮。 -tutorial.drillturret = 双管炮需要[accent]铜[]作弹药来射击。\n可以放一个钻头在炮塔附近供应铜。 -tutorial.pause = 在战斗中,您可以[accent]暂停游戏[]。\n暂停时您可以规划建筑物。\n\n按[accent]空格[]暂停。 -tutorial.pause.mobile = 在战斗中,您可以[accent]暂停游戏[]。\n暂停时您可以规划建筑物。\n\n[accent]点击左上角的按钮以暂停。 -tutorial.unpause = 现在再次按空格以继续。 -tutorial.unpause.mobile = 现在再次点按以继续。 -tutorial.breaking = 建筑经常需要拆除。\n[accent]按住鼠标右键[]来拆除选中的建筑。[]\n\n[accent]使用范围拆除来拆除核心左侧的废墙。 -tutorial.breaking.mobile = 建筑经常需要拆除。\n[accent]选择拆除模式[],点击建筑以拆除。\n[accent]长按几秒[]并拖动来范围拆除。\n点击对号来确定。\n\n[accent]使用范围拆除来拆除核心左侧的废墙。 -tutorial.withdraw = 有时,从建筑中取出物品是必要的。\n[accent]点击包含物品的建筑[],然后[accent]点击在方框中的物品[]。\n可以通过[accent]点击或长按[]来取出物品。\n\n[accent]从核心中取出一些铜[]。 -tutorial.deposit = 将物品从机甲拖向建筑来放下物品。\n\n[accent]将铜放回核心[]。 -tutorial.waves = [lightgray]敌人[]来了。\n\n保护核心,防御两波攻击。造更多的炮塔。[accent]点击[]以射击。\n建造更多的炮塔和钻头,并采更多的矿。 -tutorial.waves.mobile = [lightgray]敌人[]来了。\n\n保护核心,防御两波攻击。造更多的炮塔。你的机甲将对敌人自动开火。\n建造更多的炮塔和钻头,并采更多的矿。 -tutorial.launch = 进入特定波次后,你可以[accent]发射核心(起飞)[],[accent]带走核心中的所有资源[]并抛下所有的建筑。\n装运的资源可用于研究科技。\n\n[accent]点击发射按钮。 +hint.skip = 跳过 +hint.desktopMove = 使用[accent][[WASD][]来移动. +hint.zoom = [accent]滚动[]放大或缩小. +hint.mine = 移动到\uf8c4铜矿附近并点按[accent]tap[]进行手动开采 +hint.desktopShoot = [accent][[Left-click][]射击. +hint.depositItems = 要转移物品,请将其从飞船上拖到核心。 +hint.respawn = 要重生飞船,请按[accent][[V][]. +hint.respawn.mobile = 您已切换控制单元/结构. 如果要重生飞船请[accent]点击左上方的图标(那个和你长得一样的).[] +hint.desktopPause = 按[accent][[Space][]暂停和取消暂停游戏. +hint.placeDrill = 选择\ue85e[accent]钻头[]右下角菜单中的标签,然后选择一个\uf870 [accent]钻头[]然后单击铜矿将其放置. +hint.placeDrill.mobile = 选择\ue85e[accent]钻头[]右下角菜单中的标签,然后选择一个\uf870 [accent]钻头[]然后点击铜矿将其放置.\n\n按下\ue800 [accent]复选标记[]在右下角按钮确认. +hint.placeConveyor = 传送带将物品从钻头移到其他块中。选择一个\uf896 [accent]传送带[]从\ue814 [accent]布局[]标签.\n\n单击并拖动以放置多个传送带.\n[accent]滚动[]旋转. +hint.placeConveyor.mobile = 传送带将物品从钻头移到其他块中。选择一个\uf896 [accent]传送带[]从\ue814 [accent]布局[]标签.\n\n按住手指一秒钟,然后拖动以放置多个传送带. +hint.placeTurret = 放置\uf861 [accent]炮塔[]保卫你的基地从敌人手中.\n\n炮塔需要弹药-在这种情况下e, \uf838copper.\n使用传送带和钻头为它们供弹。 +hint.breaking = [accent]右击[]并拖动以拆除方块. +hint.breaking.mobile = 激活\ue817 [accent]锤子[]在右下角点击以拆除方块.\n\n按住手指一秒钟,然后拖动以选择. +hint.research = 使用\ue875 [accent]科技树[]按钮研究新技术. +hint.research.mobile = 使用\ue875 [accent]科技树[]按钮在\ue88c [accent]菜单[]去研究新技术. +hint.unitControl = 按住[accent][[L-ctrl][]和[accent]点击[]控制友军单位或炮塔。 +hint.unitControl.mobile = [accent][双击[]控制友军单位或炮塔(双击)。 +hint.launch = 一旦收集到足够的资源,您就可以[accent]发射[]通过选择附近的区域从\ue827 [accent]地图[]在右下角. +hint.launch.mobile = 一旦收集到足够的资源,您就可以[accent]发射[]通过选择附近的区域从\ue827 [accent]地图[]在\ue88c [accent]菜单[]. +hint.schematicSelect = 按住[accent][[F][]并拖动以选择要复制和粘贴的块.\n\n[accent][[Middle Click][]复制单个块类型. +hint.conveyorPathfind = 按住[accent][[L-Ctrl][]拖动,传送带会自动生成路径. +hint.conveyorPathfind.mobile = 启用\ue844 [accent]对角线模式[]并拖动,传送带会自动生成路径. +hint.boost = 按住[accent][[L-Shift][]用当前单位飞越障碍物.\n\n只有少数地面单位有助推器.(首先排除爬虫家族) +hint.command = 按accent][[G][]指挥附近的单位编队. +hint.command.mobile = [accent][双击][]您的部队指挥附近的部队编队.(双击) +hint.payloadPickup = 按[accent][[[]捡起小方块或单位. +hint.payloadPickup.mobile = [accent]点住]一个小方块或一个单位来捡起来. +hint.payloadDrop = 按[accent]][]放下有效载荷. +hint.payloadDrop.mobile = [accent]点住[]一个空的位置将有效载荷丢到那里.(不是很精准) +hint.waveFire = [accent]进攻波[]炮塔加水弹药会自动扑灭附近的大火.(浪涌和海啸) +hint.generator = \uf879 [accent]燃烧发电机[]燃烧煤炭并将电力传输到相邻方块.\n\n电力传输范围可以扩展,用\uf87f [accent]能量节点[]. item.copper.description = 一种最基本的的建筑材料。在各种类型的建筑中被广泛使用。 +item.copper.details = 铜. 在Serpulo上的金属异常丰富。 除非加固,否则结构较弱。 item.lead.description = 一种基本的电力材料。广泛用于电子设备和液体输送模块。 +item.lead.details = Dense. Inert. Extensively used in batteries.\nNote: Likely toxic to biological life forms. Not that there are many left here. item.metaglass.description = 一种致密坚硬的复合玻璃。广泛用于液体输送和存储。 item.graphite.description = 一种高密度的碳材料,用于弹药和电器元件。 item.sand.description = 一种常见的材料,广泛用于冶炼,包括制作合金和助熔剂。 diff --git a/core/assets/contributors b/core/assets/contributors index cb64660dae..3af0a9eee0 100644 --- a/core/assets/contributors +++ b/core/assets/contributors @@ -102,3 +102,4 @@ newlocknew (freesound.org) dsmolenaers (freesound.org) Headphaze (freesound.org) VolasYouKnow +Ángel Rodríguez Aguilera diff --git a/core/assets/maps/biomassFacility.msav b/core/assets/maps/biomassFacility.msav index bf16a3b7ea..738d890f70 100644 Binary files a/core/assets/maps/biomassFacility.msav and b/core/assets/maps/biomassFacility.msav differ diff --git a/core/assets/maps/craters.msav b/core/assets/maps/craters.msav index 94bba211ac..c52303c3a1 100644 Binary files a/core/assets/maps/craters.msav and b/core/assets/maps/craters.msav differ diff --git a/core/assets/maps/desolateRift.msav b/core/assets/maps/desolateRift.msav index ca3181301a..71c433d81a 100644 Binary files a/core/assets/maps/desolateRift.msav and b/core/assets/maps/desolateRift.msav differ diff --git a/core/assets/maps/extractionOutpost.msav b/core/assets/maps/extractionOutpost.msav index 5728a4b217..7ce6a6904e 100644 Binary files a/core/assets/maps/extractionOutpost.msav and b/core/assets/maps/extractionOutpost.msav differ diff --git a/core/assets/maps/fungalPass.msav b/core/assets/maps/fungalPass.msav index f0edb0987b..bc86d8c69c 100644 Binary files a/core/assets/maps/fungalPass.msav and b/core/assets/maps/fungalPass.msav differ diff --git a/core/assets/maps/impact0078.msav b/core/assets/maps/impact0078.msav index 56f5570bfb..08a71a5673 100644 Binary files a/core/assets/maps/impact0078.msav and b/core/assets/maps/impact0078.msav differ diff --git a/core/assets/maps/nuclearComplex.msav b/core/assets/maps/nuclearComplex.msav index aa9424850b..1b15a5878b 100644 Binary files a/core/assets/maps/nuclearComplex.msav and b/core/assets/maps/nuclearComplex.msav differ diff --git a/core/assets/maps/overgrowth.msav b/core/assets/maps/overgrowth.msav index 0fd4902d1d..a51978cb0f 100644 Binary files a/core/assets/maps/overgrowth.msav and b/core/assets/maps/overgrowth.msav differ diff --git a/core/assets/maps/planetaryTerminal.msav b/core/assets/maps/planetaryTerminal.msav index c705da368f..7c45ebfca2 100644 Binary files a/core/assets/maps/planetaryTerminal.msav and b/core/assets/maps/planetaryTerminal.msav differ diff --git a/core/assets/maps/ruinousShores.msav b/core/assets/maps/ruinousShores.msav index 48727feae4..441fb2044d 100644 Binary files a/core/assets/maps/ruinousShores.msav and b/core/assets/maps/ruinousShores.msav differ diff --git a/core/assets/maps/stainedMountains.msav b/core/assets/maps/stainedMountains.msav index 082f96ad7b..b5ec28c9d4 100644 Binary files a/core/assets/maps/stainedMountains.msav and b/core/assets/maps/stainedMountains.msav differ diff --git a/core/assets/maps/tarFields.msav b/core/assets/maps/tarFields.msav index 006be2fb0f..04055ac8b7 100644 Binary files a/core/assets/maps/tarFields.msav and b/core/assets/maps/tarFields.msav differ diff --git a/core/assets/maps/windsweptIslands.msav b/core/assets/maps/windsweptIslands.msav index 2c8547f6f9..690a924716 100644 Binary files a/core/assets/maps/windsweptIslands.msav and b/core/assets/maps/windsweptIslands.msav differ diff --git a/core/src/mindustry/ClientLauncher.java b/core/src/mindustry/ClientLauncher.java index 3777da85c7..978361898a 100644 --- a/core/src/mindustry/ClientLauncher.java +++ b/core/src/mindustry/ClientLauncher.java @@ -112,8 +112,8 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform super.add(module); //autoload modules when necessary - if(module instanceof Loadable){ - assets.load((Loadable)module); + if(module instanceof Loadable l){ + assets.load(l); } } diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index 21a8b3fb45..d5b9778f67 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -47,6 +47,8 @@ public class Vars implements Loadable{ public static final int bufferSize = 8192; /** global charset, since Android doesn't support the Charsets class */ public static final Charset charset = Charset.forName("UTF-8"); + /** mods suggested for import */ + public static final String[] suggestedMods = {""}; /** main application name, capitalized */ public static final String appName = "Mindustry"; /** URL for itch.io donations. */ @@ -56,7 +58,7 @@ public class Vars implements Loadable{ /** URL for sending crash reports to */ public static final String crashReportURL = "http://192.99.169.18/report"; /** URL the links to the wiki's modding guide.*/ - public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/"; + public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/1-modding/"; /** URL to the JSON file containing all the global, public servers. Not queried in BE. */ public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers.json"; /** URL to the JSON file containing all the BE servers. Only queried in BE. */ @@ -88,7 +90,7 @@ public class Vars implements Loadable{ /** duration of time between turns in ticks */ public static final float turnDuration = 2 * Time.toMinutes; /** chance of an invasion per turn, 1 = 100% */ - public static final float baseInvasionChance = 1f / 75f; + public static final float baseInvasionChance = 1f / 100f; /** how many turns have to pass before invasions start */ public static final int invasionGracePeriod = 20; /** min armor fraction damage; e.g. 0.05 = at least 5% damage */ diff --git a/core/src/mindustry/ai/BaseAI.java b/core/src/mindustry/ai/BaseAI.java index 395493d57f..dd34626dcb 100644 --- a/core/src/mindustry/ai/BaseAI.java +++ b/core/src/mindustry/ai/BaseAI.java @@ -55,11 +55,12 @@ public class BaseAI{ public void update(){ if(data.team.rules().aiCoreSpawn && timer.get(timerSpawn, 60 * 2.5f) && data.hasCore()){ CoreBlock block = (CoreBlock)data.core().block; + int coreUnits = Groups.unit.count(u -> u.team == data.team && u.type == block.unitType); - //create AI core unit - if(!state.isEditor() && !Groups.unit.contains(u -> u.team() == data.team && u.type == block.unitType)){ + //create AI core unit(s) + if(!state.isEditor() && coreUnits < data.cores.size){ Unit unit = block.unitType.create(data.team); - unit.set(data.core()); + unit.set(data.cores.random()); unit.add(); Fx.spawn.at(unit); } diff --git a/core/src/mindustry/ai/Pathfinder.java b/core/src/mindustry/ai/Pathfinder.java index 392481b3ac..c5b03f40bd 100644 --- a/core/src/mindustry/ai/Pathfinder.java +++ b/core/src/mindustry/ai/Pathfinder.java @@ -13,6 +13,7 @@ import mindustry.game.EventType.*; import mindustry.game.*; import mindustry.gen.*; import mindustry.world.*; +import mindustry.world.blocks.storage.*; import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -115,7 +116,7 @@ public class Pathfinder implements Runnable{ } return PathTile.get( - tile.build == null || !tile.solid() ? 0 : Math.min((int)(tile.build.health / 40), 80), + tile.build == null || !tile.solid() || tile.block() instanceof CoreBlock ? 0 : Math.min((int)(tile.build.health / 40), 80), tile.getTeamID(), tile.solid(), tile.floor().isLiquid, @@ -458,7 +459,7 @@ public class Pathfinder implements Runnable{ /** costs of getting to a specific tile */ public int[][] weights; /** search IDs of each position - the highest, most recent search is prioritized and overwritten */ - int[][] searches; + public int[][] searches; /** search frontier, these are Pos objects */ IntQueue frontier = new IntQueue(); /** all target positions; these positions have a cost of 0, and must be synchronized on! */ diff --git a/core/src/mindustry/ai/types/FormationAI.java b/core/src/mindustry/ai/types/FormationAI.java index 2379b28e07..bb4182c254 100644 --- a/core/src/mindustry/ai/types/FormationAI.java +++ b/core/src/mindustry/ai/types/FormationAI.java @@ -67,7 +67,7 @@ public class FormationAI extends AIController implements FormationMember{ if(core != null && leader.mineTile.drop() != null && unit.within(core, unit.type.range) && !unit.acceptsItem(leader.mineTile.drop())){ if(core.acceptStack(unit.stack.item, unit.stack.amount, unit) > 0){ - Call.transferItemTo(unit.stack.item, unit.stack.amount, unit.x, unit.y, core); + Call.transferItemTo(unit, unit.stack.item, unit.stack.amount, unit.x, unit.y, core); unit.clearItem(); } diff --git a/core/src/mindustry/ai/types/MinerAI.java b/core/src/mindustry/ai/types/MinerAI.java index 97d8198bb2..28306deb84 100644 --- a/core/src/mindustry/ai/types/MinerAI.java +++ b/core/src/mindustry/ai/types/MinerAI.java @@ -65,7 +65,7 @@ public class MinerAI extends AIController{ if(unit.within(core, unit.type.range)){ if(core.acceptStack(unit.stack.item, unit.stack.amount, unit) > 0){ - Call.transferItemTo(unit.stack.item, unit.stack.amount, unit.x, unit.y, core); + Call.transferItemTo(unit, unit.stack.item, unit.stack.amount, unit.x, unit.y, core); } unit.clearItem(); diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 363256dc83..b324b24190 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1388,7 +1388,7 @@ public class Blocks implements ContentList{ size = 5; unitCapModifier = 24; - researchCostMultiplier = 0.05f; + researchCostMultiplier = 0.06f; }}; vault = new StorageBlock("vault"){{ diff --git a/core/src/mindustry/content/Bullets.java b/core/src/mindustry/content/Bullets.java index c7fa47a62b..04a04ffbb1 100644 --- a/core/src/mindustry/content/Bullets.java +++ b/core/src/mindustry/content/Bullets.java @@ -37,7 +37,7 @@ public class Bullets implements ContentList{ waterShot, cryoShot, slagShot, oilShot, heavyWaterShot, heavyCryoShot, heavySlagShot, heavyOilShot, //environment, misc. - damageLightning, damageLightningGround, fireball, basicFlame, pyraFlame, driverBolt, healBullet, healBulletBig; + damageLightning, damageLightningGround, fireball, basicFlame, pyraFlame, driverBolt; @Override public void load(){ @@ -374,20 +374,6 @@ public class Bullets implements ContentList{ knockback = 0.7f; }}; - healBullet = new LaserBoltBulletType(5.2f, 13){{ - healPercent = 3f; - collidesTeam = true; - backColor = Pal.heal; - frontColor = Color.white; - }}; - - healBulletBig = new LaserBoltBulletType(5.2f, 15){{ - healPercent = 5.5f; - collidesTeam = true; - backColor = Pal.heal; - frontColor = Color.white; - }}; - fireball = new BulletType(1f, 4){ { pierce = true; diff --git a/core/src/mindustry/content/SectorPresets.java b/core/src/mindustry/content/SectorPresets.java index dbfddbc142..e84547dd5f 100644 --- a/core/src/mindustry/content/SectorPresets.java +++ b/core/src/mindustry/content/SectorPresets.java @@ -83,7 +83,7 @@ public class SectorPresets implements ContentList{ }}; desolateRift = new SectorPreset("desolateRift", serpulo, 123){{ - captureWave = 30; + captureWave = 18; difficulty = 8; }}; diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java index 31becb5f57..a20917c054 100644 --- a/core/src/mindustry/content/TechTree.java +++ b/core/src/mindustry/content/TechTree.java @@ -98,11 +98,11 @@ public class TechTree implements ContentList{ node(platedConduit, () -> { }); - }); - node(rotaryPump, () -> { - node(thermalPump, () -> { + node(rotaryPump, () -> { + node(thermalPump, () -> { + }); }); }); }); @@ -471,7 +471,8 @@ public class TechTree implements ContentList{ node(desolateRift, Seq.with( new SectorComplete(impact0078), new Research(thermalGenerator), - new Research(thoriumReactor) + new Research(thoriumReactor), + new Research(coreNucleus) ), () -> { node(planetaryTerminal, Seq.with( new SectorComplete(desolateRift), diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 83f3aa3db7..8866bd2578 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -292,6 +292,7 @@ public class UnitTypes implements ContentList{ shootSound = Sounds.lasershoot; bullet = new LaserBoltBulletType(5.2f, 14){{ + lifetime = 37f; healPercent = 5f; collidesTeam = true; backColor = Pal.heal; @@ -311,7 +312,7 @@ public class UnitTypes implements ContentList{ mineTier = 2; mineSpeed = 5f; - commandLimit = 8; + commandLimit = 9; abilities.add(new ShieldRegenFieldAbility(20f, 40f, 60f * 5, 60f)); ammoType = AmmoTypes.power; @@ -619,7 +620,7 @@ public class UnitTypes implements ContentList{ drag = 0.4f; hitSize = 12f; rotateSpeed = 3f; - health = 800; + health = 900; immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting); legCount = 6; legLength = 13f; @@ -650,7 +651,7 @@ public class UnitTypes implements ContentList{ bullet = new SapBulletType(){{ sapStrength = 0.4f; length = 75f; - damage = 18; + damage = 20; shootEffect = Fx.shootSmall; hitColor = color = Color.valueOf("bf92f9"); despawnEffect = Fx.none; @@ -670,7 +671,7 @@ public class UnitTypes implements ContentList{ bullet = new SapBulletType(){{ sapStrength = 0.8f; length = 40f; - damage = 15; + damage = 16; shootEffect = Fx.shootSmall; hitColor = color = Color.valueOf("bf92f9"); despawnEffect = Fx.none; @@ -975,7 +976,7 @@ public class UnitTypes implements ContentList{ zenith = new UnitType("zenith"){{ health = 700; - speed = 1.7f; + speed = 1.8f; accel = 0.04f; drag = 0.016f; flying = true; @@ -997,7 +998,7 @@ public class UnitTypes implements ContentList{ velocityRnd = 0.2f; shootSound = Sounds.missile; - bullet = new MissileBulletType(3f, 12){{ + bullet = new MissileBulletType(3f, 14){{ width = 8f; height = 8f; shrinkY = 0f; @@ -1005,7 +1006,7 @@ public class UnitTypes implements ContentList{ homingRange = 60f; keepVelocity = false; splashDamageRadius = 25f; - splashDamage = 10f; + splashDamage = 16f; lifetime = 60f; trailColor = Pal.unitBack; backColor = Pal.unitBack; @@ -1251,8 +1252,8 @@ public class UnitTypes implements ContentList{ mineTier = 3; mineSpeed = 4f; - health = 500; - armor = 5f; + health = 460; + armor = 3f; speed = 2.5f; accel = 0.06f; drag = 0.017f; @@ -1264,6 +1265,7 @@ public class UnitTypes implements ContentList{ engineSize = 3f; payloadCapacity = (2 * 2) * tilePayload; buildSpeed = 2.6f; + isCounted = false; ammoType = AmmoTypes.power; @@ -1274,7 +1276,13 @@ public class UnitTypes implements ContentList{ x = 8f; y = -6f; rotate = true; - bullet = Bullets.healBulletBig; + bullet = new LaserBoltBulletType(5.2f, 10){{ + lifetime = 35f; + healPercent = 5.5f; + collidesTeam = true; + backColor = Pal.heal; + frontColor = Color.white; + }}; }}, new Weapon("heal-weapon-mount"){{ shootSound = Sounds.lasershoot; @@ -1282,7 +1290,13 @@ public class UnitTypes implements ContentList{ x = 4f; y = 5f; rotate = true; - bullet = Bullets.healBullet; + bullet = new LaserBoltBulletType(5.2f, 8){{ + lifetime = 35f; + healPercent = 3f; + collidesTeam = true; + backColor = Pal.heal; + frontColor = Color.white; + }}; }}); }}; @@ -1643,6 +1657,7 @@ public class UnitTypes implements ContentList{ recoil = 3f; occlusion = 12f; ejectEffect = Fx.casing3; + shootSound = Sounds.shootBig; shots = 3; shotDelay = 4f; @@ -1735,13 +1750,13 @@ public class UnitTypes implements ContentList{ top = false; ejectEffect = Fx.casing1; - bullet = new BasicBulletType(2.5f, 10){{ + bullet = new BasicBulletType(2.5f, 11){{ width = 7f; height = 9f; lifetime = 60f; shootEffect = Fx.shootSmall; smokeEffect = Fx.shootSmallSmoke; - tileDamageMultiplier = 0.02f; + tileDamageMultiplier = 0.01f; }}; }}); }}; @@ -1777,13 +1792,13 @@ public class UnitTypes implements ContentList{ spacing = 0f; ejectEffect = Fx.casing1; - bullet = new BasicBulletType(3f, 10){{ + bullet = new BasicBulletType(3f, 11){{ width = 7f; height = 9f; lifetime = 60f; shootEffect = Fx.shootSmall; smokeEffect = Fx.shootSmallSmoke; - tileDamageMultiplier = 0.02f; + tileDamageMultiplier = 0.01f; }}; }}); }}; @@ -1817,13 +1832,13 @@ public class UnitTypes implements ContentList{ shotDelay = 3f; ejectEffect = Fx.casing1; - bullet = new BasicBulletType(3.5f, 10){{ + bullet = new BasicBulletType(3.5f, 11){{ width = 6.5f; height = 11f; lifetime = 70f; shootEffect = Fx.shootSmall; smokeEffect = Fx.shootSmallSmoke; - tileDamageMultiplier = 0.02f; + tileDamageMultiplier = 0.01f; homingPower = 0.04f; }}; }}); diff --git a/core/src/mindustry/content/Weathers.java b/core/src/mindustry/content/Weathers.java index 86dac06f7b..2006e6fb05 100644 --- a/core/src/mindustry/content/Weathers.java +++ b/core/src/mindustry/content/Weathers.java @@ -53,10 +53,11 @@ public class Weathers implements ContentList{ baseSpeed = 5.4f; attrs.set(Attribute.light, -0.1f); attrs.set(Attribute.water, -0.1f); - opacityMultiplier = 0.5f; + opacityMultiplier = 0.35f; force = 0.1f; sound = Sounds.wind; - soundVol = 0.3f; + soundVol = 0.8f; + duration = 7f * Time.toMinutes; }}; sporestorm = new ParticleWeather("sporestorm"){{ @@ -77,7 +78,8 @@ public class Weathers implements ContentList{ opacityMultiplier = 0.75f; force = 0.1f; sound = Sounds.wind; - soundVol = 0.3f; + soundVol = 0.7f; + duration = 7f * Time.toMinutes; }}; fog = new ParticleWeather("fog"){{ diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index bc5acc066f..c67572d559 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -334,9 +334,28 @@ public class Control implements ApplicationListener, Loadable{ state.wave = 1; //set up default wave time state.wavetime = state.rules.waveSpacing * 2f; + //reset captured state + sector.info.wasCaptured = false; + //re-enable waves + state.rules.waves = true; //reset win wave?? - state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null ? sector.preset.captureWave : 40; + state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null ? sector.preset.captureWave : state.rules.winWave > state.wave ? state.rules.winWave : 40; + + //if there's still an enemy base left, fix it + if(state.rules.attackMode){ + //replace all broken blocks + for(var plan : state.rules.waveTeam.data().blocks){ + Tile tile = world.tile(plan.x, plan.y); + if(tile != null){ + tile.setBlock(content.block(plan.block), state.rules.waveTeam, plan.rotation); + if(plan.config != null && tile.build != null){ + tile.build.configure(plan.config); + } + } + } + state.rules.waveTeam.data().blocks.clear(); + } //kill all units, since they should be dead anyway Groups.unit.clear(); diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index 02222bd327..a13e37cbac 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -109,6 +109,13 @@ public class Logic implements ApplicationListener{ } state.rules.waveTeam.rules().aiTier = state.getSector().threat * 0.8f; state.rules.waveTeam.rules().infiniteResources = true; + + //fill enemy cores by default. + for(var core : state.rules.waveTeam.cores()){ + for(Item item : content.items()){ + core.items.set(item, core.block.itemCapacity); + } + } } //save settings @@ -128,8 +135,8 @@ public class Logic implements ApplicationListener{ //convert all blocks to neutral, randomly killing them if(tile.isCenter() && tile.build != null && tile.build.team == state.rules.waveTeam){ Building b = tile.build; + Call.setTeam(b, Team.derelict); Time.run(Mathf.random(0f, 60f * 6f), () -> { - Call.setTeam(b, Team.derelict); if(Mathf.chance(0.25)){ b.kill(); } @@ -260,6 +267,8 @@ public class Logic implements ApplicationListener{ if(state.rules.sector == null) return; + state.rules.sector.info.wasCaptured = true; + //fire capture event Events.fire(new SectorCaptureEvent(state.rules.sector)); diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index c0a35c625b..5f7dfd100b 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -447,6 +447,11 @@ public class NetServer implements ApplicationListener{ return; } + if(currentlyKicking[0].target.team() != player.team()){ + player.sendMessage("[scarlet]You can't vote for other teams."); + return; + } + if(!arg[0].toLowerCase().equals("y") && !arg[0].toLowerCase().equals("n")){ player.sendMessage("[scarlet]Vote either 'y' (yes) or 'n' (no)."); return; diff --git a/core/src/mindustry/core/UI.java b/core/src/mindustry/core/UI.java index 4437bb4d48..3b7504be6d 100644 --- a/core/src/mindustry/core/UI.java +++ b/core/src/mindustry/core/UI.java @@ -258,11 +258,11 @@ public class UI implements ApplicationListener, Loadable{ TextField field = cont.field(def, t -> {}).size(330f, 50f).get(); field.setFilter((f, c) -> field.getText().length() < textLength && filter.acceptChar(f, c)); buttons.defaults().size(120, 54).pad(4); + buttons.button("@cancel", this::hide); buttons.button("@ok", () -> { confirmed.get(field.getText()); hide(); }).disabled(b -> field.getText().isEmpty()); - buttons.button("@cancel", this::hide); keyDown(KeyCode.enter, () -> { String text = field.getText(); if(!text.isEmpty()){ diff --git a/core/src/mindustry/core/World.java b/core/src/mindustry/core/World.java index c4819ed222..a167a32ecb 100644 --- a/core/src/mindustry/core/World.java +++ b/core/src/mindustry/core/World.java @@ -311,7 +311,7 @@ public class World{ //TODO bad code boolean hasSnow = floors[0].name.contains("ice") || floors[0].name.contains("snow"); boolean hasRain = !hasSnow && content.contains(Liquids.water) && !floors[0].name.contains("sand"); - boolean hasDesert = !hasSnow && !hasRain && floors[0].name.contains("sand"); + boolean hasDesert = !hasSnow && !hasRain && floors[0] == Blocks.sand; boolean hasSpores = floors[0].name.contains("spore") || floors[0].name.contains("moss") || floors[0].name.contains("tainted"); if(hasSnow){ diff --git a/core/src/mindustry/editor/WaveGraph.java b/core/src/mindustry/editor/WaveGraph.java index e908e7d934..d6a33bf6ff 100644 --- a/core/src/mindustry/editor/WaveGraph.java +++ b/core/src/mindustry/editor/WaveGraph.java @@ -17,7 +17,7 @@ import mindustry.ui.*; public class WaveGraph extends Table{ public Seq groups = new Seq<>(); - public int from, to = 20; + public int from = 0, to = 20; private Mode mode = Mode.counts; private int[][] values; @@ -114,7 +114,7 @@ public class WaveGraph extends Table{ Lines.line(cx, cy, cx, cy + len); if(i == values.length/2){ - font.draw("" + (i + from), cx, cy - 2f, Align.center); + font.draw("" + (i + from + 1), cx, cy - 2f, Align.center); } } font.setColor(Color.white); diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index a3dd3913f1..64c08f318c 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -2,7 +2,6 @@ package mindustry.entities; import arc.*; import arc.func.*; -import arc.graphics.*; import arc.math.*; import arc.math.geom.*; import arc.struct.*; @@ -33,15 +32,22 @@ public class Damage{ private static Unit tmpUnit; /** Creates a dynamic explosion based on specified parameters. */ - public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color, boolean damage){ + public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, boolean damage){ + dynamicExplosion(x, y, flammability, explosiveness, power, radius, damage, true, null); + } + + /** Creates a dynamic explosion based on specified parameters. */ + public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, boolean damage, boolean fire, @Nullable Team ignoreTeam){ if(damage){ for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i++){ int branches = 5 + Mathf.clamp((int)(power / 30), 1, 20); Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3, x, y, Mathf.random(360f), branches + Mathf.range(2))); } - for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i++){ - Time.run(i / 2f, () -> Call.createBullet(Bullets.fireball, Team.derelict, x, y, Mathf.random(360f), Bullets.fireball.damage, 1, 1)); + if(fire){ + for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i++){ + Time.run(i / 2f, () -> Call.createBullet(Bullets.fireball, Team.derelict, x, y, Mathf.random(360f), Bullets.fireball.damage, 1, 1)); + } } int waves = Mathf.clamp((int)(explosiveness / 4), 0, 30); @@ -49,7 +55,7 @@ public class Damage{ for(int i = 0; i < waves; i++){ int f = i; Time.run(i * 2f, () -> { - Damage.damage(x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), explosiveness / 2f); + Damage.damage(ignoreTeam, x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), explosiveness / 2f, false); Fx.blockExplosionSmoke.at(x + Mathf.range(radius), y + Mathf.range(radius)); }); } diff --git a/core/src/mindustry/entities/Fires.java b/core/src/mindustry/entities/Fires.java index 754a8766b9..2ae2253356 100644 --- a/core/src/mindustry/entities/Fires.java +++ b/core/src/mindustry/entities/Fires.java @@ -15,7 +15,7 @@ public class Fires{ private static final float baseLifetime = 1000f; private static final IntMap map = new IntMap<>(); - /** Start a fire on the tile. If there already is a file there, refreshes its lifetime. */ + /** Start a fire on the tile. If there already is a fire there, refreshes its lifetime. */ public static void create(Tile tile){ if(net.client() || tile == null || !state.rules.fire) return; //not clientside. diff --git a/core/src/mindustry/entities/Lightning.java b/core/src/mindustry/entities/Lightning.java index 61f42f2e72..ce5a3f97da 100644 --- a/core/src/mindustry/entities/Lightning.java +++ b/core/src/mindustry/entities/Lightning.java @@ -53,7 +53,7 @@ public class Lightning{ world.raycastEach(World.toTile(from.getX()), World.toTile(from.getY()), World.toTile(to.getX()), World.toTile(to.getY()), (wx, wy) -> { Tile tile = world.tile(wx, wy); - if(tile != null && tile.block().insulated){ + if(tile != null && tile.block().insulated && tile.team() != team){ bhit = true; //snap it instead of removing lines.get(lines.size -1).set(wx * tilesize, wy * tilesize); diff --git a/core/src/mindustry/entities/Puddles.java b/core/src/mindustry/entities/Puddles.java index 0abdae4928..a57f689884 100644 --- a/core/src/mindustry/entities/Puddles.java +++ b/core/src/mindustry/entities/Puddles.java @@ -38,9 +38,9 @@ public class Puddles{ Puddle p = map.get(tile.pos()); - if(generation == 0 && p != null && p.lastRipple() <= Time.time() - 40f){ + if(generation == 0 && p != null && p.lastRipple() <= Time.time - 40f){ Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, 1f, tile.floor().liquidDrop.color); - p.lastRipple(Time.time()); + p.lastRipple(Time.time); } return; } @@ -62,9 +62,9 @@ public class Puddles{ }else if(p.liquid() == liquid){ p.accepting(Math.max(amount, p.accepting())); - if(generation == 0 && p.lastRipple() <= Time.time() - 40f && p.amount() >= maxLiquid / 2f){ + if(generation == 0 && p.lastRipple() <= Time.time - 40f && p.amount() >= maxLiquid / 2f){ Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, 1f, p.liquid().color); - p.lastRipple(Time.time()); + p.lastRipple(Time.time); } }else{ p.amount(p.amount() + reactPuddle(p.liquid(), liquid, amount, p.tile(), (p.x() + source.worldx())/2f, (p.y() + source.worldy())/2f)); diff --git a/core/src/mindustry/entities/abilities/RepairFieldAbility.java b/core/src/mindustry/entities/abilities/RepairFieldAbility.java index 8df0a96e2c..9e2890589a 100644 --- a/core/src/mindustry/entities/abilities/RepairFieldAbility.java +++ b/core/src/mindustry/entities/abilities/RepairFieldAbility.java @@ -30,7 +30,7 @@ public class RepairFieldAbility extends Ability{ Units.nearby(unit.team, unit.x, unit.y, range, other -> { if(other.damaged()){ - healEffect.at(unit); + healEffect.at(other); wasHealed = true; } other.heal(amount); diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index 7d94602844..4d93321367 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -273,7 +273,8 @@ public abstract class BulletType extends Content{ } if(weaveMag > 0){ - b.vel.rotate(Mathf.sin(Mathf.randomSeed(b.id, 10f) + b.time, weaveScale, weaveMag) * Time.delta); + float scl = Mathf.randomSeed(id, 0.9f, 1.1f); + b.vel.rotate(Mathf.sin(b.time + Mathf.PI * weaveScale/2f * scl, weaveScale * scl, weaveMag) * Time.delta); } if(trailChance > 0){ diff --git a/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java b/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java index 3e570c6309..07ae245719 100644 --- a/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java +++ b/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java @@ -85,10 +85,10 @@ public class ContinuousLaserBulletType extends BulletType{ Lines.lineAngle(b.x, b.y, b.rotation(), baseLen); for(int s = 0; s < colors.length; s++){ - Draw.color(Tmp.c1.set(colors[s]).mul(1f + Mathf.absin(Time.time(), 1f, 0.1f))); + Draw.color(Tmp.c1.set(colors[s]).mul(1f + Mathf.absin(Time.time, 1f, 0.1f))); for(int i = 0; i < tscales.length; i++){ Tmp.v1.trns(b.rotation() + 180f, (lenscales[i] - 1f) * spaceMag); - Lines.stroke((width + Mathf.absin(Time.time(), oscScl, oscMag)) * fout * strokes[s] * tscales[i]); + Lines.stroke((width + Mathf.absin(Time.time, oscScl, oscMag)) * fout * strokes[s] * tscales[i]); Lines.lineAngle(b.x + Tmp.v1.x, b.y + Tmp.v1.y, b.rotation(), baseLen * lenscales[i], false); } } diff --git a/core/src/mindustry/entities/comp/BoundedComp.java b/core/src/mindustry/entities/comp/BoundedComp.java index c266ae3e51..c02d34a760 100644 --- a/core/src/mindustry/entities/comp/BoundedComp.java +++ b/core/src/mindustry/entities/comp/BoundedComp.java @@ -16,11 +16,13 @@ abstract class BoundedComp implements Velc, Posc, Healthc, Flyingc{ @Override public void update(){ - //repel unit out of bounds - if(x < 0) vel.x += (-x/warpDst); - if(y < 0) vel.y += (-y/warpDst); - if(x > world.unitWidth()) vel.x -= (x - world.unitWidth())/warpDst; - if(y > world.unitHeight()) vel.y -= (y - world.unitHeight())/warpDst; + if(!net.client() || isLocal()){ + //repel unit out of bounds + if(x < 0) vel.x += (-x/warpDst); + if(y < 0) vel.y += (-y/warpDst); + if(x > world.unitWidth()) vel.x -= (x - world.unitWidth())/warpDst; + if(y > world.unitHeight()) vel.y -= (y - world.unitHeight())/warpDst; + } //clamp position if not flying if(isGrounded()){ diff --git a/core/src/mindustry/entities/comp/BuilderComp.java b/core/src/mindustry/entities/comp/BuilderComp.java index a1e218c05a..b00b43774f 100644 --- a/core/src/mindustry/entities/comp/BuilderComp.java +++ b/core/src/mindustry/entities/comp/BuilderComp.java @@ -11,6 +11,7 @@ import mindustry.annotations.Annotations.*; import mindustry.content.*; import mindustry.entities.units.*; import mindustry.game.EventType.*; +import mindustry.game.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.type.*; @@ -28,6 +29,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ @Import float x, y, rotation; @Import UnitType type; + @Import Team team; @SyncLocal Queue plans = new Queue<>(1); @SyncLocal transient boolean updateBuilding = true; @@ -75,27 +77,27 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ Tile tile = world.tile(current.x, current.y); if(!(tile.block() instanceof ConstructBlock)){ - if(!current.initialized && !current.breaking && Build.validPlace(current.block, team(), current.x, current.y, current.rotation)){ + if(!current.initialized && !current.breaking && Build.validPlace(current.block, team, current.x, current.y, current.rotation)){ boolean hasAll = infinite || !Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item)); if(hasAll){ - Call.beginPlace(current.block, team(), current.x, current.y, current.rotation); + Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation); }else{ current.stuck = true; } - }else if(!current.initialized && current.breaking && Build.validBreak(team(), current.x, current.y)){ - Call.beginBreak(team(), current.x, current.y); + }else if(!current.initialized && current.breaking && Build.validBreak(team, current.x, current.y)){ + Call.beginBreak(self(), team, current.x, current.y); }else{ plans.removeFirst(); return; } - }else if(tile.team() != team()){ + }else if(tile.team() != team){ plans.removeFirst(); return; } if(tile.build instanceof ConstructBuild && !current.initialized){ - Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, team(), (Builderc)this, current.breaking))); + Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, team, self(), current.breaking))); current.initialized = true; } @@ -128,7 +130,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ control.input.drawBreaking(request); }else{ request.block.drawRequest(request, control.input.allRequests(), - Build.validPlace(request.block, team(), request.x, request.y, request.rotation) || control.input.requestMatches(request)); + Build.validPlace(request.block, team, request.x, request.y, request.rotation) || control.input.requestMatches(request)); } } @@ -138,7 +140,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ /** @return whether this request should be skipped, in favor of the next one. */ boolean shouldSkip(BuildPlan request, @Nullable Building core){ //requests that you have at least *started* are considered - if(state.rules.infiniteResources || team().rules().infiniteResources || request.breaking || core == null) return false; + if(state.rules.infiniteResources || team.rules().infiniteResources || request.breaking || core == null) return false; return (request.stuck && !core.items.has(request.block.requirements)) || (Structs.contains(request.block.requirements, i -> !core.items.has(i.item) && Mathf.round(i.amount * state.rules.buildCostMultiplier) > 0) && !request.initialized); } @@ -222,7 +224,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ float tx = plan.drawx(), ty = plan.drawy(); Lines.stroke(1f, Pal.accent); - float focusLen = 3.8f + Mathf.absin(Time.time(), 1.1f, 0.6f); + float focusLen = 3.8f + Mathf.absin(Time.time, 1.1f, 0.6f); float px = x + Angles.trnsx(rotation, focusLen); float py = y + Angles.trnsy(rotation, focusLen); @@ -244,7 +246,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ Lines.line(px, py, x1, y1); Lines.line(px, py, x3, y3); - Fill.circle(px, py, 1.6f + Mathf.absin(Time.time(), 0.8f, 1.5f)); + Fill.circle(px, py, 1.6f + Mathf.absin(Time.time, 0.8f, 1.5f)); Draw.color(); } diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index fca91f0417..37f9b59ec9 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -14,6 +14,7 @@ import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; import arc.util.io.*; +import mindustry.*; import mindustry.annotations.Annotations.*; import mindustry.audio.*; import mindustry.content.*; @@ -29,8 +30,8 @@ import mindustry.logic.*; import mindustry.type.*; import mindustry.ui.*; import mindustry.world.*; -import mindustry.world.blocks.*; import mindustry.world.blocks.ConstructBlock.*; +import mindustry.world.blocks.*; import mindustry.world.blocks.environment.*; import mindustry.world.blocks.payloads.*; import mindustry.world.blocks.power.*; @@ -435,7 +436,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, } /** Handle a stack input. */ - public void handleStack(Item item, int amount, Teamc source){ + public void handleStack(Item item, int amount, @Nullable Teamc source){ noSleep(); items.add(item, amount); } @@ -519,6 +520,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, public void dumpLiquid(Liquid liquid){ int dump = this.cdump; + if(liquids.get(liquid) <= 0.0001f) return; + if(!net.client() && state.isCampaign() && team == state.rules.defaultTeam) liquid.unlock(); for(int i = 0; i < proximity.size; i++){ @@ -619,6 +622,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, * containers, it gets added to the block's inventory. */ public void offload(Item item){ + produced(item, 1); int dump = this.cdump; if(!net.client() && state.isCampaign() && team == state.rules.defaultTeam) item.unlock(); @@ -652,6 +656,14 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, return false; } + public void produced(Item item){ + produced(item, 1); + } + + public void produced(Item item, int amount){ + if(Vars.state.rules.sector != null && team == state.rules.defaultTeam) Vars.state.rules.sector.info.handleProduction(item, amount); + } + /** Try dumping any item near the */ public boolean dump(){ return dump(null); @@ -917,6 +929,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, //null is of type void.class; anonymous classes use their superclass. Class type = value == null ? void.class : value.getClass().isAnonymousClass() || value.getClass().getSimpleName().startsWith("adapter") ? value.getClass().getSuperclass() : value.getClass(); + if(value instanceof Block) type = Block.class; + if(builder != null && builder.isPlayer()){ lastAccessed = builder.getPlayer().name; } @@ -970,34 +984,13 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, }); } - Damage.dynamicExplosion(x, y, flammability, explosiveness * 3.5f, power, tilesize * block.size / 2f, Pal.darkFlame, state.rules.damageExplosions); + Damage.dynamicExplosion(x, y, flammability, explosiveness * 3.5f, power, tilesize * block.size / 2f, state.rules.damageExplosions); if(!floor().solid && !floor().isLiquid){ Effect.rubble(x, y, block.size); } } - /** - * Returns the flammability of the Used for fire calculations. - * Takes flammability of floor liquid into account. - */ - public float getFlammability(){ - if(!block.hasItems){ - if(floor().isLiquid && !block.solid){ - return floor().liquidDrop.flammability; - } - return 0; - }else{ - float result = items.sum((item, amount) -> item.flammability * amount); - - if(block.hasLiquids){ - result += liquids.sum((liquid, amount) -> liquid.flammability * amount / 3f); - } - - return result; - } - } - public String getDisplayName(){ return block.localizedName; } diff --git a/core/src/mindustry/entities/comp/FireComp.java b/core/src/mindustry/entities/comp/FireComp.java index 43fc3cdae9..7981e061b6 100644 --- a/core/src/mindustry/entities/comp/FireComp.java +++ b/core/src/mindustry/entities/comp/FireComp.java @@ -26,7 +26,7 @@ abstract class FireComp implements Timedc, Posc, Firec, Syncc{ @Override public void update(){ - if(Mathf.chance(0.1 * Time.delta)){ + if(Mathf.chance(0.09 * Time.delta)){ Fx.fire.at(x + Mathf.range(4f), y + Mathf.range(4f)); } @@ -59,7 +59,7 @@ abstract class FireComp implements Timedc, Posc, Firec, Syncc{ } if(baseFlammability < 0 || block != tile.block()){ - baseFlammability = tile.build == null ? 0 : tile.build.getFlammability(); + baseFlammability = tile.build == null ? 0 : tile.getFlammability(); block = tile.block(); } @@ -77,12 +77,12 @@ abstract class FireComp implements Timedc, Posc, Firec, Syncc{ } } - if(Mathf.chance(0.1 * Time.delta)){ + if(Mathf.chance(0.025 * Time.delta)){ Puddlec p = Puddles.get(tile); puddleFlammability = p != null ? p.getFlammability() / 3f : 0; if(damage){ - entity.damage(0.4f); + entity.damage(1.6f); } Damage.damageUnits(null, tile.worldx(), tile.worldy(), tilesize, 3f, unit -> !unit.isFlying() && !unit.isImmune(StatusEffects.burning), diff --git a/core/src/mindustry/entities/comp/FlyingComp.java b/core/src/mindustry/entities/comp/FlyingComp.java index be7b003baa..43955b75a1 100644 --- a/core/src/mindustry/entities/comp/FlyingComp.java +++ b/core/src/mindustry/entities/comp/FlyingComp.java @@ -46,8 +46,8 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{ } void wobble(){ - x += Mathf.sin(Time.time() + id() * 99, 25f, 0.05f) * Time.delta * elevation; - y += Mathf.cos(Time.time() + id() * 99, 25f, 0.05f) * Time.delta * elevation; + x += Mathf.sin(Time.time + (id() % 10) * 12, 25f, 0.05f) * Time.delta * elevation; + y += Mathf.cos(Time.time + (id() % 10) * 12, 25f, 0.05f) * Time.delta * elevation; } void moveAt(Vec2 vector, float acceleration){ diff --git a/core/src/mindustry/entities/comp/MinerComp.java b/core/src/mindustry/entities/comp/MinerComp.java index 9368918d8c..8eff7d58ce 100644 --- a/core/src/mindustry/entities/comp/MinerComp.java +++ b/core/src/mindustry/entities/comp/MinerComp.java @@ -55,7 +55,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{ if(core != null && mineTile != null && mineTile.drop() != null && !acceptsItem(mineTile.drop()) && within(core, mineTransferRange) && !offloadImmediately()){ int accepted = core.acceptStack(item(), stack().amount, this); if(accepted > 0){ - Call.transferItemTo(item(), accepted, + Call.transferItemTo(self(), item(), accepted, mineTile.worldx() + Mathf.range(tilesize / 2f), mineTile.worldy() + Mathf.range(tilesize / 2f), core); clearItem(); @@ -76,8 +76,12 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{ if(mineTimer >= 50f + item.hardness*15f){ mineTimer = 0; + if(state.rules.sector != null && team() == state.rules.defaultTeam) state.rules.sector.info.handleProduction(item, 1); + if(core != null && within(core, mineTransferRange) && core.acceptStack(item, 1, this) == 1 && offloadImmediately()){ - Call.transferItemTo(item, 1, + //add item to inventory before it is transferred + if(item() == item) addItem(item); + Call.transferItemTo(self(), item, 1, mineTile.worldx() + Mathf.range(tilesize / 2f), mineTile.worldy() + Mathf.range(tilesize / 2f), core); }else if(acceptsItem(item)){ @@ -101,25 +105,25 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{ @Override public void draw(){ if(!mining()) return; - float focusLen = hitSize / 2f + Mathf.absin(Time.time(), 1.1f, 0.5f); + float focusLen = hitSize / 2f + Mathf.absin(Time.time, 1.1f, 0.5f); float swingScl = 12f, swingMag = tilesize / 8f; float flashScl = 0.3f; float px = x + Angles.trnsx(rotation, focusLen); float py = y + Angles.trnsy(rotation, focusLen); - float ex = mineTile.worldx() + Mathf.sin(Time.time() + 48, swingScl, swingMag); - float ey = mineTile.worldy() + Mathf.sin(Time.time() + 48, swingScl + 2f, swingMag); + float ex = mineTile.worldx() + Mathf.sin(Time.time + 48, swingScl, swingMag); + float ey = mineTile.worldy() + Mathf.sin(Time.time + 48, swingScl + 2f, swingMag); Draw.z(Layer.flyingUnit + 0.1f); - Draw.color(Color.lightGray, Color.white, 1f - flashScl + Mathf.absin(Time.time(), 0.5f, flashScl)); + Draw.color(Color.lightGray, Color.white, 1f - flashScl + Mathf.absin(Time.time, 0.5f, flashScl)); Drawf.laser(team(), Core.atlas.find("minelaser"), Core.atlas.find("minelaser-end"), px, py, ex, ey, 0.75f); if(isLocal()){ Lines.stroke(1f, Pal.accent); - Lines.poly(mineTile.worldx(), mineTile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Time.time()); + Lines.poly(mineTile.worldx(), mineTile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Time.time); } Draw.color(); diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index 0f8236377c..5e6c214cc6 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -243,7 +243,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra } if(Core.settings.getBool("playerchat") && ((textFadeTime > 0 && lastText != null) || typing)){ - String text = textFadeTime <= 0 || lastText == null ? "[lightgray]" + Strings.animated(Time.time(), 4, 15f, ".") : lastText; + String text = textFadeTime <= 0 || lastText == null ? "[lightgray]" + Strings.animated(Time.time, 4, 15f, ".") : lastText; float width = 100f; float visualFadeTime = 1f - Mathf.curve(1f - textFadeTime, 0.9f); font.setColor(1f, 1f, 1f, textFadeTime <= 0 || lastText == null ? 1f : visualFadeTime); diff --git a/core/src/mindustry/entities/comp/PuddleComp.java b/core/src/mindustry/entities/comp/PuddleComp.java index a447bd633a..720aee2f93 100644 --- a/core/src/mindustry/entities/comp/PuddleComp.java +++ b/core/src/mindustry/entities/comp/PuddleComp.java @@ -101,10 +101,10 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{ float sscl = 25f; Draw.color(tmp.set(liquid.color).shiftValue(-0.05f)); - Fill.circle(x + Mathf.sin(Time.time() + seeds * 532, sscl, smag), y + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 8f); + Fill.circle(x + Mathf.sin(Time.time + seeds * 532, sscl, smag), y + Mathf.sin(Time.time + seeds * 53, sscl, smag), f * 8f); Angles.randLenVectors(id(), 3, f * 6f, (ex, ey) -> { - Fill.circle(x + ex + Mathf.sin(Time.time() + seeds * 532, sscl, smag), - y + ey + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 5f); + Fill.circle(x + ex + Mathf.sin(Time.time + seeds * 532, sscl, smag), + y + ey + Mathf.sin(Time.time + seeds * 53, sscl, smag), f * 5f); seeds++; }); Draw.color(); diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 9451fc7278..b2f81d5526 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -90,8 +90,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I public float prefRotation(){ if(activelyBuilding()){ return angleTo(buildPlan()); - }else if(mineTile() != null){ - return angleTo(mineTile()); + }else if(mineTile != null){ + return angleTo(mineTile); }else if(moving()){ return vel().angle(); } @@ -310,7 +310,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I drag = type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f); //apply knockback based on spawns - if(team != state.rules.waveTeam && state.hasSpawns()){ + if(team != state.rules.waveTeam && state.hasSpawns() && (!net.client() || isLocal())){ float relativeSize = state.rules.dropZoneRadius + hitSize/2f + 1f; for(Tile spawn : spawner.getSpawns()){ if(within(spawn.worldx(), spawn.worldy(), relativeSize)){ @@ -397,9 +397,12 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I /** Actually destroys the unit, removing it and creating explosions. **/ public void destroy(){ - float explosiveness = 2f + item().explosiveness * stack().amount / 3f; - float flammability = item().flammability * stack().amount / 3f; - Damage.dynamicExplosion(x, y, flammability, explosiveness, 0f, bounds() / 2f, Pal.darkFlame, state.rules.damageExplosions); + float explosiveness = 2f + item().explosiveness * stack().amount * 1.53f; + float flammability = item().flammability * stack().amount / 1.9f; + + if(!spawnedByCore){ + Damage.dynamicExplosion(x, y, flammability, explosiveness, 0f, bounds() / 2f, state.rules.damageExplosions, item().flammability > 1, team); + } float shake = hitSize / 3f; @@ -415,7 +418,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I } //if this unit crash landed (was flying), damage stuff in a radius - if(type.flying){ + if(type.flying && !spawnedByCore){ Damage.damage(team,x, y, Mathf.pow(hitSize, 0.94f) * 1.25f, Mathf.pow(hitSize, 0.75f) * type.crashDamageMultiplier * 5f, true, false, true); } diff --git a/core/src/mindustry/game/EventType.java b/core/src/mindustry/game/EventType.java index f0aa3278b2..3fd2826cb5 100644 --- a/core/src/mindustry/game/EventType.java +++ b/core/src/mindustry/game/EventType.java @@ -278,11 +278,13 @@ public class EventType{ public static class BlockBuildBeginEvent{ public final Tile tile; public final Team team; + public final @Nullable Unit unit; public final boolean breaking; - public BlockBuildBeginEvent(Tile tile, Team team, boolean breaking){ + public BlockBuildBeginEvent(Tile tile, Team team, Unit unit, boolean breaking){ this.tile = tile; this.team = team; + this.unit = unit; this.breaking = breaking; } } @@ -310,10 +312,10 @@ public class EventType{ public static class BuildSelectEvent{ public final Tile tile; public final Team team; - public final Builderc builder; + public final Unit builder; public final boolean breaking; - public BuildSelectEvent(Tile tile, Team team, Builderc builder, boolean breaking){ + public BuildSelectEvent(Tile tile, Team team, Unit builder, boolean breaking){ this.tile = tile; this.team = team; this.builder = builder; diff --git a/core/src/mindustry/game/Objectives.java b/core/src/mindustry/game/Objectives.java index bf306cb957..31fc92e1b3 100644 --- a/core/src/mindustry/game/Objectives.java +++ b/core/src/mindustry/game/Objectives.java @@ -59,7 +59,7 @@ public class Objectives{ @Override public boolean complete(){ - return preset.sector.save != null && !preset.sector.isAttacked() && preset.sector.hasBase(); + return preset.sector.save != null && (!preset.sector.isAttacked() || preset.sector.info.wasCaptured) && preset.sector.hasBase(); } @Override diff --git a/core/src/mindustry/game/SectorInfo.java b/core/src/mindustry/game/SectorInfo.java index e8aa42262b..045d9aa2e9 100644 --- a/core/src/mindustry/game/SectorInfo.java +++ b/core/src/mindustry/game/SectorInfo.java @@ -23,6 +23,8 @@ public class SectorInfo{ /** Core input statistics. */ public ObjectMap production = new ObjectMap<>(); + /** Raw item production statistics. */ + public ObjectMap rawProduction = new ObjectMap<>(); /** Export statistics. */ public ObjectMap export = new ObjectMap<>(); /** Items stored in all cores. */ @@ -33,6 +35,8 @@ public class SectorInfo{ public int storageCapacity = 0; /** Whether a core is available here. */ public boolean hasCore = true; + /** Whether this sector was ever fully captured. */ + public boolean wasCaptured = false; /** Sector that was launched from. */ public @Nullable Sector origin; /** Launch destination. */ @@ -69,19 +73,27 @@ public class SectorInfo{ public boolean shown = false; /** Special variables for simulation. */ - public float sumHealth, sumRps, sumDps, waveHealthBase, waveHealthSlope, waveDpsBase, waveDpsSlope; + public float sumHealth, sumRps, sumDps, waveHealthBase, waveHealthSlope, waveDpsBase, waveDpsSlope, bossHealth, bossDps; + /** Wave where first boss shows up. */ + public int bossWave = -1; /** Counter refresh state. */ private transient Interval time = new Interval(); - /** Core item storage to prevent spoofing. */ - private transient int[] coreItemCounts; + /** Core item storage input/output deltas. */ + private @Nullable transient int[] coreDeltas; + /** Core item storage input/output deltas. */ + private @Nullable transient int[] productionDeltas; /** Handles core item changes. */ public void handleCoreItem(Item item, int amount){ - if(coreItemCounts == null){ - coreItemCounts = new int[content.items().size]; - } - coreItemCounts[item.id] += amount; + if(coreDeltas == null) coreDeltas = new int[content.items().size]; + coreDeltas[item.id] += amount; + } + + /** Handles raw production stats. */ + public void handleProduction(Item item, int amount){ + if(productionDeltas == null) productionDeltas = new int[content.items().size]; + productionDeltas[item.id] += amount; } /** @return the real location items go when launched on this sector */ @@ -172,6 +184,11 @@ public class SectorInfo{ damage = 0; hasSpawns = spawner.countSpawns() > 0; + //cap production at raw production. + production.each((item, stat) -> { + stat.mean = Math.min(stat.mean, rawProduction.get(item, ExportStat::new).mean); + }); + if(state.rules.sector != null){ state.rules.sector.saveInfo(); } @@ -185,8 +202,6 @@ public class SectorInfo{ //updating in multiplayer as a client doesn't make sense if(net.client()) return; - CoreBuild ent = state.rules.defaultTeam.core(); - //refresh throughput if(time.get(refreshPeriod)){ @@ -204,30 +219,34 @@ public class SectorInfo{ stat.mean = stat.means.rawMean(); }); - if(coreItemCounts == null){ - coreItemCounts = new int[content.items().size]; - } + if(coreDeltas == null) coreDeltas = new int[content.items().size]; + if(productionDeltas == null) productionDeltas = new int[content.items().size]; //refresh core items for(Item item : content.items()){ - ExportStat stat = production.get(item, ExportStat::new); - if(!stat.loaded){ - stat.means.fill(stat.mean); - stat.loaded = true; - } + updateDelta(item, production, coreDeltas); + updateDelta(item, rawProduction, productionDeltas); - //get item delta - int delta = coreItemCounts[item.id]; - - //store means - stat.means.add(delta); - stat.mean = stat.means.rawMean(); + production.get(item).mean = Math.min(production.get(item).mean, rawProduction.get(item).mean); } - Arrays.fill(coreItemCounts, 0); + Arrays.fill(coreDeltas, 0); + Arrays.fill(productionDeltas, 0); } } + void updateDelta(Item item, ObjectMap map, int[] deltas){ + ExportStat stat = map.get(item, ExportStat::new); + if(!stat.loaded){ + stat.means.fill(stat.mean); + stat.loaded = true; + } + + //store means + stat.means.add(deltas[item.id]); + stat.mean = stat.means.rawMean(); + } + public ObjectFloatMap exportRates(){ ObjectFloatMap map = new ObjectFloatMap<>(); export.each((item, value) -> map.put(item, value.mean)); diff --git a/core/src/mindustry/game/Universe.java b/core/src/mindustry/game/Universe.java index b57c1fe337..50f1f006d7 100644 --- a/core/src/mindustry/game/Universe.java +++ b/core/src/mindustry/game/Universe.java @@ -6,6 +6,7 @@ import arc.struct.*; import arc.util.*; import mindustry.content.*; import mindustry.game.EventType.*; +import mindustry.game.SectorInfo.*; import mindustry.maps.*; import mindustry.type.*; import mindustry.world.blocks.storage.*; @@ -180,6 +181,7 @@ public class Universe{ }else if(attacked && wavesPassed > 0 && sector.info.winWave > 1 && sector.info.wave + wavesPassed >= sector.info.winWave && !sector.hasEnemyBase()){ //autocapture the sector sector.info.waves = false; + sector.info.wasCaptured = true; //fire the event Events.fire(new SectorCaptureEvent(sector)); @@ -198,6 +200,13 @@ public class Universe{ } } + sector.info.export.each((item, amount) -> { + if(sector.info.items.get(item) <= 0 && sector.info.production.get(item, ExportStat::new).mean < 0){ + //disable export when production is negative. + sector.info.export.get(item).mean = 0f; + } + }); + //add production, making sure that it's capped sector.info.production.each((item, stat) -> sector.info.items.add(item, Math.min((int)(stat.mean * newSecondsPassed * scl), sector.info.storageCapacity - sector.info.items.get(item)))); //prevent negative values with unloaders @@ -216,9 +225,11 @@ public class Universe{ if(sector.isBeingPlayed()){ state.rules.winWave = waveMax; state.rules.waves = true; + state.rules.attackMode = false; }else{ sector.info.winWave = waveMax; sector.info.waves = true; + sector.info.attack = false; sector.saveInfo(); } diff --git a/core/src/mindustry/graphics/BlockRenderer.java b/core/src/mindustry/graphics/BlockRenderer.java index a5a78811f5..651e1d01d7 100644 --- a/core/src/mindustry/graphics/BlockRenderer.java +++ b/core/src/mindustry/graphics/BlockRenderer.java @@ -129,7 +129,7 @@ public class BlockRenderer implements Disposable{ if(!camera.bounds(Tmp.r1).grow(tilesize * 2f).overlaps(Tmp.r2.setSize(b.size * tilesize).setCenter(block.x * tilesize + b.offset, block.y * tilesize + b.offset))) continue; Draw.alpha(0.33f * brokenFade); - Draw.mixcol(Color.white, 0.2f + Mathf.absin(Time.globalTime(), 6f, 0.2f)); + Draw.mixcol(Color.white, 0.2f + Mathf.absin(Time.globalTime, 6f, 0.2f)); Draw.rect(b.icon(Cicon.full), block.x * tilesize + b.offset, block.y * tilesize + b.offset, b.rotate ? block.rotation * 90 : 0f); } Draw.reset(); diff --git a/core/src/mindustry/graphics/MenuRenderer.java b/core/src/mindustry/graphics/MenuRenderer.java index 87ab169670..efa42cfc89 100644 --- a/core/src/mindustry/graphics/MenuRenderer.java +++ b/core/src/mindustry/graphics/MenuRenderer.java @@ -257,11 +257,11 @@ public class MenuRenderer implements Disposable{ Draw.color(Pal.engine); Fill.circle(x + Angles.trnsx(rotation + 180, engineOffset), y + Angles.trnsy(rotation + 180, engineOffset), - engineSize + Mathf.absin(Time.time(), 2f, engineSize / 4f)); + engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f)); Draw.color(Color.white); Fill.circle(x + Angles.trnsx(rotation + 180, engineOffset - 1f), y + Angles.trnsy(rotation + 180, engineOffset - 1f), - (engineSize + Mathf.absin(Time.time(), 2f, engineSize / 4f)) / 2f); + (engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f)) / 2f); Draw.color(); Draw.rect(icon, x, y, flyerRot - 90); diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index 6cc1a1a851..40de5e0d63 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -89,7 +89,7 @@ public class OverlayRenderer{ } Lines.stroke(unitFade); - Lines.square(select.x, select.y, select.hitSize() * 1.5f, Time.time() * 2f); + Lines.square(select.x, select.y, select.hitSize() * 1.5f, Time.time * 2f); Draw.reset(); } @@ -112,14 +112,14 @@ public class OverlayRenderer{ if(dst < state.rules.enemyCoreBuildRadius * 2.2f){ Draw.color(Color.darkGray); Lines.circle(core.x, core.y - 2, state.rules.enemyCoreBuildRadius); - Draw.color(Pal.accent, core.team.color, 0.5f + Mathf.absin(Time.time(), 10f, 0.5f)); + Draw.color(Pal.accent, core.team.color, 0.5f + Mathf.absin(Time.time, 10f, 0.5f)); Lines.circle(core.x, core.y, state.rules.enemyCoreBuildRadius); } }); } Lines.stroke(2f); - Draw.color(Color.gray, Color.lightGray, Mathf.absin(Time.time(), 8f, 1f)); + Draw.color(Color.gray, Color.lightGray, Mathf.absin(Time.time, 8f, 1f)); if(state.hasSpawns()){ for(Tile tile : spawner.getSpawns()){ @@ -167,15 +167,15 @@ public class OverlayRenderer{ float size = 8; Draw.rect(player.unit().item().icon(Cicon.medium), v.x, v.y, size, size); Draw.color(Pal.accent); - Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time(), 5f, 1f)); + Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time, 5f, 1f)); Draw.reset(); Building tile = world.buildWorld(v.x, v.y); if(input.canDropItem() && tile != null && tile.interactable(player.team()) && tile.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(tile, itemTransferRange)){ Lines.stroke(3f, Pal.gray); - Lines.square(tile.x, tile.y, tile.block.size * tilesize / 2f + 3 + Mathf.absin(Time.time(), 5f, 1f)); + Lines.square(tile.x, tile.y, tile.block.size * tilesize / 2f + 3 + Mathf.absin(Time.time, 5f, 1f)); Lines.stroke(1f, Pal.place); - Lines.square(tile.x, tile.y, tile.block.size * tilesize / 2f + 2 + Mathf.absin(Time.time(), 5f, 1f)); + Lines.square(tile.x, tile.y, tile.block.size * tilesize / 2f + 2 + Mathf.absin(Time.time, 5f, 1f)); Draw.reset(); } diff --git a/core/src/mindustry/graphics/Shaders.java b/core/src/mindustry/graphics/Shaders.java index fbe0404b9f..ac3aef896c 100644 --- a/core/src/mindustry/graphics/Shaders.java +++ b/core/src/mindustry/graphics/Shaders.java @@ -66,7 +66,7 @@ public class Shaders{ public void apply(){ setUniformf("u_resolution", Core.graphics.getWidth(), Core.graphics.getHeight()); - setUniformf("u_time", Time.globalTime() / 10f); + setUniformf("u_time", Time.globalTime / 10f); setUniformf("u_campos", camera.position); setUniformf("u_rcampos", Tmp.v31.set(camera.position).sub(planet.position)); setUniformf("u_light", planet.getLightNormal()); @@ -174,7 +174,7 @@ public class Shaders{ setUniformf("u_color", color); setUniformf("u_uv", region.u, region.v); setUniformf("u_uv2", region.u2, region.v2); - setUniformf("u_time", Time.time()); + setUniformf("u_time", Time.time); setUniformf("u_texsize", region.texture.width, region.texture.height); } } @@ -188,7 +188,7 @@ public class Shaders{ @Override public void apply(){ setUniformf("u_dp", Scl.scl(1f)); - setUniformf("u_time", Time.time() / Scl.scl(1f)); + setUniformf("u_time", Time.time / Scl.scl(1f)); setUniformf("u_offset", Core.camera.position.x - Core.camera.width / 2, Core.camera.position.y - Core.camera.height / 2); @@ -216,7 +216,7 @@ public class Shaders{ setUniformf("u_campos", Core.camera.position.x, Core.camera.position.y); setUniformf("u_ccampos", Core.camera.position); setUniformf("u_resolution", Core.graphics.getWidth(), Core.graphics.getHeight()); - setUniformf("u_time", Time.time()); + setUniformf("u_time", Time.time); texture.bind(1); renderer.effectBuffer.getTexture().bind(0); @@ -240,7 +240,7 @@ public class Shaders{ public void apply(){ setUniformf("u_campos", Core.camera.position.x - Core.camera.width / 2, Core.camera.position.y - Core.camera.height / 2); setUniformf("u_resolution", Core.camera.width, Core.camera.height); - setUniformf("u_time", Time.time()); + setUniformf("u_time", Time.time); if(hasUniform("u_noise")){ Core.assets.get("sprites/noise.png", Texture.class).bind(1); diff --git a/core/src/mindustry/graphics/g3d/PlanetRenderer.java b/core/src/mindustry/graphics/g3d/PlanetRenderer.java index 46fcef4edf..9e70ced734 100644 --- a/core/src/mindustry/graphics/g3d/PlanetRenderer.java +++ b/core/src/mindustry/graphics/g3d/PlanetRenderer.java @@ -37,6 +37,7 @@ public class PlanetRenderer implements Disposable{ public final VertexBatch3D batch = new VertexBatch3D(20000, false, true, 0); public float zoom = 1f; + public float orbitAlpha = 1f; private final Mesh[] outlines = new Mesh[10]; public final PlaneBatch3D projector = new PlaneBatch3D(); @@ -168,7 +169,7 @@ public class PlanetRenderer implements Disposable{ Vec3 center = planet.parent.position; float radius = planet.orbitRadius; int points = (int)(radius * 10); - Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray)); + Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray.write(Tmp.c1).a(orbitAlpha))); batch.flush(Gl.lineLoop); } @@ -208,7 +209,7 @@ public class PlanetRenderer implements Disposable{ for(int i = 0; i < pointCount + 1; i++){ float f = i / (float)pointCount; - Tmp.c1.set(from).lerp(to, (f+Time.globalTime()/timeScale)%1f); + Tmp.c1.set(from).lerp(to, (f+ Time.globalTime /timeScale)%1f); batch.color(Tmp.c1); batch.vertex(Tmp.bz3.valueAt(Tmp.v32, f)); @@ -217,7 +218,7 @@ public class PlanetRenderer implements Disposable{ } public void drawBorders(Sector sector, Color base){ - Color color = Tmp.c1.set(base).a(base.a + 0.3f + Mathf.absin(Time.globalTime(), 5f, 0.3f)); + Color color = Tmp.c1.set(base).a(base.a + 0.3f + Mathf.absin(Time.globalTime, 5f, 0.3f)); float r1 = 1f; float r2 = outlineRad + 0.001f; diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index ddc84131ba..ad0e6b32f9 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -629,8 +629,8 @@ public class DesktopInput extends InputHandler{ unit.moveAt(movement); }else{ unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len())); - if(!movement.isZero() && ground){ - unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed); + if(!movement.isZero()){ + unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1)); } } diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 2df91588b6..bf6607b2fe 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -96,18 +96,17 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } @Remote(called = Loc.server, unreliable = true) - public static void transferItemTo(Item item, int amount, float x, float y, Building build){ + public static void setItem(Building build, Item item, int amount){ if(build == null || build.items == null) return; - for(int i = 0; i < Mathf.clamp(amount / 5, 1, 8); i++){ - Time.run(i * 3, () -> createItemTransfer(item, amount, x, y, build, () -> {})); - } - build.items.add(item, amount); + build.items.set(item, amount); } @Remote(called = Loc.server, unreliable = true) - public static void transferItemTo(Unit unit, Item item, int amount, float x, float y, Building build){ + public static void transferItemTo(@Nullable Unit unit, Item item, int amount, float x, float y, Building build){ if(build == null || build.items == null) return; - unit.stack.amount = Math.max(unit.stack.amount - amount, 0); + + if(unit != null && unit.item() == item) unit.stack.amount = Math.max(unit.stack.amount - amount, 0); + for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){ Time.run(i * 3, () -> createItemTransfer(item, amount, x, y, build, () -> {})); } @@ -750,7 +749,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ boolean valid = validPlace(request.x, request.y, request.block, request.rotation); Draw.reset(); - Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime(), 6f, 0.28f)); + Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime, 6f, 0.28f)); Draw.alpha(1f); request.block.drawRequestConfigTop(request, selectRequests); Draw.reset(); diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index 8baf077073..3c3fd8be76 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -376,8 +376,8 @@ public class MobileInput extends InputHandler implements GestureListener{ float radius = Interp.swingIn.apply(crosshairScale); - Lines.poly(target.getX(), target.getY(), 4, 7f * radius, Time.time() * 1.5f); - Lines.spikes(target.getX(), target.getY(), 3f * radius, 6f * radius, 4, Time.time() * 1.5f); + Lines.poly(target.getX(), target.getY(), 4, 7f * radius, Time.time * 1.5f); + Lines.spikes(target.getX(), target.getY(), 3f * radius, 6f * radius, 4, Time.time * 1.5f); } Draw.reset(); @@ -769,7 +769,7 @@ public class MobileInput extends InputHandler implements GestureListener{ @Override public boolean pan(float x, float y, float deltaX, float deltaY){ - if(Core.scene.hasDialog() || Core.settings.getBool("keyboard")) return false; + if(Core.scene == null || Core.scene.hasDialog() || Core.settings.getBool("keyboard")) return false; float scale = Core.camera.width / Core.graphics.getWidth(); deltaX *= scale; @@ -836,7 +836,7 @@ public class MobileInput extends InputHandler implements GestureListener{ if(type == null) return; boolean omni = unit.type.omniMovement; - boolean legs = unit.isGrounded(); + boolean ground = unit.isGrounded(); boolean allowHealing = type.canHeal; boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team && ((Building)target).damaged() && target.within(unit, type.range); @@ -908,8 +908,8 @@ public class MobileInput extends InputHandler implements GestureListener{ unit.moveAt(movement); }else{ unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len())); - if(!movement.isZero() && legs){ - unit.vel.rotateTo(movement.angle(), type.rotateSpeed); + if(!movement.isZero()){ + unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1)); } } diff --git a/core/src/mindustry/logic/LAssembler.java b/core/src/mindustry/logic/LAssembler.java index e06927cca2..560ac986ec 100644 --- a/core/src/mindustry/logic/LAssembler.java +++ b/core/src/mindustry/logic/LAssembler.java @@ -14,7 +14,7 @@ import mindustry.world.*; /** "Compiles" a sequence of statements into instructions. */ public class LAssembler{ public static ObjectMap> customParsers = new ObjectMap<>(); - public static final int maxTokenLength = 40; + public static final int maxTokenLength = 36; private int lastVar; /** Maps names to variable IDs. */ diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 244746ef81..e2498fd431 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -285,6 +285,8 @@ public class LExecutor{ exec.setnum(outX, cache.x); exec.setnum(outY, cache.y); } + }else{ + exec.setbool(outFound, false); } } diff --git a/core/src/mindustry/maps/SectorDamage.java b/core/src/mindustry/maps/SectorDamage.java index 187778e470..e2da570bf8 100644 --- a/core/src/mindustry/maps/SectorDamage.java +++ b/core/src/mindustry/maps/SectorDamage.java @@ -68,6 +68,11 @@ public class SectorDamage{ float enemyDps = info.waveDpsBase + info.waveDpsSlope * (i); float enemyHealth = info.waveHealthBase + info.waveHealthSlope * (i); + if(info.bossWave == i){ + enemyDps += info.bossDps; + enemyHealth += info.bossHealth; + } + //happens due to certain regressions if(enemyHealth < 0 || enemyDps < 0) continue; @@ -305,6 +310,7 @@ public class SectorDamage{ //calculate DPS and health for the next few waves and store in list var reg = new LinearRegression(); + SpawnGroup bossGroup = null; Seq waveDps = new Seq<>(), waveHealth = new Seq<>(); for(int wave = state.wave; wave < state.wave + 10; wave ++){ @@ -320,6 +326,11 @@ public class SectorDamage{ float healthMult = 1f + Mathf.clamp(group.type.armor / 20f); StatusEffect effect = (group.effect == null ? StatusEffects.none : group.effect); int spawned = group.getSpawned(wave); + //save the boss group + if(group.effect == StatusEffects.boss){ + bossGroup = group; + continue; + } if(spawned <= 0) continue; sumWaveHealth += spawned * (group.getShield(wave) + group.type.health * effect.healthMultiplier * healthMult); sumWaveDps += spawned * group.type.dpsEstimate * effect.damageMultiplier; @@ -328,6 +339,21 @@ public class SectorDamage{ waveHealth.add(new Vec2(wave, sumWaveHealth)); } + if(bossGroup != null){ + float bossMult = 1.1f; + //calculate first boss appearaance + for(int wave = state.wave; wave < state.wave + 60; wave++){ + int spawned = bossGroup.getSpawned(wave - 1); + if(spawned > 0){ + //set up relevant stats + info.bossWave = wave; + info.bossDps = spawned * bossGroup.type.dpsEstimate * StatusEffects.boss.damageMultiplier * bossMult; + info.bossHealth = spawned * (bossGroup.getShield(wave) + bossGroup.type.health * StatusEffects.boss.healthMultiplier * (1f + Mathf.clamp(bossGroup.type.armor / 20f))) * bossMult; + break; + } + } + } + //calculate linear regression of the wave data and store it reg.calculate(waveHealth); info.waveHealthBase = reg.intercept; @@ -338,9 +364,9 @@ public class SectorDamage{ info.waveDpsSlope = reg.slope; //enemy units like to aim for a lot of non-essential things, so increase resulting health slightly - info.sumHealth = sumHealth * 1.2f; + info.sumHealth = sumHealth * 1.05f; //players tend to have longer range units/turrets, so assume DPS is higher - info.sumDps = sumDps * 1.2f; + info.sumDps = sumDps * 1.05f; info.sumRps = sumRps; info.wavesSurvived = getWavesSurvived(info); @@ -356,7 +382,7 @@ public class SectorDamage{ for(Tile tile : tiles){ if((tile.block() instanceof CoreBlock && tile.team() == state.rules.waveTeam) || tile.overlay() == Blocks.spawn){ frontier.add(tile); - values[tile.x][tile.y] = fraction * 26; + values[tile.x][tile.y] = fraction * 24; } } diff --git a/core/src/mindustry/maps/planet/TantrosPlanetGenerator.java b/core/src/mindustry/maps/planet/TantrosPlanetGenerator.java index 934291dab8..d74f94e250 100644 --- a/core/src/mindustry/maps/planet/TantrosPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/TantrosPlanetGenerator.java @@ -3,6 +3,8 @@ package mindustry.maps.planet; import arc.graphics.*; import arc.math.*; import arc.math.geom.*; +import mindustry.content.*; +import mindustry.game.*; import mindustry.maps.generators.*; public class TantrosPlanetGenerator extends PlanetGenerator{ @@ -18,4 +20,13 @@ public class TantrosPlanetGenerator extends PlanetGenerator{ float depth = (float)noise.octaveNoise3D(2, 0.56, 1.7f, position.x, position.y, position.z) / 2f; return c1.write(out).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(0.6f); } + + @Override + protected void generate(){ + pass((x, y) -> { + floor = Blocks.deepwater; + }); + + Schematics.placeLaunchLoadout(width / 2, height / 2); + } } diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 5f2bbdb637..e95639ed2e 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -225,7 +225,7 @@ public class ContentParser{ currentContent = block; read(() -> { - if(value.has("consumes")){ + if(value.has("consumes") && value.get("consumes").isObject()){ for(JsonValue child : value.get("consumes")){ if(child.name.equals("item")){ block.consumes.item(find(ContentType.item, child.asString())); @@ -309,6 +309,10 @@ public class ContentParser{ } + if(value.has("controller")){ + unit.defaultController = make(resolve(value.getString("controller"), "mindustry.ai.type")); + } + //read extra default waves if(value.has("waves")){ JsonValue waves = value.remove("waves"); diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index f505358a40..a2706a0723 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -247,7 +247,7 @@ public class Mods implements Loadable{ mods.add(mod); }catch(Throwable e){ if(e instanceof ClassNotFoundException && e.getMessage().contains("mindustry.plugin.Plugin")){ - Log.info("Plugin @ is outdated and needs to be ported to 6.0! Update its main class to inherit from 'mindustry.mod.Plugin'."); + Log.info("Plugin @ is outdated and needs to be ported to 6.0! Update its main class to inherit from 'mindustry.mod.Plugin'. See https://mindustrygame.github.io/wiki/modding/6-migrationv6/"); }else{ Log.err("Failed to load mod file @. Skipping.", file); Log.err(e); diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index f5a40de645..57a5aba215 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -502,9 +502,9 @@ public class UnitType extends UnlockableContent{ //draw back items if(unit.item() != null && unit.itemTime > 0.01f){ - float size = (itemSize + Mathf.absin(Time.time(), 5f, 1f)) * unit.itemTime; + float size = (itemSize + Mathf.absin(Time.time, 5f, 1f)) * unit.itemTime; - Draw.mixcol(Pal.accent, Mathf.absin(Time.time(), 5f, 0.5f)); + Draw.mixcol(Pal.accent, Mathf.absin(Time.time, 5f, 0.5f)); Draw.rect(unit.item().icon(Cicon.medium), unit.x + Angles.trnsx(unit.rotation + 180f, itemOffsetY), unit.y + Angles.trnsy(unit.rotation + 180f, itemOffsetY), @@ -516,7 +516,7 @@ public class UnitType extends UnlockableContent{ Lines.circle( unit.x + Angles.trnsx(unit.rotation + 180f, itemOffsetY), unit.y + Angles.trnsy(unit.rotation + 180f, itemOffsetY), - (3f + Mathf.absin(Time.time(), 5f, 1f)) * unit.itemTime); + (3f + Mathf.absin(Time.time, 5f, 1f)) * unit.itemTime); if(unit.isLocal() && !renderer.pixelator.enabled()){ Fonts.outline.draw(unit.stack.amount + "", @@ -538,20 +538,20 @@ public class UnitType extends UnlockableContent{ if(unit instanceof Trailc){ Trail trail = ((Trailc)unit).trail(); - trail.draw(unit.team.color, (engineSize + Mathf.absin(Time.time(), 2f, engineSize / 4f) * scale) * trailScl); + trail.draw(unit.team.color, (engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f) * scale) * trailScl); } Draw.color(unit.team.color); Fill.circle( unit.x + Angles.trnsx(unit.rotation + 180, offset), unit.y + Angles.trnsy(unit.rotation + 180, offset), - (engineSize + Mathf.absin(Time.time(), 2f, engineSize / 4f)) * scale + (engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f)) * scale ); Draw.color(Color.white); Fill.circle( unit.x + Angles.trnsx(unit.rotation + 180, offset - 1f), unit.y + Angles.trnsy(unit.rotation + 180, offset - 1f), - (engineSize + Mathf.absin(Time.time(), 2f, engineSize / 4f)) / 2f * scale + (engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f)) / 2f * scale ); Draw.color(); } @@ -632,7 +632,7 @@ public class UnitType extends UnlockableContent{ } public Color cellColor(Unit unit){ - return Tmp.c1.set(Color.black).lerp(unit.team.color, unit.healthf() + Mathf.absin(Time.time(), Math.max(unit.healthf() * 5f, 1f), 1f - unit.healthf())); + return Tmp.c1.set(Color.black).lerp(unit.team.color, unit.healthf() + Mathf.absin(Time.time, Math.max(unit.healthf() * 5f, 1f), 1f - unit.healthf())); } public void drawLight(Unit unit){ diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index 348e70b7b2..ec0c00da14 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -13,7 +13,7 @@ import mindustry.io.*; public class Weapon{ /** displayed weapon region */ - public String name; + public String name = ""; /** bullet shot */ public BulletType bullet; /** shell ejection effect */ diff --git a/core/src/mindustry/type/Weather.java b/core/src/mindustry/type/Weather.java index 9daaf11087..3f815f03e8 100644 --- a/core/src/mindustry/type/Weather.java +++ b/core/src/mindustry/type/Weather.java @@ -19,9 +19,9 @@ import mindustry.world.blocks.*; import static mindustry.Vars.*; -public abstract class Weather extends UnlockableContent{ +public class Weather extends UnlockableContent{ /** Default duration of this weather event in ticks. */ - public float duration = 9f * Time.toMinutes; + public float duration = 10f * Time.toMinutes; public float opacityMultiplier = 1f; public Attributes attrs = new Attributes(); public Sound sound = Sounds.none; @@ -90,7 +90,7 @@ public abstract class Weather extends UnlockableContent{ } if(!headless && sound != Sounds.none){ - float noise = soundVolOscMag > 0 ? (float)Math.abs(Noise.rawNoise(Time.time() / soundVolOscScl)) * soundVolOscMag : 0; + float noise = soundVolOscMag > 0 ? (float)Math.abs(Noise.rawNoise(Time.time / soundVolOscScl)) * soundVolOscMag : 0; control.sound.loop(sound, Math.max((soundVol + noise) * state.opacity, soundVolMin)); } } @@ -120,8 +120,8 @@ public abstract class Weather extends UnlockableContent{ float scl = rand.random(0.5f, 1f); float scl2 = rand.random(0.5f, 1f); float size = rand.random(sizeMin, sizeMax); - float x = (rand.random(0f, world.unitWidth()) + Time.time() * windx * scl2); - float y = (rand.random(0f, world.unitHeight()) + Time.time() * windy * scl); + float x = (rand.random(0f, world.unitWidth()) + Time.time * windx * scl2); + float y = (rand.random(0f, world.unitHeight()) + Time.time * windy * scl); float alpha = rand.random(minAlpha, maxAlpha); x += Mathf.sin(y, rand.random(sinSclMin, sinSclMax), rand.random(sinMagMin, sinMagMax)); @@ -155,8 +155,8 @@ public abstract class Weather extends UnlockableContent{ float scl = rand.random(0.5f, 1f); float scl2 = rand.random(0.5f, 1f); float size = rand.random(sizeMin, sizeMax); - float x = (rand.random(0f, world.unitWidth()) + Time.time() * xspeed * scl2); - float y = (rand.random(0f, world.unitHeight()) - Time.time() * yspeed * scl); + float x = (rand.random(0f, world.unitWidth()) + Time.time * xspeed * scl2); + float y = (rand.random(0f, world.unitHeight()) - Time.time * yspeed * scl); float tint = rand.random(1f) * alpha; x -= Tmp.r1.x; @@ -180,7 +180,7 @@ public abstract class Weather extends UnlockableContent{ int total = (int)(Tmp.r1.area() / density * intensity) / 2; Lines.stroke(stroke); - float t = Time.time() / timeScale; + float t = Time.time / timeScale; for(int i = 0; i < total; i++){ float offset = rand.random(0f, 1f); @@ -227,7 +227,7 @@ public abstract class Weather extends UnlockableContent{ float windx = vwindx * speed, windy = vwindy * speed; float scale = 1f / noisescl; - float scroll = Time.time() * scale + offset; + float scroll = Time.time * scale + offset; Tmp.tr1.texture = noise; Core.camera.bounds(Tmp.r1); Tmp.tr1.set(Tmp.r1.x*scale, Tmp.r1.y*scale, (Tmp.r1.x + Tmp.r1.width)*scale, (Tmp.r1.y + Tmp.r1.height)*scale); @@ -262,7 +262,7 @@ public abstract class Weather extends UnlockableContent{ /** Creates a weather entry with some approximate weather values. */ public WeatherEntry(Weather weather){ - this(weather, weather.duration * 3f, weather.duration * 6f, weather.duration / 2f, weather.duration * 1.5f); + this(weather, weather.duration * 2f, weather.duration * 6f, weather.duration / 2f, weather.duration * 1.5f); } public WeatherEntry(Weather weather, float minFrequency, float maxFrequency, float minDuration, float maxDuration){ diff --git a/core/src/mindustry/ui/Bar.java b/core/src/mindustry/ui/Bar.java index 8e3bd511de..dbb7e9cc6f 100644 --- a/core/src/mindustry/ui/Bar.java +++ b/core/src/mindustry/ui/Bar.java @@ -29,7 +29,11 @@ public class Bar extends Element{ public Bar(Prov name, Prov color, Floatp fraction){ this.fraction = fraction; - lastValue = value = Mathf.clamp(fraction.get()); + try{ + lastValue = value = Mathf.clamp(fraction.get()); + }catch(Exception e){ //getting the fraction may involve referring to invalid data + lastValue = value = 0f; + } update(() -> { try{ this.name = name.get(); @@ -78,6 +82,9 @@ public class Bar extends Element{ lastValue = computed; } + if(Float.isNaN(computed)) computed = 0; + if(Float.isInfinite(computed)) computed = 1f; + blink = Mathf.lerpDelta(blink, 0f, 0.2f); value = Mathf.lerpDelta(value, computed, 0.15f); diff --git a/core/src/mindustry/ui/dialogs/JoinDialog.java b/core/src/mindustry/ui/dialogs/JoinDialog.java index fe5ea1bdaf..a0987c5a49 100644 --- a/core/src/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/mindustry/ui/dialogs/JoinDialog.java @@ -199,7 +199,7 @@ public class JoinDialog extends BaseDialog{ void refreshServer(Server server){ server.content.clear(); - server.content.label(() -> Core.bundle.get("server.refreshing") + Strings.animated(Time.time(), 4, 11, ".")); + server.content.label(() -> Core.bundle.get("server.refreshing") + Strings.animated(Time.time, 4, 11, ".")); net.pingHost(server.ip, server.port, host -> setupServer(server, host), e -> { server.content.clear(); @@ -340,7 +340,7 @@ public class JoinDialog extends BaseDialog{ local.clear(); local.background(null); - local.table(Tex.button, t -> t.label(() -> "[accent]" + Core.bundle.get("hosts.discovering.any") + Strings.animated(Time.time(), 4, 10f, ".")).pad(10f)).growX(); + local.table(Tex.button, t -> t.label(() -> "[accent]" + Core.bundle.get("hosts.discovering.any") + Strings.animated(Time.time, 4, 10f, ".")).pad(10f)).growX(); net.discoverServers(this::addLocalHost, this::finishLocalHosts); } diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index 866c3460e4..63b94b277b 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -102,12 +102,16 @@ public class ModsDialog extends BaseDialog{ t.button("@mod.import.github", Icon.github, bstyle, () -> { dialog.hide(); + var modString = Core.settings.getString("lastmod", ""); + var suggested = Structs.random(suggestedMods); - ui.showTextInput("@mod.import.github", "", 64, Core.settings.getString("lastmod", "Anuken/ExampleMod"), text -> { - Core.settings.put("lastmod", text); + ui.showTextInput("@mod.import.github", "", 64, modString.isEmpty() ? suggested : modString, text -> { + if(!modString.isEmpty() || !Structs.eq(suggested, text)){ + Core.settings.put("lastmod", text); + } ui.loadfrag.show(); - //Try to download the 6.0 branch first, but if it doesn't exist try master. + //Try to download the 6.0 branch first, but if it doesn't exist, try master. githubImport("6.0", text, e1 -> { githubImport("master", text, e2 -> { githubImport("main", text, e3 -> { diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index 347c18c4a2..710fc29895 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -287,7 +287,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ Color color = sec.hasBase() ? Tmp.c2.set(Team.sharded.color).lerp(Team.crux.color, sec.hasEnemyBase() ? 0.5f : 0f) : - sec.preset != null ? Tmp.c2.set(Team.derelict.color).lerp(Color.white, Mathf.absin(Time.time(), 10f, 1f)) : + sec.preset != null ? Tmp.c2.set(Team.derelict.color).lerp(Color.white, Mathf.absin(Time.time, 10f, 1f)) : sec.hasEnemyBase() ? Team.crux.color : null; @@ -409,6 +409,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ @Override public void draw(){ + planets.orbitAlpha = selectAlpha; planets.render(PlanetDialog.this); if(Core.scene.getDialog() == PlanetDialog.this){ Core.scene.setScrollFocus(PlanetDialog.this); @@ -562,7 +563,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ if(t.getChildren().any()){ c.add(name).left().row(); - c.add(t).padLeft(10f).row(); + c.add(t).padLeft(10f).left().row(); } }; @@ -626,6 +627,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ Table stable = sectorTop; if(sector == null){ + stable.clear(); return; } @@ -711,6 +713,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ stable.table(t -> { t.add("@sectors.resources").padRight(4); for(UnlockableContent c : sector.info.resources){ + if(c == null) continue; //apparently this is possible. t.image(c.icon(Cicon.small)).padRight(3).size(Cicon.small.size); } }).padLeft(10f).fillX().row(); diff --git a/core/src/mindustry/ui/dialogs/ResearchDialog.java b/core/src/mindustry/ui/dialogs/ResearchDialog.java index bb609cb167..49701dbe76 100644 --- a/core/src/mindustry/ui/dialogs/ResearchDialog.java +++ b/core/src/mindustry/ui/dialogs/ResearchDialog.java @@ -257,18 +257,6 @@ public class ResearchDialog extends BaseDialog{ return node.content.unlocked() || !node.objectives.contains(i -> !i.complete()); } - public void showToast(String info){ - Table table = new Table(); - table.actions(Actions.fadeOut(0.5f, Interp.fade), Actions.remove()); - table.top().add(info); - table.name = "toast"; - table.update(() -> { - table.toFront(); - table.setPosition(Core.graphics.getWidth() / 2f, Core.graphics.getHeight() - 21, Align.top); - }); - Core.scene.add(table); - } - boolean locked(TechNode node){ return node.content.locked(); } @@ -451,7 +439,6 @@ public class ResearchDialog extends BaseDialog{ void unlock(TechNode node){ node.content.unlock(); - showToast(Core.bundle.format("researched", node.content.localizedName)); checkNodes(root); hoverNode = null; treeLayout(); diff --git a/core/src/mindustry/ui/fragments/HudFragment.java b/core/src/mindustry/ui/fragments/HudFragment.java index 685cdd6e88..dc9620fb42 100644 --- a/core/src/mindustry/ui/fragments/HudFragment.java +++ b/core/src/mindustry/ui/fragments/HudFragment.java @@ -275,7 +275,7 @@ public class HudFragment extends Fragment{ t.name = "nearpoint"; t.touchable = Touchable.disabled; t.table(Styles.black, c -> c.add("@nearpoint") - .update(l -> l.setColor(Tmp.c1.set(Color.white).lerp(Color.scarlet, Mathf.absin(Time.time(), 10f, 1f)))) + .update(l -> l.setColor(Tmp.c1.set(Color.white).lerp(Color.scarlet, Mathf.absin(Time.time, 10f, 1f)))) .get().setAlignment(Align.center, Align.center)) .margin(6).update(u -> u.color.a = Mathf.lerpDelta(u.color.a, Mathf.num(spawner.playerNear()), 0.1f)).get().color.a = 0f; }); @@ -317,7 +317,7 @@ public class HudFragment extends Fragment{ return coreAttackOpacity[0] > 0; }); t.table(Tex.button, top -> top.add("@coreattack").pad(2) - .update(label -> label.color.set(Color.orange).lerp(Color.scarlet, Mathf.absin(Time.time(), 2f, 1f)))).touchable(Touchable.disabled); + .update(label -> label.color.set(Color.orange).lerp(Color.scarlet, Mathf.absin(Time.time, 2f, 1f)))).touchable(Touchable.disabled); }); //'saving' indicator diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 6eec5c2b20..5e38bfa8a8 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -392,7 +392,7 @@ public class Block extends UnlockableContent{ public void drawRequest(BuildPlan req, Eachable list, boolean valid){ Draw.reset(); - Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime(), 6f, 0.28f)); + Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime, 6f, 0.28f)); Draw.alpha(1f); float prevScale = Draw.scl; Draw.scl *= req.animScale; diff --git a/core/src/mindustry/world/Build.java b/core/src/mindustry/world/Build.java index 70e6bb653b..86cca0d3d7 100644 --- a/core/src/mindustry/world/Build.java +++ b/core/src/mindustry/world/Build.java @@ -20,7 +20,7 @@ public class Build{ private static final IntSet tmp = new IntSet(); @Remote(called = Loc.server) - public static void beginBreak(Team team, int x, int y){ + public static void beginBreak(@Nullable Unit unit, Team team, int x, int y){ if(!validBreak(team, x, y)){ return; } @@ -40,14 +40,14 @@ public class Build{ tile.setBlock(sub, team, rotation); tile.bc().setDeconstruct(previous); tile.build.health = tile.build.maxHealth * prevPercent; + if(unit != null && unit.isPlayer()) tile.build.lastAccessed = unit.getPlayer().name; - - Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, true))); + Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, unit, true))); } /** Places a ConstructBlock at this location. */ @Remote(called = Loc.server) - public static void beginPlace(Block result, Team team, int x, int y, int rotation){ + public static void beginPlace(@Nullable Unit unit, Block result, Team team, int x, int y, int rotation){ if(!validPlace(result, team, x, y, rotation)){ return; } @@ -57,6 +57,15 @@ public class Build{ //just in case if(tile == null) return; + //auto-rotate the block to the correct orientation and bail out + if(tile.team() == team && tile.block == result && tile.build != null && tile.block.quickRotate){ + if(unit != null && unit.isPlayer()) tile.build.lastAccessed = unit.getPlayer().name; + tile.build.rotation = Mathf.mod(rotation, 4); + tile.build.updateProximity(); + tile.build.noSleep(); + return; + } + Block previous = tile.block(); Block sub = ConstructBlock.get(result.size); Seq prevBuild = new Seq<>(9); @@ -76,10 +85,11 @@ public class Build{ build.setConstruct(previous.size == sub.size ? previous : Blocks.air, result); build.prevBuild = prevBuild; + if(unit != null && unit.isPlayer()) build.lastAccessed = unit.getPlayer().name; result.placeBegan(tile, previous); - Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, false))); + Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, unit, false))); } /** Returns whether a tile can be placed at this location by this team. */ diff --git a/core/src/mindustry/world/DirectionalItemBuffer.java b/core/src/mindustry/world/DirectionalItemBuffer.java index 4b7a7bca2f..48cbdc84c0 100644 --- a/core/src/mindustry/world/DirectionalItemBuffer.java +++ b/core/src/mindustry/world/DirectionalItemBuffer.java @@ -23,7 +23,7 @@ public class DirectionalItemBuffer{ public void accept(int buffer, Item item){ if(!accepts(buffer)) return; - buffers[buffer][indexes[buffer]++] = BufferItem.get((byte)item.id, Time.time()); + buffers[buffer][indexes[buffer]++] = BufferItem.get((byte)item.id, Time.time); } public Item poll(int buffer, float speed){ @@ -31,7 +31,7 @@ public class DirectionalItemBuffer{ long l = buffers[buffer][0]; float time = BufferItem.time(l); - if(Time.time() >= time + speed || Time.time() < time){ + if(Time.time >= time + speed || Time.time < time){ return content.item(BufferItem.item(l)); } } diff --git a/core/src/mindustry/world/ItemBuffer.java b/core/src/mindustry/world/ItemBuffer.java index 6ab014bd2f..e9001ac534 100644 --- a/core/src/mindustry/world/ItemBuffer.java +++ b/core/src/mindustry/world/ItemBuffer.java @@ -20,7 +20,7 @@ public class ItemBuffer{ public void accept(Item item, short data){ //if(!accepts()) return; - buffer[index++] = Pack.longInt(Float.floatToIntBits(Time.time()), Pack.shortInt(item.id, data)); + buffer[index++] = Pack.longInt(Float.floatToIntBits(Time.time), Pack.shortInt(item.id, data)); } public void accept(Item item){ @@ -32,7 +32,7 @@ public class ItemBuffer{ long l = buffer[0]; float time = Float.intBitsToFloat(Pack.leftInt(l)); - if(Time.time() >= time + speed || Time.time() < time){ + if(Time.time >= time + speed || Time.time < time){ return content.item(Pack.leftShort(Pack.rightInt(l))); } } diff --git a/core/src/mindustry/world/Tile.java b/core/src/mindustry/world/Tile.java index e8a27b7c05..b91b26d699 100644 --- a/core/src/mindustry/world/Tile.java +++ b/core/src/mindustry/world/Tile.java @@ -103,6 +103,28 @@ public class Tile implements Position, QuadTreeObject, Displayable{ return -1; } + /** + * Returns the flammability of the Used for fire calculations. + * Takes flammability of floor liquid into account. + */ + public float getFlammability(){ + if(!block.hasItems){ + if(floor.liquidDrop != null && !block.solid){ + return floor.liquidDrop.flammability; + } + return 0; + }else if(build != null){ + float result = build.items.sum((item, amount) -> item.flammability * amount); + + if(block.hasLiquids){ + result += build.liquids.sum((liquid, amount) -> liquid.flammability * amount / 3f); + } + + return result; + } + return 0; + } + /** Convenience method that returns the building of this tile with a cast. * Method name is shortened to prevent conflict. */ @SuppressWarnings("unchecked") diff --git a/core/src/mindustry/world/blocks/ConstructBlock.java b/core/src/mindustry/world/blocks/ConstructBlock.java index 871e43a898..c99f36f36b 100644 --- a/core/src/mindustry/world/blocks/ConstructBlock.java +++ b/core/src/mindustry/world/blocks/ConstructBlock.java @@ -19,6 +19,7 @@ import mindustry.graphics.*; import mindustry.type.*; import mindustry.ui.*; import mindustry.world.*; +import mindustry.world.blocks.storage.CoreBlock.*; import mindustry.world.modules.*; import static mindustry.Vars.*; @@ -275,8 +276,9 @@ public class ConstructBlock extends Block{ if(clampedAmount > 0 && accumulated > 0){ //if it's positive, add it to the core if(core != null && requirements[i].item.unlockedNow()){ //only accept items that are unlocked - int accepting = core.acceptStack(requirements[i].item, accumulated, builder); - core.handleStack(requirements[i].item, accepting, builder); + int accepting = Math.min(accumulated, ((CoreBuild)core).storageCapacity - core.items.get(requirements[i].item)); + //transfer items directly, as this is not production. + core.items.add(requirements[i].item, accepting); accumulator[i] -= accepting; }else{ accumulator[i] -= accumulated; diff --git a/core/src/mindustry/world/blocks/campaign/Accelerator.java b/core/src/mindustry/world/blocks/campaign/Accelerator.java index 7c8359a6bf..9fc423509e 100644 --- a/core/src/mindustry/world/blocks/campaign/Accelerator.java +++ b/core/src/mindustry/world/blocks/campaign/Accelerator.java @@ -51,7 +51,7 @@ public class Accelerator extends Block{ for(int l = 0; l < 4; l++){ float length = 7f + l * 5f; - Draw.color(team.color, Pal.darkMetal, Mathf.absin(Time.time() + l*50f, 10f, 1f)); + Draw.color(team.color, Pal.darkMetal, Mathf.absin(Time.time + l*50f, 10f, 1f)); for(int i = 0; i < 4; i++){ float rot = i*90f + 45f; @@ -67,13 +67,13 @@ public class Accelerator extends Block{ Lines.square(x, y, rad * 1.22f, 45f); Lines.stroke(3f, Pal.accent); - Lines.square(x, y, rad, Time.time() / scl); - Lines.square(x, y, rad, -Time.time() / scl); + Lines.square(x, y, rad, Time.time / scl); + Lines.square(x, y, rad, -Time.time / scl); Draw.color(team.color); for(int i = 0; i < 4; i++){ - float rot = i*90f + 45f + (-Time.time()/3f)%360f; + float rot = i*90f + 45f + (-Time.time /3f)%360f; float length = 26f; Draw.rect(arrowRegion, x + Angles.trnsx(rot, length), y + Angles.trnsy(rot, length), rot + 180f); } diff --git a/core/src/mindustry/world/blocks/campaign/LaunchPad.java b/core/src/mindustry/world/blocks/campaign/LaunchPad.java index d72c1f133a..ef60f9a482 100644 --- a/core/src/mindustry/world/blocks/campaign/LaunchPad.java +++ b/core/src/mindustry/world/blocks/campaign/LaunchPad.java @@ -56,6 +56,11 @@ public class LaunchPad extends Block{ bars.add("items", entity -> new Bar(() -> Core.bundle.format("bar.items", entity.items.total()), () -> Pal.items, () -> (float)entity.items.total() / itemCapacity)); } + @Override + public boolean outputsItems(){ + return false; + } + public class LaunchPadBuild extends Building{ @Override diff --git a/core/src/mindustry/world/blocks/defense/MendProjector.java b/core/src/mindustry/world/blocks/defense/MendProjector.java index 1c0231f434..25a4c64544 100644 --- a/core/src/mindustry/world/blocks/defense/MendProjector.java +++ b/core/src/mindustry/world/blocks/defense/MendProjector.java @@ -104,10 +104,10 @@ public class MendProjector extends Block{ public void draw(){ super.draw(); - float f = 1f - (Time.time() / 100f) % 1f; + float f = 1f - (Time.time / 100f) % 1f; Draw.color(baseColor, phaseColor, phaseHeat); - Draw.alpha(heat * Mathf.absin(Time.time(), 10f, 1f) * 0.5f); + Draw.alpha(heat * Mathf.absin(Time.time, 10f, 1f) * 0.5f); Draw.rect(topRegion, x, y); Draw.alpha(1f); Lines.stroke((2f * f + 0.2f) * heat); diff --git a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java index cc2c60288e..ad845991c7 100644 --- a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java @@ -114,10 +114,10 @@ public class OverdriveProjector extends Block{ public void draw(){ super.draw(); - float f = 1f - (Time.time() / 100f) % 1f; + float f = 1f - (Time.time / 100f) % 1f; Draw.color(baseColor, phaseColor, phaseHeat); - Draw.alpha(heat * Mathf.absin(Time.time(), 10f, 1f) * 0.5f); + Draw.alpha(heat * Mathf.absin(Time.time, 10f, 1f) * 0.5f); Draw.rect(topRegion, x, y); Draw.alpha(1f); Lines.stroke((2f * f + 0.1f) * heat); diff --git a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java index e10b1612e9..44d4f63f93 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java @@ -11,7 +11,7 @@ import mindustry.world.meta.*; import static mindustry.Vars.*; -public abstract class BaseTurret extends Block{ +public class BaseTurret extends Block{ public float range = 80f; public float rotateSpeed = 5; diff --git a/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java index 33538771a1..bc172e9c46 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java @@ -9,7 +9,7 @@ import mindustry.world.meta.values.*; import static mindustry.Vars.*; -public abstract class ReloadTurret extends BaseTurret{ +public class ReloadTurret extends BaseTurret{ public float reloadTime = 10f; public ReloadTurret(String name){ diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 4572852eb2..4409fa6533 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -27,7 +27,7 @@ import mindustry.world.meta.*; import static mindustry.Vars.*; -public abstract class Turret extends ReloadTurret{ +public class Turret extends ReloadTurret{ //after being logic-controlled and this amount of time passes, the turret will resume normal AI public final static float logicControlCooldown = 60 * 2; diff --git a/core/src/mindustry/world/blocks/distribution/Conveyor.java b/core/src/mindustry/world/blocks/distribution/Conveyor.java index b3218ea7be..23fa7a2a46 100644 --- a/core/src/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/mindustry/world/blocks/distribution/Conveyor.java @@ -114,7 +114,7 @@ public class Conveyor extends Block implements Autotiler{ @Override public void draw(){ - int frame = enabled && clogHeat <= 0.5f ? (int)(((Time.time() * speed * 8f * timeScale())) % 4) : 0; + int frame = enabled && clogHeat <= 0.5f ? (int)(((Time.time * speed * 8f * timeScale())) % 4) : 0; //draw extra conveyors facing this one for non-square tiling purposes Draw.z(Layer.blockUnder); @@ -311,7 +311,7 @@ public class Conveyor extends Block implements Autotiler{ if(len >= capacity) return false; Tile facing = Edges.getFacingEdge(source.tile, tile); int direction = Math.abs(facing.relativeTo(tile.x, tile.y) - rotation); - return (((direction == 0) && minitem >= itemSpace) || ((direction % 2 == 1) && minitem > 0.7f)) && !(source.block.rotate && (source.rotation + 2) % 4 == rotation); + return (((direction == 0) && minitem >= itemSpace) || ((direction % 2 == 1) && minitem > 0.7f)) && !(source.block.rotate && next == source); } @Override diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index 6e310d0e55..1cad3c94be 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -93,7 +93,7 @@ public class ItemBridge extends Block{ Draw.reset(); Draw.color(Pal.placing); Lines.stroke(1f); - if(link != null){ + if(link != null && Math.abs(link.x - x) + Math.abs(link.y - y) > 1){ int rot = link.absoluteRelativeTo(x, y); float w = (link.x == x ? tilesize : Math.abs(link.x - x) * tilesize - tilesize); float h = (link.y == y ? tilesize : Math.abs(link.y - y) * tilesize - tilesize); @@ -145,7 +145,7 @@ public class ItemBridge extends Block{ if(config != null) return; Tile link = findLink(tile.x, tile.y); - if(linkValid(tile, link)){ + if(linkValid(tile, link) && !proximity.contains(link.build)){ link.build.configure(tile.pos()); } @@ -170,7 +170,7 @@ public class ItemBridge extends Block{ Tmp.v2.trns(tile.angleTo(other), 2f); float tx = tile.drawx(), ty = tile.drawy(); float ox = other.drawx(), oy = other.drawy(); - float alpha = Math.abs((linked ? 100 : 0)-(Time.time() * 2f) % 100f) / 100f; + float alpha = Math.abs((linked ? 100 : 0)-(Time.time * 2f) % 100f) / 100f; float x = Mathf.lerp(ox, tx, alpha); float y = Mathf.lerp(oy, ty, alpha); @@ -207,7 +207,7 @@ public class ItemBridge extends Block{ boolean linked = other.pos() == link; Drawf.select(other.drawx(), other.drawy(), - other.block().size * tilesize / 2f + 2f + (linked ? 0f : Mathf.absin(Time.time(), 4f, 1f)), linked ? Pal.place : Pal.breakInvalid); + other.block().size * tilesize / 2f + 2f + (linked ? 0f : Mathf.absin(Time.time, 4f, 1f)), linked ? Pal.place : Pal.breakInvalid); } } } @@ -298,7 +298,7 @@ public class ItemBridge extends Block{ int i = relativeTo(other.x, other.y); - Draw.color(Color.white, Color.black, Mathf.absin(Time.time(), 6f, 0.07f)); + Draw.color(Color.white, Color.black, Mathf.absin(Time.time, 6f, 0.07f)); Draw.alpha(Math.max(uptime, 0.25f) * opacity); Draw.rect(endRegion, x, y, i * 90 + 90); diff --git a/core/src/mindustry/world/blocks/distribution/Junction.java b/core/src/mindustry/world/blocks/distribution/Junction.java index 4f8b3a9869..a60e13fb2b 100644 --- a/core/src/mindustry/world/blocks/distribution/Junction.java +++ b/core/src/mindustry/world/blocks/distribution/Junction.java @@ -44,7 +44,7 @@ public class Junction extends Block{ long l = buffer.buffers[i][0]; float time = BufferItem.time(l); - if(Time.time() >= time + speed / timeScale || Time.time() < time){ + if(Time.time >= time + speed / timeScale || Time.time < time){ Item item = content.item(BufferItem.item(l)); Building dest = nearby(i); diff --git a/core/src/mindustry/world/blocks/distribution/MassDriver.java b/core/src/mindustry/world/blocks/distribution/MassDriver.java index 9191e7dfe1..c1824c7414 100644 --- a/core/src/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/mindustry/world/blocks/distribution/MassDriver.java @@ -65,7 +65,7 @@ public class MassDriver extends Block{ if(selected == null || !(selected.block instanceof MassDriver) || !(selected.within(x * tilesize, y * tilesize, range))) return; //if so, draw a dotted line towards it while it is in range - float sin = Mathf.absin(Time.time(), 6f, 1f); + float sin = Mathf.absin(Time.time, 6f, 1f); Tmp.v1.set(x * tilesize + offset, y * tilesize + offset).sub(selected.x, selected.y).limit((size / 2f + 1) * tilesize + sin + 0.5f); float x2 = x * tilesize - Tmp.v1.x, y2 = y * tilesize - Tmp.v1.y, x1 = selected.x + Tmp.v1.x, y1 = selected.y + Tmp.v1.y; @@ -202,7 +202,7 @@ public class MassDriver extends Block{ @Override public void drawConfigure(){ - float sin = Mathf.absin(Time.time(), 6f, 1f); + float sin = Mathf.absin(Time.time, 6f, 1f); Draw.color(Pal.accent); Lines.stroke(1f); diff --git a/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java b/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java index c2c014d969..122278238a 100644 --- a/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java @@ -204,7 +204,7 @@ public class PayloadConveyor extends Block{ } public float time(){ - return Time.time(); + return Time.time; } @Override @@ -234,6 +234,12 @@ public class PayloadConveyor extends Block{ updatePayload(); } + @Override + public void onRemoved(){ + super.onRemoved(); + if(item != null) item.dump(); + } + @Override public void write(Writes write){ super.write(write); diff --git a/core/src/mindustry/world/blocks/environment/OverlayFloor.java b/core/src/mindustry/world/blocks/environment/OverlayFloor.java index 4c57943aed..c20eccceaf 100644 --- a/core/src/mindustry/world/blocks/environment/OverlayFloor.java +++ b/core/src/mindustry/world/blocks/environment/OverlayFloor.java @@ -4,7 +4,7 @@ import arc.graphics.g2d.*; import arc.math.*; import mindustry.world.*; -/**A type of floor that is overlaid on top of over floors.*/ +/**A type of floor that is overlaid on top of other floors.*/ public class OverlayFloor extends Floor{ public OverlayFloor(String name){ diff --git a/core/src/mindustry/world/blocks/environment/TreeBlock.java b/core/src/mindustry/world/blocks/environment/TreeBlock.java index cd199d8d25..d0354c2811 100644 --- a/core/src/mindustry/world/blocks/environment/TreeBlock.java +++ b/core/src/mindustry/world/blocks/environment/TreeBlock.java @@ -22,7 +22,7 @@ public class TreeBlock extends Block{ public void drawBase(Tile tile){ float x = tile.worldx(), y = tile.worldy(); - float rot = Mathf.randomSeed(tile.pos(), 0, 4) * 90 + Mathf.sin(Time.time() + x, 50f, 0.5f) + Mathf.sin(Time.time() - y, 65f, 0.9f) + Mathf.sin(Time.time() + y - x, 85f, 0.9f); + float rot = Mathf.randomSeed(tile.pos(), 0, 4) * 90 + Mathf.sin(Time.time + x, 50f, 0.5f) + Mathf.sin(Time.time - y, 65f, 0.9f) + Mathf.sin(Time.time + y - x, 85f, 0.9f); float w = region.width * Draw.scl, h = region.height * Draw.scl; float scl = 30f, mag = 0.2f; @@ -34,8 +34,8 @@ public class TreeBlock extends Block{ Draw.z(Layer.power + 1); Draw.rectv(region, x, y, w, h, rot, vec -> { vec.add( - Mathf.sin(vec.y*3 + Time.time(), scl, mag) + Mathf.sin(vec.x*3 - Time.time(), 70, 0.8f), - Mathf.cos(vec.x*3 + Time.time() + 8, scl + 6f, mag * 1.1f) + Mathf.sin(vec.y*3 - Time.time(), 50, 0.2f) + Mathf.sin(vec.y*3 + Time.time, scl, mag) + Mathf.sin(vec.x*3 - Time.time, 70, 0.8f), + Mathf.cos(vec.x*3 + Time.time + 8, scl + 6f, mag * 1.1f) + Mathf.sin(vec.y*3 - Time.time, 50, 0.2f) ); }); } diff --git a/core/src/mindustry/world/blocks/power/ImpactReactor.java b/core/src/mindustry/world/blocks/power/ImpactReactor.java index dec8e52702..156e5c13ce 100644 --- a/core/src/mindustry/world/blocks/power/ImpactReactor.java +++ b/core/src/mindustry/world/blocks/power/ImpactReactor.java @@ -101,12 +101,12 @@ public class ImpactReactor extends PowerGenerator{ Draw.rect(bottomRegion, x, y); for(int i = 0; i < plasmaRegions.length; i++){ - float r = size * tilesize - 3f + Mathf.absin(Time.time(), 2f + i * 1f, 5f - i * 0.5f); + float r = size * tilesize - 3f + Mathf.absin(Time.time, 2f + i * 1f, 5f - i * 0.5f); Draw.color(plasma1, plasma2, (float)i / plasmaRegions.length); - Draw.alpha((0.3f + Mathf.absin(Time.time(), 2f + i * 2f, 0.3f + i * 0.05f)) * warmup); + Draw.alpha((0.3f + Mathf.absin(Time.time, 2f + i * 2f, 0.3f + i * 0.05f)) * warmup); Draw.blend(Blending.additive); - Draw.rect(plasmaRegions[i], x, y, r, r, Time.time() * (12 + i * 6f) * warmup); + Draw.rect(plasmaRegions[i], x, y, r, r, Time.time * (12 + i * 6f) * warmup); Draw.blend(); } diff --git a/core/src/mindustry/world/blocks/power/ItemLiquidGenerator.java b/core/src/mindustry/world/blocks/power/ItemLiquidGenerator.java index 2a0982a069..16cd34fb7b 100644 --- a/core/src/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -164,7 +164,7 @@ public class ItemLiquidGenerator extends PowerGenerator{ if(hasItems){ Draw.color(heatColor); - Draw.alpha(heat * 0.4f + Mathf.absin(Time.time(), 8f, 0.6f) * heat); + Draw.alpha(heat * 0.4f + Mathf.absin(Time.time, 8f, 0.6f) * heat); Draw.rect(topRegion, x, y); Draw.reset(); } diff --git a/core/src/mindustry/world/blocks/power/PowerBlock.java b/core/src/mindustry/world/blocks/power/PowerBlock.java index e71c17aba7..4aad16ec6e 100644 --- a/core/src/mindustry/world/blocks/power/PowerBlock.java +++ b/core/src/mindustry/world/blocks/power/PowerBlock.java @@ -3,7 +3,7 @@ package mindustry.world.blocks.power; import mindustry.world.*; import mindustry.world.meta.*; -public abstract class PowerBlock extends Block{ +public class PowerBlock extends Block{ public PowerBlock(String name){ super(name); diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 4883206e25..f744dbe0b5 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -362,7 +362,7 @@ public class PowerNode extends PowerBlock{ @Override public void drawConfigure(){ - Drawf.circles(x, y, tile.block().size * tilesize / 2f + 1f + Mathf.absin(Time.time(), 4f, 1f)); + Drawf.circles(x, y, tile.block().size * tilesize / 2f + 1f + Mathf.absin(Time.time, 4f, 1f)); Drawf.circles(x, y, laserRange * tilesize); for(int x = (int)(tile.x - laserRange - 2); x <= tile.x + laserRange + 2; x++){ diff --git a/core/src/mindustry/world/blocks/production/Cultivator.java b/core/src/mindustry/world/blocks/production/Cultivator.java index a5aede4e25..5949d7b947 100644 --- a/core/src/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/mindustry/world/blocks/production/Cultivator.java @@ -78,7 +78,7 @@ public class Cultivator extends GenericCrafter{ for(int i = 0; i < 12; i++){ float offset = random.nextFloat() * 999999f; float x = random.range(4f), y = random.range(4f); - float life = 1f - (((Time.time() + offset) / 50f) % recurrence); + float life = 1f - (((Time.time + offset) / 50f) % recurrence); if(life > 0){ Lines.stroke(warmup * (life * 1f + 0.2f)); diff --git a/core/src/mindustry/world/blocks/production/Drill.java b/core/src/mindustry/world/blocks/production/Drill.java index cc0c14b278..d2ffceb033 100644 --- a/core/src/mindustry/world/blocks/production/Drill.java +++ b/core/src/mindustry/world/blocks/production/Drill.java @@ -259,7 +259,7 @@ public class Drill extends Block{ progress += delta() * dominantItems * speed * warmup; if(Mathf.chanceDelta(updateEffectChance * warmup)) - updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f)); + updateEffect.at(x + Mathf.range(size * 2f), y + Mathf.range(size * 2f)); }else{ lastDrillSpeed = 0f; warmup = Mathf.lerpDelta(warmup, 0f, warmupSpeed); @@ -274,7 +274,7 @@ public class Drill extends Block{ index ++; progress %= delay; - drillEffect.at(getX() + Mathf.range(size), getY() + Mathf.range(size), dominantItem.color); + drillEffect.at(x + Mathf.range(size), y + Mathf.range(size), dominantItem.color); } } @@ -291,7 +291,7 @@ public class Drill extends Block{ if(drawRim){ Draw.color(heatColor); - Draw.alpha(warmup * ts * (1f - s + Mathf.absin(Time.time(), 3f, s))); + Draw.alpha(warmup * ts * (1f - s + Mathf.absin(Time.time, 3f, s))); Draw.blend(Blending.additive); Draw.rect(rimRegion, x, y); Draw.blend(); diff --git a/core/src/mindustry/world/blocks/production/GenericSmelter.java b/core/src/mindustry/world/blocks/production/GenericSmelter.java index c96e1018dc..57108317ed 100644 --- a/core/src/mindustry/world/blocks/production/GenericSmelter.java +++ b/core/src/mindustry/world/blocks/production/GenericSmelter.java @@ -30,13 +30,13 @@ public class GenericSmelter extends GenericCrafter{ float r = 0.06f; float cr = Mathf.random(0.1f); - Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * warmup); + Draw.alpha(((1f - g) + Mathf.absin(Time.time, 8f, g) + Mathf.random(r) - r) * warmup); Draw.tint(flameColor); - Fill.circle(x, y, 3f + Mathf.absin(Time.time(), 5f, 2f) + cr); + Fill.circle(x, y, 3f + Mathf.absin(Time.time, 5f, 2f) + cr); Draw.color(1f, 1f, 1f, warmup); Draw.rect(topRegion, x, y); - Fill.circle(x, y, 1.9f + Mathf.absin(Time.time(), 5f, 1f) + cr); + Fill.circle(x, y, 1.9f + Mathf.absin(Time.time, 5f, 1f) + cr); Draw.color(); } diff --git a/core/src/mindustry/world/blocks/production/Incinerator.java b/core/src/mindustry/world/blocks/production/Incinerator.java index d51caf06c2..35765f6961 100644 --- a/core/src/mindustry/world/blocks/production/Incinerator.java +++ b/core/src/mindustry/world/blocks/production/Incinerator.java @@ -42,7 +42,7 @@ public class Incinerator extends Block{ float g = 0.3f; float r = 0.06f; - Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * heat); + Draw.alpha(((1f - g) + Mathf.absin(Time.time, 8f, g) + Mathf.random(r) - r) * heat); Draw.tint(flameColor); Fill.circle(x, y, 2f); diff --git a/core/src/mindustry/world/blocks/production/PayloadAcceptor.java b/core/src/mindustry/world/blocks/production/PayloadAcceptor.java index 512eeebdad..2852d00a13 100644 --- a/core/src/mindustry/world/blocks/production/PayloadAcceptor.java +++ b/core/src/mindustry/world/blocks/production/PayloadAcceptor.java @@ -82,6 +82,12 @@ public class PayloadAcceptor extends Block{ return t; } + @Override + public void onRemoved(){ + super.onRemoved(); + if(payload != null) payload.dump(); + } + public boolean blends(int direction){ return PayloadAcceptor.blends(this, direction); } diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 995834c977..e53bd84eff 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -229,12 +229,12 @@ public class CoreBlock extends StorageBlock{ @Override public boolean acceptItem(Building source, Item item){ - return items.get(item) < getMaximumAccepted(item) || incinerate(); + return items.get(item) < getMaximumAccepted(item); } @Override public int getMaximumAccepted(Item item){ - return storageCapacity; + return incinerate() ? storageCapacity * 2 : storageCapacity; } @Override @@ -270,10 +270,15 @@ public class CoreBlock extends StorageBlock{ @Override public void handleStack(Item item, int amount, Teamc source){ - super.handleStack(item, amount, source); + int realAmount = Math.min(amount, storageCapacity - items.get(item)); + super.handleStack(item, realAmount, source); if(team == state.rules.defaultTeam && state.isCampaign()){ state.rules.sector.info.handleCoreItem(item, amount); + + if(realAmount == 0){ + Fx.coreBurn.at(x, y); + } } } @@ -377,7 +382,7 @@ public class CoreBlock extends StorageBlock{ state.rules.sector.info.handleCoreItem(item, 1); } - if(items.get(item) >= getMaximumAccepted(item)){ + if(items.get(item) >= storageCapacity){ //create item incineration effect at random intervals if(!noEffect){ incinerateEffect(this, source); diff --git a/core/src/mindustry/world/blocks/storage/StorageBlock.java b/core/src/mindustry/world/blocks/storage/StorageBlock.java index b7581b4dfb..7bfda601d1 100644 --- a/core/src/mindustry/world/blocks/storage/StorageBlock.java +++ b/core/src/mindustry/world/blocks/storage/StorageBlock.java @@ -10,6 +10,8 @@ import mindustry.world.*; import mindustry.world.blocks.storage.CoreBlock.*; import mindustry.world.meta.*; +import static mindustry.Vars.*; + public class StorageBlock extends Block{ public StorageBlock(String name){ @@ -57,6 +59,24 @@ public class StorageBlock extends Block{ } } + @Override + public void itemTaken(Item item){ + if(linkedCore != null){ + linkedCore.itemTaken(item); + } + } + + @Override + public int removeStack(Item item, int amount){ + int result = super.removeStack(item, amount); + + if(linkedCore != null && team == state.rules.defaultTeam && state.isCampaign()){ + state.rules.sector.info.handleCoreItem(item, -result); + } + + return result; + } + @Override public int getMaximumAccepted(Item item){ return itemCapacity; diff --git a/core/src/mindustry/world/blocks/units/ControlCenter.java b/core/src/mindustry/world/blocks/units/ControlCenter.java deleted file mode 100644 index ab99470b93..0000000000 --- a/core/src/mindustry/world/blocks/units/ControlCenter.java +++ /dev/null @@ -1,16 +0,0 @@ -package mindustry.world.blocks.units; - -import mindustry.gen.*; -import mindustry.world.*; - -public class ControlCenter extends Block{ - - public ControlCenter(String name){ - super(name); - update = true; - } - - public class ControlCenterBuild extends Building{ - - } -} diff --git a/core/src/mindustry/world/meta/values/WeaponListValue.java b/core/src/mindustry/world/meta/values/WeaponListValue.java index 419e689e98..706077b967 100644 --- a/core/src/mindustry/world/meta/values/WeaponListValue.java +++ b/core/src/mindustry/world/meta/values/WeaponListValue.java @@ -21,7 +21,7 @@ public class WeaponListValue implements StatValue{ @Override public void display(Table table){ table.row(); - for(int i = 0;i < weapons.size;i ++){ + for(int i = 0; i < weapons.size;i ++){ Weapon weapon = weapons.get(i); if(weapon.flipSprite){ @@ -29,7 +29,7 @@ public class WeaponListValue implements StatValue{ continue; } - TextureRegion region = weapon.outlineRegion.found() ? weapon.outlineRegion : unit.icon(Cicon.full); + TextureRegion region = !weapon.name.equals("") && weapon.outlineRegion.found() ? weapon.outlineRegion : unit.icon(Cicon.full); table.image(region).size(60).scaling(Scaling.bounded).right().top(); diff --git a/desktop/src/mindustry/desktop/steam/SAchievement.java b/desktop/src/mindustry/desktop/steam/SAchievement.java index 71e04a2c3c..ffa429c868 100644 --- a/desktop/src/mindustry/desktop/steam/SAchievement.java +++ b/desktop/src/mindustry/desktop/steam/SAchievement.java @@ -5,8 +5,8 @@ public enum SAchievement{ kill100kEnemies(SStat.unitsDestroyed, 100_000), launch100kItems(SStat.itemsLaunched, 100_000), - produce1kMin(SStat.maxProduction, 1000), - produce20kMin(SStat.maxProduction, 20_000), + produce5kMin(SStat.maxProduction, 5000), + produce50kMin(SStat.maxProduction, 50_000), win10Attack(SStat.attacksWon, 10), win10PvP(SStat.pvpsWon, 10), defeatAttack5Waves, @@ -25,7 +25,7 @@ public enum SAchievement{ publishMap(SStat.mapsPublished, 1), defeatBoss(SStat.bossesDefeated, 1), captureAllSectors, - control10Sectors, + control10Sectors(SStat.sectorsControlled, 10), drop10kitems, powerupImpactReactor, obtainThorium, diff --git a/desktop/src/mindustry/desktop/steam/SStat.java b/desktop/src/mindustry/desktop/steam/SStat.java index be67714d4d..7b6ad442b4 100644 --- a/desktop/src/mindustry/desktop/steam/SStat.java +++ b/desktop/src/mindustry/desktop/steam/SStat.java @@ -5,7 +5,6 @@ public enum SStat{ attacksWon, pvpsWon, timesLaunched, - zoneMechsUsed, //TODO blocksDestroyed, itemsLaunched, reactorsOverheated, diff --git a/fastlane/metadata/android/en-US/changelogs/29730.txt b/fastlane/metadata/android/en-US/changelogs/29730.txt new file mode 100644 index 0000000000..c98275f647 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29730.txt @@ -0,0 +1,10 @@ +This should be one of the last beta builds. In a couple of days, I will make a final release with the most recent translation bundles & bugfixes. + +- Fixed infinitely looping Vela laser sound +- Fixed fire not burning on tar +- Disabled fire for items with flammability <= 1 (this means coal bombing no longer causes fire) +- Disabled unit explosion team damage +- Disabled core unit crash damage +- Disabled automatic linking of adjacent bridges + +Campaign: diff --git a/fastlane/metadata/android/en-US/changelogs/29733.txt b/fastlane/metadata/android/en-US/changelogs/29733.txt new file mode 100644 index 0000000000..da6bfa3221 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29733.txt @@ -0,0 +1,11 @@ +The final beta build. + +- Updated link to wiki modding guide, now points to new wiki +- Fixed weaving missiles consistently moving off to one direction +- Fixed units shooting fast bullets on servers in certain conditions +- Fixed some crashes +- Made construction of rotated blocks free/instant (i.e. equivalent to manually rotating it) + +Campaign: +- Better production calculation system +- Fixed deconstruction counting as production diff --git a/gradle.properties b/gradle.properties index e5c7e5fe4d..190a2e6b2e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=7a2a357f6cfdc3725ce581093a0ced91f4474222 +archash=e13f9a192be0bad00766ff15a6bf7d2897ba00d1 diff --git a/servers_v6.json b/servers_v6.json index c627e00001..80c8cf3fab 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -2,6 +2,10 @@ { "name": "mindustry.pl", "address": ["mindustry.pl:6000", "mindustry.pl:6666"] + }, + { + "name": "Atanner", + "address": ["atannergaming.com:13000"] }, { "name": "C.A.M.S.", @@ -15,6 +19,10 @@ "name": "Chaotic Neutral", "address": ["Chaotic-Neutral.ddns.net:5555", "Chaotic-Neutral.ddns.net:6666"] }, + { + "name": "Ranked", + "address": ["mindustryranked.ddns.net:16567"] + }, { "address": "cheginde.ddns.net" }