Merge branch 'master' of https://github.com/Anuken/Mindustry into v9

# Conflicts:
#	gradle.properties
This commit is contained in:
Anuken
2026-09-20 17:28:10 -04:00
28 changed files with 618 additions and 369 deletions

View File

@@ -211,10 +211,7 @@ public abstract class BaseProcessor extends AbstractProcessor{
if(round++ >= rounds) return false; //only process 1 round
if(rootDirectory == null){
try{
String path = Fi.get(filer.getResource(StandardLocation.CLASS_OUTPUT, "no", "no")
.toUri().toURL().toString().substring(OS.isWindows ? 6 : "file:".length()))
.parent().parent().parent().parent().parent().parent().parent().toString().replace("%20", " ");
rootDirectory = Fi.get(path).parent();
rootDirectory = new Fi(new File(filer.getResource(StandardLocation.CLASS_OUTPUT, "no", "no").toUri())).parent().parent().parent().parent().parent().parent().parent().parent();
}catch(IOException e){
throw new RuntimeException(e);
}

View File

@@ -42,7 +42,7 @@ allprojects{
if(!project.hasProperty("versionModifier")) versionModifier = 'alpha'
if(!project.hasProperty("versionType")) versionType = 'official'
appName = 'Mindustry'
steamworksVersion = 'da41c05b7a2a44c8625ca0ba7d6ca1a2e73f621a'
steamworksVersion = '185e76cfe630a6f0e1dd7b9bf57be41f6064a1f2'
rhinoVersion = '32395f942976a6d1d21ec9877664554cd5762306'
loadVersionProps = {

View File

@@ -1310,7 +1310,7 @@ bar.cargounitcap = Cargo Unit Cap Reached
bar.drillspeed = Drill Speed: {0}/s
bar.pumpspeed = Pump Speed: {0}/s
bar.efficiency = Efficiency: {0}%
bar.yield = Yield: +{0}%
bar.yield = Yield: {0}%
bar.boost = Boost: +{0}%
bar.powerbuffer = Batteries: {0}/{1}
bar.powerbalance = Power: {0}/s
@@ -3402,7 +3402,7 @@ logicrule.label.wavetimer = wave timer?
logicrule.label.waves = waves
logicrule.label.wave = wave
logicrule.label.wavespacing = wave spacing
logicrule.label.wavesending = waves ending?
logicrule.label.wavesending = waves sending?
logicrule.label.attackmode = attack mode?
logicrule.label.enemycorebuildradius = enemy core build radius
logicrule.label.dropzoneradius = drop zone radius

View File

@@ -844,7 +844,7 @@ objective.destroyblock.name = Destruir bloque
objective.destroyblocks.name = Destruir bloques
objective.destroycore.name = Destruir núcleo
objective.commandmode.name = Modo comando
objective.flag.name = Etiqueta
objective.flag.name = Flag
marker.shapetext.name = Forma del texto
marker.point.name = Punto
@@ -1244,7 +1244,7 @@ stat.reactive = Reacciona con
stat.immunities = Inmune a
stat.healing = Curación
stat.status = Efecto de estado
stat.efficiency = [stat]{0}% Eficiencia
stat.efficiency = {0}% Eficiencia
stat.chance = [stat]{0}%[lightgray] probabilidad de [white]
stat.hitsize = Tamaño de Unidad
stat.resettime = Tiempo de Reinicio
@@ -1305,7 +1305,7 @@ bar.cargounitcap = Se alcanzó el límite de carga de unidades
bar.drillspeed = Velocidad del taladro: {0}/s
bar.pumpspeed = Velocidad de bombeado: {0}/s
bar.efficiency = Eficiencia: {0}%
bar.yield = Yield: +{0}%
bar.yield = Producción: {0}%
bar.boost = Aceleración: +{0}%
bar.powerbuffer = Poder en baterías: {0}/{1}
bar.powerbalance = Energía: {0}/s
@@ -1325,7 +1325,7 @@ bar.nevermelts = nunca hace fusión
bar.heatamount = Calor: {0}
bar.heatpercent = Calor: {0} ({1}%)
bar.power = Energía
bar.progress = Construyendo...
bar.progress = {0}% Construido
bar.loadprogress = Progreso
bar.launchcooldown = Recarga de lanzamiento
bar.input = Entrada
@@ -1996,8 +1996,8 @@ block.metal-tiles-13.name = Casilla de metal 13
block.metal-wall-1.name = Muro de metal 1
block.metal-wall-2.name = Muro de metal 2
block.metal-wall-3.name = Muro de metal 3
block.colored-floor.name = Piso coloreado
block.colored-wall.name = Muro coloreado
block.colored-floor.name = Suelo de Color
block.colored-wall.name = Muro de Color
block.character-overlay.name = Caracter
block.character-overlay-white.name = Caracter (Blanco)
block.rune-overlay.name = Runa
@@ -2763,7 +2763,7 @@ block.ship-refabricator.description = Mejora al segundo nivel la nave selecciona
block.mech-refabricator.description = Mejora al segundo nivel el mech seleccionado.
block.prime-refabricator.description = Mejora al tercer nivel las unidades entrantes.
block.basic-assembler-module.description = Incrementa el nivel del ensamblador si se coloca junto a un área de construcción. Requiere energía. Se puede usar como entrada de un cargador.
block.small-deconstructor.description = Deconstruye las estructuras y unidades entrantes. Devuelve el 100% de su coste de construcción.
block.small-deconstructor.description = Deconstruye las estructuras y unidades entrantes. Devuelve el 100% de su coste de construcción. Guarda los objetos en diferentes capacidades de objetos.
block.reinforced-payload-conveyor.description = Mueve los lotes de carga en una dirección.
block.reinforced-payload-router.description = Distribuye las cargas a los bloques adyacentes. Funcionará como un clasificador si se le establece un filtro.
block.payload-mass-driver.description = Estructura de transporte de carga de largo alcance. Dispara las cargas entrantes a otras catapultas enlazadas.
@@ -2951,63 +2951,63 @@ laccess.displayheight = Alto de un bloque de pantalla, en pixeles.
laccess.buffersize = Número de comandos sin ejecutar en el buffer gráfico de una pantalla.
laccess.operations = Número de operaciones ejecutadas en el bloque.\nPara pantallas, retorna el número de operaciones drawflush.
laccess.maxunits = Unidades máximas que un equipo puede tener.\nSolo puede ser obtenido de los núcleos.
laccess.totalitems = Total number of items contained.
laccess.firstitem = First item contained, or null if empty.
laccess.totalliquids = Total amount of liquid contained.
laccess.totalpower = For blocks with a buffered power store, the amount of power stored; for other blocks, buffer fullness from 0 to 1.
laccess.itemcapacity = Maximum number of items this building can hold.
laccess.liquidcapacity = Maximum amount of liquid this building can hold.
laccess.powercapacity = Maximum amount of power this building can store.
laccess.powernetstored = Total power stored in the connected power grid.
laccess.powernetcapacity = Total power storage capacity of the connected power grid.
laccess.powernetin = Power entering the connected power grid, per second.
laccess.powernetout = Power leaving the connected power grid, per second.
laccess.ammo = Current ammo count of a turret.
laccess.ammocapacity = Maximum ammo count of a turret.
laccess.health = Current health.\nFor bullets, their damage.
laccess.maxhealth = Maximum health.\nFor bullets, the base damage.
laccess.heat = Current heat of a turret that consumes heat, 0 to 1.
laccess.shield = Current shield amount of a unit.
laccess.armor = Armor value; flat damage reduction per hit.
laccess.efficiency = Operating efficiency of a building, where 1 is nominal.
laccess.timescale = Time scale multiplier affecting a building, where 1 is normal speed.
laccess.rotation = Facing angle of a unit or turret, in degrees.\nFor most other buildings, the 0 to 3 orientation.
laccess.x = X position, in tiles.
laccess.y = Y position, in tiles.
laccess.velocityx = X velocity of a unit, in tiles/sec.
laccess.velocityy = Y velocity of a unit, in tiles/sec.
laccess.shootx = X coordinate a unit or turret is aiming at.
laccess.shooty = Y coordinate a unit or turret is aiming at.
laccess.camerax = X position of the controlling player's camera.
laccess.cameray = Y position of the controlling player's camera.
laccess.camerawidth = Width of the controlling player's view, in tiles.
laccess.cameraheight = Height of the controlling player's view, in tiles.
laccess.solid = Whether this building blocks movement.
laccess.range = Range of a unit or turret, in tiles.
laccess.shooting = Whether a unit or turret is currently shooting.
laccess.boosting = Whether a unit is currently boosting or flying over terrain.
laccess.minex = X tile coordinate a unit is mining, or -1 if not mining.
laccess.miney = Y tile coordinate a unit is mining, or -1 if not mining.
laccess.mining = Whether a unit is currently mining.
laccess.buildx = X tile coordinate a unit is building at, or -1 if not building.
laccess.buildy = Y tile coordinate a unit is building at, or -1 if not building.
laccess.pingx = X coordinate a player is pinging, or null if not pinging.
laccess.pingy = Y coordinate a player is pinging, or null if not pinging.
laccess.pingtext = Text of a player's current ping, or null if not pinging.
laccess.building = Building a unit is currently constructing, or null.
laccess.breaking = Building a unit is currently deconstructing, or null.
laccess.team = Team ID of a unit or building.
laccess.flag = Numeric flag value stored on a unit.
laccess.flying = Whether a unit is currently airborne.
laccess.name = Name of the player controlling this unit, or null.
laccess.payloadcount = Number of payloads currently held.
laccess.payloadtype = Type of the last payload picked up, or null.
laccess.totalpayload = Combined size of all held payloads.
laccess.payloadcapacity = Maximum combined payload size a unit or building can carry.
laccess.selectedblock = Block currently selected by the controlling player, or null.
laccess.selectedrotation = Build rotation currently selected by the controlling player, 0 to 3.
laccess.bulletlifetime = Total lifetime of a bullet, in ticks.
laccess.bullettime = Time a bullet has existed, in ticks.
laccess.totalitems = Número total de items dentro.
laccess.firstitem = Primer item dentro, Devuelve null si se encuentra vacío.
laccess.totalliquids = Cantidad total de líquido contenido.
laccess.totalpower = Para bloques con la capacidad de almacenar energía, la cantidad de energía almacenada; para otros bloques, de 0 a 1.
laccess.itemcapacity = Número total de items que esta construcción o unidad puede almacenar.
laccess.liquidcapacity = Tamaño máximo de liquido que esta construcción puede almacenar.
laccess.powercapacity = Cantidad máxima de energía que esta construcción puede almacenar.
laccess.powernetstored = Total de energía almacenada en la red de energía conectada.
laccess.powernetcapacity = Capacidad de almacenamiento total en la red de energía conectada.
laccess.powernetin = Energía que entra en la red de energía conectada, por segundo.
laccess.powernetout = Energía que abandona la red de energía conectada, por segundo.
laccess.ammo = Cantidad de munición actual de una torreta.
laccess.ammocapacity = Cantidad de munición máxima de una torreta.
laccess.health = Salud actual.\nPara balas, su daño.
laccess.maxhealth = Salud máxima.\nPara balas, su daño base.
laccess.heat = Calor actual de una torreta que puede usarlo, 0 a 1.
laccess.shield = Cantidad de escudo actual de una unidad.
laccess.armor = Valor de armadura; reducción plana de daño por golpe.
laccess.efficiency = Eficiencia operativa de la construcción, donde 1 es el valor nominal.
laccess.timescale = Multiplicador de escala de tiempo afectando a la construcción, donde 1 es la velocidad normal.
laccess.rotation = El ángulo al que está mirando una unidad o torreta, en grados.\nPara muchas de las otras construcciones, la orientación de 0 a 3.
laccess.x = Posición X, en casillas.
laccess.y = Posición Y, en casillas.
laccess.velocityx = Velocidad horizontal de una unidad, en casillas/segundo.
laccess.velocityy = Velocidad vertical de una unidad, en casillas/segundo.
laccess.shootx = Coordenada X a la cual una unidad o torreta está apuntando.
laccess.shooty = Coordenada Y a la cual una unidad o torreta está apuntando.
laccess.camerax = Posición X de la camara del jugador que está controlando.
laccess.cameray = Posición Y de la camara del jugador que está controlando.
laccess.camerawidth = Ancho de la vista del jugador que está controlando, en casillas.
laccess.cameraheight = Largo de la vista del jugador que está controlando, en casillas.
laccess.solid = Si una construcción bloquea el movimiento sobre de ella.
laccess.range = Rango de una unidad o torreta, en casillas.
laccess.shooting = Si una unidad o torreta se encuentra disparando.
laccess.boosting = Si una unidad está volando sobrevolando o volando sobre el terreno.
laccess.minex = Coordenada X de la casilla en la cual una unidad está minando, o -1 si no está minando.
laccess.miney = Coordenada Y de la casilla en la cual una unidad está minando, o -1 si no está minando.
laccess.mining = Si una unidad se encuentra minando.
laccess.buildx = Coordenada X de la casilla en la cual una unidad está construyendo, o -1 si no está construyendo.
laccess.buildy = Coordenada Y de la casilla en la cual una unidad está construyendo, o -1 si no está construyendo.
laccess.pingx = Coordenada X en la cual un jugador esta pingeando, o null si no está pingeando.
laccess.pingy = Coordenada Y en la cual un jugador está pingeando, o null si no está pingeando.
laccess.pingtext = Texto del ping actual de un jugador, o null si no está pingeando.
laccess.building = Construcción que la unidad está construyendo actualmente, o null.
laccess.breaking = Construcción que la unidad está deconstruyendo actualmente, o null.
laccess.team = Identificador de equipo de una unidad o construcción.
laccess.flag = Valor numérico o flag almacenada en una unidad.
laccess.flying = Si la unidad se encuentra volando.
laccess.name = Nombre del jugador controlando esta unidad, o null.
laccess.payloadcount = Numero de carga que se lleva actualmente.
laccess.payloadtype = Tipo de la última carga recogida, o null.
laccess.totalpayload = Tamaño combinado de toda la carga llevada.
laccess.payloadcapacity = Tamaño máximo combinado que una unidad o construcción pueden cargar.
laccess.selectedblock = Bloque seleccionado actualmente por el jugador que está controlando, o null.
laccess.selectedrotation = Rotación del bloque actualmente seleccionado por el jugador que está controland, de 0 a 3.
laccess.bulletlifetime = Tiempo de vida total de una bala, en ticks.
laccess.bullettime = Tiempo que una bala ha existido, en ticks.
lcategory.unknown = Desconocido
lcategory.unknown.description = Instrucciones no clasificadas.
@@ -3192,8 +3192,8 @@ instruction.print = Agregar texto
instruction.printchar = Agregar Carácter
instruction.format = Reemplazar Formato
instruction.drawflush = Dibujar Gráficos
instruction.printflush = Imprimir
instruction.getlink = Obtener Enlazados
instruction.printflush = Imprimir Texto
instruction.getlink = Obtener Enlazado
instruction.control = Controlar
instruction.radar = Radar
instruction.sensor = Sensor
@@ -3201,9 +3201,9 @@ instruction.set = Asignar
instruction.operation = Operación
instruction.select = Seleccionar
instruction.wait = Esperar
instruction.stop = Detener
instruction.stop = Detener Ejecución
instruction.lookup = Buscar
instruction.jump = Salto Condicional
instruction.jump = Jump
instruction.end = Terminar
instruction.unitbind = Vincular Unidad
instruction.unitcontrol = Controlar Unidad
@@ -3212,31 +3212,31 @@ instruction.unitlocate = Localizar con Unidad
instruction.query = Query
instruction.getblock = Obtener Bloque
instruction.setblock = Crear Bloque
instruction.spawnunit = Aparecer Unidad
instruction.spawnbullet = Aparecer Bala
instruction.spawnunit = Crear Unidad
instruction.spawnbullet = Crear Bala
instruction.applystatus = Aplicar Estado
instruction.weathersense = Detectar Clima
instruction.weathersense = Obtener Clima
instruction.weatherset = Establecer Clima
instruction.spawnwave = Aparecer Oleada
instruction.spawnwave = Generar Oleada
instruction.setrule = Cambiar Regla
instruction.flushmessage = Flush Message
instruction.flushmessage = Mostrar Mensaje
instruction.cutscene = Cinematica
instruction.effect = Efecto
instruction.explosion = Explosion
instruction.setrate = Set Rate
instruction.setrate = Establecer Velocidad
instruction.fetch = Buscar
instruction.sync = Sincronizar
instruction.clientdata = Datos del Cliente
instruction.getflag = Get Flag
instruction.setflag = Set Flag
instruction.setprop = Set Prop
instruction.getflag = Obtener Flag Global
instruction.setflag = Asignar Flag Global
instruction.setprop = Asignar Propiedad
instruction.playsound = Reproducir Sonido
instruction.playmusic = Reproducir Musica
instruction.setmarker = Set Marker
instruction.makemarker = Make Marker
instruction.localeprint = Locale Print
instruction.packcolor = Desagrupar Color
instruction.unpackcolor = Agrupar Color
instruction.packcolor = Agrupar Color
instruction.unpackcolor = Desagrupar Color
instruction.invalid = Instrucción Invalida
# Implemented via the enumText() method
blockflag.label.core = núcleos
@@ -3269,22 +3269,22 @@ fetchtype.label.unitcount = cantidad de unidades
fetchtype.label.playercount = cantidad de jugadores
fetchtype.label.corecount = cantidad de núcleos
fetchtype.label.buildcount = cantidad de construcciones
graphicstype.label.clear = clear
graphicstype.label.clear = llenar
graphicstype.label.color = color
graphicstype.label.col = col
graphicstype.label.stroke = stroke
graphicstype.label.line = line
graphicstype.label.rect = rect
graphicstype.label.linerect = line rect
graphicstype.label.poly = poly
graphicstype.label.linepoly = line poly
graphicstype.label.triangle = triangle
graphicstype.label.image = image
graphicstype.label.print = print
graphicstype.label.stroke = ancho
graphicstype.label.line = linea
graphicstype.label.rect = rectangulo
graphicstype.label.linerect = lineas rect
graphicstype.label.poly = poligono
graphicstype.label.linepoly = lineas poly
graphicstype.label.triangle = triangulo
graphicstype.label.image = imágen
graphicstype.label.print = texto
graphicstype.label.translate = translate
graphicstype.label.scale = scale
graphicstype.label.rotate = rotate
graphicstype.label.reset = reset
graphicstype.label.scale = escalar
graphicstype.label.rotate = rotar
graphicstype.label.reset = reiniciar
laccess.label.totalitems = total de objetos
laccess.label.firstitem = primer objeto
laccess.label.totalliquids = liquido total
@@ -3324,27 +3324,27 @@ laccess.label.displayheight = largo de pantalla
laccess.label.buffersize = tamaño de buffer
laccess.label.operations = operaciones
laccess.label.size = tamaño
laccess.label.solid = ¿solido?
laccess.label.dead = ¿muerto?
laccess.label.solid = solido?
laccess.label.dead = muerto?
laccess.label.range = rango
laccess.label.shooting = ¿disparando?
laccess.label.boosting = ¿sobrevolando?
laccess.label.shooting = disparando?
laccess.label.boosting = sobrevolando?
laccess.label.minex = minando x
laccess.label.miney = minando y
laccess.label.mining = ¿minando?
laccess.label.mining = minando?
laccess.label.buildx = construyendo x
laccess.label.buildy = construyendo y
laccess.label.pingx = ping x
laccess.label.pingy = ping y
laccess.label.pingtext = texto en ping
laccess.label.building = ¿construyendo?
laccess.label.breaking = ¿deconstruyendo?
laccess.label.building = construyendo?
laccess.label.breaking = deconstruyendo?
laccess.label.speed = velocidad
laccess.label.team = equipo
laccess.label.type = tipo
laccess.label.flag = flag
laccess.label.flying = ¿puede volar?
laccess.label.controlled = ¿controlada?
laccess.label.flying = puede volar?
laccess.label.controlled = controlada?
laccess.label.controller = controlador
laccess.label.name = nombre
laccess.label.payloadcount = conteo de carga
@@ -3357,7 +3357,7 @@ laccess.label.selectedblock = bloque seleccionado
laccess.label.selectedrotation = rotación seleccionada
laccess.label.bulletlifetime = tiempo de vida de la bala
laccess.label.bullettime = tiempo de bala
laccess.label.enabled = ¿activado?
laccess.label.enabled = activado?
laccess.label.shoot = disparo
laccess.label.shootp = disparo con predicción
laccess.label.config = configuración
@@ -3393,17 +3393,17 @@ lmarkercontrol.label.posi = posi
lmarkercontrol.label.uvi = uvi
lmarkercontrol.label.colori = colori
logicrule.label.currentwavetime = tiempo restante oleada actual
logicrule.label.wavetimer = ¿temporizador de oleada?
logicrule.label.waves = ¿oleadas activas?
logicrule.label.wavetimer = temporizador de oleada?
logicrule.label.waves = oleadas activas?
logicrule.label.wave = oleada
logicrule.label.wavespacing = tiempo entre oleadas
logicrule.label.wavesending = ¿adelantar oleada?
logicrule.label.attackmode = ¿modo de juego ataque?
logicrule.label.wavesending = enviar oleadas?
logicrule.label.attackmode = modo de juego ataque?
logicrule.label.enemycorebuildradius = radio de construccion de núcleo enemiga
logicrule.label.dropzoneradius = radio de zona de aparición
logicrule.label.unitcap = capacidad de unidades
logicrule.label.maparea = area del mapa
logicrule.label.lighting = ¿iluminación?
logicrule.label.lighting = iluminación?
logicrule.label.cangameover = se puede perder
logicrule.label.ambientlight = iluminación ambiental
logicrule.label.unitlight = iluminación de unidad
@@ -3411,7 +3411,7 @@ logicrule.label.solarmultiplier = multiplicador solar
logicrule.label.dragmultiplier = multiplicador de arrastre
logicrule.label.ban = banear
logicrule.label.unban = desbanear
logicrule.label.pausedisabled = ¿desactivar pausa?
logicrule.label.pausedisabled = desactivar pausa?
logicrule.label.musicvolume = volumen de la música
logicrule.label.buildspeed = velocidad de construcción
logicrule.label.unithealth = salud de unidad
@@ -3427,29 +3427,29 @@ lunitcontrol.label.idle = inactiva
lunitcontrol.label.stop = detenerse
lunitcontrol.label.unbind = desvincular
lunitcontrol.label.move = mover
lunitcontrol.label.approach = aproximar
lunitcontrol.label.pathfind = encontrarRuta
lunitcontrol.label.autopathfind = encontrarRuta auto
lunitcontrol.label.target = target
lunitcontrol.label.targetp = target predict
lunitcontrol.label.approach = acercar
lunitcontrol.label.pathfind = seguir ruta
lunitcontrol.label.autopathfind = auto-seguir ruta
lunitcontrol.label.target = disparar
lunitcontrol.label.targetp = disparar con predicción
lunitcontrol.label.itemdrop = soltar objeto
lunitcontrol.label.itemtake = tomar objeto
lunitcontrol.label.paydrop = soltar carga
lunitcontrol.label.paytake = tomar carga
lunitcontrol.label.payenter = entrar como carga
lunitcontrol.label.flag = etiqueta
lunitcontrol.label.flag = flag
lunitcontrol.label.mine = minar
lunitcontrol.label.build = construir bloque
lunitcontrol.label.getblock = obtener bloque
lunitcontrol.label.deconstruct = deconstruir
lunitcontrol.label.within = ¿dentro de?
lunitcontrol.label.boost = ¿potenciar?
lunitcontrol.label.within = dentro de?
lunitcontrol.label.boost = sobrevolar?
messagetype.label.notify = notify
messagetype.label.announce = announce
messagetype.label.toast = toast
messagetype.label.mission = mission
querytype.label.unit = unit
querytype.label.building = building
querytype.label.unit = unidad
querytype.label.building = construcción
radarsort.label.distance = distancia
radarsort.label.health = salud
radarsort.label.maxhealth = salud máxima
@@ -3463,40 +3463,40 @@ radartarget.label.attacker = unidad armada
radartarget.label.flying = unidad aérea
radartarget.label.ground = unidad terrestre
radartarget.label.boss = boss
tilelayer.label.floor = floor
tilelayer.label.ore = ore
tilelayer.label.block = block
tilelayer.label.building = building
tilelayer.label.floor = suelo
tilelayer.label.ore = mineral
tilelayer.label.block = bloque
tilelayer.label.building = construcción
name.token.color = color
name.token.width = width
name.token.height = height
name.token.sides = sides
name.token.radius = radius
name.token.rotation = rotation
name.token.image = image
name.token.size = size
name.token.align = align
name.token.set = crear
name.token.of = of
name.token.width = ancho
name.token.height = largo
name.token.sides = lados
name.token.radius = radio
name.token.rotation = rotación
name.token.image = imagen
name.token.size = tamaño
name.token.align = alinear
name.token.set = asigna
name.token.of = de
name.token.to = a
name.token.at = en
name.token.in = en
name.token.damage = daño
name.token.velocityScl = velocity scale
name.token.lifeScl = life scale
name.token.aimX = aim X
name.token.aimY = aim Y
name.token.read = read
name.token.write = write
name.token.from = from
name.token.char = char
name.token.velocityScl = escala de velocidad
name.token.lifeScl = escala de salud
name.token.aimX = apuntar X
name.token.aimY = apuntar Y
name.token.read = lee
name.token.write = escribe
name.token.from = de
name.token.char = carácter
name.token.linknum = link#
name.token.draw = draw
name.token.clear = clear
name.token.apply = apply
name.token.circle = circle
name.token.rect = rect
name.token.draw = dibujar
name.token.clear = limpiar
name.token.apply = aplicar
name.token.circle = circulo
name.token.rect = recta
name.token.positional = posicional
name.token.global = global
name.token.target = objetivo
@@ -3513,43 +3513,43 @@ name.token.then = then
name.token.else = else
name.token.find = localizar
name.token.group = grupo
name.token.enemy = ¿enemigo?
name.token.enemy = enemigo?
name.token.ore = mineral
name.token.outX = X obtenida
name.token.outY = Y obtenida
name.token.owner = owner
name.token.found = ¿encontrado?
name.token.found = encontrado?
name.token.building = construcción
name.token.always = always
name.token.not = not
name.token.pack = pack
name.token.unpack = unpack
name.token.-lookup = = lookup
name.token.type = type
name.token.pack = agrupar
name.token.unpack = desagrupar
name.token.-lookup = = bucar
name.token.type = tipo
name.token.get = get
name.token.team = team
name.token.angle = angle
name.token.spawn = spawn
name.token.-bullet = = bullet
name.token.unit = unit
name.token.weather = weather
name.token.state = state
name.token.team = equipo
name.token.angle = ángulo
name.token.spawn = crear
name.token.-bullet = = bala
name.token.unit = unidad
name.token.weather = clima
name.token.state = estado
name.token.natural = natural
name.token.speed = speed
name.token.level = level
name.token.duration = duration
name.token.seconds = seconds
name.token.duration = duración
name.token.seconds = segundos
name.token.shown = shown
name.token.data = data
name.token.effect = effect
name.token.pierce = pierce
name.token.ground = ground
name.token.effect = efecto
name.token.pierce = atraviesa
name.token.ground = terrestre
name.token.air = air
name.token.flag = flag
name.token.volume = volume
name.token.volume = volumen
name.token.pitch = pitch
name.token.pan = pan
name.token.limit = limit
name.token.limit = limite
name.token.id = id #
name.token.replace = replace?
name.token.for = for
@@ -3568,13 +3568,13 @@ name.token.name = name
name.token.index = index
name.token.block-unit = block/unit
name.token.enable = enable
name.token.amount = amount
name.token.amount = cantidad
name.token.item = item
name.token.takeUnits = take units
name.token.takeUnits = tomar unidades?
name.token.value = value
name.token.floor = floor
name.token.result = resultado
name.token.config = config
name.token.config = configuración
name.token.shapeText = shape text
name.token.point = point
name.token.shape = shape
@@ -3583,12 +3583,12 @@ name.token.line = line
name.token.texture = texture
name.token.quad = quad
name.token.light = light
name.token.snowing = snowing
name.token.rain = rain
name.token.sandstorm = sand storm
name.token.sporestorm = spore storm
name.token.fog = fog
name.token.suspend-particles = suspended particles
name.token.snowing = nevando
name.token.rain = lloviendo
name.token.sandstorm = tormenta de arena
name.token.sporestorm = tormenta de esporas
name.token.fog = neblina
name.token.suspend-particles = particulas suspendidas
name.token.topLeft = top left
name.token.top = top
name.token.topRight = top right
@@ -3632,15 +3632,15 @@ name.token.sparkExplosion = explosión con chispas
name.token.crossExplosion = explosión con cruz
name.token.wave = oleada
name.token.bubble = burbuja
name.token.music = music
name.token.interrupt = interrupt
name.token.music = musica
name.token.interrupt = interrumpe
name.token.all = Todos
name.token.beams = Rayos
name.token.block = Bloques
name.token.block = bloque
name.token.charge = Carga
name.token.environment = Clima
name.token.explosions = Explosiones
name.token.loops = Bucles
name.token.movement = Movimiento
name.token.shoot = Disparos
name.token.ui = Interfaz Usuario
name.token.shoot = disparar
name.token.ui = Interfaz de Usuario

View File

@@ -1025,7 +1025,7 @@ sector.crateredBattleground.description = Víz gyűlt össze ebben a kráterben,
sector.ruinousShores.description = A pusztaság mögött a partvonal húzódik. Valaha ezen a helyen egy partvédelmi rendszer állt. Nem sok minden maradt belőle. Csak a legalapvetőbb védelmi szerkezetek maradtak érintetlenül, minden más csak törmelék lett.\nFolytasd a terjeszkedést. Fedezd fel újra a technológiát.
sector.stainedMountains.description = Mélyebben a szárazföldön fekszenek a hegyek, a spóráktól még érintetlenül.\nTermeld ki a bőséges titán készleteket a körzetben. Tanuld meg felhasználni.\n\nAz ellenség itt nagyobb létszámban van jelen. Ne hagyj nekik időt, hogy a legerősebb egységeiket hadba állíthassák.
sector.overgrowth.description = Ez a terület közelebb esik a spórák forrásához, a spórák már kinőtték.\nAz ellenség egy helyőrséget létesített itt. Építs Mace egységeket. Pusztítsd el a bázist.
sector.tarFields.description = Egy olajtermelő övezet peremvidéke a hegyek és a sivatag határán. Egy azon kevés szektorok közül, ahol még hasznosítható kátránykészletek találhatók.\nBár a terület elhagyatott, veszélyes ellenséges erők fészkelnek a közelben. Ne becsüld alá őket.\n\n[lightgray]Fedezd fel az olajfeldolgozási lehetőségeket, ha tudod.
sector.tarFields.description = Egy olajtermelő övezet peremvidéke a hegyek és a sivatag határán. Azon kevés szektorok egyike, ahol még hasznosítható kátránykészletek találhatók.\nBár a terület elhagyatott, veszélyes ellenséges erők fészkelnek a közelben. Ne becsüld alá őket.\n\n[lightgray]Fedezd fel az olajfeldolgozási lehetőségeket, ha tudod.
sector.desolateRift.description = Ez egy rendkívül veszélyes zóna. Bár nyersanyagokban gazdag, kevés hely áll rendelkezésre. Magas a kockázat. Építs szárazföldi és légvédelmet, amint csak tudsz. Ne tévesszen meg a hosszú szünet az ellenség támadásai között.
sector.nuclearComplex.description = Egy néhai tóriumkitermelő és feldolgozó létesítmény, romokban.\n[lightgray]Fedezd fel a tóriumot és a sokrétű felhasználását.\n\nAz ellenség nagy létszámban van jelen, és folyamatosan megfigyelés alatt tartják a környéket.
sector.fungalPass.description = Átmeneti terület a magas hegyek és a mélyebben fekvő, spórák uralta lapály között. Egy kisebb ellenséges megfigyelő állomás található itt.\nSemmisítsd meg.\nHasználj Dagger egységeket. Pusztítsd el a támaszpontot.
@@ -1305,7 +1305,7 @@ bar.cargounitcap = Az egység raktere megtelt
bar.drillspeed = Termelés: {0}/mp
bar.pumpspeed = Termelés: {0}/mp
bar.efficiency = Hatásfok: {0}%
bar.yield = Hozam: +{0}%
bar.yield = Hozam: {0}%
bar.boost = Erősítés: +{0}%
bar.powerbuffer = Akkumulátorok: {0}/{1}
bar.powerbalance = Áram: {0}/mp
@@ -3397,14 +3397,14 @@ logicrule.label.wavetimer = hullámidőzítő?
logicrule.label.waves = hullámok
logicrule.label.wave = hullám
logicrule.label.wavespacing = hullámok közötti idő
logicrule.label.wavesending = hullámok véget érnek?
logicrule.label.wavesending = hullámok küldése?
logicrule.label.attackmode = támadó mód?
logicrule.label.enemycorebuildradius = ellenséges támaszpont építési sugara
logicrule.label.dropzoneradius = ledobási zóna sugara
logicrule.label.unitcap = egységkorlát
logicrule.label.maparea = térkép területe
logicrule.label.lighting = világítás?
logicrule.label.cangameover = lehetséges játék vége
logicrule.label.cangameover = befejeződhet a játék
logicrule.label.ambientlight = környezeti fény
logicrule.label.unitlight = egység fénye
logicrule.label.solarmultiplier = napelemszorzó

View File

@@ -888,7 +888,7 @@ bannedunits.whitelist = Unit yang Dilarang Sebagai Whitelist
bannedblocks.whitelist = Blok yang Dilarang Sebagai Whitelist
addall = Tambah Semua
launch.from = Meluncurkan Dari: [accent]{0}
launch.capacity = Kapasitas item yang Diluncurkan: [accent]{0}
launch.capacity = Kapasitas Item yang Diluncurkan: [accent]{0}
launch.destination = Destinasi: {0}
landing.sources = Total Sumber Sektor: [accent]{0}[]
landing.import = Total Impor Maksimum: {0}[accent]{1}[lightgray]/mnt
@@ -1080,7 +1080,7 @@ sector.caldera-erekir.description = Sumber daya yang terdeteksi di sektor ini te
sector.stronghold.description = Markas musuh yang besar di sektor ini menjaga simpanan [accent]torium[] dalam jumlah besar.\nGunakan itu untuk mengembangkan unit dan menara ke tingkat yang lebih tinggi.
sector.crevice.description = Musuh akan mengirimkan pasukan serangan yang hebat untuk menghancurkan markasmu di sektor ini.\nKembangkan [accent]karbida[] dan [accent]Generator Pirolisis[] mungkin imperatif untuk bertahan hidup.
sector.siege.description = Sektor ini memiliki dua ngarai paralel yang akan memaksa serangan dari dua arah.\nRiset [accent]sianogen[] untuk mendapatkan kemampuan untuk memproduksi unit tank yang lebih kuat.\nPeringatan: Rudal jarak jauh milik musuh telah terdeteksi. Rudal tersebut mungkin ditembak jatuh sebelum terjadi benturan.
sector.crossroads.description = Markas musuh di sektor ini telah didirikan di berbagai medan. Riset unit yang berbeda untuk beradaptasi.\nSelain itu, beberapa markas telah dilindungi oleh perisai. Cari tahu bagaimana mereka diberi daya.
sector.crossroads.description = Markas musuh di sektor ini telah didirikan di berbagai medan. Riset unit yang berbeda untuk beradaptasi.\nSelain itu, beberapa markas telah dilindungi oleh perisai. Cari tahu bagaimana mereka diberi tenaga.
sector.karst.description = Sektor ini kaya akan sumber daya, namun akan diserang oleh musuh begitu inti baru mendarat.\nManfaatkan sumber daya dan riset [accent]fabrik phase[].
sector.origin.description = Sektor terakhir dengan kehadiran musuh yang signifikan.\nTidak ada peluang riset yang tersisa - fokus menghancurkan semua inti musuh.
@@ -1305,7 +1305,7 @@ bar.cargounitcap = Kapasitas Unit Kargo Telah Mencapai Batas
bar.drillspeed = Kecepatan Bor: {0}/d
bar.pumpspeed = Kecepatan Pompa: {0}/d
bar.efficiency = Efisiensi: {0}%
bar.yield = Hasil: +{0}%
bar.yield = Hasil: {0}%
bar.boost = Pendorongan: +{0}%
bar.powerbuffer = Tenaga Baterai: {0}/{1}
bar.powerbalance = Tenaga: {0}/d
@@ -1453,7 +1453,7 @@ setting.autotarget.name = Bidik Musuh Secara Otomatis
setting.autotarget.description = Ketika diaktifkan, unit Anda akan secara otomatis membidik dan menembaki musuh di sekitar.
setting.keyboard.name = Kontrol Tetikus+Papan Ketik
setting.fpscap.name = Batas FPS
setting.fpscap.description = Mengatur jumlah maksimum bingkai per detik (FPS) saat permainan berjalan.\nNilai yang lebih tinggi dapat meningkatkan konsumsi daya baterai.
setting.fpscap.description = Mengatur jumlah maksimum bingkai per detik (FPS) saat permainan berjalan.\nNilai yang lebih tinggi dapat meningkatkan konsumsi baterai.
setting.fpscap.none = Tidak Ada
setting.fpscap.text = {0} FPS
setting.uiscale.name = Skala UI
@@ -2459,7 +2459,7 @@ onset.defenses = [accent]Siapkan pertahanan:[lightgray] {0}
onset.attack = Musuh dalam keadaan rentan diserang. Lancarkan serangan balasan.
onset.cores = Inti baru dapat ditempatkan di [accent]ubin inti[].\nInti baru berfungsi sebagai pangkalan depan dan berbagi sumber daya dengan inti lainnya.\nTempatkan sebuah :core-bastion: inti.
onset.detect = Musuh akan dapat mendeteksi Anda dalam 2 menit.\nSiapkan pertahanan, penambangan, dan produksi.
onset.commandmode = Tahan [accent]shift[] untuk masuk ke[accent]mode perintah[].\n[accent]Klik kiri dan seret[] untuk memilih unit.\n[accent]Klik kanan[] untuk memerintahkan unit yang dipilih untuk bergerak atau menyerang.
onset.commandmode = Tahan [accent]shift[] untuk masuk ke [accent]mode perintah[].\n[accent]Klik kiri dan seret[] untuk memilih unit.\n[accent]Klik kanan[] untuk memerintahkan unit yang dipilih untuk bergerak atau menyerang.
onset.commandmode.mobile = Tekan tombol [accent]perintah[] untuk masuk ke [accent]mode perintah[].\nTekan dan tahan jari Anda, lalu [accent]seret[] untuk memilih unit.\n[accent]Ketuk[] untuk memerintahkan unit yang dipilih untuk bergerak atau menyerang.
aegis.tungsten = Tungsten dapat ditambang menggunakan [accent]bor tumbukan[].\nBangunan ini memerlukan [accent]air[] dan [accent]tenaga[].
@@ -2692,7 +2692,7 @@ block.smite.description = Menembakan semburan peluru yang menusuk dan menyambar.
block.malign.description = Menembakkan rentetan muatan laser pelacak ke arah musuh. Memerlukan pemanasan ekstensif.
block.silicon-arc-furnace.description = Memurnikan silikon dari pasir dan grafit.
block.oxidation-chamber.description = Mengubah berilium dan ozon menjadi oksida. Memancarkan panas sebagai produk sampingan.
block.electric-heater.description = Pemanas yang menghadap ke arah blok. Memerlukan daya yang besar.
block.electric-heater.description = Pemanas yang menghadap ke arah blok. Memerlukan tenaga yang besar.
block.slag-heater.description = Pemanas yang menghadap ke arah blok. Memerlukan lava.
block.phase-heater.description = Pemanas yang menghadap ke arah blok. Memerlukan fabrik phase.
block.heat-redirector.description = Mengalihkan akumulasi panas ke blok lain.
@@ -2706,7 +2706,7 @@ block.carbide-crucible.description = Memadukan grafit dan tungsten menjadi karbi
block.cyanogen-synthesizer.description = Mensintesis sianogen dari arkisit dan grafit. Memerlukan panas.
block.slag-incinerator.description = Membakar benda atau cairan yang tidak mudah menguap. Memerlukan lava.
block.vent-condenser.description = Mengondensasi gas ventilasi menjadi air. Memerlukan tenaga.
block.plasma-bore.description = Saat ditempatkan menghadap dinding bijih, mengeluarkan bahan tanpa batas. Memerlukan daya dalam jumlah kecil.
block.plasma-bore.description = Saat ditempatkan menghadap dinding bijih, mengeluarkan bahan tanpa batas. Memerlukan tenaga dalam jumlah kecil.
block.large-plasma-bore.description = Bor plasma yang lebih besar. Mampu menambang tungsten dan torium. Memerlukan hidrogen dan tenaga.
block.cliff-crusher.description = Menghancurkan dinding, mengeluarkan pasir tanpa batas. Memerlukan tenaga. Efisiensi bervariasi berdasarkan jenis dinding.
block.large-cliff-crusher.description = Menghancurkan dinding, mengeluarkan pasir tanpa batas. Memerlukan tenaga dan hidrogen. Efisiensi bervariasi berdasarkan jenis dinding. Dapat menggunakan grafit untuk meningkatkan efisiensi.
@@ -2747,7 +2747,7 @@ block.turbine-condenser.description = Menghasilkan tenaga ketika ditempatkan pad
block.chemical-combustion-chamber.description = Menghasilkan tenaga dari arkisit dan ozon.
block.pyrolysis-generator.description = Menghasilkan tenaga dalam jumlah besar dari arkisit dan lava. Memproduksi air sebagai produk sampingan.
block.flux-reactor.description = Menghasilkan tenaga dalam jumlah besar ketika dipanaskan. Memerlukan sianogen sebagai penstabil. Tenaga yang dihasilkan dan kebutuhan sianogen sebanding dengan panas yang masuk.\nMeledak jika sianogen yang disediakan tidak mencukupi.
block.neoplasia-reactor.description = Menggunakan arkisit, air, dan fabrik phase untuk menghasilkan daya dalam jumlah besar. Menghasilkan panas dan neoplasma yang berbahaya sebagai produk sampingan.\nMeledak jika neoplasma tidak dikeluarkan dari reaktor melalui saluran.
block.neoplasia-reactor.description = Menggunakan arkisit, air, dan fabrik phase untuk menghasilkan tenaga dalam jumlah besar. Menghasilkan panas dan neoplasma yang berbahaya sebagai produk sampingan.\nMeledak jika neoplasma tidak dikeluarkan dari reaktor melalui saluran.
block.build-tower.description = Secara otomatis membangun kembali bangunan dalam jangkauan dan membantu unit lain dalam konstruksi.
block.regen-projector.description = Perlahan memperbaiki bangunan sekutu di perimeter persegi. Memerlukan hidrogen. Dapat menggunakan fabrik phase untuk meningkatkan efisiensi.
block.reinforced-container.description = Menyimpan sejumlah kecil item. Isi kontainer dapat dibongkar melalui pembongkar muatan. Tidak dapat meningkatkan kapasitas penyimpanan inti.
@@ -2951,63 +2951,63 @@ laccess.displayheight = Tinggi blok tampilan logika dalam piksel.
laccess.buffersize = Untuk pesan: Panjang dari isi pesan.\nUntuk tampilan: Jumlah dari perintah grafis mentah.
laccess.operations = Jumlah operasi yang dilakukan pada blok.\nUntuk tampilan, mengembalikan jumlah dari operasi drawflush.
laccess.maxunits = Jumlah unit maksimum yang dapat dimiliki sebuah tim.\nHanya dapat dideteksi dari inti.
laccess.totalitems = Total number of items contained.
laccess.firstitem = First item contained, or null if empty.
laccess.totalliquids = Total amount of liquid contained.
laccess.totalpower = For blocks with a buffered power store, the amount of power stored; for other blocks, buffer fullness from 0 to 1.
laccess.itemcapacity = Maximum number of items this building can hold.
laccess.liquidcapacity = Maximum amount of liquid this building can hold.
laccess.powercapacity = Maximum amount of power this building can store.
laccess.powernetstored = Total power stored in the connected power grid.
laccess.powernetcapacity = Total power storage capacity of the connected power grid.
laccess.powernetin = Power entering the connected power grid, per second.
laccess.powernetout = Power leaving the connected power grid, per second.
laccess.ammo = Current ammo count of a turret.
laccess.ammocapacity = Maximum ammo count of a turret.
laccess.health = Current health.\nFor bullets, their damage.
laccess.maxhealth = Maximum health.\nFor bullets, the base damage.
laccess.heat = Current heat of a turret that consumes heat, 0 to 1.
laccess.shield = Current shield amount of a unit.
laccess.armor = Armor value; flat damage reduction per hit.
laccess.efficiency = Operating efficiency of a building, where 1 is nominal.
laccess.timescale = Time scale multiplier affecting a building, where 1 is normal speed.
laccess.rotation = Facing angle of a unit or turret, in degrees.\nFor most other buildings, the 0 to 3 orientation.
laccess.x = X position, in tiles.
laccess.y = Y position, in tiles.
laccess.velocityx = X velocity of a unit, in tiles/sec.
laccess.velocityy = Y velocity of a unit, in tiles/sec.
laccess.shootx = X coordinate a unit or turret is aiming at.
laccess.shooty = Y coordinate a unit or turret is aiming at.
laccess.camerax = X position of the controlling player's camera.
laccess.cameray = Y position of the controlling player's camera.
laccess.camerawidth = Width of the controlling player's view, in tiles.
laccess.cameraheight = Height of the controlling player's view, in tiles.
laccess.solid = Whether this building blocks movement.
laccess.range = Range of a unit or turret, in tiles.
laccess.shooting = Whether a unit or turret is currently shooting.
laccess.boosting = Whether a unit is currently boosting or flying over terrain.
laccess.minex = X tile coordinate a unit is mining, or -1 if not mining.
laccess.miney = Y tile coordinate a unit is mining, or -1 if not mining.
laccess.mining = Whether a unit is currently mining.
laccess.buildx = X tile coordinate a unit is building at, or -1 if not building.
laccess.buildy = Y tile coordinate a unit is building at, or -1 if not building.
laccess.pingx = X coordinate a player is pinging, or null if not pinging.
laccess.pingy = Y coordinate a player is pinging, or null if not pinging.
laccess.pingtext = Text of a player's current ping, or null if not pinging.
laccess.building = Building a unit is currently constructing, or null.
laccess.breaking = Building a unit is currently deconstructing, or null.
laccess.team = Team ID of a unit or building.
laccess.flag = Numeric flag value stored on a unit.
laccess.flying = Whether a unit is currently airborne.
laccess.name = Name of the player controlling this unit, or null.
laccess.payloadcount = Number of payloads currently held.
laccess.payloadtype = Type of the last payload picked up, or null.
laccess.totalpayload = Combined size of all held payloads.
laccess.payloadcapacity = Maximum combined payload size a unit or building can carry.
laccess.selectedblock = Block currently selected by the controlling player, or null.
laccess.selectedrotation = Build rotation currently selected by the controlling player, 0 to 3.
laccess.bulletlifetime = Total lifetime of a bullet, in ticks.
laccess.bullettime = Time a bullet has existed, in ticks.
laccess.totalitems = Jumlah total item yang tersimpan.
laccess.firstitem = Item pertama yang dimuat, atau null jika kosong.
laccess.totalliquids = Jumlah total cairan yang tersimpan.
laccess.totalpower = Untuk blok dengan penyimpanan tenaga berpenyangga (dioda), jumlah tenaga yang tersimpan; untuk blok lainnya, tingkat keterisian penyangga dari 0 hingga 1.
laccess.itemcapacity = Jumlah maksimum item yang dapat disimpan oleh bangunan ini.
laccess.liquidcapacity = Jumlah maksimum cairan yang dapat disimpan oleh bangunan ini.
laccess.powercapacity = Jumlah tenaga maksimum yang dapat disimpan oleh bangunan ini.
laccess.powernetstored = Total Tenaga yang tersimpan dalam jaringan listrik yang terhubung.
laccess.powernetcapacity = Total kapasitas penyimpanan tenaga dari jaringan listrik yang terhubung.
laccess.powernetin = Tenaga yang masuk ke jaringan listrik yang terhubung, per detik.
laccess.powernetout = Tenaga yang keluar dari jaringan listrik yang terhubung, per detik.
laccess.ammo = Jumlah amunisi menara saat ini.
laccess.ammocapacity = Jumlah amunisi maksimum menara.
laccess.health = Nyawa saat ini.\nUntuk peluru, besaran damage-nya.
laccess.maxhealth = Nyawa maksimum.\nUntuk peluru, damage dasar.
laccess.heat = Unit panas saat ini dari menara yang mengonsumsi unit panas, 0 hingga 1.
laccess.shield = Jumlah perisai yang dimiliki oleh unit saat ini.
laccess.armor = Nilai armor; pengurangan damage tetap per serangan.
laccess.efficiency = Efisiensi operasional bangunan, dengan nilai nominal 1.
laccess.timescale = Pengali skala waktu yang memengaruhi bangunan, dengan nilai 1 berarti kecepatan normal.
laccess.rotation = Sudut hadap unit atau turret, dalam derajat.\nUntuk sebagian besar bangunan lainnya, orientasi berkisar antara 0 hingga 3.
laccess.x = Posisi X, dalam satuan ubin.
laccess.y = Posisi Y, dalam satuan ubin.
laccess.velocityx = Kecepatan X suatu unit, dalam satuan ubin/detik.
laccess.velocityy = Kecepatan Y suatu unit, dalam satuan ubin/detik.
laccess.shootx = Koordinat X yang dituju oleh unit atau turret.
laccess.shooty = Koordinat Y yang dituju oleh unit atau turret.
laccess.camerax = Posisi X kamera pemain yang memegang kendali.
laccess.cameray = Posisi Y kamera pemain yang memegang kendali.
laccess.camerawidth = Lebar pandangan pemain yang memegang kendali, dalam satuan ubin.
laccess.cameraheight = Tinggi pandangan pemain yang memegang kendali, dalam satuan ubin.
laccess.solid = Apakah bangunan ini menghalangi pergerakan.
laccess.range = Jangkauan unit atau turret, dalam satuan ubin.
laccess.shooting = Apakah unit atau turret sedang menembak.
laccess.boosting = Apakah unit saat ini sedang mengaktifkan pendorong atau terbang melintasi medan.
laccess.minex = Koordinat ubin X tempat unit sedang menambang, atau -1 jika tidak sedang menambang.
laccess.miney = Koordinat ubin Y tempat unit sedang menambang, atau -1 jika tidak sedang menambang.
laccess.mining = Apakah suatu unit sedang menambang.
laccess.buildx = Koordinat ubin X tempat unit sedang membangun, atau -1 jika tidak sedang membangun.
laccess.buildy = Koordinat ubin Y tempat unit sedang membangun, atau -1 jika tidak sedang membangun.
laccess.pingx = Koordinat X yang sedang ditandai oleh pemain, atau null jika tidak sedang menandai.
laccess.pingy = Koordinat Y yang sedang ditandai oleh pemain, atau null jika tidak sedang menandai.
laccess.pingtext = Teks yang menunjukkan ping pemain saat ini, atau null jika tidak sedang melakukan ping.
laccess.building = Unit yang sedang membangun saat ini, atau null.
laccess.breaking = Unit yang sedang mendekonstruksi saat ini, atau null.
laccess.team = ID Tim dari unit atau bangunan.
laccess.flag = Nilai flag numerik yang disimpan pada unit.
laccess.flying = Apakah suatu unit saat ini sedang berada di udara.
laccess.name = Nama pemain yang mengendalikan unit ini, atau null.
laccess.payloadcount = Jumlah muatan yang saat ini dimiliki.
laccess.payloadtype = Jenis muatan terakhir yang diambil, atau null.
laccess.totalpayload = Ukuran gabungan dari semua muatan yang disimpan.
laccess.payloadcapacity = Ukuran muatan gabungan maksimum yang dapat dibawa oleh unit atau bangunan.
laccess.selectedblock = Blok yang saat ini dipilih oleh pemain yang memegang kendali, atau null.
laccess.selectedrotation = Rotasi bangunan yang saat ini dipilih oleh pemain yang memegang kendali, 0 hingga 3.
laccess.bulletlifetime = Total masa hidup peluru, dalam satuan tick.
laccess.bullettime = Durasi peluru aktif, dalam satuan tick.
lcategory.unknown = Tak Diketahui
lcategory.unknown.description = Instruksi tanpa kategori.
@@ -3288,7 +3288,7 @@ graphicstype.label.reset = atur ulang
laccess.label.totalitems = total item
laccess.label.firstitem = item pertama
laccess.label.totalliquids = total cairan
laccess.label.totalpower = total daya
laccess.label.totalpower = total tenaga
laccess.label.itemcapacity = kapasitas item
laccess.label.liquidcapacity = kapasitas cairan
laccess.label.powercapacity = kapasitas tenaga
@@ -3357,7 +3357,7 @@ laccess.label.selectedblock = blok terpilih
laccess.label.selectedrotation = rotasi terpilih
laccess.label.bulletlifetime = masa aktif peluru
laccess.label.bullettime = waktu peluru
laccess.label.enabled = diaktifkan
laccess.label.enabled = aktifkan
laccess.label.shoot = tembak
laccess.label.shootp = prediksi tembak
laccess.label.config = konfig
@@ -3462,7 +3462,7 @@ radartarget.label.player = pemain
radartarget.label.attacker = penyerang
radartarget.label.flying = terbang
radartarget.label.ground = darat
radartarget.label.boss = boss
radartarget.label.boss = penjaga
tilelayer.label.floor = lantai
tilelayer.label.ore = bijih
tilelayer.label.block = blok

View File

@@ -1305,7 +1305,7 @@ bar.cargounitcap = Достигнут предел грузовой единиц
bar.drillspeed = Скорость бурения: {0}/с
bar.pumpspeed = Скорость выкачивания: {0}/с
bar.efficiency = Эффективность: {0}%
bar.yield = Получение: +{0}%
bar.yield = Получение: {0}%
bar.boost = Ускорение: +{0}%
bar.powerbuffer = Энергия в аккумуляторах: {0}/{1}
bar.powerbalance = Энергия: {0}/с
@@ -2951,63 +2951,63 @@ laccess.displayheight = Высота дисплея, в пикселях.
laccess.buffersize = Количество необработанных команд в графическом буфере дисплея.
laccess.operations = Количество операций, выполненных в блоке.\nДля дисплеев, возвращает количество выполненных операций Вывод рисования/drawflush.
laccess.maxunits = Максимальное количество единиц, которое может быть у команды.\nОпределяется с помощью ядер.
laccess.totalitems = Total number of items contained.
laccess.firstitem = First item contained, or null if empty.
laccess.totalliquids = Total amount of liquid contained.
laccess.totalpower = For blocks with a buffered power store, the amount of power stored; for other blocks, buffer fullness from 0 to 1.
laccess.itemcapacity = Maximum number of items this building can hold.
laccess.liquidcapacity = Maximum amount of liquid this building can hold.
laccess.powercapacity = Maximum amount of power this building can store.
laccess.powernetstored = Total power stored in the connected power grid.
laccess.powernetcapacity = Total power storage capacity of the connected power grid.
laccess.powernetin = Power entering the connected power grid, per second.
laccess.powernetout = Power leaving the connected power grid, per second.
laccess.ammo = Current ammo count of a turret.
laccess.ammocapacity = Maximum ammo count of a turret.
laccess.health = Current health.\nFor bullets, their damage.
laccess.maxhealth = Maximum health.\nFor bullets, the base damage.
laccess.heat = Current heat of a turret that consumes heat, 0 to 1.
laccess.shield = Current shield amount of a unit.
laccess.armor = Armor value; flat damage reduction per hit.
laccess.efficiency = Operating efficiency of a building, where 1 is nominal.
laccess.timescale = Time scale multiplier affecting a building, where 1 is normal speed.
laccess.rotation = Facing angle of a unit or turret, in degrees.\nFor most other buildings, the 0 to 3 orientation.
laccess.x = X position, in tiles.
laccess.y = Y position, in tiles.
laccess.velocityx = X velocity of a unit, in tiles/sec.
laccess.velocityy = Y velocity of a unit, in tiles/sec.
laccess.shootx = X coordinate a unit or turret is aiming at.
laccess.shooty = Y coordinate a unit or turret is aiming at.
laccess.camerax = X position of the controlling player's camera.
laccess.cameray = Y position of the controlling player's camera.
laccess.camerawidth = Width of the controlling player's view, in tiles.
laccess.cameraheight = Height of the controlling player's view, in tiles.
laccess.solid = Whether this building blocks movement.
laccess.range = Range of a unit or turret, in tiles.
laccess.shooting = Whether a unit or turret is currently shooting.
laccess.boosting = Whether a unit is currently boosting or flying over terrain.
laccess.minex = X tile coordinate a unit is mining, or -1 if not mining.
laccess.miney = Y tile coordinate a unit is mining, or -1 if not mining.
laccess.mining = Whether a unit is currently mining.
laccess.buildx = X tile coordinate a unit is building at, or -1 if not building.
laccess.buildy = Y tile coordinate a unit is building at, or -1 if not building.
laccess.pingx = X coordinate a player is pinging, or null if not pinging.
laccess.pingy = Y coordinate a player is pinging, or null if not pinging.
laccess.pingtext = Text of a player's current ping, or null if not pinging.
laccess.building = Building a unit is currently constructing, or null.
laccess.breaking = Building a unit is currently deconstructing, or null.
laccess.team = Team ID of a unit or building.
laccess.flag = Numeric flag value stored on a unit.
laccess.flying = Whether a unit is currently airborne.
laccess.name = Name of the player controlling this unit, or null.
laccess.payloadcount = Number of payloads currently held.
laccess.payloadtype = Type of the last payload picked up, or null.
laccess.totalpayload = Combined size of all held payloads.
laccess.payloadcapacity = Maximum combined payload size a unit or building can carry.
laccess.selectedblock = Block currently selected by the controlling player, or null.
laccess.selectedrotation = Build rotation currently selected by the controlling player, 0 to 3.
laccess.bulletlifetime = Total lifetime of a bullet, in ticks.
laccess.bullettime = Time a bullet has existed, in ticks.
laccess.totalitems = Общее количество хранимых предметов.
laccess.firstitem = Первый хранимый предмет. Если пусто - возвращает null.
laccess.totalliquids = Общее количество хранимой жидкости.
laccess.totalpower = Для блоков, хранящих энергию, возвращает её количество; для остальных блоков, их уровень энергии от 0 до 1.
laccess.itemcapacity = Максимальное количество предметов, хранимых этой постройкой.
laccess.liquidcapacity = Максимальное количество жидкости, хранимой этой постройкой.
laccess.powercapacity = Максимальное количество энергии, хранимой этой постройкой.
laccess.powernetstored = Общее количество энергии, хранимой в сети.
laccess.powernetcapacity = Максимальное количество энергии, хранимой в сети.
laccess.powernetin = Энергия, входящая в сеть за секунду.
laccess.powernetout = Энергия, выходящая из сети за секунду.
laccess.ammo = Текущее количество боеприпасов в турели.
laccess.ammocapacity = Максимальное количество боеприпасов в турели.
laccess.health = Текущее здоровье.\nДля пуль возвращает их урон.
laccess.maxhealth = Максимальное здоровье.\nДля пуль возвращает их базовый урон.
laccess.heat = Текущий нагрев турели, от 0 до 1.
laccess.shield = Общее количество щита у юнита.
laccess.armor = Значение брони; на сколько снизится получаемый урон за удар.
laccess.efficiency = Эффективность работы постройки. 1 - обычная эффективность.
laccess.timescale = Множитель скорости, применённый на эту постройку. 1 - обычная скорость.
laccess.rotation = Угол направления юнита или турели в градусах.\nДля большинства других построек возвращает 0-3 в зависимости от их направления.
laccess.x = Позиция X блока/юнита в блоках.
laccess.y = Позиция Y блока/юнита в блоках.
laccess.velocityx = Скорость юнита по X в блоках/сек.
laccess.velocityy = Скорость юнита по Y в блоках/сек.
laccess.shootx = Позиция X, в которую нацелен юнит или турель.
laccess.shooty = Позиция Y, в которую нацелен юнит или турель.
laccess.camerax = Позиция X камеры управляющего игрока.
laccess.cameray = Позиция Y камеры управляющего игрока.
laccess.camerawidth = Ширина камеры управляющего игрока в блоках.
laccess.cameraheight = Высота камеры управляющего игрока в блоках.
laccess.solid = Блокирует ли этот блок движение.
laccess.range = Радиус юнита или турели в блоках.
laccess.shooting = Стреляет ли юнит/турель в данный момент.
laccess.boosting = Летает ли этот наземный юнит.
laccess.minex = Позиция X руды, которую сейчас добывает юнит, или -1, если не добывает.
laccess.miney = Позиция Y руды, которую сейчас добывает юнит, или -1, если не добывает.
laccess.mining = Добывает ли юнит руду.
laccess.buildx = Позиция X, на которой сейчас строит юнит, или -1, если не строит.
laccess.buildy = Позиция Y, на которой сейчас строит юнит, или -1, если не строит.
laccess.pingx = Позиция X отметки, поставленной игроком, или null, если отметки нет.
laccess.pingy = Позиция Y отметки, поставленной игроком, или null, если отметки нет.
laccess.pingtext = Текст отметки, поставленной игроком, или null, если отметки нет.
laccess.building = Блок, который сейчас строится юнитом, или null.
laccess.breaking = Блок, который сейчас разбирается юнитом, или null.
laccess.team = ID команды юнита/блока.
laccess.flag = Числовой флаг, назначенный юниту.
laccess.flying = Летает ли этот юнит.
laccess.name = Имя управляющего игрока, или null.
laccess.payloadcount = Количество перевозимых грузов.
laccess.payloadtype = Тип последнего подобранного груза, или null.
laccess.totalpayload = Суммарный размер всех перевозимых грузов.
laccess.payloadcapacity = Максимальный суммарный размер всех перевозимых грузов юнита.
laccess.selectedblock = Блок, выбранный управляющим игроком, или null.
laccess.selectedrotation = Вращение блока, выбранного управляющим игроком, от 0 до 3.
laccess.bulletlifetime = Максимальное время жизни пули в тиках.
laccess.bullettime = Время существования пули в тиках.
lcategory.unknown = Неизвестно
lcategory.unknown.description = Нет категории.
@@ -3502,9 +3502,9 @@ name.token.global = глобальный
name.token.target = цель
name.token.and = и
name.token.or = или
name.token.b-and = бит-и
name.token.xor = ис-или
name.token.flip = бит-не
name.token.b-and = b-and
name.token.xor = xor
name.token.flip = flip
name.token.order = порядок
name.token.sort = сортировка
name.token.output = выход
@@ -3515,8 +3515,8 @@ name.token.find = найти
name.token.group = группа
name.token.enemy = враг?
name.token.ore = руда
name.token.outX = X
name.token.outY = Y
name.token.outX = X цели
name.token.outY = Y цели
name.token.owner = владелец
name.token.found = найден?
name.token.building = постройка
@@ -3538,7 +3538,7 @@ name.token.natural = естественная
name.token.speed = скорость
name.token.level = уровень
name.token.duration = длительность
name.token.seconds = seconds
name.token.seconds = секунд
name.token.shown = отображается
name.token.data = данные
name.token.effect = эффект
@@ -3605,7 +3605,7 @@ name.token.blockFall = падение блока
name.token.placeBlock = размещение блока
name.token.placeBlockSpark = размещение блока (искры)
name.token.breakBlock = разрушение блока
name.token.-spawn = = spawn
name.token.-spawn = = создать
name.token.trail = след
name.token.breakProp = разрушение валуна
name.token.smokeCloud = облако дыма

View File

@@ -8,7 +8,6 @@ import arc.struct.*;
import arc.util.TaskQueue;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.core.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
@@ -263,7 +262,7 @@ public class Pathfinder implements Runnable{
tile.build == null || !solid || tile.block() instanceof CoreBlock ? 0 : Math.min((int)(tile.build.health / 40), 80),
tid == 0 && tile.build != null && state.rules.coreCapture ? 255 : tid, //use teamid = 255 when core capture is enabled to mark out derelict structures
solid,
tile.floor().isLiquid && tile.block() == Blocks.air,
tile.floor().isLiquid && !tile.block().solid,
tile.legSolid(),
nearLiquid,
nearGround,

View File

@@ -415,8 +415,9 @@ public class UI implements ApplicationListener, Loadable{
table.touchable = Touchable.disabled;
table.setFillParent(true);
if(cinfo.visible && !state.isMenu()) table.marginTop(cinfo.getPrefHeight() / Scl.scl() / 2);
table.update(() -> {
table.visible(() -> {
if(state.isMenu()) table.remove();
return ui.hudfrag.shown;
});
table.actions(Actions.delay(duration * 0.9f), Actions.fadeOut(duration * 0.1f, Interp.fade), Actions.remove());
table.top().table(Styles.black3, t -> t.margin(4).add(info).style(Styles.outlineLabel)).padTop(10);
@@ -438,11 +439,12 @@ public class UI implements ApplicationListener, Loadable{
}
table.setFillParent(true);
table.touchable = Touchable.disabled;
table.update(() -> {
table.visible(() -> {
if(state.isMenu()){
table.remove();
if(id != null) popups.remove(id);
}
return ui.hudfrag.shown;
});
table.actions(Actions.delay(duration), Actions.remove(), Actions.run(() -> { if(id != null) popups.remove(id); }));
table.align(align).table(Styles.black3, t -> t.margin(4).add(info).style(Styles.outlineLabel)).pad(top, left, bottom, right);

View File

@@ -84,7 +84,7 @@ public class Lightning{
Unit furthest = Geometry.findFurthest(x, y, entities);
if(furthest != null && furthest.dst(x, y) < length * 1.5f){
if(furthest != null && furthest.within(x, y, hitRange * 2f)){
hit.add(furthest.id());
x = furthest.x();
y = furthest.y();

View File

@@ -16,6 +16,7 @@ abstract class TargetDummyComp implements Unitc, Healthc{
}
}
@Replace
@Override
public void rawDamage(float amount){
if(building instanceof TargetDummyBuild td){

View File

@@ -11,9 +11,6 @@ import mindustry.logic.LExecutor.*;
public class LAssembler{
public static ObjectMap<String, Func<String[], LStatement>> customParsers = new ObjectMap<>();
private static final long invalidNumNegative = Long.MIN_VALUE;
private static final long invalidNumPositive = Long.MAX_VALUE;
public boolean privileged;
/** Maps names to variable. */
public OrderedMap<String, LVar> vars = new OrderedMap<>();
@@ -110,23 +107,48 @@ public class LAssembler{
}
double parseDouble(String symbol){
//fail fast for obvious non-numbers
if(symbol.isEmpty() || !isNumStart(symbol.charAt(0))) return Double.NaN;
//parse hex/binary syntax
if(symbol.startsWith("0b")) return parseLong(false, symbol, 2, 2, symbol.length());
if(symbol.startsWith("+0b")) return parseLong(false, symbol, 2, 3, symbol.length());
if(symbol.startsWith("-0b")) return parseLong(true,symbol, 2, 3, symbol.length());
if(symbol.startsWith("0x")) return parseLong(false,symbol, 16, 2, symbol.length());
if(symbol.startsWith("+0x")) return parseLong(false,symbol, 16, 3, symbol.length());
if(symbol.startsWith("-0x")) return parseLong(true,symbol, 16, 3, symbol.length());
if(symbol.startsWith("0b")) return parseHexOrBin(false, symbol, true, 2);
if(symbol.startsWith("+0b")) return parseHexOrBin(false, symbol, true, 3);
if(symbol.startsWith("-0b")) return parseHexOrBin(true, symbol, true, 3);
if(symbol.startsWith("0x")) return parseHexOrBin(false, symbol, false, 2);
if(symbol.startsWith("+0x")) return parseHexOrBin(false, symbol, false, 3);
if(symbol.startsWith("-0x")) return parseHexOrBin(true, symbol, false, 3);
if(symbol.startsWith("%[") && symbol.endsWith("]") && symbol.length() > 3) return parseNamedColor(symbol);
if(symbol.startsWith("%") && (symbol.length() == 7 || symbol.length() == 9)) return parseColor(symbol);
return Strings.parseDouble(symbol, Double.NaN);
}
double parseLong(boolean negative, String s, int radix, int start, int end) {
long usedInvalidNum = negative ? invalidNumPositive : invalidNumNegative;
long l = Strings.parseLong(s, radix, start, end, usedInvalidNum);
return l == usedInvalidNum ? Double.NaN : negative ? -l : l;
boolean isNumStart(char c){
//note that 'e10' isn't a valid number; '%ffffff' is. Hex numbers start with '0x'.
return c >= '0' && c <= '9' || c == '.' || c == '-' || c == '+' || c == '%';
}
//parses *unsigned* hex or bin number, including negative ones (0xffffffffffffffff as -1)
//detects overflow by input length and uses bit manipulation to avoid signed arithmetics
double parseHexOrBin(boolean negative, String s, boolean binary, int offset){
int end = s.length();
if(offset >= end) return Double.NaN;
int pos = offset;
while(pos < end && s.charAt(pos) == '0') pos ++; //skip leading zeros to avoid incorrect overflow detection
int shift = binary ? 1 : 4;
if(end - pos > 64 / shift) return Double.NaN;
long acc = 0;
int radix = 1 << shift;
while(pos < end){
int digit = Character.digit(s.charAt(pos), radix);
if(digit < 0) return Double.NaN;
acc = acc << shift | digit;
pos ++;
}
return negative ? -acc : acc;
}
double parseColor(String symbol){
@@ -178,4 +200,4 @@ public class LAssembler{
return vars.get(name);
}
}
}

View File

@@ -2541,7 +2541,7 @@ public class LStatements{
b.label(() -> bundle(type));
b.clicked(() -> showSelect(b, MapObjectives.allMarkerTypeNames.toArray(String.class), type, t -> {
type = bundle(t);
type = t;
build(table);
}, 2, cell -> cell.size(160, 50)));
}, Styles.logict, () -> {}).size(180, 40).color(table.color).left().padLeft(2);

View File

@@ -195,8 +195,8 @@ public class DataPatcher{
//register global variables
for(var cont : all){
if(!cont.hasErrored() && cont instanceof UnlockableContent u && Vars.logicVars.get("@" + u.name) == null){
addedVars.add(Vars.logicVars.put("@" + u.name, u, false));
if(!cont.hasErrored() && cont instanceof UnlockableContent u && Vars.logicVars.get("@" + (u instanceof StatusEffect ? "status-" : "") + u.name) == null){
addedVars.add(Vars.logicVars.put("@" + (u instanceof StatusEffect ? "status-" : "") + u.name, u, false));
}
}

View File

@@ -1,10 +1,16 @@
package mindustry.mod;
import arc.struct.*;
import arc.util.*;
import mindustry.ui.dialogs.*;
/** Mod listing as a data class. */
public class ModListing{
public String repo, name, internalName, author, lastUpdated, description, minGameVersion, version, iconHash = "";
public boolean hasScripts, hasJava, iosCompatible, legacyCompatible, hasIcon;
public String[] contentTypes = {};
/** game build -> release ID + mod version */
public @Nullable ArrayMap<String, ModRelease> releases;
public String[] tags = {};
public int stars;
@Override
@@ -22,4 +28,30 @@ public class ModListing{
", stars=" + stars +
'}';
}
/** @return the specific release that matches the current game version, or null if no specific match is found (i.e. /latest should be used) */
public @Nullable ModRelease getMatchingRelease(){
if(releases == null) return null;
for(var entry : releases){
if(ModsDialog.matchesGameVersion(ModsDialog.parseVersion(entry.key))){
return entry.value;
}
}
return null;
}
public static class ModRelease{
/** Github release ID ($API/releases/$ID) */
public String id = "";
/** Actual mod version string in release's mod.json */
public String version = "";
@Override
public String toString(){
return "ModRelease{" +
"id='" + id + '\'' +
", version='" + version + '\'' +
'}';
}
}
}

View File

@@ -130,7 +130,7 @@ public class EditorMapsDialog extends MapListDialog{
if(!map.tags.get("description", "").isEmpty()){
t.add("@editor.description").padRight(10).color(Color.gray).top();
t.row();
t.add(map.description()).growX().wrap().padTop(2);
t.add(map.description()).growX().wrap(true).padTop(2);
}
}).height(mapsize).width(mapsize);

View File

@@ -65,6 +65,11 @@ public class ModBrowserDialog extends BaseDialog{
shown(this::rebuildBrowser);
}
public @Nullable ModListing getCachedMod(String repo){
if(modList == null) return null;
return modList.find(m -> m.repo.equalsIgnoreCase(repo));
}
public void getModList(Cons<Seq<ModListing>> listener){
//mods already fetched, use that
if(modList != null){
@@ -247,7 +252,7 @@ public class ModBrowserDialog extends BaseDialog{
textureCache.put(repo, last = Core.atlas.find("nomap"));
if(mod.hasIcon){
Fi cacheFolder = Vars.mobile ? Core.files.cache("modIconCache"): dataDirectory.child("modIconCache");
Fi cacheFolder = mobile ? Core.files.cache("modIconCache"): dataDirectory.child("modIconCache");
cacheFolder.mkdirs();
Fi cacheFile = cacheFolder.child(Strings.sanitizeFilename(mod.repo + "_" + mod.iconHash) + ".png");
@@ -337,7 +342,7 @@ public class ModBrowserDialog extends BaseDialog{
var found = mods.list().find(l -> mod.repo != null && mod.repo.equals(l.getRepo()));
sel.buttons.button(found == null ? "@mods.browser.add" : "@mods.browser.reinstall", Icon.download, () -> {
sel.hide();
ui.mods.githubImportMod(mod.repo, mod.hasJava, null, true);
ui.mods.githubImportMod(mod);
});
if(Core.graphics.isPortrait()){

View File

@@ -17,6 +17,7 @@ import arc.util.Http.*;
import arc.util.io.*;
import arc.util.serialization.*;
import arc.util.serialization.Jval.*;
import mindustry.core.*;
import mindustry.ctype.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
@@ -26,10 +27,13 @@ import mindustry.mod.Mods.*;
import mindustry.ui.*;
import java.util.*;
import java.util.regex.*;
import static mindustry.Vars.*;
public class ModsDialog extends BaseDialog{
private static final Pattern modVersionPattern = Pattern.compile("\\[[vb](\\d+)(?:\\.(\\d+))?\\]");
public ModBrowserDialog browser;
protected float modImportProgress;
@@ -105,7 +109,11 @@ public class ModsDialog extends BaseDialog{
var mod = repoToMod.get(entry.repo);
if(mod != null){
modToListing.put(mod, entry);
if(Strings.checkNewerSemver(entry.version, mod.meta.version)) withUpdates.add(mod);
var release = entry.getMatchingRelease();
//Only compare to the release that fits the current version the client is using, if one exists; don't look for updates that don't match the version
if(Strings.checkNewerSemver(entry.version, release == null ? mod.meta.version : release.version)){
withUpdates.add(mod);
}
}
}
@@ -171,8 +179,15 @@ public class ModsDialog extends BaseDialog{
if(text.startsWith("https://github.com/")) text = text.substring("https://github.com/".length());
Core.settings.put("lastmod", text);
//there's no good way to know if it's a java mod here, so assume it's not
githubImportMod(text, false, null, true);
var listing = browser.getCachedMod(text);
if(listing != null){
//auto-choose release when a listing is found
githubImportMod(listing);
}else{
//this will auto-detect whether it's java, then grab latest release unconditionally
//TODO: would be nice to grab version-appropriate release but I don't want to copy-paste browser logic for this
githubImportMod(text, false, null, true);
}
});
}).margin(12f);
});
@@ -526,7 +541,7 @@ public class ModsDialog extends BaseDialog{
}
}
public void viewReleases(String repo, boolean isJava, boolean reinstall) {
public void viewReleases(String repo, boolean isJava, boolean reinstall){
BaseDialog load = new BaseDialog("");
load.cont.add("[accent]" + Core.bundle.get("mods.browser.fetching"));
load.show();
@@ -596,6 +611,11 @@ public class ModsDialog extends BaseDialog{
}));
}
public void githubImportMod(ModListing mod){
var matchingRelease = mod.getMatchingRelease();
githubImportMod(mod.repo, mod.hasJava, matchingRelease == null ? null : matchingRelease.id, true);
}
public void githubImportMod(String repo, boolean isJava, boolean forceEnable){
githubImportMod(repo, isJava, null, forceEnable);
}
@@ -686,4 +706,52 @@ public class ModsDialog extends BaseDialog{
}, this::importFail);
}
}
/** @return {major, minor} parsed from a leading/trailing "[v{major}]" or "[v{major}.{minor}]" tag, or null if none is found at either end (or the numbers are unparseable). */
public static @Nullable int[] parseVersionTag(String str){
if(str == null) return null;
Matcher m = modVersionPattern.matcher(str);
while(m.find()){
if(m.start() == 0 || m.end() == str.length()){
int major = Strings.parseInt(m.group(1));
//any major version below 15 is likely a major-version tag like [v7] and should be ignored
if(major == Integer.MIN_VALUE || major < 15) return null;
int minor = m.group(2) != null ? Strings.parseInt(m.group(2)) : 0;
if(minor == Integer.MIN_VALUE) return null;
return new int[]{major, minor};
}
}
return null;
}
public static @Nullable int[] parseVersion(String str){
if(str == null || str.isEmpty()) return null;
int dot = str.indexOf('.');
String majorStr = dot == -1 ? str : str.substring(0, dot);
String minorStr = dot == -1 ? null : str.substring(dot + 1);
if(majorStr.isEmpty() || (dot != -1 && (minorStr.isEmpty() || str.indexOf('.', dot + 1) != -1))) return null;
int major = Strings.parseInt(majorStr);
if(major == Integer.MIN_VALUE) return null;
int minor = minorStr != null ? Strings.parseInt(minorStr) : 0;
if(minor == Integer.MIN_VALUE) return null;
return new int[]{major, minor};
}
/** @return whether the specified release name and its tags match the current game build (e.g. "Bingus Mod [v160]" should only match build 160) */
public static boolean matchesGameVersion(String releaseTitle){
return matchesGameVersion(parseVersionTag(releaseTitle));
}
public static boolean matchesGameVersion(@Nullable int[] tag){
//version not specified, matches anything.
if(tag == null) return true;
//must match exactly; custom builds (-1) do not match.
//for revisions, either match if the revision is unspecified (v160 -> matches ALL 160.x builds), OR, if it is specified, match the exact version (the mod author must have had a good reason for it)
return Version.build == tag[0] && (tag[1] == 0 || Version.revision == tag[1]);
}
}

View File

@@ -235,8 +235,6 @@ public class PlayerListFragment{
dialog.cont.button("@back", Icon.left, dialog::hide).padTop(-1f).size(220f, 55f);
dialog.show();
}).size(h);
}
}else if(!user.isLocal() && !user.admin && net.client() && Groups.player.size() >= 3 && player.team() == user.team()){ //votekick

View File

@@ -756,7 +756,7 @@ public class Block extends UnlockableContent implements Senseable{
}
//nothing was added, so it's safe to add a dynamic liquid bar (probably?)
if(!added){
if(!added && liquidCapacity > 0f){
addLiquidBar(build -> build.liquids.current());
}
}

View File

@@ -186,7 +186,7 @@ public class Build{
return false;
}
if(!state.rules.editor && checkCoreRadius){
if(!state.rules.editor && checkCoreRadius && !(!checkVisible && team == Team.derelict)){
//find closest core, if it doesn't match the team, placing is not legal
if(state.rules.polygonCoreProtection){
float mindst = Float.MAX_VALUE;

View File

@@ -11,11 +11,15 @@ import mindustry.world.meta.*;
/** A crafter that gains efficiency from attribute tiles. */
public class AttributeCrafter extends GenericCrafter{
public Attribute attribute = Attribute.heat;
/** Base efficiency of the crafter. */
public float baseEfficiency = 1f;
/** Maximum efficiency/output boost from attributes. */
public float maxBoost = 1f;
/** Minimum efficiency required to place this block. */
public float minEfficiency = -1f;
public boolean displayEfficiency = true;
public boolean displayScaledOutput = true;
/** Whether to show this bar in the UI. */
public boolean displayEfficiency = true, displayScaledOutput = true;
/** Whether liquid consumption scales with efficiency. */
public boolean scaleLiquidConsumption = false;
/** Scaled output (yield) multiplier, scales with attribute. <=0 to disable. */
public float outputScale = 0f;
@@ -34,12 +38,10 @@ public class AttributeCrafter extends GenericCrafter{
drawPlaceText(
(displayEfficiency && boostScale > 0f ?
Core.bundle.format("bar.efficiency",
(int)((baseEfficiency + Math.min(maxBoost, boostScale * sumAttribute(attribute, x, y))) * 100f))
Core.bundle.format("bar.efficiency", (int)((baseEfficiency + Math.min(maxBoost, boostScale * sumAttribute(attribute, x, y))) * 100f))
: "") +
(displayScaledOutput && outputScale > 0f ? "\n" +
Core.bundle.format("bar.yield",
(int)(Math.min(maxBoost, outputScale * sumAttribute(attribute, x, y)) * 100f))
(displayScaledOutput && outputScale > 0f ?
"\n" + Core.bundle.format("bar.yield", (int)((1f + Math.min(maxBoost, outputScale * sumAttribute(attribute, x, y))) * 100f))
: ""), x, y, valid);
}
@@ -59,7 +61,7 @@ public class AttributeCrafter extends GenericCrafter{
if(displayScaledOutput && outputScale > 0f){
addBar("yield", (AttributeCrafterBuild entity) ->
new Bar(
() -> Core.bundle.format("bar.yield", (int)((entity.outputMultiplier() - baseEfficiency) * 100)),
() -> Core.bundle.format("bar.yield", (int)(entity.outputMultiplier() * 100)),
() -> Pal.lightOrange,
entity::outputMultiplier));
}

View File

@@ -334,7 +334,10 @@ public class GenericCrafter extends Block{
public void dumpOutputs(){
if(outputItems != null && timer(timerDump, dumpTime / timeScale)){
for(ItemStack output : outputItems){
dump(output.item);
int amount = Math.max(1, Mathf.round(scaleOutput(output.amount)));
for(int i = 0; i < amount; i++){
if(!dump(output.item)) break;
}
}
}

View File

@@ -97,7 +97,7 @@ public class ItemModule extends BlockModule{
/** @return a specific item's flow rate in items/s; any value < 0 means not ready.*/
public float getFlowRate(Item item){
return flow == null ? -1f : displayFlow[item.id] * 60;
return flow == null ? -1f : displayFlow != null ? displayFlow[item.id] * 60 : -1f;
}
public boolean hasFlowItem(Item item){

View File

@@ -78,7 +78,7 @@ public class LiquidModule extends BlockModule{
/** @return current liquid's flow rate in u/s; any value < 0 means 'not ready'. */
public float getFlowRate(Liquid liquid){
return flow == null ? -1f : displayFlow[liquid.id] * 60;
return flow == null ? -1f : displayFlow != null ? displayFlow[liquid.id] * 60 : -1f;
}
public boolean hasFlowLiquid(Liquid liquid){

View File

@@ -26,4 +26,4 @@ org.gradle.caching=true
org.gradle.internal.http.socketTimeout=100000
org.gradle.internal.http.connectionTimeout=100000
android.enableR8.fullMode=false
archash=c082cc548b
archash=ac71a73ac8

View File

@@ -38,6 +38,8 @@
<true/>
<key>UIRequiresFullScreen</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSPhotoLibraryAddUsageDescription</key>

View File

@@ -1,3 +1,4 @@
import arc.graphics.*;
import mindustry.logic.*;
import mindustry.logic.LExecutor.*;
import org.junit.jupiter.api.*;
@@ -243,6 +244,123 @@ public class LogicTests{
);
}
/** Values that must resolve to a numeric constant (isobj == false) or an object constant. */
static Stream<Arguments> parseValCases(){
return Stream.of(
// name, symbol, expected (Double => numeric, anything else => object)
Arguments.of("parse null", "null", null),
//decimal
Arguments.of("decimal: zero", "0", 0.0),
Arguments.of("decimal: positive integer", "42", 42.0),
Arguments.of("decimal: negative integer", "-42", -42.0),
Arguments.of("decimal: explicit plus sign", "+42", 42.0),
Arguments.of("decimal: fraction", "3.14", 3.14),
Arguments.of("decimal: negative fraction", "-3.14", -3.14),
Arguments.of("decimal: leading dot", ".5", 0.5),
Arguments.of("decimal: large integer", "123456789012", 123456789012.0),
Arguments.of("decimal: scientific", "1e3", 1000.0),
Arguments.of("decimal: scientific negative exponent", "1.5e-2", 0.015),
//hex
Arguments.of("hex: zero", "0x0", 0.0),
Arguments.of("hex: uppercase digits", "0xFF", 255.0),
Arguments.of("hex: lowercase digits", "0xff", 255.0),
Arguments.of("hex: mixed case", "0xDeadBeef", 3735928559.0),
Arguments.of("hex: explicit plus", "+0xFF", 255.0),
Arguments.of("hex: negative", "-0xFF", -255.0),
Arguments.of("hex: many leading zeros aren't overflow", "0x0000000000000000000000FF", 255.0),
Arguments.of("hex: only zeros", "0x" + "0".repeat(100), 0.0),
Arguments.of("hex: Long.MAX_VALUE", "0x7FFFFFFFFFFFFFFF", (double)Long.MAX_VALUE),
Arguments.of("hex: Long.MIN_VALUE (0x8000...)", "0x8000000000000000", (double)Long.MIN_VALUE),
Arguments.of("hex: unsigned long max wraps to -1", "0xFFFFFFFFFFFFFFFF", -1.0),
Arguments.of("hex: unsigned long max - 1 wraps to -2", "0xFFFFFFFFFFFFFFFE", -2.0),
Arguments.of("hex: negated -1 wrap gives 1", "-0xFFFFFFFFFFFFFFFF", 1.0),
Arguments.of("hex: negative Long.MAX_VALUE", "-0x7FFFFFFFFFFFFFFF", -(double)Long.MAX_VALUE),
//binary
Arguments.of("bin: zero", "0b0", 0.0),
Arguments.of("bin: one", "0b1", 1.0),
Arguments.of("bin: ten", "0b1010", 10.0),
Arguments.of("bin: explicit plus", "+0b1010", 10.0),
Arguments.of("bin: negative", "-0b1010", -10.0),
Arguments.of("bin: many leading zeros aren't overflow", "0b" + "0".repeat(70) + "1", 1.0),
Arguments.of("bin: 63 ones is Long.MAX_VALUE", "0b0" + "1".repeat(63), (double)Long.MAX_VALUE),
Arguments.of("bin: 1 followed by 63 zeros is Long.MIN_VALUE", "0b1" + "0".repeat(63), (double)Long.MIN_VALUE),
Arguments.of("bin: 64 ones wraps to -1", "0b" + "1".repeat(64), -1.0)
);
}
@ParameterizedTest(name = "{0}")
@MethodSource("parseValCases")
void parseVarValues(String name, String symbol, Object expected){
LAssembler asm = new LAssembler();
LVar v = asm.var(symbol);
if(expected instanceof Double d){
assertFalse(v.isobj, "should be numeric: " + symbol);
assertEquals(d, v.numval, 0.00001f);
}else{
assertTrue(v.isobj);
assertEquals(expected, v.objval);
}
}
/** Colors are packed into the bits of a (tiny, denormal) double, so they need an exact comparison. */
static Stream<Arguments> parseColorCases(){
return Stream.of(
Arguments.of("color: rgb white", "%ffffff", Color.toDoubleBits(255, 255, 255, 255)),
Arguments.of("color: rgba", "%ff000080", Color.toDoubleBits(255, 0, 0, 128)),
Arguments.of("color: named", "%[red]", Colors.get("red").toDoubleBits())
);
}
@ParameterizedTest(name = "{0}")
@MethodSource("parseColorCases")
void parseColorValues(String name, String symbol, double expected){
LAssembler asm = new LAssembler();
LVar v = asm.var(symbol);
assertFalse(v.isobj);
assertEquals(expected, v.numval, 0.0);
}
/** Anything here must NOT be parsed as a number (i.e. it becomes a plain variable name). */
static Stream<String> invalidNumberCases(){
return Stream.of(
//fail-fast: first char can't start a number
"",
"abc",
"e10",
"NaN",
"Infinity",
//prefix with no digits
"0x", "0b", "+0x", "-0b",
//invalid digits
"0xG", "0x12G4", "0b2", "0b102", "0x-1", "0x1.5",
//overflow: more than 64 significant bits
"0x1" + "0".repeat(16), //17 hex digits
"-0x1" + "0".repeat(16),
"0x" + "F".repeat(17),
"0b1" + "0".repeat(64), //65 binary digits
"0b" + "1".repeat(65),
//malformed colors
"%fff",
"%[nosuchcolor]"
);
}
@ParameterizedTest(name = "invalid: [{0}]")
@MethodSource("invalidNumberCases")
void parseInvalidNumbers(String symbol){
LAssembler asm = new LAssembler();
LVar v = asm.var(symbol);
assertTrue(v.isobj, "should not parse as a number: " + symbol);
assertNull(v.objval);
}
//unterminated / malformed string literals: these must fail loudly, never silently misparse
@ParameterizedTest(name = "{0}")