mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-10-04 12:20:21 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
beaa1da276 | ||
|
|
a378c35fb6 | ||
|
|
69ed90bb9d | ||
|
|
e337452d46 | ||
|
|
9f70386466 | ||
|
|
e7de4e1a10 | ||
|
|
4cc15b84f6 | ||
|
|
f3bfa418a5 | ||
|
|
663b0b8737 | ||
|
|
3a54813513 | ||
|
|
3e43d88374 | ||
|
|
580f8f5217 | ||
|
|
067c720a88 | ||
|
|
2541682bee | ||
|
|
78921a064e | ||
|
|
92d53b01fc | ||
|
|
8f1a4c5541 | ||
|
|
e2ccb6ea96 | ||
|
|
2f3a3979a4 | ||
|
|
9f065cea59 | ||
|
|
d2c5e09413 | ||
|
|
1cc5d54fde | ||
|
|
4ef2a6d81e | ||
|
|
be14e4173e | ||
|
|
c58aac5f67 | ||
|
|
cada4b2543 | ||
|
|
ccc5bebc3b | ||
|
|
8b80186320 | ||
|
|
1e8317fbac | ||
|
|
6500b5b6de | ||
|
|
eff677e112 | ||
|
|
543dae701c | ||
|
|
ec2bc54339 | ||
|
|
ca2c51896d | ||
|
|
c640ae21ad | ||
|
|
b8f392a116 | ||
|
|
bfa31bf184 | ||
|
|
088486c1ad | ||
|
|
acf891e419 | ||
|
|
ca90af5f56 | ||
|
|
45b82b9fa2 | ||
|
|
22cf431170 | ||
|
|
b513d92456 | ||
|
|
b3be63437e | ||
|
|
c801b625ac | ||
|
|
0bbc4c6777 | ||
|
|
4eed142ccc | ||
|
|
42ec5c9685 | ||
|
|
ca9876544e | ||
|
|
73d5865908 | ||
|
|
f474eab926 | ||
|
|
b76147ec50 | ||
|
|
22ca0ce33f | ||
|
|
4368c6e60e | ||
|
|
7591c51b60 | ||
|
|
93c88fea8c | ||
|
|
9de4deed37 | ||
|
|
254fd3e28d | ||
|
|
9a886aa582 | ||
|
|
a51047a80d | ||
|
|
55dba0c156 | ||
|
|
a98a7ba227 | ||
|
|
56348b3e31 | ||
|
|
89527f879b | ||
|
|
78646f512e | ||
|
|
fd4eac0f81 | ||
|
|
60cc6a1839 | ||
|
|
3d56fefb51 | ||
|
|
a5c178ae5a | ||
|
|
06163708bd | ||
|
|
137c6201c0 | ||
|
|
a341cff83f | ||
|
|
7501697f02 | ||
|
|
776214f7bb | ||
|
|
6df25c8308 | ||
|
|
ab51304dd6 | ||
|
|
e751e240db | ||
|
|
e675535cb7 | ||
|
|
84cdf2bbfe | ||
|
|
6f4914d5cb | ||
|
|
c7945610ee | ||
|
|
c6512c0b00 | ||
|
|
cc5a63109a | ||
|
|
43aa0d95f5 | ||
|
|
42ad617bbd | ||
|
|
e433d5f334 |
@@ -1,5 +1,5 @@
|
||||
If your pull request is **not** translation or serverlist-related, read the list of requirements below and check each box:
|
||||
If your pull request is **not** translation-related, read the list of requirements below and check each box:
|
||||
|
||||
- [ ] I have read the [contribution guidelines](https://github.com/Anuken/Mindustry/blob/master/CONTRIBUTING.md).
|
||||
- [ ] I have ensured that my code compiles, if applicable.
|
||||
- [ ] I have ensured that any new features in this PR function correctly in-game, if applicable.
|
||||
- [ ] I have ensured that any new features or fixes in this PR function correctly in-game, if applicable.
|
||||
- [ ] I affirm that this code follows Mindustry's [AI policy](https://github.com/Anuken/Mindustry/blob/master/CONTRIBUTING.md#ai-policy).
|
||||
+17
-9
@@ -4,9 +4,6 @@ This is for code contributions. For translations, see [TRANSLATING](TRANSLATING.
|
||||
|
||||
## Basic Guidelines
|
||||
|
||||
### Use an IDE.
|
||||
Specifically, IntelliJ IDEA. Download the (free) Community Edition of it [here](https://www.jetbrains.com/idea/download/). Some people use other tools, like VS Code, but I would personally not recommend them for Java development.
|
||||
|
||||
### Always test your changes.
|
||||
Do not submit something without at least running the game to see if it compiles.
|
||||
If you are submitting a new block, make sure it has a name and description, and that it works correctly in-game. If you are changing existing block mechanics, test them out first.
|
||||
@@ -20,11 +17,19 @@ Yes, there are occurrences of trailing spaces, extra newlines, empty indents, an
|
||||
|
||||
I **especially** do not want to see PRs that apply any kind of automated analysis to the source code to "optimize" anything - my IDE can do that already. If the PR doesn't actually change anything useful, I'm not going to review or merge it.
|
||||
|
||||
### Do not make AI "contributions".
|
||||
## AI Policy
|
||||
|
||||
If I see a PR with significant amounts of code that's obviously written by AI, I will reject your PR, and you will be blocked. Don't waste my time with slop.
|
||||
Mindustry's AI contribution policies are similar to that of [the Rust language](https://forge.rust-lang.org/policies/llm-usage.html), which are summarized as follows:
|
||||
|
||||
Asking AI questions, and using that information to help you write code? Fine. Using it to actually write code? No.
|
||||
- ✔️ You **are** allowed use AI to review your own code, summarize, inform, and answer questions.
|
||||
- ✔️ You **are** allowed to use AI to translate your *human-written* messages into English, if necessary.
|
||||
|
||||
- ❌ You are **not** allowed to submit PRs that are generated by AI.
|
||||
- ❌ You are **not** allowed to use AI to *generate* any text posted (PRs, issues, commit messages, etc.)
|
||||
|
||||
- ⚠️ If you post *anything* that is based on AI output (potential solution to a bug, crash diagnosis...), it must be clearly marked as being sourced from AI.
|
||||
|
||||
Repeated (or particularly egregious) violations of these rules will get you banned from this repository.
|
||||
|
||||
## Style Guidelines
|
||||
|
||||
@@ -67,7 +72,6 @@ What you'll usually need to change:
|
||||
### Avoid boxed types (Integer, Boolean)
|
||||
Never create variables or collections with boxed types `Seq<Integer>` or `ObjectMap<Integer, ...>`. Use the collections specialized for this task, e.g. `IntSeq` and `IntMap`.
|
||||
|
||||
|
||||
### Do not allocate anything if possible.
|
||||
Never allocate `new` objects in the main loop. If you absolutely require new objects, use `Pools` to obtain and free object instances.
|
||||
Otherwise, use the `Tmp` variables for things like vector/shape operations, or create `static` variables for re-use.
|
||||
@@ -77,9 +81,13 @@ If using a list, make it a static variable and clear it every time it is used. R
|
||||
This is situational, but in essence, what it means is to avoid using any sort of getters and setters unless absolutely necessary. Public or protected fields should suffice for most things.
|
||||
If something needs to be encapsulated in the future, IntelliJ can handle it with a few clicks.
|
||||
|
||||
|
||||
### Do not create methods unless necessary.
|
||||
Unless a block of code is very large or used in more than 1-2 places, don't split it up into a separate method. Making unnecessary methods only creates confusion, and may slightly decrease performance.
|
||||
|
||||
## Other Notes
|
||||
If you would like your name to appear in the game's credits, add it to the [list of contributors](https://github.com/Anuken/Mindustry/blob/master/core/assets/contributors) as part of your PR.
|
||||
|
||||
- If you would like your name to appear in the game's credits, add it to the [list of contributors](https://github.com/Anuken/Mindustry/blob/master/core/assets/contributors) as part of your PR.
|
||||
|
||||
- Using an IDE is highly recommended, but not required.
|
||||
- I use IntelliJ; download it [here](https://www.jetbrains.com/idea/download/).
|
||||
- Some people use other tools, like VS Code, but I haven't used them for Java myself, and cannot guarantee that they will work well for this codebase.
|
||||
@@ -1,3 +0,0 @@
|
||||
# Note: The v7 server list is frozen. No new servers will be accepted. All v8 server PRs should be made [here](https://github.com/Anuken/MindustryServerList).
|
||||
|
||||
*PRs to edit addresses of existing servers will still be accepted, although very infrequently.*
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ allprojects{
|
||||
if(!project.hasProperty("versionModifier")) versionModifier = 'release'
|
||||
if(!project.hasProperty("versionType")) versionType = 'official'
|
||||
appName = 'Mindustry'
|
||||
steamworksVersion = 'da41c05b7a2a44c8625ca0ba7d6ca1a2e73f621a'
|
||||
steamworksVersion = '185e76cfe630a6f0e1dd7b9bf57be41f6064a1f2'
|
||||
rhinoVersion = '32395f942976a6d1d21ec9877664554cd5762306'
|
||||
|
||||
loadVersionProps = {
|
||||
|
||||
@@ -1304,7 +1304,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
|
||||
@@ -3396,7 +3396,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
|
||||
|
||||
@@ -838,7 +838,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
|
||||
@@ -1238,7 +1238,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
|
||||
@@ -1299,7 +1299,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
|
||||
@@ -1319,7 +1319,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
|
||||
@@ -1990,8 +1990,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
|
||||
@@ -2757,7 +2757,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.
|
||||
@@ -2945,63 +2945,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.
|
||||
@@ -3186,8 +3186,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
|
||||
@@ -3195,9 +3195,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
|
||||
@@ -3206,31 +3206,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
|
||||
@@ -3263,22 +3263,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
|
||||
@@ -3318,27 +3318,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
|
||||
@@ -3351,7 +3351,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
|
||||
@@ -3387,17 +3387,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
|
||||
@@ -3405,7 +3405,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
|
||||
@@ -3421,29 +3421,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
|
||||
@@ -3457,40 +3457,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
|
||||
@@ -3507,43 +3507,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
|
||||
@@ -3562,13 +3562,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
|
||||
@@ -3577,12 +3577,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
|
||||
@@ -3626,15 +3626,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
|
||||
|
||||
@@ -1019,7 +1019,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.
|
||||
@@ -1299,7 +1299,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
|
||||
@@ -1414,8 +1414,8 @@ category.function = Funkció
|
||||
category.optional = Lehetséges fejlesztések
|
||||
setting.alwaysmusic.name = Folyamatos zenelejátszás
|
||||
setting.alwaysmusic.description = Amikor engedélyezve van, akkor a zene folyamatosan szól a játékban.\nHa ki van kapcsolva, akkor csak véletlenszerű időközönként szólal meg.
|
||||
setting.skipcoreanimation.name = Támaszpont animációjának kihagyása kilövéskor és leszálláskor
|
||||
setting.skipcoreanimation.description = Ha engedélyezve van, akkor a támaszpont fel- és leszállásának\nanimációja nem lesz megjelenítve.
|
||||
setting.skipcoreanimation.name = Támaszpont animációinak kihagyása
|
||||
setting.skipcoreanimation.description = Ha engedélyezve van, akkor a támaszpont fel- és leszállási\nanimációja nem lesz megjelenítve.
|
||||
setting.landscape.name = Fekvő mód zárolása
|
||||
setting.landscape.description = Ha engedélyezve van, akkor a képernyő tájolása fekvő módban lesz rögzítve.
|
||||
setting.blockreplace.name = Automatikus blokkjavaslatok
|
||||
@@ -1468,8 +1468,8 @@ setting.destroyedblocks.name = Lerombolt építmények megjelenítése
|
||||
setting.destroyedblocks.description = Ha engedélyezve van, akkor a megsemmisített blokkok\ntörmeléket hagynak maguk után.
|
||||
setting.blockstatus.name = Blokkok állapotának megjelenítése
|
||||
setting.blockstatus.description = A blokkok felett színes állapotikonok jelennek meg.
|
||||
setting.conveyorpathfinding.name = Szállítószalag nyomvonalkeresése építéskor
|
||||
setting.conveyorpathfinding.description = Ha engedélyezve van, akkor a szállítószalagok elhelyezésekor a rendszer\nautomatikusan megpróbálja megtalálni az útvonalat a célállomásig.
|
||||
setting.conveyorpathfinding.name = Nyomvonalkeresés szállítószalag-építéskor
|
||||
setting.conveyorpathfinding.description = Ha engedélyezve van, akkor a szállítószalagok elhelyezésekor a rendszer\nautomatikusan megpróbálja megtalálni azok nyomvonalát a célállomásig.
|
||||
setting.sensitivity.name = Játékvezérlők érzékenysége
|
||||
setting.sensitivity.description = A játékvezérlők (joystick) érzékenységét lehet vele finomhangolni.
|
||||
setting.saveinterval.name = Mentési időköz
|
||||
@@ -1478,7 +1478,7 @@ setting.seconds = {0} másodperc
|
||||
setting.milliseconds = {0} ezredmásodperc
|
||||
setting.fullscreen.name = Teljes képernyő
|
||||
setting.fps.name = FPS, memóriahasználat és ping megjelenítése
|
||||
setting.fps.description = Megjeleníti a jelenlegi képkockasebességet (FPS), a memóriahasználatot MB/GB-ban\nés a hálózati pinget a képernyő sarkában.
|
||||
setting.fps.description = Megjeleníti a jelenlegi képkockasebességet, a memóriahasználatot MB/GB-ban\nés a hálózati pinget a képernyő sarkában.
|
||||
setting.console.name = Konzol engedélyezése
|
||||
setting.console.description = Engedélyezi a játékon belüli JavaScript-konzolt.
|
||||
setting.drawhitboxes.name = Ütközési dobozok megjelenítése
|
||||
@@ -2922,7 +2922,7 @@ lglobal.@clientName = A kódot futtató kliens játékosneve
|
||||
lglobal.@clientTeam = A kódot futtató kliens csapatazonosítója
|
||||
lglobal.@clientMobile = Igaz, ha a kódot futtató kliens egy hordozható eszköz, egyébként hamis
|
||||
lglobal.@clientMusicPlaying = Igaz, ha jelenleg folyamatban van bármilyen zene lejátszása
|
||||
lglobal.@clientCurrentMusic = A jelenleg játszott zeneszám neve, vagy nulla
|
||||
lglobal.@clientCurrentMusic = A jelenleg játszott zeneszám neve, vagy null
|
||||
|
||||
lenum.type = Az épület/egység típusa.\nPéldául bármilyen elosztó esetén a [accent]@router[] értéket adja vissza.\nNem karakterlánc.
|
||||
lenum.shoot = Lövés egy adott pontra.
|
||||
@@ -2945,63 +2945,63 @@ laccess.displayheight = Egy kijelzőblokk magassága pixelben.
|
||||
laccess.buffersize = Üzenetek esetén: A tartalom hossza.\nKijelzők esetén: A feldolgozatlan grafikus parancsok száma.
|
||||
laccess.operations = A blokkon végrehajtott műveletek száma.\nKijelzők esetén a drawflush-műveletek számát adja vissza.
|
||||
laccess.maxunits = Egy csapat maximális egységeinek száma.\nCsak támaszpontokból érzékelhető.
|
||||
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 = A tárolt elemek teljes száma.
|
||||
laccess.firstitem = Az első tárolt elem, vagy null, ha üres.
|
||||
laccess.totalliquids = A tárolt folyadék teljes mennyisége.
|
||||
laccess.totalpower = Pufferezett energiatárolóval rendelkező blokkoknál a tárolt energia mennyisége; más blokkoknál a puffer telítettsége 0-tól 1-ig.
|
||||
laccess.itemcapacity = A maximális elemszám, amit ez az épület tárolni tud.
|
||||
laccess.liquidcapacity = A maximális folyadékmennyiség, amit ez az épület tárolni tud.
|
||||
laccess.powercapacity = A maximális energiamennyiség, amit ez az épület tárolni tud.
|
||||
laccess.powernetstored = Az összekapcsolt energiahálózatban tárolt teljes energiamennyiség.
|
||||
laccess.powernetcapacity = Az összekapcsolt energiahálózat teljes energiatárolási kapacitása.
|
||||
laccess.powernetin = Az összekapcsolt energiahálózatba másodpercenként belépő energia.
|
||||
laccess.powernetout = Az összekapcsolt energiahálózatból másodpercenként kilépő energia.
|
||||
laccess.ammo = Egy lövegtorony jelenlegi lőszerkészlete.
|
||||
laccess.ammocapacity = Egy lövegtorony maximális lőszerkészlete.
|
||||
laccess.health = Jelenlegi életerő.\nLövedékek esetén azok sebzése.
|
||||
laccess.maxhealth = Maximális életerő.\nLövedékek esetén az alapsebzés.
|
||||
laccess.heat = Hőt fogyasztó lövegtorony jelenlegi hője, 0-tól 1-ig.
|
||||
laccess.shield = Egy egység jelenlegi pajzsának mennyisége.
|
||||
laccess.armor = Páncélzat értéke; fix sebzéscsökkentés találatonként.
|
||||
laccess.efficiency = Egy épület működési hatásfoka, ahol az 1 a normális érték.
|
||||
laccess.timescale = Egy épületre ható időskálaszorzó, ahol az 1 a normál sebesség.
|
||||
laccess.rotation = Egy egység vagy lövegtorony irányszöge fokban.\nA legtöbb más épületnél a 0-tól 3-ig terjedő tájolás.
|
||||
laccess.x = X-pozíció mezőkben.
|
||||
laccess.y = Y-pozíció mezőkben.
|
||||
laccess.velocityx = Egy egység X-irányú sebessége (mező/mp).
|
||||
laccess.velocityy = Egy egység Y-irányú sebessége (mező/mp).
|
||||
laccess.shootx = Annak a mezőnek az X-koordinátája, amire egy egység vagy lövegtorony céloz.
|
||||
laccess.shooty = Annak a mezőnek az Y-koordinátája, amire egy egység vagy lövegtorony céloz.
|
||||
laccess.camerax = Az irányító játékos kamerájának X-pozíciója.
|
||||
laccess.cameray = Az irányító játékos kamerájának Y-pozíciója.
|
||||
laccess.camerawidth = Az irányító játékos nézetének szélessége mezőkben.
|
||||
laccess.cameraheight = Az irányító játékos nézetének magassága mezőkben.
|
||||
laccess.solid = Meghatározza, hogy akadályozza-e ez az épület a mozgást.
|
||||
laccess.range = Egy egység vagy lövegtorony hatótávolsága mezőkben.
|
||||
laccess.shooting = Meghatározza, hogy éppen lő-e egy egység vagy lövegtorony.
|
||||
laccess.boosting = Meghatározza, hogy gyorsít-e, vagy repül-e éppen a terep felett egy egység.
|
||||
laccess.minex = Annak a mezőnek az X-koordinátája, amit egy egység bányászik, vagy -1, ha nem.
|
||||
laccess.miney = Annak a mezőnek az Y-koordinátája, amit egy egység bányászik, vagy -1, ha nem.
|
||||
laccess.mining = Meghatározza, hogy éppen bányászik-e egy egység.
|
||||
laccess.buildx = Annak a mezőnek az X-koordinátája, ahol egy egység épít, vagy -1, ha nem.
|
||||
laccess.buildy = Annak a mezőnek az Y-koordinátája, ahol egy egység épít, vagy -1, ha nem.
|
||||
laccess.pingx = Annak a mezőnek az X-koordinátája, amit egy játékos pingel,\nvagy null, ha nem.
|
||||
laccess.pingy = Annak a mezőnek az Y-koordinátája, amit egy játékos pingel,\nvagy null, ha nem.
|
||||
laccess.pingtext = Egy játékos jelenlegi pingjének szövege, vagy null, ha nincs ping.
|
||||
laccess.building = Az az épület, amit egy egység éppen épít, vagy null.
|
||||
laccess.breaking = Az az épület, amit egy egység éppen lebont, vagy null.
|
||||
laccess.team = Egy egység vagy épület csapatának azonosítója.
|
||||
laccess.flag = Egy egységen tárolt számszerű jelző értéke.
|
||||
laccess.flying = Meghatározza, hogy repül-e éppen egy egység.
|
||||
laccess.name = Az egységet irányító játékos neve, vagy null.
|
||||
laccess.payloadcount = A jelenleg hordozott rakományok száma.
|
||||
laccess.payloadtype = A legutóbb felvett rakomány típusa, vagy null.
|
||||
laccess.totalpayload = Az összes hordozott rakomány együttes mérete.
|
||||
laccess.payloadcapacity = A maximális együttes rakományméret, amit egy egység vagy épület elbír.
|
||||
laccess.selectedblock = Az irányító játékos által jelenleg kiválasztott blokk, vagy null.
|
||||
laccess.selectedrotation = Az irányító játékos által jelenleg kiválasztott építési irány, 0-tól 3-ig.
|
||||
laccess.bulletlifetime = Egy lövedék teljes élettartama tickekben.
|
||||
laccess.bullettime = Az idő, amióta egy lövedék létezik, tickekben.
|
||||
|
||||
lcategory.unknown = Ismeretlen
|
||||
lcategory.unknown.description = Nem kategorizált utasítások.
|
||||
@@ -3145,11 +3145,11 @@ lenum.boost = Erősítés indítása/leállítása.
|
||||
|
||||
lenum.flushtext = Az írási puffer tartalmának ürítése a jelölőre, ha alkalmazható.\nHa a „fetch” igaz, akkor megpróbálja lekérni a tulajdonságokat a pálya nyelvi csomagjából vagy a játék csomagjából.
|
||||
lenum.texture = A textúra neve közvetlenül a játék textúra-atlaszából (úgynevezett „kebab-case” elnevezési stílus használatával).\nHa a „printFlush” igaz, akkor a szöveges puffer tartalmát használja szöveges argumentumként.
|
||||
lenum.texturesize = A textúra mérete mezőben. A nulla érték a jelölő szélességét az eredeti textúra méretére skálázza.
|
||||
lenum.texturesize = A textúra mérete mezőben. A null érték a jelölő szélességét az eredeti textúra méretére skálázza.
|
||||
lenum.autoscale = Meghatározza, hogy a jelölő a játékos nagyítási szintjéhez igazodik-e.
|
||||
lenum.posi = Indexelt pozíció, vonal- és négyszögjelzőkhöz használatos, ahol a nulla az első pozíció.
|
||||
lenum.posi = Indexelt pozíció, vonal- és négyszögjelzőkhöz használatos, ahol a null az első pozíció.
|
||||
lenum.uvi = A textúra pozíciója nullától egyig, négyzetjelölőkhöz használatos.
|
||||
lenum.colori = Indexelt szín, vonal- és négyzetjelölőkhöz használatos, ahol a nulla az első szín.
|
||||
lenum.colori = Indexelt szín, vonal- és négyzetjelölőkhöz használatos, ahol a null az első szín.
|
||||
|
||||
lenum.wavetimer = Meghatározza, hogy a hullámok automatikusan indulnak-e az időzítő alapján. Ha nem, akkor a hullámok a lejátszásgomb megnyomásakor indulnak.
|
||||
lenum.wave = Jelenlegi hullámszám. Bármi lehet a nem-hullámalapú játékmódokban.
|
||||
@@ -3391,14 +3391,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ó
|
||||
@@ -3456,7 +3456,7 @@ radartarget.label.player = játékos
|
||||
radartarget.label.attacker = támadó
|
||||
radartarget.label.flying = légi
|
||||
radartarget.label.ground = földi
|
||||
radartarget.label.boss = boss
|
||||
radartarget.label.boss = főellenség
|
||||
tilelayer.label.floor = padló
|
||||
tilelayer.label.ore = érc
|
||||
tilelayer.label.block = blokk
|
||||
@@ -3522,7 +3522,7 @@ name.token.-lookup = = keresés
|
||||
name.token.type = típus
|
||||
name.token.get = lekérés
|
||||
name.token.team = csapat
|
||||
name.token.angle = angle
|
||||
name.token.angle = szög
|
||||
name.token.spawn = elhelyezés
|
||||
name.token.-bullet = = lövedék
|
||||
name.token.unit = egység
|
||||
|
||||
@@ -882,7 +882,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
|
||||
@@ -1074,7 +1074,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.
|
||||
|
||||
@@ -1299,7 +1299,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
|
||||
@@ -1447,7 +1447,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
|
||||
@@ -2453,7 +2453,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[].
|
||||
|
||||
@@ -2686,7 +2686,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.
|
||||
@@ -2700,7 +2700,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.
|
||||
@@ -2741,7 +2741,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.
|
||||
@@ -2945,63 +2945,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.
|
||||
@@ -3282,7 +3282,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
|
||||
@@ -3351,7 +3351,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
|
||||
@@ -3456,7 +3456,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
|
||||
|
||||
@@ -1299,7 +1299,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}/с
|
||||
@@ -2945,63 +2945,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 = Нет категории.
|
||||
@@ -3496,9 +3496,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 = выход
|
||||
@@ -3509,8 +3509,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 = постройка
|
||||
@@ -3532,7 +3532,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 = эффект
|
||||
@@ -3599,7 +3599,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 = облако дыма
|
||||
|
||||
@@ -50,7 +50,7 @@ mods.browser.add = 安装
|
||||
mods.browser.reinstall = 重新安装
|
||||
mods.browser.view-releases = 查看版本
|
||||
mods.browser.noreleases = [scarlet]找不到任何版本\n[accent]无法找到该模组的任何版本。请检查一下该模组的仓库是否发布了版本。
|
||||
mods.browser.current = [lightgray]Most recent commit
|
||||
mods.browser.current = [lightgray]最新提交
|
||||
mods.browser.latest = [lightgray][最新]
|
||||
mods.browser.releases = 版本
|
||||
mods.browser.fetching = 获取版本中...
|
||||
@@ -145,7 +145,7 @@ mods.initfailed = [red]⚠[] Mindustry 上一次启动失败。这可能是由
|
||||
mods = 模组
|
||||
mods.name = 模组:
|
||||
mods.none = [lightgray]未找到模组!
|
||||
mods.restore = Restore Failed
|
||||
mods.restore = 恢复失败
|
||||
mods.guide = 模组指南
|
||||
mods.report = 举报错误
|
||||
mods.openfolder = 打开文件夹
|
||||
@@ -164,7 +164,7 @@ mod.installed = [[已安装]
|
||||
mod.display = [gray]模组:[orange] {0}
|
||||
mod.enabled = [lightgray]已启用
|
||||
mod.disabled = [red]未启用
|
||||
mod.failed = [red]Failed
|
||||
mod.failed = [red]失败
|
||||
mod.multiplayer.compatible = [gray]支持多人游戏
|
||||
mod.disable = 禁用
|
||||
mod.version = 版本:
|
||||
@@ -1237,9 +1237,9 @@ stat.buildspeedmultiplier = 建造速度倍率
|
||||
stat.reactive = 反应
|
||||
stat.immunities = 免疫
|
||||
stat.healing = 治疗
|
||||
stat.status = Status Effect
|
||||
stat.status = 状态效果
|
||||
stat.efficiency = [stat]{0}% 效率
|
||||
stat.chance = [stat]{0}%[lightgray] chance of [white]
|
||||
stat.chance = [stat]{0}%[lightgray] 概率 [white]
|
||||
stat.hitsize = 碰撞箱大小
|
||||
stat.resettime = 重置时间
|
||||
|
||||
@@ -1288,7 +1288,7 @@ ability.stat.minspeed = [stat]{0}格/秒[lightgray] 最低速度
|
||||
ability.stat.duration = [stat]{0} 秒[lightgray] 持续时间
|
||||
ability.stat.buildtime = [stat]{0} 秒[lightgray] 建造时间
|
||||
|
||||
bar.displaytoolarge = 尺寸太大\n(Max:{0}x{0})
|
||||
bar.displaytoolarge = 尺寸太大\n(上限:{0}x{0})
|
||||
bar.onlycoredeposit = 仅可将资源丢入核心
|
||||
bar.drilltierreq = 需要更高级的钻头
|
||||
bar.nobatterypower = 电池电力储存不足
|
||||
@@ -1299,7 +1299,7 @@ bar.cargounitcap = 达到货运单位上限
|
||||
bar.drillspeed = 挖掘速度:{0}/秒
|
||||
bar.pumpspeed = 泵送速度:{0}/秒
|
||||
bar.efficiency = 效率:{0}%
|
||||
bar.yield = Yield: +{0}%
|
||||
bar.yield = 产量: +{0}%
|
||||
bar.boost = 超速:+{0}%
|
||||
bar.powerbuffer = 电池电力:{0}/{1}
|
||||
bar.powerbalance = 电力:{0}/秒
|
||||
@@ -1435,8 +1435,8 @@ setting.distinctcontrolgroups.name = 每单位限制一个编队
|
||||
setting.distinctcontrolgroups.description = 启用后,每个单位只能从属于一个编队。
|
||||
setting.modcrashdisable.name = 游戏启动崩溃后禁用模组
|
||||
setting.modcrashdisable.description = 启用后,若启动时模组崩溃,则会禁用所有模组以避免无休止的崩溃。
|
||||
setting.animatedwater.name = 动态液体
|
||||
setting.animatedwater.description = 是否开启液体表面的动画,如水和矿渣。
|
||||
setting.animatedwater.name = 动态效果
|
||||
setting.animatedwater.description = 是否显示水、矿渣和护盾等表面的动画。
|
||||
setting.playerindicators.name = 玩家指示器
|
||||
setting.playerindicators.description = 在地图上显示标记,来指示其他玩家的方向。
|
||||
setting.showpings.name = 显示标记
|
||||
@@ -1738,7 +1738,7 @@ rules.enemyteam = 敌方队伍
|
||||
rules.playerteam = 玩家队伍
|
||||
rules.title.waves = 波次
|
||||
rules.title.resourcesbuilding = 资源与建筑
|
||||
rules.title.enemy = 敌对阵营
|
||||
rules.title.enemy = 敌人
|
||||
rules.title.unit = 单位
|
||||
rules.title.experimental = 实验性
|
||||
rules.title.environment = 环境
|
||||
@@ -2831,7 +2831,7 @@ lst.read = 从连接的内存读取数字。
|
||||
lst.write = 向连接的内存写入数字。
|
||||
lst.print = 添加文字到打印缓存\n使用[accent]打印文本[]后才会真正显示。
|
||||
lst.printchar = 向打印缓存添加一个 UTF-16 字符或内容图标。\n直到使用[accent]打印文本[]后才会真正显示。
|
||||
lst.format = 用一个值替换文本缓冲区中的下一个占位符。\n如果占位符模式无效,则不会执行任何操作。\n占位模式:"{[accent]number 0-9[]}"\n示例:\n[accent]打印 "test {0}"\n格式 “示例”。
|
||||
lst.format = 用一个值替换文本缓冲区中的下一个占位符。\n如果占位符模式无效,则不会执行任何操作。\n占位模式:"{[accent]number 0-9[]}"\n示例:\n[accent]打印 "test {0}"\n格式化 “示例”。
|
||||
lst.draw = 添加绘图操作到绘图缓存\n使用[accent]打印绘图[]后才会真正显示。
|
||||
lst.drawflush = 将绘图缓存中的[accent]绘图[]队列刷新到显示屏。
|
||||
lst.printflush = 将打印缓存中的[accent]打印[]队列刷新到信息板。
|
||||
@@ -2945,63 +2945,63 @@ laccess.displayheight = 显示屏的高度(以像素为单位)。
|
||||
laccess.buffersize = 显示器图形缓冲区中未处理的命令数。
|
||||
laccess.operations = 方块执行操作的次数。\n对于显示屏,返回[accent]打印绘图[]调用次数。
|
||||
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 = 存储在单位身上的 flag。
|
||||
laccess.flying = 单位当前是否正在飞行。
|
||||
laccess.name = 控制该单位的玩家名称,若无则为 null。
|
||||
laccess.payloadcount = 当前持有的有效载荷数量。
|
||||
laccess.payloadtype = 最后获取的有效载荷类型,若无则为 null。
|
||||
laccess.totalpayload = 所有持有的有效载荷的总大小。
|
||||
laccess.payloadcapacity = 单位或建筑所能承载的最大综合有效载荷大小。
|
||||
laccess.selectedblock = 玩家当前在建筑列表选中的方块,若无则为 null。
|
||||
laccess.selectedrotation = 玩家当前在建筑列表选择的建造旋转角度,范围为 0 到 3。
|
||||
laccess.bulletlifetime = 子弹可存在的总时长(以 tick 为单位)。
|
||||
laccess.bullettime = 子弹已存在的时长(以 tick 为单位)。
|
||||
|
||||
lcategory.unknown = 未知
|
||||
lcategory.unknown.description = 未分类的指令
|
||||
@@ -3111,7 +3111,7 @@ unitradar.output = 找到的单位存入该变量
|
||||
|
||||
control.of = 要控制的建筑
|
||||
control.unit = 要瞄准的单位或建筑
|
||||
control.shoot = 是否射击
|
||||
control.shoot = 射击?
|
||||
|
||||
unitlocate.enemy = 是否搜寻敌方建筑(0 或 false 则搜寻己方建筑)
|
||||
unitlocate.found = 若找到,在该变量中存入 true;未找到则存入 false
|
||||
@@ -3154,7 +3154,7 @@ lenum.colori = 索引位置,用于线和四边形标记,索引零表示第
|
||||
lenum.wavetimer = 波次是否自动出现在计时器上。如果没有,按下播放按钮时会出现波次
|
||||
lenum.wave = 当前波数,可以是非波次模式下的任何值
|
||||
lenum.currentwavetime = 波次倒计时(以 tick 为单位)
|
||||
lenum.waves = 波次是否可以生成
|
||||
lenum.waves = 波次是否可生成
|
||||
lenum.wavesending = 是否可以通过播放按钮手动生成波次
|
||||
lenum.attackmode = 游戏是否为进攻模式
|
||||
lenum.wavespacing = 波次之间的时间间隔(以 tick 为单位)
|
||||
@@ -3221,8 +3221,8 @@ instruction.setrate = 设置速率
|
||||
instruction.fetch = 获取对象
|
||||
instruction.sync = 网络同步
|
||||
instruction.clientdata = 客户端数据
|
||||
instruction.getflag = 获取flag
|
||||
instruction.setflag = 设置flag
|
||||
instruction.getflag = 获取 flag
|
||||
instruction.setflag = 设置 flag
|
||||
instruction.setprop = 设置属性
|
||||
instruction.playsound = 播放音效
|
||||
instruction.playmusic = 播放音乐
|
||||
@@ -3253,8 +3253,8 @@ cutsceneaction.label.pan = 移动
|
||||
cutsceneaction.label.zoom = 缩放
|
||||
cutsceneaction.label.stop = 停止
|
||||
cutsceneaction.label.shake = 抖动
|
||||
cutsceneaction.label.gethud = 获取Hud
|
||||
cutsceneaction.label.sethud = 设置Hud
|
||||
cutsceneaction.label.gethud = 获取 Hud
|
||||
cutsceneaction.label.sethud = 设置 Hud
|
||||
fetchtype.label.unit = 单位
|
||||
fetchtype.label.player = 玩家控制单位
|
||||
fetchtype.label.core = 核心
|
||||
@@ -3294,8 +3294,8 @@ laccess.label.ammo = 弹药量
|
||||
laccess.label.ammocapacity = 弹药容量
|
||||
laccess.label.currentammotype = 当前弹药类型
|
||||
laccess.label.memorycapacity = 内存块单元数量
|
||||
laccess.label.health = 生命值
|
||||
laccess.label.maxhealth = 最大生命值
|
||||
laccess.label.health = 生命值/伤害
|
||||
laccess.label.maxhealth = 最大生命值/基础伤害
|
||||
laccess.label.heat = 热量
|
||||
laccess.label.shield = 护盾
|
||||
laccess.label.armor = 护甲
|
||||
@@ -3309,10 +3309,10 @@ laccess.label.velocityx = X轴移动速度
|
||||
laccess.label.velocityy = Y轴移动速度
|
||||
laccess.label.shootx = 射击X坐标
|
||||
laccess.label.shooty = 射击Y坐标
|
||||
laccess.label.camerax = 相机X坐标
|
||||
laccess.label.cameray = 相机Y坐标
|
||||
laccess.label.camerawidth = 相机宽度
|
||||
laccess.label.cameraheight = 相机高度
|
||||
laccess.label.camerax = 镜头X坐标
|
||||
laccess.label.cameray = 镜头Y坐标
|
||||
laccess.label.camerawidth = 镜头宽度
|
||||
laccess.label.cameraheight = 镜头高度
|
||||
laccess.label.displaywidth = 显示屏宽度
|
||||
laccess.label.displayheight = 显示屏高度
|
||||
laccess.label.buffersize = 缓冲区大小
|
||||
@@ -3321,18 +3321,18 @@ laccess.label.size = 大小/长度
|
||||
laccess.label.solid = 实体
|
||||
laccess.label.dead = 已摧毁/失效
|
||||
laccess.label.range = 雷达范围
|
||||
laccess.label.shooting = 射击状态
|
||||
laccess.label.boosting = 助推状态
|
||||
laccess.label.shooting = 射击?
|
||||
laccess.label.boosting = 助推?
|
||||
laccess.label.minex = 采矿X坐标
|
||||
laccess.label.miney = 采矿Y坐标
|
||||
laccess.label.mining = 采矿状态
|
||||
laccess.label.mining = 采矿?
|
||||
laccess.label.buildx = 建造于X坐标
|
||||
laccess.label.buildy = 建造于Y坐标
|
||||
laccess.label.pingx = 标记点X坐标
|
||||
laccess.label.pingy = 标记点Y坐标
|
||||
laccess.label.pingtext = 标记点文本
|
||||
laccess.label.building = 建造状态
|
||||
laccess.label.breaking = 破坏状态
|
||||
laccess.label.building = 建造的建筑
|
||||
laccess.label.breaking = 破坏的建筑
|
||||
laccess.label.speed = 速度
|
||||
laccess.label.team = 队伍
|
||||
laccess.label.type = 类型
|
||||
@@ -3380,7 +3380,7 @@ lmarkercontrol.label.fontsize = 字体大小
|
||||
lmarkercontrol.label.textheight = 文本高度
|
||||
lmarkercontrol.label.textalign = 文本对齐
|
||||
lmarkercontrol.label.linealign = 线对齐
|
||||
lmarkercontrol.label.labelflags = flag标签
|
||||
lmarkercontrol.label.labelflags = flag 标签
|
||||
lmarkercontrol.label.texture = 纹理
|
||||
lmarkercontrol.label.texturesize = 纹理大小
|
||||
lmarkercontrol.label.posi = 位置
|
||||
@@ -3388,7 +3388,7 @@ lmarkercontrol.label.uvi = 纹理位置范围
|
||||
lmarkercontrol.label.colori = 颜色
|
||||
logicrule.label.currentwavetime = 波次倒计时
|
||||
logicrule.label.wavetimer = 有波次计时器?
|
||||
logicrule.label.waves = 波次是否可以生成
|
||||
logicrule.label.waves = 波次可生成?
|
||||
logicrule.label.wave = 当前波数
|
||||
logicrule.label.wavespacing = 波次间隔
|
||||
logicrule.label.wavesending = 手动生成波次?
|
||||
@@ -3398,7 +3398,7 @@ logicrule.label.dropzoneradius = 敌人出生点半径
|
||||
logicrule.label.unitcap = 单位上限
|
||||
logicrule.label.maparea = 地图大小和有效范围
|
||||
logicrule.label.lighting = 启用环境光?
|
||||
logicrule.label.cangameover = 游戏可否结束
|
||||
logicrule.label.cangameover = 游戏可结束?
|
||||
logicrule.label.ambientlight = 环境光颜色
|
||||
logicrule.label.unitlight = 单位光
|
||||
logicrule.label.solarmultiplier = 太阳能板效率
|
||||
@@ -3431,7 +3431,7 @@ lunitcontrol.label.itemtake = 从建筑取出物品
|
||||
lunitcontrol.label.paydrop = 卸下载荷
|
||||
lunitcontrol.label.paytake = 拾取载荷
|
||||
lunitcontrol.label.payenter = 进入载荷
|
||||
lunitcontrol.label.flag = 赋予单位flag
|
||||
lunitcontrol.label.flag = 赋予单位 flag
|
||||
lunitcontrol.label.mine = 采集矿物
|
||||
lunitcontrol.label.build = 建造建筑
|
||||
lunitcontrol.label.getblock = 用坐标获取类型
|
||||
|
||||
@@ -2461,7 +2461,7 @@ split.pickup = 某些物品可以被核心單位撿起。\n撿起這個[accent]
|
||||
split.pickup.mobile = 某些物品可以被核心單位撿起。\n撿起這個[accent]容器[],然後放到 [accent]重物裝載機[] 上。\n(要撿起或放下東西,請長按該物品。)
|
||||
split.acquire = 您必須獲取一些鎢才能建造單位。
|
||||
split.build = 單位必須被運送到牆的另一邊。\n在牆的兩側各放一個[accent]重物質量驅動器[]。\n通過按壓其中一個來設置連結,然後選擇另一個。
|
||||
split.container = 類似於容器,單位也可以使用[accent]重物質量驅動器[]進行運輸。\n將一個單位兵工廠放置在重物裝載機旁邊以裝載它們,然後將它們送到牆的另一側以進攻敵方基地。
|
||||
split.container = 類似於容器,單位也可以使用[accent]重物質量驅動器[]進行運輸。\n將一個單位兵工廠放置在重物質量驅動器旁邊以裝載它們,然後將它們送到牆的另一側以進攻敵方基地。
|
||||
|
||||
item.copper.description = 最基本的結構材料。在各種類型的方塊中廣泛使用。
|
||||
item.copper.details = 銅,蕈孢星上異常常見的金屬。加工前結構脆弱。
|
||||
|
||||
Binary file not shown.
@@ -183,7 +183,10 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
||||
|
||||
assets.load(schematics);
|
||||
|
||||
assets.loadRun("contentinit", ContentLoader.class, () -> content.init(), () -> content.load());
|
||||
assets.loadRun("contentinit", ContentLoader.class, () -> content.init(), () -> {
|
||||
content.load();
|
||||
mods.loadModPatches();
|
||||
});
|
||||
assets.loadRun("baseparts", BaseRegistry.class, () -> {}, () -> bases.load());
|
||||
|
||||
Core.assets.load("sprites/schematic-background.png", Texture.class).loaded = t -> t.setWrap(TextureWrap.repeat);
|
||||
|
||||
@@ -164,6 +164,7 @@ public class ControlPathfinder implements Runnable{
|
||||
|
||||
//main thread only!
|
||||
long lastUpdateId = state.updateId;
|
||||
long lastRecomputeTime;
|
||||
|
||||
//both threads
|
||||
volatile boolean notFound = false;
|
||||
@@ -456,7 +457,7 @@ public class ControlPathfinder implements Runnable{
|
||||
Cluster[][] dim1 = clusters[team];
|
||||
|
||||
if(dim1 == null){
|
||||
dim1 = clusters[team] = new Cluster[Team.all.length][];
|
||||
dim1 = clusters[team] = new Cluster[costTypes.size][];
|
||||
}
|
||||
|
||||
Cluster[] dim2 = dim1[pathCost];
|
||||
@@ -1192,7 +1193,9 @@ public class ControlPathfinder implements Runnable{
|
||||
long fieldKey = FieldIndex.get(destPos, costId, team);
|
||||
|
||||
//use existing request if it exists.
|
||||
if(request != null && request.destination == destPos){
|
||||
if(request != null && (request.destination == destPos ||
|
||||
//can only recompute path only twice a second, unless it's far away
|
||||
(Time.timeSinceMillis(request.lastRecomputeTime) < 1000 && Mathf.dst(destX, destY, request.destination % wwidth, request.destination / wwidth) <= 4f))){
|
||||
request.lastUpdateId = state.updateId;
|
||||
|
||||
Tile initialTileOn = tileOn;
|
||||
@@ -1313,6 +1316,7 @@ public class ControlPathfinder implements Runnable{
|
||||
unitRequests.put(unit, request = new PathRequest(unit, team, costId, destPos));
|
||||
|
||||
PathRequest f = request;
|
||||
request.lastRecomputeTime = Time.millis();
|
||||
|
||||
//on the pathfinding thread: initialize the request
|
||||
queue.post(() -> {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -259,7 +259,8 @@ public class CommandAI extends AIController{
|
||||
targetPos = new Vec2();
|
||||
lastTargetPos = targetPos;
|
||||
}
|
||||
targetPos.set(attackTarget);
|
||||
//don't target where target dummies are right now, target their block
|
||||
targetPos.set(attackTarget instanceof TargetDummyUnit t && t.building != null ? t.building : attackTarget);
|
||||
|
||||
if(unit.isGrounded() && attackTarget instanceof Building build && build.tile.solid() && unit.type.pathCostId != ControlPathfinder.costIdLegs && !ramming){
|
||||
Tile best = build.findClosestEdge(unit, Tile::solid);
|
||||
|
||||
@@ -92,7 +92,7 @@ public class AvoidanceProcess implements AsyncProcess{
|
||||
float rad = Float.intBitsToFloat(items[i + 1]);
|
||||
float rad2 = rad * rad;
|
||||
|
||||
int r = Math.max(1, Mathf.ceil(rad));
|
||||
int r = Mathf.clamp(1, Mathf.ceil(rad), 20);
|
||||
|
||||
for(int dx = -r; dx <= r; dx++){
|
||||
for(int dy = -r; dy <= r; dy++){
|
||||
|
||||
@@ -26,6 +26,7 @@ public class PhysicsProcess implements AsyncProcess{
|
||||
private PhysicsWorld[] physics;
|
||||
private Seq<PhysicRef> refs = new Seq<>(false, 20, PhysicRef.class);
|
||||
private Seq<Future<?>> futures = new Seq<>(false, layers, Future.class);
|
||||
private Seq<PhysicRef> pendingAdds = new Seq<>(false, 20, PhysicRef.class);
|
||||
|
||||
private static volatile long maxPhysicsTime = 0;
|
||||
|
||||
@@ -44,7 +45,8 @@ public class PhysicsProcess implements AsyncProcess{
|
||||
PhysicRef ref = new PhysicRef(unit, body);
|
||||
refs.add(ref);
|
||||
|
||||
if(ref.lastLayer >= 0) physics[ref.lastLayer].add(body);
|
||||
//defer adds until physics update is done
|
||||
pendingAdds.add(ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,6 +70,13 @@ public class PhysicsProcess implements AsyncProcess{
|
||||
PerfCounter.unitPhysicsAsync.add(maxPhysicsTime);
|
||||
maxPhysicsTime = 0;
|
||||
|
||||
//flush newly added entities
|
||||
for(int i = 0; i < pendingAdds.size; i++){
|
||||
PhysicRef ref = pendingAdds.items[i];
|
||||
if(ref.lastLayer >= 0) physics[ref.lastLayer].add(ref.body);
|
||||
}
|
||||
pendingAdds.clear();
|
||||
|
||||
//move entities
|
||||
for(PhysicRef ref : refs){
|
||||
Physicsc entity = ref.entity;
|
||||
|
||||
@@ -392,13 +392,15 @@ public class SoundControl{
|
||||
ambientThread.inputSources.add(source);
|
||||
}else{
|
||||
launchingAmbientThread = true;
|
||||
ambientThread = new AudioThread();
|
||||
ambientThread.setDaemon(true);
|
||||
AudioThread thread = new AudioThread();
|
||||
thread.setDaemon(true);
|
||||
ambientThread = thread;
|
||||
|
||||
//start thread with all the sources that were added during launch
|
||||
Core.app.post(() -> {
|
||||
if(ambientThread != null){
|
||||
if(!ambientThread.isAlive()) ambientThread.start();
|
||||
//only start if this is still the active thread, and only ever once
|
||||
if(ambientThread == thread){
|
||||
thread.start();
|
||||
launchingAmbientThread = false;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6484,7 +6484,7 @@ public class Blocks{
|
||||
regionSuffix = "-dark";
|
||||
|
||||
size = 3;
|
||||
configurable = false;
|
||||
showAllCommands = false;
|
||||
consumePower(3f);
|
||||
consumeLiquid(Liquids.hydrogen, 3f / 60f);
|
||||
consumeItems(with(Items.silicon, 40, Items.tungsten, 30));
|
||||
@@ -6502,7 +6502,7 @@ public class Blocks{
|
||||
regionSuffix = "-dark";
|
||||
|
||||
size = 3;
|
||||
configurable = false;
|
||||
showAllCommands = false;
|
||||
consumePower(2.5f);
|
||||
consumeLiquid(Liquids.hydrogen, 3f / 60f);
|
||||
consumeItems(with(Items.silicon, 60, Items.tungsten, 40));
|
||||
@@ -6521,7 +6521,7 @@ public class Blocks{
|
||||
regionSuffix = "-dark";
|
||||
|
||||
size = 3;
|
||||
configurable = false;
|
||||
showAllCommands = false;
|
||||
consumePower(2.5f);
|
||||
consumeLiquid(Liquids.hydrogen, 3f / 60f);
|
||||
consumeItems(with(Items.silicon, 50, Items.tungsten, 40));
|
||||
@@ -6534,7 +6534,6 @@ public class Blocks{
|
||||
);
|
||||
}};
|
||||
|
||||
//yes very silly name
|
||||
primeRefabricator = new Reconstructor("prime-refabricator"){{
|
||||
requirements(Category.units, with(Items.thorium, 250, Items.oxide, 200, Items.tungsten, 200, Items.silicon, 400));
|
||||
regionSuffix = "-dark";
|
||||
@@ -6542,7 +6541,7 @@ public class Blocks{
|
||||
researchCostMultipliers.put(Items.thorium, 0.2f);
|
||||
|
||||
size = 5;
|
||||
configurable = false;
|
||||
showAllCommands = false;
|
||||
consumePower(4.5f);
|
||||
consumeLiquid(Liquids.nitrogen, 10f / 60f);
|
||||
consumeItems(with(Items.thorium, 80, Items.silicon, 100));
|
||||
|
||||
@@ -4647,6 +4647,8 @@ public class UnitTypes{
|
||||
useUnitCap = false;
|
||||
killable = false;
|
||||
physics = false;
|
||||
internal = true;
|
||||
internalGenerateSprites = true;
|
||||
|
||||
flyingLayer = Layer.flyingUnit - 1f;
|
||||
drag = 0.33f;
|
||||
|
||||
@@ -413,6 +413,7 @@ public class Logic implements ApplicationListener{
|
||||
|
||||
//map is over, no more world processor objective stuff
|
||||
state.rules.disableWorldProcessors = true;
|
||||
state.markers.clear(); //TODO: should this optional?
|
||||
|
||||
Call.clearObjectives();
|
||||
|
||||
|
||||
@@ -972,8 +972,10 @@ public class NetServer implements ApplicationListener{
|
||||
}else{
|
||||
Seq<DataAsset> res = new Seq<>();
|
||||
Seq<DataAsset> allAssets = state.data.getAllExternalAssets();
|
||||
Bits requestedIds = new Bits(allAssets.size);
|
||||
for(short id : ids){
|
||||
if(id >= allAssets.size || id < 0) continue;
|
||||
if(id >= allAssets.size || id < 0 || requestedIds.get(id)) continue;
|
||||
requestedIds.set(id);
|
||||
res.add(allAssets.get(id));
|
||||
}
|
||||
|
||||
|
||||
@@ -408,8 +408,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);
|
||||
@@ -431,11 +432,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);
|
||||
|
||||
@@ -78,7 +78,11 @@ public class MapEditor{
|
||||
if(build != null && tile.isCenter()){
|
||||
builds.add(build);
|
||||
}
|
||||
tiles.seti(i, new EditorTile(tile.x, tile.y, tile.floorID(), tile.overlayID(), build == null ? tile.blockID() : 0));
|
||||
|
||||
var newTile = new EditorTile(tile.x, tile.y, tile.floorID(), tile.overlayID(), build == null ? tile.blockID() : 0);
|
||||
newTile.floorData = tile.floorData;
|
||||
newTile.extraData = tile.extraData;
|
||||
tiles.seti(i, newTile);
|
||||
}
|
||||
|
||||
for(var build : builds){
|
||||
|
||||
@@ -38,10 +38,15 @@ public class MapAudioView implements AssetView{
|
||||
Fi file = asset.getCacheFile();
|
||||
var audioSource = (AudioSource)Core.assets.getOrNull(DataAudioLoader.prefix + asset.name, (Class<?>)(type == DataAssetType.music ? Music.class : Sound.class));
|
||||
|
||||
if(file == null || audioSource == null || !audioSource.valid()){
|
||||
if(file == null || audioSource == null || (!audioSource.valid() && !audioSource.isLazy())){
|
||||
list.button(Icon.warning, Styles.graySquarei, iconMed, () -> ui.showInfo(file == null ? "@asset.broken" : "@asset.audio.invalid")).size(h);
|
||||
}else{
|
||||
list.button(Icon.play, Styles.graySquarei, iconMed, () -> {
|
||||
if(!audioSource.valid() && !audioSource.isLazy()){
|
||||
ui.showInfo("@asset.audio.invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
if(lastPlaying != null && lastPlaying.countPlaying() > 0){
|
||||
lastPlaying.stop();
|
||||
if(lastPlaying == audioSource){
|
||||
@@ -56,16 +61,26 @@ public class MapAudioView implements AssetView{
|
||||
lastPlaying = s;
|
||||
s.play(control.sound.uiBus);
|
||||
}
|
||||
}).update(i -> i.getStyle().imageUp = audioSource != null && audioSource.countPlaying() > 0 ? Icon.pause : Icon.play).size(h);
|
||||
}).update(i -> i.getStyle().imageUp = (!audioSource.isLazy() && !audioSource.valid()) ? Icon.warning : audioSource.countPlaying() > 0 ? Icon.pause : Icon.play).size(h);
|
||||
}
|
||||
|
||||
float w = (mobile ? 390f : 450f);
|
||||
list.table(Styles.grayPanel, in -> {
|
||||
in.left();
|
||||
in.table(v -> {
|
||||
v.left();
|
||||
v.add("[accent]" + asset.name).labelAlign(Align.left).left().ellipsis(true).width(w / 2f);
|
||||
v.add("[accent]" + asset.name).labelAlign(Align.left).left().ellipsis(true).width(audioSource instanceof Music ? w / 2f : w * 0.8f);
|
||||
v.row();
|
||||
v.add("[lightgray][[" + (audioSource == null ? "?" : UI.formatTime(audioSource.getLength() * 60f)) + "]").left();
|
||||
if(audioSource != null){
|
||||
Runnable addTime = () -> v.add("[lightgray][[" + UI.formatTime(audioSource.getLength() * 60f) + "]").left();
|
||||
|
||||
if(audioSource.valid()){
|
||||
addTime.run();
|
||||
}else if(audioSource instanceof Sound s){
|
||||
//force-load sounds when viewing so that length/invalid status is shown
|
||||
s.checkLazyLoad(addTime);
|
||||
}
|
||||
}
|
||||
}).width(w / 2f).tooltip("dp-" + asset.name.replace(' ', '_'));
|
||||
|
||||
if(audioSource instanceof Music m){
|
||||
|
||||
@@ -23,7 +23,7 @@ public class Effect{
|
||||
|
||||
public static final Seq<Effect> all = new Seq<>();
|
||||
|
||||
private boolean initialized;
|
||||
private transient boolean initialized;
|
||||
|
||||
public final int id;
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ public class Lightning{
|
||||
|
||||
Unit furthest = Geometry.findFurthest(x, y, entities);
|
||||
|
||||
if(furthest != null){
|
||||
if(furthest != null && furthest.within(x, y, hitRange * 2f)){
|
||||
hit.add(furthest.id());
|
||||
x = furthest.x();
|
||||
y = furthest.y();
|
||||
|
||||
@@ -1843,7 +1843,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
}
|
||||
|
||||
public boolean canPickup(){
|
||||
return block.canPickup;
|
||||
return block.allowedInPayloads;
|
||||
}
|
||||
|
||||
/** Called right before this building is picked up. */
|
||||
|
||||
@@ -16,10 +16,18 @@ abstract class TargetDummyComp implements Unitc, Healthc{
|
||||
}
|
||||
}
|
||||
|
||||
@Replace
|
||||
@Override
|
||||
public void rawDamage(float amount){
|
||||
if(building instanceof TargetDummyBuild td){
|
||||
td.dummyHit(amount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Replace
|
||||
public boolean canLand(){
|
||||
//dummies should always respect the boost config even when the landing area is obstructed (usually by other dummies)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -174,7 +174,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
|
||||
/** @return whether there is solid, un-occupied ground under this unit. */
|
||||
public boolean canLand(){
|
||||
return !onSolid() && Units.count(x, y, physicSize(), f -> f != self() && f.isGrounded()) == 0;
|
||||
float psize = physicSize();
|
||||
return !onSolid() && !Units.any(x - psize/2f, y - psize/2f, psize, psize, f -> f != self() && f.isGrounded());
|
||||
}
|
||||
|
||||
public boolean inRange(Position other){
|
||||
|
||||
@@ -87,9 +87,9 @@ public class ParticleEffect extends Effect{
|
||||
float rawfin = e.fin();
|
||||
float fin = e.fin(interp);
|
||||
float colFin = e.fin(colorInterp);
|
||||
float rad = sizeInterp.apply(sizeFrom, sizeTo, Mathf.curve(rawfin, sizeChangeStart / lifetime, 1f)) * 2;
|
||||
float width = rad * (widthInterp.apply(widthFrom, widthTo, Mathf.curve(rawfin, widthChangeStart / lifetime, 1f)) * 2);
|
||||
float height = rad * (heightInterp.apply(heightFrom, heightTo, Mathf.curve(rawfin, heightChangeStart / lifetime, 1f)) * 2);
|
||||
float rad = sizeInterp.apply(sizeFrom, sizeTo, Mathf.curve(rawfin, sizeChangeStart / lifetime, 1f)) * 2f;
|
||||
float width = rad * widthInterp.apply(widthFrom, widthTo, Mathf.curve(rawfin, widthChangeStart / lifetime, 1f));
|
||||
float height = rad * heightInterp.apply(heightFrom, heightTo, Mathf.curve(rawfin, heightChangeStart / lifetime, 1f));
|
||||
float ox = e.x + Angles.trnsx(realRotation, offsetX * flip, offsetY), oy = e.y + Angles.trnsy(realRotation, offsetX * flip, offsetY);
|
||||
|
||||
Draw.color(colorFrom, colorTo, colFin);
|
||||
|
||||
@@ -7,8 +7,9 @@ import mindustry.game.MapObjectives.*;
|
||||
import mindustry.io.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class MapMarkers{
|
||||
public class MapMarkers implements Iterable<ObjectiveMarker>{
|
||||
/** Maps marker unique ID to marker. */
|
||||
private IntMap<ObjectiveMarker> map = new IntMap<>();
|
||||
|
||||
@@ -16,6 +17,13 @@ public class MapMarkers{
|
||||
public Seq<ObjectiveMarker> mapMarkers = new Seq<>(false);
|
||||
public Seq<ObjectiveMarker> lightMarkers = new Seq<>(false);
|
||||
|
||||
public void clear(){
|
||||
worldMarkers.clear();
|
||||
mapMarkers.clear();
|
||||
lightMarkers.clear();
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public void add(int id, ObjectiveMarker marker){
|
||||
if(marker == null) return;
|
||||
var prev = map.put(id, marker);
|
||||
@@ -111,4 +119,10 @@ public class MapMarkers{
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated use the seq fields instead */
|
||||
@Deprecated
|
||||
@Override
|
||||
public Iterator<ObjectiveMarker> iterator(){
|
||||
return worldMarkers.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,6 +343,10 @@ public class Rules{
|
||||
return unitFactoryActivationDelay + teams.get(team).unitFactoryActivationDelay;
|
||||
}
|
||||
|
||||
public boolean isInfiniteResources(Team team){
|
||||
return infiniteResources || teams.get(team).infiniteResources;
|
||||
}
|
||||
|
||||
/** A team-specific ruleset. */
|
||||
public static class TeamRule{
|
||||
/** Whether, when AI is enabled, ships should be spawned from the core. TODO remove / unnecessary? */
|
||||
|
||||
@@ -6,6 +6,7 @@ import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import arc.util.serialization.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.content.TechTree.*;
|
||||
import mindustry.core.*;
|
||||
@@ -554,6 +555,14 @@ public abstract class SaveVersion extends SaveFileReader{
|
||||
public void readDataPatches(DataInput stream, SaveReadState saveState) throws IOException{
|
||||
stream.readInt(); //version - ignored for now
|
||||
|
||||
//the requiredPlanets filter needs this, since the rules aren't read yet
|
||||
if(headless){
|
||||
try{
|
||||
Planet planet = content.planet(new JsonReader().parse(saveState.ruleString).getString("planet", Planets.serpulo.name));
|
||||
state.rules.planet = planet == null ? Planets.serpulo : planet;
|
||||
}catch(Exception ignored){}
|
||||
}
|
||||
|
||||
int total = stream.readInt();
|
||||
Seq<DataAsset> assets = new Seq<>(total);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,8 @@ public class LExecutor{
|
||||
/** Loads with a specified assembler. Resets all variables. */
|
||||
public void load(LAssembler builder){
|
||||
stop = false;
|
||||
textBuffer.setLength(0);
|
||||
graphicsBuffer.clear();
|
||||
nameMap = null;
|
||||
//retain constants that are links, which, by convention, don't start with @ (builtin) or _ (numeric constant)
|
||||
vars = builder.vars.values().toSeq().retainAll(var -> !var.constant || var.name.charAt(0) != '_' && var.name.charAt(0) != '@').toArray(LVar.class);
|
||||
@@ -1583,7 +1585,7 @@ public class LExecutor{
|
||||
public void run(LExecutor exec){
|
||||
if(net.client()) return;
|
||||
|
||||
Tile tile = world.tile(Mathf.round(x.numf()), Mathf.round(y.numf()));
|
||||
Tile tile = world.tile(x.numi(), y.numi());
|
||||
if(tile != null && block.obj() instanceof Block b){
|
||||
switch(layer){
|
||||
case ore -> {
|
||||
|
||||
@@ -90,7 +90,7 @@ public abstract class LStatement{
|
||||
/** Sanitizes variable input strings from text fields into values that will not break logic parsing. */
|
||||
public static String sanitize(String value){
|
||||
if(value.length() == 0){
|
||||
return "";
|
||||
return "null";
|
||||
}else if(value.length() == 1){
|
||||
if(value.charAt(0) == '"' || value.charAt(0) == ';' || value.charAt(0) == ' ' ||
|
||||
value.charAt(0) == '\n' || value.charAt(0) == '\t' || value.charAt(0) == '#'){
|
||||
|
||||
@@ -440,11 +440,8 @@ public class LStatements{
|
||||
|
||||
//Q: why don't you just use arrays for this?
|
||||
//A: arrays aren't as easy to serialize so the code generator doesn't handle them
|
||||
int c = 0;
|
||||
for(int i = 0; i < type.params.length; i++){
|
||||
|
||||
fields(table, type.params[i], i == 0 ? p1 : i == 1 ? p2 : i == 2 ? p3 : p4, i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : i == 2 ? v -> p3 = v : v -> p4 = v);
|
||||
|
||||
fields(table, type.params[i], type.params.length > 1 && LCanvas.isCompact(), i == 0 ? p1 : i == 1 ? p2 : i == 2 ? p3 : p4, i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : i == 2 ? v -> p3 = v : v -> p4 = v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,7 +534,7 @@ public class LStatements{
|
||||
|
||||
table.add(" = ");
|
||||
|
||||
tfield = field(table, type, str -> type = str).padRight(0f).get();
|
||||
tfield = field(table, type, str -> type = str).width(LCanvas.isCompact() ? 140f : 180f).padRight(0f).get();
|
||||
|
||||
table.button(b -> {
|
||||
b.image(Icon.pencilSmall);
|
||||
@@ -699,16 +696,7 @@ public class LStatements{
|
||||
}else{
|
||||
//"function"-type operations have the name at the left and arguments on the right
|
||||
if(op.func){
|
||||
if(LCanvas.isCompact()){
|
||||
table.left();
|
||||
table.table(c -> {
|
||||
c.color.set(category().color);
|
||||
c.left();
|
||||
funcs(c, table);
|
||||
}).colspan(2).left();
|
||||
}else{
|
||||
funcs(table, table);
|
||||
}
|
||||
funcs(table, table);
|
||||
}else{
|
||||
field(table, a, str -> a = str);
|
||||
|
||||
@@ -1947,9 +1935,7 @@ public class LStatements{
|
||||
fields(table, "team", team, s -> team = s);
|
||||
|
||||
if(type != FetchType.coreCount && type != FetchType.playerCount && type != FetchType.unitCount && type != FetchType.buildCount){
|
||||
table.add(" # ");
|
||||
|
||||
fields(table, index, i -> index = i);
|
||||
fields(table, "#", index, i -> index = i);
|
||||
}
|
||||
|
||||
if(type == FetchType.buildCount || type == FetchType.build){
|
||||
@@ -2408,7 +2394,7 @@ public class LStatements{
|
||||
private static String soundCategory(String entryName){
|
||||
String normalized = entryName.replace('\\', '/');
|
||||
int end = normalized.lastIndexOf('/');
|
||||
if(end < 0) return "Data Patch";
|
||||
if(end < 0) return "data patch";
|
||||
|
||||
int start = normalized.lastIndexOf('/', end - 1);
|
||||
return normalized.substring(start + 1, end);
|
||||
@@ -2555,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);
|
||||
|
||||
@@ -30,7 +30,8 @@ public class DataAudioLoader{
|
||||
}
|
||||
|
||||
Fi file = asset.getCacheFile();
|
||||
Sound sound = Vars.headless || file == null ? new Sound() : Sound.createStream(file);
|
||||
//large sounds become streams, standard ones don't
|
||||
Sound sound = Vars.headless || file == null ? new Sound() : file.length() > 100_000 ? Sound.createStream(file) : Sound.createLazy(file);
|
||||
loadedSounds.add(sound);
|
||||
|
||||
Sounds.registerSound(sound, nextSoundId ++);
|
||||
|
||||
@@ -12,6 +12,7 @@ import arc.util.*;
|
||||
import arc.util.Log.*;
|
||||
import mindustry.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.mod.data.*;
|
||||
|
||||
import java.io.*;
|
||||
@@ -106,6 +107,8 @@ public class DataImagePacker{
|
||||
|
||||
try{
|
||||
Pixmap pixmap = new Pixmap(cacheFile);
|
||||
Pixmaps.antialias(pixmap);
|
||||
Drawf.checkBleed(pixmap);
|
||||
//don't add the double dp prefix, only add it if it's not already present
|
||||
String name = (image.isGenerated() && image.name.contains("-dp-") ? "" : regionPrefix) + image.name;
|
||||
|
||||
@@ -178,7 +181,7 @@ public class DataImagePacker{
|
||||
public void unload(){
|
||||
if(patchAtlas != null){
|
||||
for(var texture : patchAtlas.getTextures()){
|
||||
if(texture != null) patchAtlas.getTextures().remove(texture);
|
||||
if(texture != null) Core.atlas.getTextures().remove(texture);
|
||||
}
|
||||
for(var region : patchAtlas.getRegions()){
|
||||
if(region != null){
|
||||
|
||||
@@ -78,6 +78,7 @@ public class DataManager{
|
||||
PixmapRegion error = new PixmapRegion(Pixmaps.blankPixmap());
|
||||
UnlockableContent[] currentContent = {null};
|
||||
String[] currentHash = {null};
|
||||
Fi serverGeneratedDir = Vars.dataDirectory.child("assets/sprites/generated");
|
||||
|
||||
MultiPacker saver = new MultiPacker(false){
|
||||
@Override
|
||||
@@ -89,10 +90,17 @@ public class DataManager{
|
||||
if(name.startsWith(DataImagePacker.regionPrefix)) name = name.substring(DataImagePacker.regionPrefix.length());
|
||||
String path = "generated/" + currentHash[0] + "/" + name + ".png";
|
||||
ImageAsset newImage = new ImageAsset();
|
||||
newImage.setPath(path);
|
||||
//it would be nice to do this async, but the pixmap typically gets disposed right after add() exist
|
||||
|
||||
//it would be nice to do this async, but the pixmap typically gets disposed right after add()
|
||||
byte[] bytes = PixmapIO.writePngBytes(region.pixmap);
|
||||
newImage.updateData(bytes);
|
||||
if(Vars.headless){ //TODO: doesn't actually work on the server yet
|
||||
Fi file = serverGeneratedDir.child(name + ".png");
|
||||
file.writeBytes(bytes);
|
||||
newImage.readOverride(path, file);
|
||||
}else{
|
||||
newImage.setPath(path);
|
||||
newImage.updateData(bytes);
|
||||
}
|
||||
|
||||
images.add(newImage);
|
||||
packed[0] ++;
|
||||
@@ -150,17 +158,15 @@ public class DataManager{
|
||||
imagePixmaps.each((key, val) -> val.pixmap.dispose());
|
||||
error.pixmap.dispose();
|
||||
|
||||
if(packed[0] > 0 || forcePack){
|
||||
if(!Vars.headless && (packed[0] > 0 || forcePack)){
|
||||
reloadImages();
|
||||
|
||||
if(!Vars.headless){
|
||||
for(var cont : contentToPack){
|
||||
try{
|
||||
cont.loadIcon();
|
||||
cont.load();
|
||||
}catch(Exception e){
|
||||
Log.err("Failed to load icons for " + cont, e);
|
||||
}
|
||||
for(var cont : contentToPack){
|
||||
try{
|
||||
cont.loadIcon();
|
||||
cont.load();
|
||||
}catch(Exception e){
|
||||
Log.err("Failed to load icons for " + cont, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.graphics.MultiPacker.*;
|
||||
import mindustry.mod.ContentParser.*;
|
||||
import mindustry.mod.data.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
|
||||
@@ -936,6 +937,24 @@ public class Mods implements Loadable{
|
||||
Events.fire(new ModContentLoadEvent());
|
||||
}
|
||||
|
||||
public void loadModPatches(){
|
||||
for(LoadedMod mod : orderedMods()){
|
||||
if(mod.root.child("patches").exists()){
|
||||
try{
|
||||
Seq<Fi> patches = mod.root.child("patches").findAll(f -> f.extEquals("json") || f.extEquals("hjson"));
|
||||
if(patches.size > 0){
|
||||
//create a new patcher per mod so the fields don't get reset
|
||||
DataPatcher patcher = new DataPatcher();
|
||||
patches.sort();
|
||||
patcher.apply(patches.map(f -> new PatchAsset(f.readString())), new Seq<>());
|
||||
}
|
||||
}catch(Exception e){
|
||||
Log.err("Failed to apply patches from mod " + mod.meta.name, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleContentError(Content content, Throwable error){
|
||||
parser.markError(content, error);
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ public class Fonts{
|
||||
|
||||
@Override
|
||||
public float imageSize(){
|
||||
return size;
|
||||
return size / Scl.scl(1f);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
number("@rules.blockdamagemultiplier", f -> rules.blockDamageMultiplier = f, () -> rules.blockDamageMultiplier);
|
||||
|
||||
if(Core.bundle.get("configure").toLowerCase().contains(ruleSearch)){
|
||||
current.button("@configure",
|
||||
current.button("@configure", Icon.boxSmall,
|
||||
() -> loadoutDialog.show(999999, rules.loadout,
|
||||
i -> true,
|
||||
() -> rules.loadout.clear().add(new ItemStack(Items.copper, 100)),
|
||||
@@ -186,7 +186,7 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
}
|
||||
|
||||
if(Core.bundle.get("bannedblocks").toLowerCase().contains(ruleSearch)){
|
||||
current.button("@bannedblocks", () -> bannedBlocks.show(rules.bannedBlocks)).left().width(300f).row();
|
||||
current.button("@bannedblocks", Icon.cancelSmall, () -> bannedBlocks.show(rules.bannedBlocks)).left().width(300f).row();
|
||||
}
|
||||
check("@rules.hidebannedblocks", b -> rules.hideBannedBlocks = b, () -> rules.hideBannedBlocks);
|
||||
check("@bannedblocks.whitelist", b -> rules.blockWhitelist = b, () -> rules.blockWhitelist);
|
||||
@@ -207,7 +207,7 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
check("@rules.logicunitdeconstruct", b -> rules.logicUnitDeconstruct = b, () -> rules.logicUnitDeconstruct, () -> rules.logicUnitControl);
|
||||
|
||||
if(Core.bundle.get("bannedunits").toLowerCase().contains(ruleSearch)){
|
||||
current.button("@bannedunits", () -> bannedUnits.show(rules.bannedUnits)).left().width(300f).row();
|
||||
current.button("@bannedunits", Icon.unitsSmall, () -> bannedUnits.show(rules.bannedUnits)).left().width(300f).row();
|
||||
}
|
||||
check("@bannedunits.whitelist", b -> rules.unitWhitelist = b, () -> rules.unitWhitelist);
|
||||
|
||||
@@ -234,7 +234,7 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
number("@rules.solarmultiplier", f -> rules.solarMultiplier = f, () -> rules.solarMultiplier);
|
||||
|
||||
if(Core.bundle.get("rules.weather").toLowerCase().contains(ruleSearch)){
|
||||
current.button("@rules.weather", this::weatherDialog).width(250f).left().row();
|
||||
current.button("@rules.weather", Icon.rainSmall, this::weatherDialog).width(250f).left().row();
|
||||
}
|
||||
|
||||
category("light");
|
||||
@@ -251,10 +251,6 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
}
|
||||
check("@rules.lighting.unitlight", b -> rules.unitLight = b, () -> rules.unitLight);
|
||||
|
||||
if(Core.bundle.get("rules.weather").toLowerCase().contains(ruleSearch)){
|
||||
current.button("@rules.weather", this::weatherDialog).width(250f).left().row();
|
||||
}
|
||||
|
||||
category("music");
|
||||
|
||||
Boolp allowMusic = () -> !rules.disableMusic;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ public class KeybindDialog extends Dialog{
|
||||
buttons.button("@back", Icon.left, this::hide).size(bw, bh).get().addListener(blocker);
|
||||
buttons.button("@settings.unbindKey", Icon.cancel, () -> {
|
||||
keyBind.unset();
|
||||
keyBind.save();
|
||||
hide();
|
||||
}).size(bw, bh).get().addListener(blocker);
|
||||
}};
|
||||
|
||||
@@ -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,9 +252,9 @@ 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.lastUpdated) + ".png");
|
||||
Fi cacheFile = cacheFolder.child(Strings.sanitizeFilename(mod.repo + "_" + mod.iconHash) + ".png");
|
||||
|
||||
if(!cacheFile.exists()){ //fetch from Github
|
||||
ConsT<HttpResponse, Exception> fetch = res -> {
|
||||
@@ -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()){
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -563,7 +563,11 @@ public class SettingsMenuDialog extends BaseDialog{
|
||||
Core.settings.put("swapdiagonal", false);
|
||||
}
|
||||
|
||||
dev.checkPref("console", false);
|
||||
dev.checkPref("console", false, val -> {
|
||||
if(val == false && ui.consolefrag != null){
|
||||
ui.consolefrag.close();
|
||||
}
|
||||
});
|
||||
dev.checkPref("drawhitboxes", false);
|
||||
dev.checkPref("showperformance", false);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class ConsoleFragment extends Table{
|
||||
font = Fonts.def;
|
||||
|
||||
visible(() -> {
|
||||
if(input.keyTap(Binding.console) && settings.getBool("console") && (scene.getKeyboardFocus() == chatfield || !(scene.getKeyboardFocus() instanceof TextField)) && !ui.chatfrag.shown()){
|
||||
if(input.keyTap(Binding.console) && (settings.getBool("console") || shown) && (scene.getKeyboardFocus() == chatfield || !(scene.getKeyboardFocus() instanceof TextField)) && !ui.chatfrag.shown()){
|
||||
shown = !shown;
|
||||
if(shown && !open && settings.getBool("console")){
|
||||
toggle();
|
||||
@@ -227,6 +227,11 @@ public class ConsoleFragment extends Table{
|
||||
open = false; //never true on mobile
|
||||
}
|
||||
|
||||
public void close(){
|
||||
shown = false;
|
||||
open = false;
|
||||
}
|
||||
|
||||
public void toggle(){
|
||||
|
||||
if(!open){
|
||||
|
||||
@@ -312,7 +312,7 @@ public class PlacementFragment{
|
||||
|
||||
button.update(() -> { //color unplacable things gray
|
||||
Building core = player.core();
|
||||
Color color = (state.rules.infiniteResources || (core != null && (core.items.has(block.requirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources))) && player.isBuilder() ? Color.white : Color.gray;
|
||||
Color color = (state.rules.isInfiniteResources(player.team()) || (core != null && (core.items.has(block.requirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources))) && player.isBuilder() ? Color.white : Color.gray;
|
||||
button.forEach(elem -> elem.setColor(color));
|
||||
button.setChecked(control.input.block == block);
|
||||
|
||||
@@ -407,7 +407,7 @@ public class PlacementFragment{
|
||||
line.label(() -> {
|
||||
Building core = player.core();
|
||||
int stackamount = Math.round(stack.amount * state.rules.buildCostMultiplier);
|
||||
if(core == null || state.rules.infiniteResources) return "*/" + stackamount;
|
||||
if(core == null || state.rules.isInfiniteResources(player.team())) return "*/" + stackamount;
|
||||
|
||||
int amount = core.items.get(stack.item);
|
||||
String color = (amount < stackamount / 2f ? "[scarlet]" : amount < stackamount ? "[accent]" : "[white]");
|
||||
|
||||
@@ -132,8 +132,7 @@ public class PlayerListFragment{
|
||||
});
|
||||
|
||||
button.add(iconTable).size(h);
|
||||
button.labelWrap("[#" + user.color().toString().toUpperCase() + "]" + user.name()).style(Styles.outlineLabel).width(170f).pad(10);
|
||||
button.add().grow();
|
||||
button.add("[#" + user.color().toString().toUpperCase() + "]" + user.name()).style(Styles.outlineLabel).growX().wrap(true).pad(10);
|
||||
|
||||
button.background(Tex.underline);
|
||||
|
||||
@@ -236,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
|
||||
@@ -249,7 +246,7 @@ public class PlayerListFragment{
|
||||
.size(h);
|
||||
}
|
||||
|
||||
content.add(button).width(350f).height(h + 14);
|
||||
content.add(button).width(mobile ? 350f : 470f).height(h + 14);
|
||||
content.row();
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
public boolean acceptsItems = false;
|
||||
/** If true, this block won't be affected by the onlyDepositCore rule. */
|
||||
public boolean alwaysAllowDeposit = false;
|
||||
/** If false, this block cannot be placed in payloads. */
|
||||
public boolean allowedInPayloads = true;
|
||||
/** Cooldown, in seconds, applied to player item depositing when any item is deposited to this block. Overrides the itemDepositCooldown if non-negative. */
|
||||
public float depositCooldown = -1f;
|
||||
/** If true, all item capacities of this block are separate instead of pooled as one number. */
|
||||
@@ -172,7 +174,8 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
public boolean updateInUnits = true;
|
||||
/** if true, this block updates in payloads in units regardless of the experimental game rule */
|
||||
public boolean alwaysUpdateInUnits = false;
|
||||
/** if true, this block can be picked up in payloads */
|
||||
/** @deprecated use allowedInPayloads instead */
|
||||
@Deprecated
|
||||
public boolean canPickup = true;
|
||||
/** if false, only incinerable liquids are dropped when deconstructing; otherwise, all liquids are dropped. */
|
||||
public boolean deconstructDropAllLiquid = false;
|
||||
@@ -757,7 +760,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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -62,7 +62,7 @@ public class BaseShield extends Block{
|
||||
hasPower = true;
|
||||
update = solid = true;
|
||||
rebuildable = false;
|
||||
canPickup = true;
|
||||
allowedInPayloads = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,15 +5,14 @@ import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.scene.ui.TextField.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
@@ -23,6 +22,8 @@ import mindustry.world.meta.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class TargetDummy extends Block{
|
||||
static final float maxDummySize = 30f;
|
||||
|
||||
public final int dpsUpdateTime = timers++;
|
||||
public UnitType unitType = UnitTypes.dummy;
|
||||
public float pullScale = 0.33f;
|
||||
@@ -38,18 +39,19 @@ public class TargetDummy extends Block{
|
||||
configurable = logicConfigurable = true;
|
||||
underBullets = true;
|
||||
targetable = false;
|
||||
|
||||
allowedInPayloads = false;
|
||||
canOverdrive = false;
|
||||
saveConfig = true;
|
||||
|
||||
config(FloatSeq.class, (TargetDummyBuild tile, FloatSeq config) -> {
|
||||
if(config.size > 0){
|
||||
tile.unitTeam = tile.team;
|
||||
if(config.get(0) == 1) tile.unitTeam = Team.get(tile.dummyTeam());
|
||||
}
|
||||
if(config.size > 1) tile.boosting = config.get(1) == 1;
|
||||
if(config.size > 2) tile.unitArmor = config.get(2);
|
||||
if(config.size > 3) tile.resetTime = config.get(3);
|
||||
if(config.size > 4) tile.dummySize = config.get(4);
|
||||
config(int[].class, (TargetDummyBuild tile, int[] config) -> {
|
||||
if(config.length != 5) return; //invalid, must have 5 values exactly
|
||||
tile.unitTeam = tile.team;
|
||||
if(config[0] == 1) tile.unitTeam = Team.get(tile.dummyTeam());
|
||||
tile.boosting = config[1] == 1;
|
||||
tile.unitArmor = Mathf.clamp(config[2], 0, 100_000);
|
||||
tile.resetTime = config[3];
|
||||
tile.dummySize = Mathf.clamp(Float.intBitsToFloat(config[4]), 0.1f, maxDummySize * tilesize);
|
||||
if(Float.isNaN(tile.dummySize) || Float.isInfinite(tile.dummySize)) tile.dummySize = 8f;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -90,6 +92,11 @@ public class TargetDummy extends Block{
|
||||
public float unitArmor;
|
||||
public Team unitTeam = Team.derelict;
|
||||
|
||||
@Override
|
||||
public boolean canPickup(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(){
|
||||
if(unitTeam == Team.derelict) unitTeam = team;
|
||||
@@ -235,24 +242,28 @@ public class TargetDummy extends Block{
|
||||
t.background(Styles.black6);
|
||||
t.defaults().left();
|
||||
|
||||
t.check(Core.bundle.get("rules.enemyteam"), unitTeam != team, b -> configureFloat(0, Mathf.num(b))).colspan(3).row();
|
||||
t.check(Core.bundle.get("stat.flying"), boosting, b -> configureFloat(1, Mathf.num(b))).colspan(3).row();
|
||||
t.check(Core.bundle.get("rules.enemyteam"), unitTeam != team, b -> configureInt(0, Mathf.num(b))).colspan(3).row();
|
||||
t.check(Core.bundle.get("stat.flying"), boosting, b -> configureInt(1, Mathf.num(b))).colspan(3).row();
|
||||
t.add(Core.bundle.get("stat.armor"));
|
||||
t.field("" + (int)unitArmor, TextFieldFilter.digitsOnly, s -> configureFloat(2, Strings.parseInt(s))).width(200f).padLeft(8f).colspan(2).row();
|
||||
t.field("" + (int)unitArmor, TextFieldFilter.digitsOnly, s -> configureInt(2, Strings.parseInt(s))).valid(val -> Strings.parseInt(val, Integer.MAX_VALUE) < 100_000).width(200f).padLeft(8f).colspan(2).row();
|
||||
t.add(Core.bundle.get("stat.resettime"));
|
||||
t.field(Strings.autoFixed(resetTime / 60f, 2), TextFieldFilter.floatsOnly, s -> configureFloat(3, Strings.parseFloat(s) * 60f)).padLeft(8f).growX();
|
||||
t.field(Strings.autoFixed(resetTime / 60f, 2), TextFieldFilter.floatsOnly, s -> configureInt(3, (int)(Strings.parseFloat(s) * 60f))).valid(Strings::canParsePositiveFloat).padLeft(8f).growX();
|
||||
t.add(StatUnit.seconds.localized()).padLeft(8).row();
|
||||
t.add(Core.bundle.get("stat.hitsize"));
|
||||
t.field("" + (dummySize/tilesize), TextFieldFilter.floatsOnly, s -> configureFloat(4, Strings.parseFloat(s) * tilesize)).padLeft(8f).growX();
|
||||
t.field("" + (dummySize/tilesize), TextFieldFilter.floatsOnly, s -> configureInt(4, Float.floatToIntBits(Strings.parseFloat(s) * tilesize)))
|
||||
.valid(val -> {
|
||||
float parsed = Strings.parseFloat(val, Float.MAX_VALUE);
|
||||
return parsed >= 0.1f && parsed <= maxDummySize;
|
||||
}).padLeft(8f).growX();
|
||||
t.add(StatUnit.blocks.localized()).padLeft(8f);
|
||||
}).top().grow().margin(8f);
|
||||
}
|
||||
|
||||
//helper to send the rest of values, since config does not support arrays
|
||||
public void configureFloat(int index, float value){
|
||||
FloatSeq seq = FloatSeq.with(Mathf.num(unitTeam != team), Mathf.num(boosting), unitArmor, resetTime, dummySize);
|
||||
seq.set(index, value);
|
||||
configure(seq);
|
||||
public void configureInt(int index, int value){
|
||||
int[] values = config();
|
||||
values[index] = value;
|
||||
configure(values);
|
||||
}
|
||||
|
||||
public int dummyTeam(){
|
||||
@@ -261,8 +272,9 @@ public class TargetDummy extends Block{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object config(){
|
||||
return FloatSeq.with(Mathf.num(unitTeam != team), Mathf.num(boosting), unitArmor, resetTime, dummySize);
|
||||
public int[] config(){
|
||||
//note: float[] is not supported in build 160
|
||||
return new int[]{Mathf.num(unitTeam != team), Mathf.num(boosting), (int)unitArmor, (int)resetTime, Float.floatToIntBits(dummySize)};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -162,7 +162,7 @@ public class DirectionalUnloader extends Block{
|
||||
public void read(Reads read, byte revision){
|
||||
super.read(read, revision);
|
||||
int id = read.s();
|
||||
unloadItem = id == -1 ? null : content.items().get(id);
|
||||
unloadItem = id == -1 ? null : content.item(id);
|
||||
offset = read.s();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ import mindustry.io.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
import mindustry.world.blocks.storage.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
@@ -87,7 +86,7 @@ public class PayloadSource extends PayloadBlock{
|
||||
}
|
||||
|
||||
public boolean canProduce(Block b){
|
||||
return !b.removed && b.isVisible() && b.size < size && !(b instanceof CoreBlock) && !state.rules.isBanned(b) && b.environmentBuildable();
|
||||
return !b.removed && b.isVisible() && b.size < size && b.allowedInPayloads && !state.rules.isBanned(b) && b.environmentBuildable();
|
||||
}
|
||||
|
||||
public boolean canProduce(UnitType t){
|
||||
|
||||
@@ -43,6 +43,15 @@ public class ThermalGenerator extends PowerGenerator{
|
||||
lightClipSize = Math.max(lightClipSize, 45f * size * 2f * 2f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPatch(){
|
||||
super.afterPatch();
|
||||
if(outputLiquid != null){
|
||||
outputsLiquid = true;
|
||||
hasLiquids = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStats(){
|
||||
super.setStats();
|
||||
@@ -82,7 +91,7 @@ public class ThermalGenerator extends PowerGenerator{
|
||||
generateEffect.at(x + Mathf.range(3f), y + Mathf.range(3f));
|
||||
}
|
||||
|
||||
if(outputLiquid != null){
|
||||
if(outputLiquid != null && hasLiquids){
|
||||
float added = Math.min(productionEfficiency * delta() * outputLiquid.amount, liquidCapacity - liquids.get(outputLiquid.liquid));
|
||||
liquids.add(outputLiquid.liquid, added);
|
||||
dumpLiquid(outputLiquid.liquid);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -335,7 +335,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ public class CoreBlock extends StorageBlock{
|
||||
envEnabled |= Env.space;
|
||||
drawCached = false;
|
||||
drawDynamic = true;
|
||||
allowedInPayloads = false;
|
||||
|
||||
//support everything
|
||||
replaceable = false;
|
||||
@@ -673,12 +674,6 @@ public class CoreBlock extends StorageBlock{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPickup(){
|
||||
//cores can never be picked up
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyed(){
|
||||
if(state.rules.coreCapture){
|
||||
|
||||
@@ -39,6 +39,7 @@ public class Reconstructor extends UnitBlock{
|
||||
|
||||
public Sound createSound = Sounds.unitCreate;
|
||||
public float createSoundVolume = 1f;
|
||||
public boolean showAllCommands = true;
|
||||
|
||||
public Reconstructor(String name){
|
||||
super(name);
|
||||
@@ -187,7 +188,7 @@ public class Reconstructor extends UnitBlock{
|
||||
if(build != null && build.team == this.team){
|
||||
commandPos.set(build);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -197,7 +198,7 @@ public class Reconstructor extends UnitBlock{
|
||||
|
||||
public boolean canSetCommand(){
|
||||
var output = unit();
|
||||
return output == null || output.allowChangeCommands;
|
||||
return showAllCommands ? (output == null || output.allowChangeCommands) : output != null && output.commands.size > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -214,6 +215,8 @@ public class Reconstructor extends UnitBlock{
|
||||
public void buildConfiguration(Table table){
|
||||
var unit = unit();
|
||||
|
||||
if(!showAllCommands && unit == null) return;
|
||||
|
||||
var group = new ButtonGroup<ImageButton>();
|
||||
group.setMinCheckCount(0);
|
||||
int i = 0, columns = 5;
|
||||
|
||||
@@ -47,8 +47,10 @@ public class ItemModule extends BlockModule{
|
||||
public void updateFlow(){
|
||||
//update the flow at N fps at most
|
||||
if(flowTimer.get(1, flowPollInterval)){
|
||||
int len = content.items().size;
|
||||
if(items.length != len) items = Arrays.copyOf(items, len);
|
||||
|
||||
if(flow == null){
|
||||
if(flow == null || flow.length != len || cacheSums == null || cacheFlow == null){
|
||||
if(cacheFlow == null || cacheFlow.length != items.length){
|
||||
cacheFlow = new WindowedMean[items.length];
|
||||
for(int i = 0; i < items.length; i++){
|
||||
@@ -95,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){
|
||||
@@ -290,6 +292,10 @@ public class ItemModule extends BlockModule{
|
||||
|
||||
public void checkArrayCapacity(int size){
|
||||
if(items.length != size) items = Arrays.copyOf(items, size);
|
||||
cacheFlow = null;
|
||||
cacheSums = null;
|
||||
displayFlow = null;
|
||||
flow = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,9 +20,9 @@ public class LiquidModule extends BlockModule{
|
||||
public static float flowVisualRefreshInterval = 15f;
|
||||
|
||||
private static final Interval flowTimer = new Interval(2);
|
||||
private static WindowedMean[] cacheFlow;
|
||||
private static float[] cacheSums;
|
||||
private static float[] displayFlow;
|
||||
private static @Nullable WindowedMean[] cacheFlow;
|
||||
private static @Nullable float[] cacheSums;
|
||||
private static @Nullable float[] displayFlow;
|
||||
private static final Bits cacheBits = new Bits();
|
||||
|
||||
private float[] liquids = new float[content.liquids().size];
|
||||
@@ -32,7 +32,10 @@ public class LiquidModule extends BlockModule{
|
||||
|
||||
public void updateFlow(){
|
||||
if(flowTimer.get(1, flowPollInterval)){
|
||||
if(flow == null){
|
||||
int len = content.liquids().size;
|
||||
if(liquids.length != len) liquids = Arrays.copyOf(liquids, len);
|
||||
|
||||
if(flow == null || flow.length != len || cacheSums == null || cacheFlow == null){
|
||||
if(cacheFlow == null || cacheFlow.length != liquids.length){
|
||||
cacheFlow = new WindowedMean[liquids.length];
|
||||
for(int i = 0; i < liquids.length; i++){
|
||||
@@ -75,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){
|
||||
@@ -152,6 +155,10 @@ public class LiquidModule extends BlockModule{
|
||||
|
||||
public void checkArrayCapacity(int size){
|
||||
if(liquids.length != size) liquids = Arrays.copyOf(liquids, size);
|
||||
cacheFlow = null;
|
||||
cacheSums = null;
|
||||
displayFlow = null;
|
||||
flow = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -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=ae321d09e6
|
||||
archash=7445105cd2
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
<true/>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||
|
||||
@@ -54,6 +54,7 @@ public class ServerLauncher implements ApplicationListener{
|
||||
mods.loadScripts();
|
||||
content.createModContent();
|
||||
content.init();
|
||||
mods.loadModPatches();
|
||||
|
||||
if(mods.hasContentErrors()){
|
||||
err("Error occurred loading mod content:");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import arc.graphics.*;
|
||||
import mindustry.logic.*;
|
||||
import mindustry.logic.LExecutor.*;
|
||||
import org.junit.jupiter.api.*;
|
||||
@@ -122,7 +123,7 @@ public class LogicTests{
|
||||
Arguments.of("a bare single semicolon is invalid", ";", "invalid"),
|
||||
Arguments.of("a bare single space is invalid", " ", "invalid"),
|
||||
Arguments.of("a single ordinary character passes through unchanged", "a", "a"),
|
||||
Arguments.of("empty input stays empty", "", ""),
|
||||
Arguments.of("empty input gets converted to null", "", "null"),
|
||||
Arguments.of("a plain already-quoted value is untouched", "\"hello\"", "\"hello\""),
|
||||
Arguments.of("a unescaped quote at the end gets doubled", "\"hello\\\"", "\"hello\\\\\""),
|
||||
Arguments.of(
|
||||
@@ -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}")
|
||||
@@ -336,4 +454,4 @@ public class LogicTests{
|
||||
void crlfLabelsResolveToTheSameJumpLocationAsLfLabels(){
|
||||
assertDoesNotThrow(() -> load("loop:\r\njump loop always\r\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,12 @@ public class SchemaGenerator{
|
||||
|
||||
var root = getTypeDecl(field.getDeclaringClass());
|
||||
if(root != null) root.getFieldByName(field.getName()).ifPresent(fdec -> {
|
||||
String[] docAndDefault = determineJavadocAndDefault(field, fdec, fdec.getVariables().getFirst().orElseThrow());
|
||||
var variable = fdec.getVariables().stream()
|
||||
.filter(v -> v.getNameAsString().equals(field.getName()))
|
||||
.findFirst().orElse(null);
|
||||
if(variable == null) return;
|
||||
|
||||
String[] docAndDefault = determineJavadocAndDefault(field, fdec, variable);
|
||||
if(docAndDefault[0] != null) inner.put("doc", docAndDefault[0]);
|
||||
if(docAndDefault[1] != null) inner.put("default", docAndDefault[1]);
|
||||
});
|
||||
@@ -302,8 +307,14 @@ public class SchemaGenerator{
|
||||
initValue = "[]";
|
||||
}
|
||||
|
||||
//field
|
||||
if(initValue.contains(".") && !(baseField.getType().isArray())){
|
||||
//numeric literal: drop the Java-only suffix (f/F/d/D/L), keep the decimal point for JSON
|
||||
boolean numeric = initValue.matches("-?(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?[fFdDlL]?");
|
||||
if(numeric){
|
||||
initValue = initValue.replaceAll("[fFdDlL]$", "");
|
||||
}
|
||||
|
||||
//field reference, e.g. Category.turret -> turret (never applied to numbers)
|
||||
if(!numeric && initValue.contains(".") && !(baseField.getType().isArray())){
|
||||
var split = initValue.split("\\.");
|
||||
initValue = split[split.length - 1];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user