diff --git a/.github/Mindustry-CodeStyle-IJ.xml b/.github/Mindustry-CodeStyle-IJ.xml new file mode 100644 index 0000000000..6a48acd1dd --- /dev/null +++ b/.github/Mindustry-CodeStyle-IJ.xml @@ -0,0 +1,85 @@ + + \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..e8870a2f23 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,69 @@ +# Contributing + +This is for code contributions. For translations, see [TRANSLATING](TRANSLATING.md). + +## 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. + + +#### Do not make large changes before discussing them first. +If you are interested in adding a large mechanic/feature or changing large amounts of code, first contact me (Anuken) via [Discord](https://discord.gg/mindustry) (preferred method) or via e-mail (*anukendev@gmail.com*). +For most changes, this should not be necessary. I just want to know if you're doing something big so I can offer advice and/or make sure you're not wasting your time on it. + + +## Style Guidelines + +#### Follow the formatting guidelines. +This means: +- No spaces around parentheses: `if(condition){`, `SomeType s = (SomeType)object` +- Same-line braces. +- 4 spaces indentation +- `camelCase`, **even for constants or enums**. Why? Because `SCREAMING_CASE` is ugly, annoying to type and does not achieve anything useful. Constants are *less* dangerous than variables, not more. +- No underscores for anything. (Yes, I know `Bindings` violates this principle, but that's for legacy reasons and really should be cleaned up some day) + +Import [this style file](.github/Mindustry-CodeStyle-IJ.xml) into IntelliJ to get correct formatting when developing Mindustry. + +#### Do not use incompatible Java features (java.util.function, java.awt). +Android [does not support](https://developer.android.com/studio/write/java8-support#supported_features) many of Java 8's features, such as the packages `java.util.function`, `java.util.stream` or `forEach` in collections. Do not use these in your code. +If you need to use functional interfaces, use the ones in `io.anuke.arc.func`, which are more or less the same with different naming schemes. + +The same applies to any class *outside* of the standard `java.[n]io` / `java.net` / `java.util` packages: Most of them are not supported. +`java.awt` is one of these packages: do not use it, ever. It is not supported on any platform, even desktop - the entire package is removed during JRE minimization. +In general, if you are using IntelliJ, you should be warned about platform incompatiblities. + + +#### Use `arc` collections and classes when possible. +Instead of using `java.util.List`, `java.util.HashMap`, and other standard Java collections, use `Array`, `ObjectMap` and other equivalents from `io.anuke.arc.collection`. +Why? Because that's what the rest of the codebase uses, and the standard collections have a lot of cruft and usability issues associated with them. +In the rare case that concurrency is required, you may use the standard Java classes for that purpose (e.g. `CopyOnWriteArrayList`). + +What you'll usually need to change: +- `HashSet` -> `ObjectSet` +- `HashMap` -> `ObjectMap` +- `List` / `ArrayList` / `Stack` -> `Array` +- `java.util.Queue` -> `io.anuke.arc.collection.Queue` +- *Many others* + + +#### Avoid boxed types (Integer, Boolean) +Never create variables or collections with boxed types `Array` or `ObjectMap`. Use the collections specialized for this task, e.g. `IntArray` 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. +If using a list, make it a static variable and clear it every time it is used. Re-use as much as possible. + +#### Avoid bloated code and unnecessary getters/setters. +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. diff --git a/README.md b/README.md index 4794ccbf73..555f3b3e09 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Logo](core/assets/sprites/logo.png) +![Logo](core/assets-raw/sprites/ui/logo.png) [![Build Status](https://travis-ci.org/Anuken/Mindustry.svg?branch=master)](https://travis-ci.org/Anuken/Mindustry) [![Discord](https://img.shields.io/discord/391020510269669376.svg)](https://discord.gg/mindustry) @@ -8,6 +8,10 @@ A sandbox tower defense game written in Java. _[Trello Board](https://trello.com/b/aE2tcUwF/mindustry-40-plans)_ _[Wiki](https://mindustrygame.github.io/wiki)_ +### Contributing + +See [CONTRIBUTING](CONTRIBUTING.md). + ### Building Bleeding-edge live builds are generated automatically for every commit. You can see them [here](https://github.com/Anuken/MindustryBuilds/releases). Old builds might still be on [jenkins](https://jenkins.hellomouse.net/job/mindustry/). diff --git a/android/build.gradle b/android/build.gradle index 15acace2ce..5486155564 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,7 +8,7 @@ buildscript{ } dependencies{ - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:3.4.1' } } @@ -69,7 +69,7 @@ android{ } defaultConfig{ - Properties props = new Properties().with{p -> p.load(file('../core/assets/version.properties').newReader()); return p } + Properties props = loadVersionProps() Integer vcode = props['androidBuildCode']?.toInteger() ?: 1 def versionNameResult = "$versionNumber-$versionType-${getBuildVersion().replace(" ", "-")}" diff --git a/build.gradle b/build.gradle index 2f542f1a8e..4e1252df97 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript{ } dependencies{ - classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.8-SNAPSHOT' + classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.8' classpath "com.badlogicgames.gdx:gdx-tools:1.9.10" classpath "com.github.anuken:packr:-SNAPSHOT" } @@ -17,7 +17,7 @@ buildscript{ allprojects{ version = 'release' - apply plugin: 'maven-publish' + apply plugin: 'maven' group = 'com.github.Anuken' ext{ @@ -26,10 +26,14 @@ allprojects{ if(!project.hasProperty("versionType")) versionType = 'official' appName = 'Mindustry' gdxVersion = '1.9.10' - roboVMVersion = '2.3.8-SNAPSHOT' + roboVMVersion = '2.3.8' steamworksVersion = '891ed912791e01fe9ee6237a6497e5212b85c256' arcHash = null + loadVersionProps = { + return new Properties().with{p -> p.load(file('../core/assets/version.properties').newReader()); return p } + } + debugged = { return new File(projectDir.parent, '../Mindustry-Debug').exists() && !project.hasProperty("release") && project.hasProperty("args") } @@ -200,6 +204,27 @@ project(":core"){ writeVersion() } + task copyChangelog{ + doLast{ + def props = loadVersionProps() + def androidVersion = props['androidBuildCode'].toInteger() - 2 + def buildVersion = props["build"] + def loglines = file("../changelog").text.split("\n") + def maxLength = 460 + + def androidLogList = loglines.findAll{ line -> !line.endsWith("]") || line.endsWith("[Mobile]") || line.endsWith("[Android]")} + def result = "" + androidLogList.forEach({line -> + if(result.length() + line.length() + 1 < maxLength){ + result += line + "\n" + } + }) + def changelogs = file("../fastlane/metadata/android/en-US/changelogs/") + new File(changelogs, buildVersion + ".txt").text = (result) + new File(changelogs, androidVersion + ".txt").text = (result) + } + } + dependencies{ if(System.properties["user.name"] == "anuke"){ task cleanGen{ diff --git a/core/assets-raw/sprites/blocks/liquid/liquid-overflow-gate-top.png b/core/assets-raw/sprites/blocks/liquid/liquid-overflow-gate-top.png new file mode 100644 index 0000000000..f6bdf7f613 Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/liquid-overflow-gate-top.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/liquid-overflow-gate.png b/core/assets-raw/sprites/blocks/liquid/liquid-overflow-gate.png new file mode 100644 index 0000000000..f608e0a6d1 Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/liquid-overflow-gate.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/plated-conduit-cap.png b/core/assets-raw/sprites/blocks/liquid/plated-conduit-cap.png new file mode 100644 index 0000000000..f4e8df2bb7 Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/plated-conduit-cap.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-0.png b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-0.png new file mode 100644 index 0000000000..21fd730109 Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-0.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-1.png b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-1.png new file mode 100644 index 0000000000..94c22fd75e Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-1.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-2.png b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-2.png new file mode 100644 index 0000000000..a9bdc10692 Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-2.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-3.png b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-3.png new file mode 100644 index 0000000000..7487e481cb Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-3.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-4.png b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-4.png new file mode 100644 index 0000000000..19fad690a4 Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-4.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-5.png b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-5.png new file mode 100644 index 0000000000..45158534c4 Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-5.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-6.png b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-6.png new file mode 100644 index 0000000000..f5b5cd1157 Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/plated-conduit-top-6.png differ diff --git a/core/assets-raw/sprites/blocks/power/illuminator-top.png b/core/assets-raw/sprites/blocks/power/illuminator-top.png new file mode 100644 index 0000000000..8597b28d97 Binary files /dev/null and b/core/assets-raw/sprites/blocks/power/illuminator-top.png differ diff --git a/core/assets-raw/sprites/blocks/power/illuminator.png b/core/assets-raw/sprites/blocks/power/illuminator.png new file mode 100644 index 0000000000..9269a33447 Binary files /dev/null and b/core/assets-raw/sprites/blocks/power/illuminator.png differ diff --git a/core/assets-raw/sprites/effects/circle-end.png b/core/assets-raw/sprites/effects/circle-end.png new file mode 100644 index 0000000000..e63f104191 Binary files /dev/null and b/core/assets-raw/sprites/effects/circle-end.png differ diff --git a/core/assets-raw/sprites/effects/circle-mid.png b/core/assets-raw/sprites/effects/circle-mid.png new file mode 100644 index 0000000000..c6805a606c Binary files /dev/null and b/core/assets-raw/sprites/effects/circle-mid.png differ diff --git a/core/assets-raw/sprites/effects/circle-shadow.png b/core/assets-raw/sprites/effects/circle-shadow.png index 2e9aaec802..129b74296d 100644 Binary files a/core/assets-raw/sprites/effects/circle-shadow.png and b/core/assets-raw/sprites/effects/circle-shadow.png differ diff --git a/core/assets-raw/sprites/ui/alpha-bg.png b/core/assets-raw/sprites/ui/alpha-bg.png new file mode 100644 index 0000000000..9cbc32b1fe Binary files /dev/null and b/core/assets-raw/sprites/ui/alpha-bg.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-f-droid.png b/core/assets-raw/sprites/ui/icons/icon-f-droid.png new file mode 100644 index 0000000000..1a2eca14f2 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-f-droid.png differ diff --git a/core/assets-raw/sprites/ui/logo.png b/core/assets-raw/sprites/ui/logo.png new file mode 100644 index 0000000000..eee1e0e658 Binary files /dev/null and b/core/assets-raw/sprites/ui/logo.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index f9582c0316..f3337a999f 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -10,6 +10,7 @@ link.dev-builds.description = Unstable development builds link.trello.description = Official Trello board for planned features link.itch.io.description = itch.io page with PC downloads link.google-play.description = Google Play store listing +link.f-droid.description = F-Droid catalogue listing link.wiki.description = Official Mindustry wiki linkfail = Failed to open link!\nThe URL has been copied to your clipboard. screenshot = Screenshot saved to {0} @@ -78,6 +79,7 @@ maps.browse = Browse Maps continue = Continue maps.none = [lightgray]No maps found! invalid = Invalid +pickcolor = Pick Color preparingconfig = Preparing Config preparingcontent = Preparing Content uploadingcontent = Uploading Content @@ -97,6 +99,7 @@ mod.enabled = [lightgray]Enabled mod.disabled = [scarlet]Disabled mod.disable = Disable mod.delete.error = Unable to delete mod. File may be in use. +mod.requiresversion = [scarlet]Requires game version: [accent]{0} mod.missingdependencies = [scarlet]Missing dependencies: {0} mod.nowdisabled = [scarlet]Mod '{0}' is missing dependencies:[accent] {1}\n[lightgray]These mods need to be downloaded first.\nThis mod will be automatically disabled. mod.enable = Enable @@ -497,6 +500,7 @@ settings.language = Language settings.data = Game Data settings.reset = Reset to Defaults settings.rebind = Rebind +settings.resetKey = Reset settings.controls = Controls settings.game = Game settings.sound = Sound @@ -590,6 +594,8 @@ unit.persecond = /sec unit.timesspeed = x speed unit.percent = % unit.items = items +unit.thousands = k +unit.millions = mil category.general = General category.power = Power category.liquids = Liquids @@ -628,9 +634,12 @@ setting.conveyorpathfinding.name = Conveyor Placement Pathfinding setting.sensitivity.name = Controller Sensitivity setting.saveinterval.name = Save Interval setting.seconds = {0} seconds +setting.blockselecttimeout.name = Block Select Timeout +setting.milliseconds = {0} milliseconds setting.fullscreen.name = Fullscreen setting.borderlesswindow.name = Borderless Window[lightgray] (may require restart) setting.fps.name = Show FPS & Ping +setting.blockselectkeys.name = Show Block Select Keys setting.vsync.name = VSync setting.pixelate.name = Pixelate[lightgray] (disables animations) setting.minimap.name = Show Minimap @@ -659,17 +668,36 @@ category.multiplayer.name = Multiplayer command.attack = Attack command.rally = Rally command.retreat = Retreat +placement.blockselectkeys = \n[lightgray]Key: [{0}, keybind.clear_building.name = Clear Building keybind.press = Press a key... keybind.press.axis = Press an axis or key... keybind.screenshot.name = Map Screenshot +keybind.toggle_power_lines.name = Toggle Power Lasers keybind.move_x.name = Move X keybind.move_y.name = Move Y keybind.mouse_move.name = Follow Mouse +keybind.dash.name = Dash keybind.schematic_select.name = Select Region keybind.schematic_menu.name = Schematic Menu keybind.schematic_flip_x.name = Flip Schematic X keybind.schematic_flip_y.name = Flip Schematic Y +keybind.category_prev.name = Previous Category +keybind.category_next.name = Next Category +keybind.block_select_left.name = Block Select Left +keybind.block_select_right.name = Block Select Right +keybind.block_select_up.name = Block Select Up +keybind.block_select_down.name = Block Select Down +keybind.block_select_01.name = Category/Block Select 1 +keybind.block_select_02.name = Category/Block Select 2 +keybind.block_select_03.name = Category/Block Select 3 +keybind.block_select_04.name = Category/Block Select 4 +keybind.block_select_05.name = Category/Block Select 5 +keybind.block_select_06.name = Category/Block Select 6 +keybind.block_select_07.name = Category/Block Select 7 +keybind.block_select_08.name = Category/Block Select 8 +keybind.block_select_09.name = Category/Block Select 9 +keybind.block_select_10.name = Category/Block Select 10 keybind.fullscreen.name = Toggle Fullscreen keybind.select.name = Select/Shoot keybind.diagonal_placement.name = Diagonal Placement @@ -683,7 +711,6 @@ keybind.menu.name = Menu keybind.pause.name = Pause keybind.pause_building.name = Pause/Resume Building keybind.minimap.name = Minimap -keybind.dash.name = Dash keybind.chat.name = Chat keybind.player_list.name = Player List keybind.console.name = Console @@ -708,6 +735,7 @@ mode.attack.description = Destroy the enemy's base. No waves.\n[gray]Requires a mode.custom = Custom Rules rules.infiniteresources = Infinite Resources +rules.reactorexplosions = Reactor Explosions rules.wavetimer = Wave Timer rules.waves = Waves rules.attack = Attack Mode @@ -733,6 +761,9 @@ rules.title.resourcesbuilding = Resources & Building rules.title.player = Players rules.title.enemy = Enemies rules.title.unit = Units +rules.title.experimental = Experimental +rules.lighting = Lighting +rules.ambientlight = Ambient Light content.item.name = Items content.liquid.name = Liquids @@ -780,6 +811,7 @@ mech.trident-ship.name = Trident mech.trident-ship.weapon = Bomb Bay mech.glaive-ship.name = Glaive mech.glaive-ship.weapon = Flame Repeater +item.corestorable = [lightgray]Storable in Core: {0} item.explosiveness = [lightgray]Explosiveness: {0}% item.flammability = [lightgray]Flammability: {0}% item.radioactivity = [lightgray]Radioactivity: {0}% @@ -895,6 +927,8 @@ block.distributor.name = Distributor block.sorter.name = Sorter block.inverted-sorter.name = Inverted Sorter block.message.name = Message +block.illuminator.name = Illuminator +block.illuminator.description = A small, compact, configurable light source. Requires power to function. block.overflow-gate.name = Overflow Gate block.silicon-smelter.name = Silicon Smelter block.phase-weaver.name = Phase Weaver @@ -961,6 +995,7 @@ block.fortress-factory.name = Fortress Mech Factory block.revenant-factory.name = Revenant Fighter Factory block.repair-point.name = Repair Point block.pulse-conduit.name = Pulse Conduit +block.plated-conduit.name = Plated Conduit block.phase-conduit.name = Phase Conduit block.liquid-router.name = Liquid Router block.liquid-tank.name = Liquid Tank @@ -1014,7 +1049,7 @@ unit.reaper.name = Reaper tutorial.next = [lightgray] tutorial.intro = You have entered the[scarlet] Mindustry Tutorial.[]\nUse [accent][[WASD][] to move.\n[accent]Hold [[Ctrl] while scrolling[] to zoom in and out.\nBegin by[accent] mining copper[]. Move close to it, then tap a copper ore vein near your core to do this.\n\n[accent]{0}/{1} copper tutorial.intro.mobile = You have entered the[scarlet] Mindustry Tutorial.[]\nSwipe the screen to move.\n[accent]Pinch with 2 fingers[] to zoom in and out.\nBegin by[accent] mining copper[]. Move close to it, then tap a copper ore vein near your core to do this.\n\n[accent]{0}/{1} copper -tutorial.drill = Mining manually is inefficient.\n[accent]Drills[] can mine automatically.\nClick the drill tab in the bottom right.\nSelect the[accent] mechanical drill[]. Place it on a copper vein by clicking.\n[accent]Right-click[] to stop building. +tutorial.drill = Mining manually is inefficient.\n[accent]Drills[] can mine automatically.\nClick the drill tab in the bottom right.\nSelect the[accent] mechanical drill[]. Place it on a copper vein by clicking.\nYou can also select the drill by tapping [accent][[2][] then [accent][[1][] quickly, regardless of which tab is open.\n[accent]Right-click[] to stop building. tutorial.drill.mobile = Mining manually is inefficient.\n[accent]Drills[] can mine automatically.\nTap the drill tab in the bottom right.\nSelect the[accent] mechanical drill[].\nPlace it on a copper vein by tapping, then press the[accent] checkmark[] below to confirm your selection.\nPress the[accent] X button[] to cancel placement. tutorial.blockinfo = Each block has different stats. Each drill can only mine certain ores.\nTo check a block's info and stats,[accent] tap the "?" button while selecting it in the build menu.[]\n\n[accent]Access the Mechanical Drill's stats now.[] tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.\n[accent]Hold down the mouse to place in a line.[]\nHold[accent] CTRL[] while selecting a line to place diagonally.\nUse the scrollwheel to rotate blocks before placing them.\n[accent]Place 2 conveyors with the line tool, then deliver an item into the core. @@ -1057,7 +1092,7 @@ mech.alpha-mech.description = The standard control mech. Based on a Dagger unit, mech.delta-mech.description = A fast, lightly-armored mech made for hit-and-run attacks. Does little damage against structures, but can kill large groups of enemy units very quickly with its arc lightning weapons. mech.tau-mech.description = The support mech. Heals allied blocks by shooting at them. Can heal allies in a radius with its repair ability. mech.omega-mech.description = A bulky and well-armored mech, made for front-line assaults. Its armor can block up to 90% of incoming damage. -mech.dart-ship.description = The standard control ship. Reasonably fast and light, but has little offensive capability and low mining speed. +mech.dart-ship.description = The standard control ship. Fast mining speed. Reasonably fast and light, but has little offensive capability. mech.javelin-ship.description = A hit-and-run strike ship. While initially slow, it can accelerate to great speeds and fly by enemy outposts, dealing large amounts of damage with its lightning and missiles. mech.trident-ship.description = A heavy bomber, built for construction and destroying enemy fortifications. Reasonably well armored. mech.glaive-ship.description = A large, well-armored gunship. Equipped with an incendiary repeater. Highly maneuverable. @@ -1129,6 +1164,7 @@ block.rotary-pump.description = An advanced pump. Pumps more liquid, but require block.thermal-pump.description = The ultimate pump. block.conduit.description = Basic liquid transport block. Moves liquids forward. Used in conjunction with pumps and other conduits. block.pulse-conduit.description = An advanced liquid transport block. Transports liquids faster and stores more than standard conduits. +block.plated-conduit.description = Moves liquids at the same rate as pulse conduits, but possesses more armor. Does not accept fluids from the sides by anything other than conduits.\nLeaks less. block.liquid-router.description = Accepts liquids from one direction and outputs them to up to 3 other directions equally. Can also store a certain amount of liquid. Useful for splitting the liquids from one source to multiple targets. block.liquid-tank.description = Stores a large amount of liquids. Use for creating buffers in situations with non-constant demand of materials or as a safeguard for cooling vital blocks. block.liquid-junction.description = Acts as a bridge for two crossing conduits. Useful in situations with two different conduits carrying different liquids to different locations. diff --git a/core/assets/bundles/bundle_eu.properties b/core/assets/bundles/bundle_eu.properties index 81927de1c5..c86b1c28cd 100644 --- a/core/assets/bundles/bundle_eu.properties +++ b/core/assets/bundles/bundle_eu.properties @@ -3,7 +3,7 @@ credits = Kredituak contributors = Itzultzaile eta kolaboratzaileak discord = Elkartu Mindustry Discord-era! link.discord.description = Mindustry Discord txat gela ofiziala -link.reddit.description = The Mindustry subreddit +link.reddit.description = Mindustry azpireddita link.github.description = Jolasaren iturburu kodea link.changelog.description = Eguneraketaren aldaketen zerrenda link.dev-builds.description = Garapen konpilazio ezegonkorrak @@ -17,29 +17,29 @@ screenshot.invalid = Mapa handiegia, baliteke pantaila-argazkirako memoria nahik gameover = Partida amaitu da gameover.pvp = [accent] {0}[] taldeak irabazi du! highscore = [accent]Marka berria! -copied = Copied. +copied = Kopiatuta. load.sound = Soinuak load.map = Mapak load.image = Irudiak load.content = Edukia load.system = Sistema -load.mod = Mods -schematic = Schematic -schematic.add = Save Schematic... -schematics = Schematics -schematic.replace = A schematic by that name already exists. Replace it? -schematic.import = Import Schematic... -schematic.exportfile = Export File -schematic.importfile = Import File -schematic.browseworkshop = Browse Workshop -schematic.copy = Copy to Clipboard -schematic.copy.import = Import from Clipboard -schematic.shareworkshop = Share on Workshop -schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Flip Schematic -schematic.saved = Schematic saved. -schematic.delete.confirm = This schematic will be utterly eradicated. -schematic.rename = Rename Schematic -schematic.info = {0}x{1}, {2} blocks +load.mod = Mod-ak +schematic = Eskama +schematic.add = Gorde eskema... +schematics = Eskemak +schematic.replace = Badago izen bereko eskema bat. Ordeztu nahi duzu? +schematic.import = Inportatu eskema... +schematic.exportfile = Esportatu fitxategia +schematic.importfile = Inportatu fitxategia +schematic.browseworkshop = Arakatu tailerra +schematic.copy = Kopiatu arbelera +schematic.copy.import = Inportatu arbeletik +schematic.shareworkshop = Partekatu tailerrean +schematic.flip = [accent][[{0}][]/[accent][[{1}][]: itzulbiratu eskema +schematic.saved = Eskema gordeta. +schematic.delete.confirm = Eskema hau behin betiko suntsituko da. +schematic.rename = Aldatu izena eskemari +schematic.info = {0}x{1}, {2} bloke stat.wave = Garaitutako boladak:[accent] {0} stat.enemiesDestroyed = Suntsitutako etsaiak:[accent] {0} stat.built = Eraikitako eraikinak:[accent] {0} @@ -48,7 +48,7 @@ stat.deconstructed = Deseraikitako eraikinak:[accent] {0} stat.delivered = Egotzitako baliabideak: stat.rank = Azken graduazioa: [accent]{0} launcheditems = [accent]Egotzitako baliabideak -launchinfo = [unlaunched][[LAUNCH] your core to obtain the items indicated in blue. +launchinfo = [unlaunched][[EGOTZI] zure muina urdinez adierazitako baliabideak eskuratzeko. map.delete = Ziur al zaude "[accent]{0}[]" mapa ezabatu nahi duzula? level.highscore = Marka: [accent]{0} level.select = Maila hautaketa @@ -64,7 +64,7 @@ customgame = Partida pertsonalizatua newgame = Partida berria none = minimap = Mapatxoa -position = Position +position = Posizioa close = Itxi website = Webgunea quit = Irten @@ -80,30 +80,30 @@ uploadingcontent = Edukia igotzen uploadingpreviewfile = Aurrebista fitxategia igotzen committingchanges = Aldaketak aplikatzen done = Egina -feature.unsupported = Your device does not support this feature. -mods.alphainfo = Keep in mind that mods are in alpha, and[scarlet] may be very buggy[].\nReport any issues you find to the Mindustry GitHub or Discord. -mods.alpha = [accent](Alpha) -mods = Mods -mods.none = [LIGHT_GRAY]No mods found! -mods.guide = Modding Guide -mods.report = Report Bug -mods.openfolder = Open Mod Folder -mod.enabled = [lightgray]Enabled -mod.disabled = [scarlet]Disabled -mod.disable = Disable -mod.delete.error = Unable to delete mod. File may be in use. -mod.missingdependencies = [scarlet]Missing dependencies: {0} -mod.nowdisabled = [scarlet]Mod '{0}' is missing dependencies:[accent] {1}\n[lightgray]These mods need to be downloaded first.\nThis mod will be automatically disabled. -mod.enable = Enable -mod.requiresrestart = The game will now close to apply the mod changes. -mod.reloadrequired = [scarlet]Reload Required -mod.import = Import Mod -mod.import.github = Import GitHub Mod -mod.remove.confirm = This mod will be deleted. -mod.author = [LIGHT_GRAY]Author:[] {0} -mod.missing = This save contains mods that you have recently updated or no longer have installed. Save corruption may occur. Are you sure you want to load it?\n[lightgray]Mods:\n{0} -mod.preview.missing = Before publishing this mod in the workshop, you must add an image preview.\nPlace an image named[accent] preview.png[] into the mod's folder and try again. -mod.folder.missing = Only mods in folder form can be published on the workshop.\nTo convert any mod into a folder, simply unzip its file into a folder and delete the old zip, then restart your game or reload your mods. +feature.unsupported = Zure gailuak ez du ezaugarri hau onartzen. +mods.alphainfo = Kontuan izan mod-ak alfa egoeran daudela, eta [scarlet] akats ugari izan ditzakete[].\nEman arazoen berri Mindustry-ren GitHub or Discord zerbitzuetan. +mods.alpha = [accent](Alfa) +mods = Mod-ak +mods.none = [LIGHT_GRAY]Ez da mod-ik aurkitu! +mods.guide = Mod-ak sortzeko gida +mods.report = Eman akatsaren berri +mods.openfolder = Ireki Mod-en karpeta +mod.enabled = [lightgray]Gaituta +mod.disabled = [scarlet]Desgaituta +mod.disable = Desgaitu +mod.delete.error = Ezin izan da mod-a ezabatu. Agian fitxategia erabilia izaten ari da. +mod.missingdependencies = [scarlet]Falta diren menpekotasunak: {0} +mod.nowdisabled = [scarlet]'{0}' mod-ak menpekotasunak ditu faltan:[accent] {1}\n[lightgray]Aurretik beste mod hauek deskargatu behar dira.\nMod hau automatikoki desgaituko da. +mod.enable = Gaitu +mod.requiresrestart = Jolasa itxi egingo da mod-aren aldaketak aplikatzeko. +mod.reloadrequired = [scarlet]Birkargatu behar da +mod.import = Importatu Mod-a +mod.import.github = Inportatu GitHub Mod-a +mod.remove.confirm = Mod hau ezabatuko da. +mod.author = [LIGHT_GRAY]Egilea:[] {0} +mod.missing = Gordetako partida honek eguneratu dituzun edo jada instalatuta ez dituzun mod-ak ditu. Gordetako partida izorratu daiteke. Ziur kargatu nahi duzula?\n[lightgray]Mod-ak:\n{0} +mod.preview.missing = Mod hau tailerrean argitaratu aurretik, aurrebista bat gehitu behar diozu.\nKokatu[accent] preview.png[] izeneko irudi bat mod-aren karpetan eta saiatu berriro. +mod.folder.missing = Karpeta formatuko mod-ak besterik ezin dira argitaratu tailerrean.\nEdozein mod karpetara bihurtzeko, deskopnrimitu fitxategia eta ezabatu zip zaharra, gero berrabiarazi jolasa edo birkargatu zure mod-ak. about.button = Honi buruz name = Izena: noname = Hautatu[accent] jokalari-izena[] aurretik. @@ -216,8 +216,8 @@ save.playtime = Jolastua: {0} warning = Abisua. confirm = Baieztatu delete = Ezabatu -view.workshop = Ikusi lantegian -workshop.listing = Edit Workshop Listing +view.workshop = Ikusi tailerrean +workshop.listing = Editatu tailerreko zerrenda ok = Ados open = Ireki customize = Aldatu arauak @@ -235,12 +235,12 @@ classic.export.text = [accent]Mindustry[] jolasak eguneraketa nagusi bat jaso du quit.confirm = Ziur irten nahi duzula? quit.confirm.tutorial = Ziur al zaude irten nahi duzula?\nTutoriala berriro hasi dezakezu hemen: [accent] Ezarpenak->Jolasa->Berriro hasi tutoriala.[] loading = [accent]Kargatzen... -reloading = [accent]Reloading Mods... +reloading = [accent]Mod-ak birkargatzen... saving = [accent]Gordetzen... -cancelbuilding = [accent][[{0}][] to clear plan -selectschematic = [accent][[{0}][] to select+copy -pausebuilding = [accent][[{0}][] to pause building -resumebuilding = [scarlet][[{0}][] to resume building +cancelbuilding = [accent][[{0}][] plan bat ezabatzeko +selectschematic = [accent][[{0}][] hautatu+kopiatzeko +pausebuilding = [accent][[{0}][] eraikiketa eteteko +resumebuilding = [scarlet][[{0}][] eraikiketa berrekiteko wave = [accent]{0}. bolada wave.waiting = [lightgray]Boladarako {0} wave.waveInProgress = [lightgray]Bolada abian @@ -259,18 +259,18 @@ map.nospawn = Mapa honek ez du muinik jokalaria sortu dadin! Gehitu muin [accent map.nospawn.pvp = Mapa honek ez du etsaien muinik jokalaria sortu dadin! Gehitu [SCARLET]laranja ez den[] muinen bat edo batzuk mapa honi editorean. map.nospawn.attack = Mapa honek ez du etsaien muinik jokalariak eraso dezan! Gehitu muin [SCARLET]gorriak[] mapa honi editorean. map.invalid = Errorea mapa kargatzean: Mapa-fitxategi baliogabe edo hondatua. -workshop.update = Update Item -workshop.error = Error fetching workshop details: {0} +workshop.update = Eguneratu elementua +workshop.error = Errorea tailerreko xehetasunak eskuratzean: {0} map.publish.confirm = Ziur mapa hau argitaratu nahi duzula?\n\n[lightgray]Ziurtatu aurretik lantegiaren erabilera arauekin bat zatozela, bestela zure mapak ez dira agertuko! -workshop.menu = Select what you would like to do with this item. -workshop.info = Item Info -changelog = Changelog (optional): +workshop.menu = Erabaki elementu honekin zer egin nahi duzun. +workshop.info = Elementuaren informazioa +changelog = Aldaketa egunkatia (aukerakoa): eula = Steam EULA -missing = This item has been deleted or moved.\n[lightgray]The workshop listing has now been automatically un-linked. -publishing = [accent]Publishing... -publish.confirm = Are you sure you want to publish this?\n\n[lightgray]Make sure you agree to the Workshop EULA first, or your items will not show up! -publish.error = Error publishing item: {0} -steam.error = Failed to initialize Steam services.\nError: {0} +missing = Elementu hau ezabatu edo lekuz aldatu da.\n[lightgray]Tailerreko zerrendatik kendu da automatikoki. +publishing = [accent]Argitaratzen... +publish.confirm = Ziur hau argitaratu nahi duzula?\n\n[lightgray]Egiaztatu tailerreko EULA lizentziarekin ados zaudela aurretik, bestela zure elementuak ez dira agertuko! +publish.error = Errorea elementua argitaratzean: {0} +steam.error = Huts egin du Steam zerbitzuak hasieratzean.\nErrorea: {0} editor.brush = Brotxa editor.openin = Ireki editorean editor.oregen = Mea sorrera @@ -411,9 +411,9 @@ abandon = Abandonatu abandon.text = Eremu hau eta bere baliabide guztiak etsaiaren esku geratuko dira. locked = Blokeatuta complete = [lightgray]Helmena: -requirement.wave = Reach Wave {0} in {1} -requirement.core = Destroy Enemy Core in {0} -requirement.unlock = Unlock {0} +requirement.wave = Iritsi {0} boladara {1} +requirement.core = Suntsitu etsaiaren muina {0} +requirement.unlock = Desblokeatu {0} resume = Berrekin:\n[lightgray]{0} bestwave = [lightgray]Bolada onena: {0} launch = < EGOTZI > @@ -424,13 +424,13 @@ launch.confirm = Honek zure muinean dauden baliabide guztiak egotziko ditu.\nEzi launch.skip.confirm = Orain ez eginez gero, geroagoko beste bolada batera itxaron beharko duzu. uncover = Estalgabetu configure = Konfiguratu zuzkidura -bannedblocks = Banned Blocks -addall = Add All +bannedblocks = Debekatutako blokeak +addall = Gehitu denak configure.locked = [lightgray]Zuzkiduraren konfigurazioa desblokeatzeko: {0} bolada. configure.invalid = Kopurua 0 eta {0} bitarteko zenbaki bat izan behar da. zone.unlocked = [lightgray]{0} desblokeatuta. zone.requirement.complete = {0}. boladara iritsia:\n{1} Eremuaren betebeharra beteta. -zone.config.unlocked = Loadout unlocked:[lightgray]\n{0} +zone.config.unlocked = Deskarga desblokeatuta:[lightgray]\n{0} zone.resources = [lightgray]Antzemandako baliabideak: zone.objective = [lightgray]Helburua: [accent]{0} zone.objective.survival = Biziraupena @@ -487,8 +487,8 @@ settings.cleardata = Garbitu jolasaren datuak... settings.clear.confirm = Ziur datu hauek garbitu nahi dituzula?\nEgindakoa ezin da desegin! settings.clearall.confirm = [scarlet]ABISUA![]\nHonek datu guztiak garbituko ditu, gordetako partidak, mapak, desblokeatutakoak, eta teklen konfigurazioak barne.\nBehin 'Ados' sakatzen duzula jolasak datuk guztiak ezabatuko ditu eta automatikoki irten. paused = [accent]< Pausatuta > -clear = Clear -banned = [scarlet]Banned +clear = Garbitu +banned = [scarlet]Debekatuta yes = Bai no = Ez info.title = Informazioa @@ -509,7 +509,7 @@ blocks.shootrange = Irismena blocks.size = Neurria blocks.liquidcapacity = Likido-edukiera blocks.powerrange = Energia irismena -blocks.powerconnections = Max Connections +blocks.powerconnections = Gehieneko konexioak blocks.poweruse = Energia-erabilera blocks.powerdamage = Energia/Kaltea blocks.itemcapacity = Elementu-edukiera @@ -531,7 +531,7 @@ blocks.reload = Tiroak/segundoko blocks.ammo = Munizioa bar.drilltierreq = Zulagailu hobea behar da bar.drillspeed = Ustiatze-abiadura: {0}/s -bar.pumpspeed = Pump Speed: {0}/s +bar.pumpspeed = Ponpatze abiadura: {0}/s bar.efficiency = Eraginkortasuna: {0}% bar.powerbalance = Energia: {0}/s bar.powerstored = Bilduta: {0}/{1} @@ -576,9 +576,9 @@ category.shooting = Tirokatzea category.optional = Aukerako hobekuntzak setting.landscape.name = Blokeatu horizontalean setting.shadows.name = Itzalak -setting.blockreplace.name = Automatic Block Suggestions +setting.blockreplace.name = Bloke proposamen automatikoak setting.linear.name = Iragazte lineala -setting.hints.name = Hints +setting.hints.name = Pistak setting.animatedwater.name = Animatutako ura setting.animatedshields.name = Animatutako ezkutuak setting.antialias.name = Antialias[lightgray] (berrabiarazi behar da)[] @@ -599,8 +599,8 @@ setting.difficulty.insane = Zoramena setting.difficulty.name = Zailtasuna: setting.screenshake.name = Pantailaren astindua setting.effects.name = Bistaratze-efektuak -setting.destroyedblocks.name = Display Destroyed Blocks -setting.conveyorpathfinding.name = Conveyor Placement Pathfinding +setting.destroyedblocks.name = Erakutsi suntsitutako blokeak +setting.conveyorpathfinding.name = Garraio-zintak kokatzeko bide-bilaketa setting.sensitivity.name = Kontrolagailuaren sentikortasuna setting.saveinterval.name = Gordetzeko tartea setting.seconds = {0} segundo @@ -610,7 +610,7 @@ setting.fps.name = Erakutsi FPS setting.vsync.name = VSync setting.pixelate.name = Pixelatu[lightgray] (animazioak desgaitzen ditu) setting.minimap.name = Erakutsi mapatxoa -setting.position.name = Show Player Position +setting.position.name = Erakutsi jokalariaren kokalekua setting.musicvol.name = Musikaren bolumena setting.ambientvol.name = Giroaren bolumena setting.mutemusic.name = Isilarazi musika @@ -620,10 +620,10 @@ setting.crashreport.name = Bidali kraskatze txosten automatikoak setting.savecreate.name = Gorde automatikoki setting.publichost.name = Partidaren ikusgaitasun publikoa setting.chatopacity.name = Txataren opakotasuna -setting.lasersopacity.name = Power Laser Opacity +setting.lasersopacity.name = Energia laserraren opakutasuna setting.playerchat.name = Erakutsi jolas barneko txata -public.confirm = Do you want to make your game public?\n[accent]Anyone will be able to join your games.\n[lightgray]This can be changed later in Settings->Game->Public Game Visibility. -public.beta = Note that beta versions of the game cannot make public lobbies. +public.confirm = Zure jolasa publikoa egin nahi duzu?\n[accent]Edonor elkartu ahal izango da zure partidetara.\n[lightgray]Hau gero ere aldatu dauteke, Ezarpenak->Partida->Partida publikoaren ikusgaitasuna. +public.beta = Kontuan izan jolasaren beta bertsioek ezin dituztela jokalarien gela publokoak sortu. uiscale.reset = Interfazearen eskala aldatu da.\nSakatu "Ados" eskala hau berresteko.\n[scarlet][accent] {0}[] segundo atzera egin eta irteteko... uiscale.cancel = Utzi eta irten setting.bloom.name = Distira @@ -635,16 +635,16 @@ category.multiplayer.name = Hainbat jokalari command.attack = Eraso command.rally = Batu command.retreat = Erretreta -keybind.clear_building.name = Clear Building +keybind.clear_building.name = Garrbitu eraikina keybind.press = Sakatu tekla bat... keybind.press.axis = Sakatu ardatza edo tekla... keybind.screenshot.name = Maparen pantaila-argazkia keybind.move_x.name = Mugitu x keybind.move_y.name = Mugitu y -keybind.schematic_select.name = Select Region -keybind.schematic_menu.name = Schematic Menu -keybind.schematic_flip_x.name = Flip Schematic X -keybind.schematic_flip_y.name = Flip Schematic Y +keybind.schematic_select.name = Hautatu eskualdea +keybind.schematic_menu.name = Eskema menua +keybind.schematic_flip_x.name = Itzulbiratu X +keybind.schematic_flip_y.name = Itzulbiratu Y keybind.fullscreen.name = Txandakatu pantaila osoa keybind.select.name = Hautatu/Tirokatu keybind.diagonal_placement.name = Kokatze diagonala @@ -656,14 +656,14 @@ keybind.zoom_hold.name = Zoom mantenduz keybind.zoom.name = Zoom keybind.menu.name = Menua keybind.pause.name = Pausatu -keybind.pause_building.name = Pause/Resume Building +keybind.pause_building.name = Pausatu/berrekin eraikiketa keybind.minimap.name = Mapatxoa keybind.dash.name = Arrapalada keybind.chat.name = Txata keybind.player_list.name = Jokalarien zerrenda keybind.console.name = Kontsola keybind.rotate.name = Biratu -keybind.rotateplaced.name = Rotate Existing (Hold) +keybind.rotateplaced.name = Biratu dagoena (Mantendu) keybind.toggle_menus.name = Txandakatu menuak keybind.chat_history_prev.name = Txat historialean aurrekoa keybind.chat_history_next.name = Txat historialean hurrengoa @@ -675,7 +675,7 @@ mode.survival.name = Biziraupena mode.survival.description = Modu arrunta. Baliabide mugatuak eta bolada automatikoak.\n[gray]Jolasteko etsaien sortze puntuak behar dira mapan. mode.sandbox.name = Jolastokia mode.sandbox.description = Baliabide amaigabeak eta boladen denboragailurik gabe. -mode.editor.name = Editor +mode.editor.name = Editorea mode.pvp.name = JvJ mode.pvp.description = Borrokatu beste jokalari batzuk lokalean.\n[gray]Gutxienez bi kolore desberdinetako muinak behar dira mapan jolasteko. mode.attack.name = Erasoa @@ -843,8 +843,8 @@ block.copper-wall.name = Kobrezko horma block.copper-wall-large.name = Kobrezko horma handia block.titanium-wall.name = Titaniozko horma block.titanium-wall-large.name = Titaniozko horma handia -block.plastanium-wall.name = Plastanium Wall -block.plastanium-wall-large.name = Large Plastanium Wall +block.plastanium-wall.name = Plastaniozko horma +block.plastanium-wall-large.name = Plastaniozko horma handia block.phase-wall.name = Fasezko horma block.phase-wall-large.name = Fasezko horma handia block.thorium-wall.name = Toriozko horma @@ -864,7 +864,7 @@ block.junction.name = Lotunea block.router.name = Bideratzailea block.distributor.name = Banatzailea block.sorter.name = Antolatzailea -block.inverted-sorter.name = Inverted Sorter +block.inverted-sorter.name = Alderantzizko antolatzailea block.message.name = Mezua block.overflow-gate.name = Gainezkatze atea block.silicon-smelter.name = Silizio galdategia @@ -983,7 +983,7 @@ unit.lich.name = Litxe unit.reaper.name = Segalaria tutorial.next = [lightgray] tutorial.intro = Hau [scarlet]Mindustry tutoriala[] da.\nHasi [accent]kobrea ustiatzen[]. Horretarako, sakatu zure muinetik hurbil dagoen kobre-mea bat.\n\n[accent]{0}/{1} kobre -tutorial.intro.mobile = You have entered the[scarlet] Mindustry Tutorial.[]\nSwipe the screen to move.\n[accent]Pinch with 2 fingers [] to zoom in and out.\nBegin by[accent] mining copper[]. Move close to it, then tap a copper ore vein near your core to do this.\n\n[accent]{0}/{1} copper +tutorial.intro.mobile = [scarlet] Mindustry Tutorialean[] sartu zara\nPasatu hatza mugitzeko.\n[accent]Egin atximurkada bi hatzekin [] zooma hurbildu edo urruntzeko.\nHasi[accent] kobrea ustiatuz[]. Hurbildu kobrera, gero sakatu zure muinetik hurbil dagoen kobre mea bat.\n\n[accent]{0}/{1} kobre tutorial.drill = Eskuz ustiatzea ez da eraginkorra.\n[accent]Zulagailuek []automatikoki ustiatu dezakete.\nSakatu zulagailuen fitxa, behean eskuman.\nHautatu[accent] zulagailu mekanikoa[]. Kokatu ezazu kobre zain batean klik eginez.\n[accent]Eskumako klik[] deseraikitzeko. tutorial.drill.mobile = Eskuz ustiatzea ez da eraginkorra.\n[accent]Zulagailuek []automatikoki ustiatu dezakete.\nSakatu zulagailuen fitxa behean eskuman.\nHautatu[accent] zulagailu mekanikoa[]. \nKokatu ezazu kobre zain batean sakatuz, gero sakatu azpiko [accent]egiaztapen-marka[] zure hautaketa berresteko.\nSakatu [accent]X botoia[] kokatzea ezeztatzeko. tutorial.blockinfo = Bloke bakoitzak estatistika desberdinak ditu. Eta zulagailu bakoitzak mea mota zehatz batzuk ustiatu ditzake soilik.\nBloke mota baten informazio eta estatistikak egiaztatzeko,[accent] hautatu blokea eraikiketa menuan eta sakatu "?" botoia .[]\n\n[accent]Atzitu zulagailu mekanikoaren estatistikak orain.[] @@ -1000,7 +1000,7 @@ tutorial.breaking.mobile = Maiz blokeak suntsitu beharko dituzu.\n[accent]Hautat tutorial.withdraw = Egoera batzuetan, blokeetatik zuzenean hartu behar dira baliabideak.\nHorretarako, [accent]sakatu baliabideak dituen bloke bat[], gero [accent]sakatu baliabidea[] inbentarioan.\nHainbat baliabide ateratzeko [accent]sakatu eta mantendu[].\n\n[accent]Atera kobre apur bat muinetik.[] tutorial.deposit = Baliabideak blokeren batean sartzeko, arrastatu zure ontzitik blokera.\n\n[accent]Sartu zure kobrea berriro muinean.[] tutorial.waves = [lightgray]Etsaia[] dator.\n\nBabestu muina 2 boladetan zehar. [accent]Egin klik[] tirokatzeko.\nEraiki dorre eta zulagailu gehiago. Ustiatu kobre gehiago. -tutorial.waves.mobile = [lightgray]Etsaia[] daor.\n\nBabestu muina 2 boladatan. Zure ontziak automatikoki tirokatuko ditu etsaiak.\nEraiki dorre eta zulagailu gehiago. Ustiatu kobre gehiago. +tutorial.waves.mobile = [lightgray]Etsaia[] dator.\n\nBabestu muina 2 boladatan. Zure ontziak automatikoki tirokatuko ditu etsaiak.\nEraiki dorre eta zulagailu gehiago. Ustiatu kobre gehiago. tutorial.launch = Bolada zehatz batera heltzean, [accent]muina egotzi[] dezakezu, zure defentsak atzean utziz [accent]eta muineko baliabide guztiak eskuratuz.[]\nBaliabide hauek teknologia berriak ikertzeko erabili daitezke.\n\n[accent]Sakatu egotzi botoia. item.copper.description = Egiturazko material oinarrizkoena. Asko erabilia bloke mota guztietarako. item.lead.description = Hastapeneko oinarrizko materiala. Bloke elektronikoak eta likidoen garraiorako blokeetan asko erabilia. @@ -1067,8 +1067,8 @@ block.copper-wall.description = Babeserako bloke merke bat.\nMuina eta dorreak l block.copper-wall-large.description = Babeserako bloke merke bat.\nMuina eta dorreak lehen boladetan babesteko erabilgarria.\nHainbat lauza hartzen ditu. block.titanium-wall.description = Zertxobait gogorra den babeserako bloke bat.\nEtsaien aurreko babes ertaina eskaintzen du. block.titanium-wall-large.description = Zertxobait gogorra den babeserako bloke bat.\nEtsaien aurreko babes ertaina eskaintzen du.\nHainbat lauza hartzen ditu. -block.plastanium-wall.description = A special type of wall that absorbs electric arcs and blocks automatic power node connections. -block.plastanium-wall-large.description = A special type of wall that absorbs electric arcs and blocks automatic power node connections.\nSpans multiple tiles. +block.plastanium-wall.description = Arku elektrikoak xurgatzen dituen eta energia-nodoen konexio automatikoak blokeatzen dituen horma berezia. +block.plastanium-wall-large.description = Arku elektrikoak xurgatzen dituen eta energia-nodoen konexio automatikoak blokeatzen dituen horma berezia..\nHainbat lauza hartzen ditu. block.thorium-wall.description = Babeserako bloke gogorra.\nEtsaitatik aterpe txukuna. block.thorium-wall-large.description = Babeserako bloke gogorra.\nEtsaitatik aterpe txukuna.\nHainbat lauza hartzen ditu. block.phase-wall.description = Fasez osatutako konposatu islatzaile batez estalitako horma bat. Talkan jasotako bala gehienak desbideratzen ditu. @@ -1088,7 +1088,7 @@ block.junction.description = Gurutzatutako bi garraio-zinten arteko zubi gisa ar block.bridge-conveyor.description = Elementuen garraiorako bloke aurreratua. Elementuak edozein gainazal edo eraikinen gainetik garraiatzen ditu 3 lauzatara gehienez. block.phase-conveyor.description = Elementuen garraiorako bloke aurreratua. Energia erabiltzen du hainbat lauzetara konektatutako beste Fasezko garraiagailu batera elementuak teleportatzeko. block.sorter.description = Elementuak antolatzen ditu. Elementu bat hautuarekin bat badator, aurrera jarraitu dezake. Bestela, elementua ezker eta eskuinera ateratzen da. -block.inverted-sorter.description = Processes items like a standard sorter, but outputs selected items to the sides instead. +block.inverted-sorter.description = Antolatzaile arruntaren antzera prozesatzen ditu elementuak, baina hautatutako elementuak alboetara ateratzen ditu. block.router.description = Elementuak onartzen ditu, eta beste gehienez 3 norabideetara ateratzen ditu kopuru berdinetan. Jatorri batetik hainbat xedeetara materialak banatzeko egokia.\n\n[scarlet]Ez jarri ekoizpen sarreren ondoan, irteerek trabatuko baitute.[] block.distributor.description = Bideratzaile aurreratu bat. Elementuak beste gehienez 7 norabideetara sakabanatzen ditu kopuru berdinetan. block.overflow-gate.description = Antolatzaile eta bideratzaile konbinatua. Soilik aurrealdea blokeatuta dagoenean ateratzen du ezker eta eskuinera. diff --git a/core/assets/bundles/bundle_fi.properties b/core/assets/bundles/bundle_fi.properties new file mode 100644 index 0000000000..b441ee0a62 --- /dev/null +++ b/core/assets/bundles/bundle_fi.properties @@ -0,0 +1,1051 @@ +credits.text = Pelin tehnyt [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[] +credits = Tekijät +contributors = Kääntäjät ja avustajat +discord = Liity Mindustryn Discordiin! +link.discord.description = Mindustryn virallinen Discord-keskusteluhuone +link.github.description = Pelin lähdekoodi +link.changelog.description = Lista päivityksien muutoksista +link.dev-builds.description = Epävakaat kehitysversiot +link.trello.description = Virallinen Trello-taulu suunnitelluille ominaisuuksille. +link.itch.io.description = itch.io -sivu tietokoneversion latausten kanssa +link.google-play.description = Google Play Kauppa -sivu +link.wiki.description = Virallinen Mindustry wiki +linkfail = Linkin avaaminen epäonnistui!\nOsoite on kopioitu leikepöydällesi. +screenshot = Kuvankaappaus tallennettu sijaintiin {0} +screenshot.invalid = Kartta liian laaja, kuvankaappaukselle ei mahdollisesti ole tarpeeksi tilaa. +gameover = Peli ohi +gameover.pvp = [accent] {0}[] joukkue voittaa! +highscore = [accent]Uusi ennätys! + +stat.wave = Aaltoja voitettu:[accent] {0} +stat.enemiesDestroyed = Vihollisia tuhottu:[accent] {0} +stat.built = Rakennuksia rakennettu:[accent] {0} +stat.destroyed = Rakennuksia tuhottu:[accent] {0} +stat.deconstructed = Rakennuksia purettu:[accent] {0} +stat.delivered = Resursseja laukaistu: +stat.rank = Lopullinen arvo: [accent]{0} + +placeline = Olet valinnut palikan.\nVoit[accent] asettaa linjassa[][accent] pitämällä sormeasi pohjassa muutaman sekunnin ajan[] ja vetämällä johonkin suuntaan.\n\n[scarlet]TEE SE. +removearea = Olet valinut poistotilan.\nVoit[accent] poistaa palikoita suorakulmiossa[][accent] pitämällä sormeasi pohjassa muutaman sekunnin ajan[] ja vetämällä.\n\n[scarlet]TEE SE. + +launcheditems = [accent]Laukaistut tavarat +map.delete = Oletko varma että haluat poistaa kartan "[accent]{0}[]"? +level.highscore = Ennätys: [accent]{0} +level.select = Tason valinta +level.mode = Pelitila: +showagain = Älä näytä uudestaan seuraavalla kerralla +coreattack = < Ytimeen hyökätään! > +nearpoint = [[ [scarlet]POISTU PUDOTUSPISTEELTÄ VÄLITTÖMÄSTI[]\nvälitön tuhoutuminen +database = Ytimen tietokanta +savegame = Tallenna peli +loadgame = Lataa peli +joingame = Liity peliin +addplayers = Lisää/Poista pelaajia +customgame = Mukautettu peli +newgame = Uusi peli +none = +minimap = Pienoiskartta +close = Sulje +website = Verkkosivu +quit = Poistu +maps = Kartat +continue = Jatka +maps.none = [lightgray]Karttoja ei löytynyt! +about.button = Tietoa +name = Nimi: +noname = Valitse ensin[accent] pelaajanimi[]. +filename = Tiedostonimi: +unlocked = Uutta sisältöä avattu! +completed = [accent]Suoritettu +techtree = Tekniikkapuu +research.list = [lightgray]Tutki: +research = Tutki +researched = [lightgray]{0} tutkittu. +players = {0} pelaajaa paikalla +players.single = {0} pelaaja paikalla +server.closing = [accent]Suljetaan palvelinta... +server.kicked.kick = Sinut on potkittu palvelimelta! +server.kicked.serverClose = Palvelin suljettu. +server.kicked.clientOutdated = Pelisi on vanhentunut! Päivitä se! +server.kicked.serverOutdated = Outdated server! Ask the host to update! +server.kicked.banned = Sinulla on portikielto tälle palvelimelle. +server.kicked.recentKick = Sinut on potkittu äskettäin.\nOdota ennen kuin yhdistät uudestaan. +server.kicked.nameInUse = Joku tuon niminen\non jo tällä palvelimella. +server.kicked.nameEmpty = Valitsemasi nimi on virheellinen. +server.kicked.idInUse = Olet jo tällä palvelimella! Kahdella käyttäjällä yhdistäminen ei ole sallittua. +server.kicked.customClient = Tämä palvelin ei tue muokattuja versioita. Lataa virallinen versio. +server.kicked.gameover = Peli ohi! +server.versions = Versiosi:[accent] {0}[]\nPalvelimen versio:[accent] {1}[] +host.info = The [accent]host[] button hosts a server on port [scarlet]6567[]. \nAnybody on the same [lightgray]wifi or local network[] should be able to see your server in their server list.\n\nIf you want people to be able to connect from anywhere by IP, [accent]port forwarding[] is required.\n\n[lightgray]Note: If someone is experiencing trouble connecting to your LAN game, make sure you have allowed Mindustry access to your local network in your firewall settings. Note that public networks sometimes do not allow server discovery. +join.info = Here, you can enter a [accent]server IP[] to connect to, or discover [accent]local network[] servers to connect to.\nBoth LAN and WAN multiplayer is supported.\n\n[lightgray]Note: There is no automatic global server list; if you want to connect to someone by IP, you would need to ask the host for their IP. +hostserver = Host Multiplayer Game +hostserver.mobile = Host\nGame +host = Host +hosting = [accent]Avataan palvelinta... +hosts.refresh = Päivitä +hosts.discovering = Discovering LAN games +server.refreshing = Päivitetään palvelimen tietoja +hosts.none = [lightgray]No local games found! +host.invalid = [scarlet]Can't connect to host. +trace = Trace Player +trace.playername = Pelaajanimi: [accent]{0} +trace.ip = IP-osoite: [accent]{0} +trace.id = Uniikki tunniste: [accent]{0} +trace.mobile = Mobile Client: [accent]{0} +trace.modclient = Custom Client: [accent]{0} +invalidid = Invalid client ID! Submit a bug report. +server.bans = Porttikiellot +server.bans.none = Porttikieltoja saaneita pelaajia ei löytynyt! +server.admins = Ylläpitäjät +server.admins.none = Ylläpitäjiä ei löytynyt! +server.add = Lisää palvelin +server.delete = Oletko varma että haluat poistaa tämän palvelimen? +server.edit = Muokkaa palvelinta +server.outdated = [crimson]Vanhentunut palvelin![] +server.outdated.client = [crimson]Vanhentunut asiakasohjelma![] +server.version = [gray]v{0} {1} +server.custombuild = [yellow]Custom Build +confirmban = Are you sure you want to ban this player? +confirmkick = Are you sure you want to kick this player? +confirmunban = Are you sure you want to unban this player? +confirmadmin = Are you sure you want to make this player an admin? +confirmunadmin = Are you sure you want to remove admin status from this player? +joingame.title = Liity peliin +joingame.ip = Osoite: +disconnect = Disconnected. +disconnect.data = Failed to load world data! +connecting = [accent]Connecting... +connecting.data = [accent]Loading world data... +server.port = Portti: +server.addressinuse = Address already in use! +server.invalidport = Invalid port number! +server.error = [crimson]Error hosting server: [accent]{0} +save.old = This save is for an older version of the game, and can no longer be used.\n\n[lightgray]Save backwards compatibility will be implemented in the full 4.0 release. +save.new = New Save +save.overwrite = Are you sure you want to overwrite\nthis save slot? +overwrite = Overwrite +save.none = No saves found! +saveload = Saving... +savefail = Failed to save game! +save.delete.confirm = Are you sure you want to delete this save? +save.delete = Delete +save.export = Export Save +save.import.invalid = [accent]This save is invalid! +save.import.fail = [crimson]Failed to import save: [accent]{0} +save.export.fail = [crimson]Failed to export save: [accent]{0} +save.import = Import Save +save.newslot = Tallennuksen nimi: +save.rename = Nimeä uudelleen +save.rename.text = Uusi nimi: +selectslot = Valitse tallennus. +slot = [accent]Paikka {0} +save.corrupted = [accent]Tallennustiedosto korruptoitunut tai viallinen!\nJos olet päivittänyt juuri pelisi, tämä on todennäköisesti muutos tallennusmuodossa [scarlet]eikä[] virhe. +empty = +on = Päällä +off = Pois +save.autosave = Automaattitallennus: {0} +save.map = Kartta: {0} +save.wave = Aalto {0} +save.difficulty = Vaikeustaso: {0} +save.date = Viimeksi tallennettu: {0} +save.playtime = Peliaika: {0} +warning = Varoitus. +confirm = Vahvista +delete = Poista +ok = OK +open = Avaa +customize = Muokkaa sääntöjä +cancel = Peruuta +openlink = Avaa linkki +copylink = Kopioi linkki +back = Takaisin +classic.export = Export Classic Data +classic.export.text = [accent]Mindustry[] has just had a major update.\nClassic (v3.5 build 40) save or map data has been detected. Would you like to export these saves to your phone's home folder, for use in the Mindustry Classic app? +quit.confirm = Are you sure you want to quit? +quit.confirm.tutorial = Are you sure you know what you're doing?\nThe tutorial can be re-taken in[accent] Settings->Game->Re-Take Tutorial.[] +loading = [accent]Ladataan... +saving = [accent]Tallennetaan... +wave = [accent]Aalto {0} +wave.waiting = [lightgray]Wave in {0} +wave.waveInProgress = [lightgray]Wave in progress +waiting = [lightgray]Odotetaan... +waiting.players = Odotetaan pelaajia... +wave.enemies = [lightgray]{0} vihollista jäljellä +wave.enemy = [lightgray]{0} vihollinen jäljellä +loadimage = Lataa kuva +saveimage = Tallenna kuva +unknown = Tuntematon +custom = Custom +builtin = Sisäänrakennettu +map.delete.confirm = Oletko varma että haluat poistaa tämän kartan? Poistoa ei voi peruuttaa! +map.random = [accent]Satunnainen kartta +map.nospawn = Tässä kartassa ei ole ytimiä joihin syntyä! Lisää[accent] oranssi[] ydin karttaan editorissa. +map.nospawn.pvp = This map does not have any enemy cores for player to spawn into! Add[SCARLET] non-orange[] cores to this map in the editor. +map.nospawn.attack = This map does not have any enemy cores for player to attack! Add[SCARLET] red[] cores to this map in the editor. +map.invalid = Error loading map: corrupted or invalid map file. +editor.brush = Brush +editor.openin = Avaa editorissa +editor.oregen = Ore Generation +editor.oregen.info = Ore Generation: +editor.mapinfo = Kartan tiedot +editor.author = Author: +editor.description = Kuvaus: +editor.waves = Aallot: +editor.rules = Säännöt: +editor.generation = Generation: +editor.ingame = Edit In-Game +editor.newmap = Uusi kartta +waves.title = Aallot +waves.remove = Remove +waves.never = +waves.every = every +waves.waves = wave(s) +waves.perspawn = per spawn +waves.to = to +waves.boss = Boss +waves.preview = Preview +waves.edit = Muokkaa... +waves.copy = Kopioi leikepöydälle +waves.load = Lataa leikepöydältä +waves.invalid = Invalid waves in clipboard. +waves.copied = Aallot kopioitu. +waves.none = No enemies defined.\nNote that empty wave layouts will automatically be replaced with the default layout. +editor.default = [lightgray] +edit = Muokkaa... +editor.name = Nimi: +editor.spawn = Spawn Unit +editor.removeunit = Remove Unit +editor.teams = Joukkueet +editor.errorload = Virhe ladattaessa tiedostoa:\n[accent]{0} +editor.errorsave = Virhe tallennettaessa tiedostoa:\n[accent]{0} +editor.errorimage = That's an image, not a map. Don't go around changing extensions expecting it to work.\n\nIf you want to import a legacy map, use the 'import legacy map' button in the editor. +editor.errorlegacy = This map is too old, and uses a legacy map format that is no longer supported. +editor.errorheader = This map file is either not valid or corrupt. +editor.errorname = Map has no name defined. Are you trying to load a save file? +editor.update = Päivitä +editor.randomize = Randomize +editor.apply = Apply +editor.generate = Generate +editor.resize = Resize +editor.loadmap = Lataa kartta +editor.savemap = Tallenna kartta +editor.saved = Tallennettu! +editor.save.noname = Your map does not have a name! Set one in the 'map info' menu. +editor.save.overwrite = Your map overwrites a built-in map! Pick a different name in the 'map info' menu. +editor.import.exists = [scarlet]Unable to import:[] a built-in map named '{0}' already exists! +editor.import = Tuo... +editor.importmap = Tuo kartta +editor.importmap.description = Import an already existing map +editor.importfile = Tuo tiedosto +editor.importfile.description = Import an external map file +editor.importimage = Import Legacy Image +editor.importimage.description = Import an external map image file +editor.export = Vie... +editor.exportfile = Vie tiedosto +editor.exportfile.description = Export a map file +editor.exportimage = Export Terrain Image +editor.exportimage.description = Export a map image file +editor.loadimage = Import Terrain +editor.saveimage = Export Terrain +editor.unsaved = [scarlet]You have unsaved changes![]\nAre you sure you want to exit? +editor.resizemap = Resize Map +editor.mapname = Kartan nimi: +editor.overwrite = [accent]Warning!\nThis overwrites an existing map. +editor.overwrite.confirm = [scarlet]Warning![] A map with this name already exists. Are you sure you want to overwrite it? +editor.selectmap = Select a map to load: + +toolmode.replace = Replace +toolmode.replace.description = Draws only on solid blocks. +toolmode.replaceall = Replace All +toolmode.replaceall.description = Replace all blocks in map. +toolmode.orthogonal = Orthogonal +toolmode.orthogonal.description = Draws only orthogonal lines. +toolmode.square = Square +toolmode.square.description = Square brush. +toolmode.eraseores = Erase Ores +toolmode.eraseores.description = Erase only ores. +toolmode.fillteams = Fill Teams +toolmode.fillteams.description = Fill teams instead of blocks. +toolmode.drawteams = Draw Teams +toolmode.drawteams.description = Draw teams instead of blocks. + +filters.empty = [lightgray]No filters! Add one with the button below. +filter.distort = Distort +filter.noise = Noise +filter.median = Median +filter.oremedian = Ore Median +filter.blend = Blend +filter.defaultores = Default Ores +filter.ore = Ore +filter.rivernoise = River Noise +filter.mirror = Mirror +filter.clear = Clear +filter.option.ignore = Ignore +filter.scatter = Scatter +filter.terrain = Terrain +filter.option.scale = Scale +filter.option.chance = Chance +filter.option.mag = Magnitude +filter.option.threshold = Threshold +filter.option.circle-scale = Circle Scale +filter.option.octaves = Octaves +filter.option.falloff = Falloff +filter.option.angle = Angle +filter.option.block = Block +filter.option.floor = Lattia +filter.option.flooronto = Target Floor +filter.option.wall = Seinä +filter.option.ore = Malmi +filter.option.floor2 = Secondary Floor +filter.option.threshold2 = Secondary Threshold +filter.option.radius = Radius +filter.option.percentile = Percentile + +width = Leveys: +height = Korkeus: +menu = Valikko +play = Pelaa +campaign = Campaign +load = Lataa +save = Tallenna +fps = FPS: {0} +tps = TPS: {0} +ping = Ping: {0}ms +language.restart = Please restart your game for the language settings to take effect. +settings = Asetukset +tutorial = Perehdytys +tutorial.retake = Re-Take Tutorial +editor = Editor +mapeditor = Map Editor +donate = Lahjoita + +abandon = Hylkää +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Lukittu +complete = [lightgray]Reach: +zone.requirement = Wave {0} in zone {1} +resume = Resume Zone:\n[lightgray]{0} +bestwave = [lightgray]Best Wave: {0} +launch = < LAUNCH > +launch.title = Launch Successful +launch.next = [lightgray]next opportunity at wave {0} +launch.unable2 = [scarlet]Unable to LAUNCH.[] +launch.confirm = This will launch all resources in your core.\nYou will not be able to return to this base. +launch.skip.confirm = If you skip now, you will not be able to launch until later waves. +uncover = Uncover +configure = Configure Loadout +configure.locked = [lightgray]Unlock configuring loadout: Wave {0}. +zone.unlocked = [lightgray]{0} unlocked. +zone.requirement.complete = Wave {0} reached:\n{1} zone requirements met. +zone.config.complete = Wave {0} reached:\nLoadout config unlocked. +zone.resources = [lightgray]Resources Detected: +zone.objective = [lightgray]Objective: [accent]{0} +zone.objective.survival = Survive +zone.objective.attack = Destroy Enemy Core +add = Add... +boss.health = Boss Health + +connectfail = [crimson]Connection error:\n\n[accent]{0} +error.unreachable = Server unreachable.\nIs the address spelled correctly? +error.invalidaddress = Invalid address. +error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! +error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! +error.alreadyconnected = Already connected. +error.mapnotfound = Map file not found! +error.io = Network I/O error. +error.any = Unknown network error. +error.bloom = Failed to initialize bloom.\nYour device may not support it. + +zone.groundZero.name = Ground Zero +zone.desertWastes.name = Desert Wastes +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.stainedMountains.name = Stained Mountains +zone.desolateRift.name = Desolate Rift +zone.nuclearComplex.name = Nuclear Production Complex +zone.overgrowth.name = Overgrowth +zone.tarFields.name = Tar Fields +zone.saltFlats.name = Salt Flats +zone.impact0078.name = Impact 0078 +zone.crags.name = Crags +zone.fungalPass.name = Fungal Pass + +zone.groundZero.description = The optimal location to begin once more. Low enemy threat. Few resources.\nGather as much lead and copper as possible.\nMove on. +zone.frozenForest.description = Even here, closer to mountains, the spores have spread. The frigid temperatures cannot contain them forever.\n\nBegin the venture into power. Build combustion generators. Learn to use menders. +zone.desertWastes.description = These wastes are vast, unpredictable, and criss-crossed with derelict sector structures.\nCoal is present in the region. Burn it for power, or synthesize graphite.\n\n[lightgray]This landing location cannot be guaranteed. +zone.saltFlats.description = On the outskirts of the desert lie the Salt Flats. Few resources can be found in this location.\n\nThe enemy has erected a resource storage complex here. Eradicate their core. Leave nothing standing. +zone.craters.description = Water has accumulated in this crater, relic of the old wars. Reclaim the area. Collect sand. Smelt metaglass. Pump water to cool turrets and drills. +zone.ruinousShores.description = Past the wastes, is the shoreline. Once, this location housed a coastal defense array. Not much of it remains. Only the most basic defense structures have remained unscathed, everything else reduced to scrap.\nContinue the expansion outwards. Rediscover the technology. +zone.stainedMountains.description = Further inland lie the mountains, yet untainted by spores.\nExtract the abundant titanium in this area. Learn how to use it.\n\nThe enemy presence is greater here. Do not give them time to send their strongest units. +zone.overgrowth.description = This area is overgrown, closer to the source of the spores.\nThe enemy has established an outpost here. Build Titan units. Destroy it. Reclaim that which was lost. +zone.tarFields.description = The outskirts of an oil production zone, between the mountains and desert. One of the few areas with usable tar reserves.\nAlthough abandoned, this area has some dangerous enemy forces nearby. Do not underestimate them.\n\n[lightgray]Research oil processing technology if possible. +zone.desolateRift.description = An extremely dangerous zone. Plentiful resources, but little space. High risk of destruction. Leave as soon as possible. Do not be fooled by the long spacing between enemy attacks. +zone.nuclearComplex.description = A former facility for the production and processing of thorium, reduced to ruins.\n[lightgray]Research the thorium and its many uses.\n\nThe enemy is present here in great numbers, constantly scouting for attackers. +zone.fungalPass.description = A transition area between high mountains and lower, spore-ridden lands. A small enemy reconnaissance base is located here.\nDestroy it.\nUse Dagger and Crawler units. Take out the two cores. +zone.impact0078.description = +zone.crags.description = + +settings.language = Language +settings.reset = Reset to Defaults +settings.rebind = Rebind +settings.controls = Controls +settings.game = Game +settings.sound = Sound +settings.graphics = Graphics +settings.cleardata = Clear Game Data... +settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone! +settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit. +settings.clearunlocks = Clear Unlocks +settings.clearall = Clear All +paused = [accent]< Paused > +yes = Yes +no = No +info.title = Info +error.title = [crimson]An error has occured +error.crashtitle = An error has occured +attackpvponly = [scarlet]Only available in Attack/PvP modes +blocks.input = Input +blocks.output = Output +blocks.booster = Booster +block.unknown = [lightgray]??? +blocks.powercapacity = Power Capacity +blocks.powershot = Power/Shot +blocks.damage = Damage +blocks.targetsair = Targets Air +blocks.targetsground = Targets Ground +blocks.itemsmoved = Move Speed +blocks.launchtime = Time Between Launches +blocks.shootrange = Range +blocks.size = Size +blocks.liquidcapacity = Liquid Capacity +blocks.powerrange = Power Range +blocks.poweruse = Power Use +blocks.powerdamage = Power/Damage +blocks.itemcapacity = Item Capacity +blocks.basepowergeneration = Base Power Generation +blocks.productiontime = Production Time +blocks.repairtime = Block Full Repair Time +blocks.speedincrease = Speed Increase +blocks.range = Range +blocks.drilltier = Drillables +blocks.drillspeed = Base Drill Speed +blocks.boosteffect = Boost Effect +blocks.maxunits = Max Active Units +blocks.health = Health +blocks.buildtime = Build Time +blocks.inaccuracy = Inaccuracy +blocks.shots = Shots +blocks.reload = Shots/Second +blocks.ammo = Ammo + +bar.drilltierreq = Better Drill Required +bar.drillspeed = Drill Speed: {0}/s +bar.efficiency = Efficiency: {0}% +bar.powerbalance = Power: {0}/s +bar.poweramount = Power: {0} +bar.poweroutput = Power Output: {0} +bar.items = Items: {0} +bar.liquid = Liquid +bar.heat = Heat +bar.power = Power +bar.progress = Build Progress +bar.spawned = Units: {0}/{1} + +bullet.damage = [stat]{0}[lightgray] damage +bullet.splashdamage = [stat]{0}[lightgray] area dmg ~[stat] {1}[lightgray] tiles +bullet.incendiary = [stat]incendiary +bullet.homing = [stat]homing +bullet.shock = [stat]shock +bullet.frag = [stat]frag +bullet.knockback = [stat]{0}[lightgray] knockback +bullet.freezing = [stat]freezing +bullet.tarred = [stat]tarred +bullet.multiplier = [stat]{0}[lightgray]x ammo multiplier +bullet.reload = [stat]{0}[lightgray]x fire rate + +unit.blocks = blocks +unit.powersecond = power units/second +unit.liquidsecond = liquid units/second +unit.itemssecond = items/second +unit.liquidunits = liquid units +unit.powerunits = power units +unit.degrees = degrees +unit.seconds = seconds +unit.persecond = /sec +unit.timesspeed = x speed +unit.percent = % +unit.items = items +category.general = General +category.power = Power +category.liquids = Liquids +category.items = Items +category.crafting = Input/Output +category.shooting = Shooting +category.optional = Optional Enhancements +setting.landscape.name = Lock Landscape +setting.shadows.name = Shadows +setting.linear.name = Linear Filtering +setting.animatedwater.name = Animated Water +setting.animatedshields.name = Animated Shields +setting.antialias.name = Antialias[lightgray] (requires restart)[] +setting.indicators.name = Enemy/Ally Indicators +setting.autotarget.name = Auto-Target +setting.keyboard.name = Mouse+Keyboard Controls +setting.fpscap.name = Max FPS +setting.fpscap.none = None +setting.fpscap.text = {0} FPS +setting.uiscale.name = UI Scaling[lightgray] (require restart)[] +setting.swapdiagonal.name = Always Diagonal Placement +setting.difficulty.training = Training +setting.difficulty.easy = Easy +setting.difficulty.normal = Normal +setting.difficulty.hard = Hard +setting.difficulty.insane = Insane +setting.difficulty.name = Difficulty: +setting.screenshake.name = Screen Shake +setting.effects.name = Display Effects +setting.sensitivity.name = Controller Sensitivity +setting.saveinterval.name = Save Interval +setting.seconds = {0} Seconds +setting.fullscreen.name = Fullscreen +setting.borderlesswindow.name = Borderless Window[lightgray] (may require restart) +setting.fps.name = Show FPS +setting.vsync.name = VSync +setting.lasers.name = Show Power Lasers +setting.pixelate.name = Pixelate[lightgray] (disables animations) +setting.minimap.name = Show Minimap +setting.musicvol.name = Music Volume +setting.ambientvol.name = Ambient Volume +setting.mutemusic.name = Mute Music +setting.sfxvol.name = SFX Volume +setting.mutesound.name = Mute Sound +setting.crashreport.name = Send Anonymous Crash Reports +setting.chatopacity.name = Chat Opacity +setting.playerchat.name = Display In-Game Chat +uiscale.reset = UI scale has been changed.\nPress "OK" to confirm this scale.\n[scarlet]Reverting and exiting in[accent] {0}[] seconds... +uiscale.cancel = Cancel & Exit +setting.bloom.name = Bloom +keybind.title = Rebind Keys +keybinds.mobile = [scarlet]Most keybinds here are not functional on mobile. Only basic movement is supported. +category.general.name = General +category.view.name = View +category.multiplayer.name = Multiplayer +command.attack = Attack +command.retreat = Retreat +command.patrol = Patrol +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select +keybind.press = Press a key... +keybind.press.axis = Press an axis or key... +keybind.screenshot.name = Map Screenshot +keybind.move_x.name = Move x +keybind.move_y.name = Move y +keybind.select.name = Select/Shoot +keybind.diagonal_placement.name = Diagonal Placement +keybind.pick.name = Pick Block +keybind.break_block.name = Break Block +keybind.deselect.name = Deselect +keybind.shoot.name = Shoot +keybind.zoom_hold.name = Zoom Hold +keybind.zoom.name = Zoom +keybind.menu.name = Menu +keybind.pause.name = Pause +keybind.minimap.name = Minimap +keybind.dash.name = Dash +keybind.chat.name = Chat +keybind.player_list.name = Player list +keybind.console.name = Console +keybind.rotate.name = Rotate +keybind.toggle_menus.name = Toggle menus +keybind.chat_history_prev.name = Chat history prev +keybind.chat_history_next.name = Chat history next +keybind.chat_scroll.name = Chat scroll +keybind.drop_unit.name = Drop Unit +keybind.zoom_minimap.name = Zoom minimap +mode.help.title = Description of modes +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves.\n[gray]Requires enemy spawns in the map to play. +mode.sandbox.name = Sandbox +mode.sandbox.description = Infinite resources and no timer for waves. +mode.pvp.name = PvP +mode.pvp.description = Fight against other players locally.\n[gray]Requires at least 2 differently-colored cores in the map to play. +mode.attack.name = Attack +mode.attack.description = Destroy the enemy's base. No waves.\n[gray]Requires a red core in the map to play. +mode.custom = Custom Rules + +rules.infiniteresources = Infinite Resources +rules.wavetimer = Wave Timer +rules.waves = Waves +rules.attack = Attack Mode +rules.enemyCheat = Infinite AI (Red Team) Resources +rules.unitdrops = Unit Drops +rules.unitbuildspeedmultiplier = Unit Production Speed Multiplier +rules.unithealthmultiplier = Unit Health Multiplier +rules.playerhealthmultiplier = Player Health Multiplier +rules.playerdamagemultiplier = Player Damage Multiplier +rules.unitdamagemultiplier = Unit Damage Multiplier +rules.enemycorebuildradius = Enemy Core No-Build Radius:[lightgray] (tiles) +rules.respawntime = Respawn Time:[lightgray] (sec) +rules.wavespacing = Wave Spacing:[lightgray] (sec) +rules.buildcostmultiplier = Build Cost Multiplier +rules.buildspeedmultiplier = Build Speed Multiplier +rules.waitForWaveToEnd = Waves wait for enemies +rules.dropzoneradius = Drop Zone Radius:[lightgray] (tiles) +rules.respawns = Max respawns per wave +rules.limitedRespawns = Limit Respawns +rules.title.waves = Waves +rules.title.respawns = Respawns +rules.title.resourcesbuilding = Resources & Building +rules.title.player = Players +rules.title.enemy = Enemies +rules.title.unit = Units + +content.item.name = Items +content.liquid.name = Liquids +content.unit.name = Units +content.block.name = Blocks +content.mech.name = Mechs +item.copper.name = Copper +item.lead.name = Lead +item.coal.name = Coal +item.graphite.name = Graphite +item.titanium.name = Titanium +item.thorium.name = Thorium +item.silicon.name = Silicon +item.plastanium.name = Plastanium +item.phase-fabric.name = Phase Fabric +item.surge-alloy.name = Surge Alloy +item.spore-pod.name = Spore Pod +item.sand.name = Hiekka +item.blast-compound.name = Blast Compound +item.pyratite.name = Pyratite +item.metaglass.name = Metaglass +item.scrap.name = Scrap +liquid.water.name = Vesi +liquid.slag.name = Slag +liquid.oil.name = Oil +liquid.cryofluid.name = Cryofluid +mech.alpha-mech.name = Alpha +mech.alpha-mech.weapon = Heavy Repeater +mech.alpha-mech.ability = Regeneration +mech.delta-mech.name = Delta +mech.delta-mech.weapon = Arc Generator +mech.delta-mech.ability = Discharge +mech.tau-mech.name = Tau +mech.tau-mech.weapon = Restruct Laser +mech.tau-mech.ability = Repair Burst +mech.omega-mech.name = Omega +mech.omega-mech.weapon = Swarm Missiles +mech.omega-mech.ability = Armored Configuration +mech.dart-ship.name = Dart +mech.dart-ship.weapon = Repeater +mech.javelin-ship.name = Javelin +mech.javelin-ship.weapon = Burst Missiles +mech.javelin-ship.ability = Discharge Booster +mech.trident-ship.name = Trident +mech.trident-ship.weapon = Bomb Bay +mech.glaive-ship.name = Glaive +mech.glaive-ship.weapon = Flame Repeater +item.explosiveness = [lightgray]Explosiveness: {0}% +item.flammability = [lightgray]Flammability: {0}% +item.radioactivity = [lightgray]Radioactivity: {0}% +unit.health = [lightgray]Health: {0} +unit.speed = [lightgray]Speed: {0} +mech.weapon = [lightgray]Weapon: {0} +mech.health = [lightgray]Health: {0} +mech.itemcapacity = [lightgray]Item Capacity: {0} +mech.minespeed = [lightgray]Mining Speed: {0}% +mech.minepower = [lightgray]Mining Power: {0} +mech.ability = [lightgray]Ability: {0} +mech.buildspeed = [lightgray]Building Speed: {0}% +liquid.heatcapacity = [lightgray]Heat Capacity: {0} +liquid.viscosity = [lightgray]Viscosity: {0} +liquid.temperature = [lightgray]Temperature: {0} + +block.sand-boulder.name = Sand Boulder +block.grass.name = Grass +block.salt.name = Salt +block.saltrocks.name = Salt Rocks +block.pebbles.name = Pebbles +block.tendrils.name = Tendrils +block.sandrocks.name = Sand Rocks +block.spore-pine.name = Spore Pine +block.sporerocks.name = Spore Rocks +block.rock.name = Rock +block.snowrock.name = Snow Rock +block.snow-pine.name = Snow Pine +block.shale.name = Shale +block.shale-boulder.name = Shale Boulder +block.moss.name = Moss +block.shrubs.name = Shrubs +block.spore-moss.name = Spore Moss +block.shalerocks.name = Shale Rocks +block.scrap-wall.name = Scrap Wall +block.scrap-wall-large.name = Large Scrap Wall +block.scrap-wall-huge.name = Huge Scrap Wall +block.scrap-wall-gigantic.name = Gigantic Scrap Wall +block.thruster.name = Thruster +block.kiln.name = Kiln +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press +block.constructing = {0} [lightgray](Constructing) +block.spawn.name = Enemy Spawn +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus +block.deepwater.name = Deep Water +block.water.name = Water +block.tainted-water.name = Tainted Water +block.darksand-tainted-water.name = Dark Sand Tainted Water +block.tar.name = Tar +block.stone.name = Stone +block.sand.name = Sand +block.darksand.name = Dark Sand +block.ice.name = Ice +block.snow.name = Snow +block.craters.name = Craters +block.sand-water.name = Sand water +block.darksand-water.name = Dark Sand Water +block.char.name = Char +block.holostone.name = Holo stone +block.ice-snow.name = Ice Snow +block.rocks.name = Rocks +block.icerocks.name = Ice rocks +block.snowrocks.name = Snow Rocks +block.dunerocks.name = Dune Rocks +block.pine.name = Pine +block.white-tree-dead.name = White Tree Dead +block.white-tree.name = White Tree +block.spore-cluster.name = Spore Cluster +block.metal-floor.name = Metal Floor 1 +block.metal-floor-2.name = Metal Floor 2 +block.metal-floor-3.name = Metal Floor 3 +block.metal-floor-5.name = Metal Floor 4 +block.metal-floor-damaged.name = Metal Floor Damaged +block.dark-panel-1.name = Dark Panel 1 +block.dark-panel-2.name = Dark Panel 2 +block.dark-panel-3.name = Dark Panel 3 +block.dark-panel-4.name = Dark Panel 4 +block.dark-panel-5.name = Dark Panel 5 +block.dark-panel-6.name = Dark Panel 6 +block.dark-metal.name = Dark Metal +block.ignarock.name = Igna Rock +block.hotrock.name = Hot Rock +block.magmarock.name = Magma Rock +block.cliffs.name = Cliffs +block.copper-wall.name = Copper Wall +block.copper-wall-large.name = Large Copper Wall +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall +block.phase-wall.name = Phase Wall +block.phase-wall-large.name = Large Phase Wall +block.thorium-wall.name = Thorium Wall +block.thorium-wall-large.name = Large Thorium Wall +block.door.name = Door +block.door-large.name = Large Door +block.duo.name = Duo +block.scorch.name = Scorch +block.scatter.name = Scatter +block.hail.name = Hail +block.lancer.name = Lancer +block.conveyor.name = Conveyor +block.titanium-conveyor.name = Titanium Conveyor +block.junction.name = Junction +block.router.name = Router +block.distributor.name = Distributor +block.sorter.name = Sorter +block.overflow-gate.name = Overflow Gate +block.silicon-smelter.name = Silicon Smelter +block.phase-weaver.name = Phase Weaver +block.pulverizer.name = Pulverizer +block.cryofluidmixer.name = Cryofluid Mixer +block.melter.name = Melter +block.incinerator.name = Incinerator +block.spore-press.name = Spore Press +block.separator.name = Separator +block.coal-centrifuge.name = Coal Centrifuge +block.power-node.name = Power Node +block.power-node-large.name = Large Power Node +block.surge-tower.name = Surge Tower +block.battery.name = Battery +block.battery-large.name = Large Battery +block.combustion-generator.name = Combustion Generator +block.turbine-generator.name = Steam Generator +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor +block.mechanical-drill.name = Mechanical Drill +block.pneumatic-drill.name = Pneumatic Drill +block.laser-drill.name = Laser Drill +block.water-extractor.name = Water Extractor +block.cultivator.name = Cultivator +block.dart-mech-pad.name = Alpha Mech Pad +block.delta-mech-pad.name = Delta Mech Pad +block.javelin-ship-pad.name = Javelin Ship Pad +block.trident-ship-pad.name = Trident Ship Pad +block.glaive-ship-pad.name = Glaive Ship Pad +block.omega-mech-pad.name = Omega Mech Pad +block.tau-mech-pad.name = Tau Mech Pad +block.conduit.name = Conduit +block.mechanical-pump.name = Mechanical Pump +block.item-source.name = Item Source +block.item-void.name = Item Void +block.liquid-source.name = Liquid Source +block.power-void.name = Power Void +block.power-source.name = Power Infinite +block.unloader.name = Unloader +block.vault.name = Vault +block.wave.name = Wave +block.swarmer.name = Swarmer +block.salvo.name = Salvo +block.ripple.name = Ripple +block.phase-conveyor.name = Phase Conveyor +block.bridge-conveyor.name = Bridge Conveyor +block.plastanium-compressor.name = Plastanium Compressor +block.pyratite-mixer.name = Pyratite Mixer +block.blast-mixer.name = Blast Mixer +block.solar-panel.name = Solar Panel +block.solar-panel-large.name = Large Solar Panel +block.oil-extractor.name = Oil Extractor +block.draug-factory.name = Draug Miner Drone Factory +block.spirit-factory.name = Spirit Repair Drone Factory +block.phantom-factory.name = Phantom Builder Drone Factory +block.wraith-factory.name = Wraith Fighter Factory +block.ghoul-factory.name = Ghoul Bomber Factory +block.dagger-factory.name = Dagger Mech Factory +block.crawler-factory.name = Crawler Mech Factory +block.titan-factory.name = Titan Mech Factory +block.fortress-factory.name = Fortress Mech Factory +block.revenant-factory.name = Revenant Fighter Factory +block.repair-point.name = Repair Point +block.pulse-conduit.name = Pulse Conduit +block.phase-conduit.name = Phase Conduit +block.liquid-router.name = Liquid Router +block.liquid-tank.name = Liquid Tank +block.liquid-junction.name = Liquid Junction +block.bridge-conduit.name = Bridge Conduit +block.rotary-pump.name = Rotary Pump +block.thorium-reactor.name = Thorium Reactor +block.mass-driver.name = Massalinko +block.blast-drill.name = Airblast Drill +block.thermal-pump.name = Thermal Pump +block.thermal-generator.name = Thermal Generator +block.alloy-smelter.name = Alloy Smelter +block.mender.name = Mender +block.mend-projector.name = Mend Projector +block.surge-wall.name = Surge Wall +block.surge-wall-large.name = Large Surge Wall +block.cyclone.name = Cyclone +block.fuse.name = Fuse +block.shock-mine.name = Shock Mine +block.overdrive-projector.name = Overdrive Projector +block.force-projector.name = Force Projector +block.arc.name = Arc +block.rtg-generator.name = RTG Generator +block.spectre.name = Spectre +block.meltdown.name = Meltdown +block.container.name = Container +block.launch-pad.name = Launch Pad +block.launch-pad-large.name = Large Launch Pad +team.blue.name = blue +team.crux.name = red +team.sharded.name = orange +team.orange.name = orange +team.derelict.name = derelict +team.green.name = green +team.purple.name = purple +unit.spirit.name = Spirit Repair Drone +unit.draug.name = Draug Miner Drone +unit.phantom.name = Phantom Builder Drone +unit.dagger.name = Dagger +unit.crawler.name = Crawler +unit.titan.name = Titan +unit.ghoul.name = Ghoul Bomber +unit.wraith.name = Wraith Fighter +unit.fortress.name = Fortress +unit.revenant.name = Revenant +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper +tutorial.next = [lightgray] +tutorial.intro = You have entered the[scarlet] Mindustry Tutorial.[]\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this.\n\n[accent]{0}/{1} copper +tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nClick the drill tab in the bottom right.\nSelect the[accent] mechanical drill[]. Place it on a copper vein by clicking.\n[accent]Right-click[] to stop building. +tutorial.drill.mobile = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nTap the drill tab in the bottom right.\nSelect the[accent] mechanical drill[].\nPlace it on a copper vein by tapping, then press the[accent] checkmark[] below to confirm your selection.\nPress the[accent] X button[] to cancel placement. +tutorial.blockinfo = Each block has different stats. Each drill can only mine certain ores.\nTo check a block's info and stats,[accent] tap the "?" button while selecting it in the build menu.[]\n\n[accent]Access the Mechanical Drill's stats now.[] +tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.\n[accent]Hold down the mouse to place in a line.[]\nHold[accent] CTRL[] while selecting a line to place diagonally.\n\n[accent]{0}/{1} conveyors placed in line\n[accent]0/1 items delivered +tutorial.conveyor.mobile = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.\n[accent] Place in a line by holding down your finger for a few seconds[] and dragging in a direction.\n\n[accent]{0}/{1} conveyors placed in line\n[accent]0/1 items delivered +tutorial.turret = Once an item enters your core, it can be used for building.\nKeep in mind that not all items can be used for building.\nItems that are not used for building, such as[accent] coal[] or[accent] scrap[], cannot be put into the core.\nDefensive structures must be built to repel the[lightgray] enemy[].\nBuild a[accent] duo turret[] near your base. +tutorial.drillturret = Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill near the turret.\nLead conveyors into the turret to supply it with copper.\n\n[accent]Ammo delivered: 0/1 +tutorial.pause = During battle, you are able to[accent] pause the game.[]\nYou may queue buildings while paused.\n\n[accent]Press space to pause. +tutorial.pause.mobile = During battle, you are able to[accent] pause the game.[]\nYou may queue buildings while paused.\n\n[accent]Press this button in the top left to pause. +tutorial.unpause = Now press space again to unpause. +tutorial.unpause.mobile = Now press it again to unpause. +tutorial.breaking = Blocks frequently need to be destroyed.\n[accent]Hold down right-click[] to destroy all blocks in a selection.[]\n\n[accent]Destroy all the scrap blocks to the left of your core using area selection. +tutorial.breaking.mobile = Blocks frequently need to be destroyed.\n[accent]Select deconstruction mode[], then tap a block to begin breaking it.\nDestroy an area by holding down your finger for a few seconds[] and dragging in a direction.\nPress the checkmark button to confirm breaking.\n\n[accent]Destroy all the scrap blocks to the left of your core using area selection. +tutorial.withdraw = In some situations, taking items directly from blocks is necessary.\nTo do this, [accent]tap a block[] with items in it, then [accent]tap the item[] in the inventory.\nMultiple items can be withdrawn by [accent]tapping and holding[].\n\n[accent]Withdraw some copper from the core.[] +tutorial.deposit = Deposit items into blocks by dragging from your ship to the destination block.\n\n[accent]Deposit your copper back into the core.[] +tutorial.waves = The[lightgray] enemy[] approaches.\n\nDefend the core for 2 waves.[accent] Click[] to shoot.\nBuild more turrets and drills. Mine more copper. +tutorial.waves.mobile = The[lightgray] enemy[] approaches.\n\nDefend the core for 2 waves. Your ship will automatically fire at enemies.\nBuild more turrets and drills. Mine more copper. +tutorial.launch = Once you reach a specific wave, you are able to[accent] launch the core[], leaving your defenses behind and[accent] obtaining all the resources in your core.[]\nThese resources can then be used to research new technology.\n\n[accent]Press the launch button. + + +item.copper.description = The most basic structural material. Used extensively in all types of blocks. +item.lead.description = A basic starter material. Used extensively in electronics and liquid transportation blocks. +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.graphite.description = Mineralized carbon, used for ammunition and electrical insulation. +item.sand.description = A common material that is used extensively in smelting, both in alloying and as a flux. +item.coal.description = Fossilized plant matter, formed long before the seeding event. Used extensively for fuel and resource production. +item.titanium.description = A rare super-light metal used extensively in liquid transportation, drills and aircraft. +item.thorium.description = A dense, radioactive metal used as structural support and nuclear fuel. +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. +item.silicon.description = An extremely useful semiconductor. Applications in solar panels, complex electronics and homing turret ammunition. +item.plastanium.description = A light, ductile material used in advanced aircraft and fragmentation ammunition. +item.phase-fabric.description = A near-weightless substance used in advanced electronics and self-repairing technology. +item.surge-alloy.description = An advanced alloy with unique electrical properties. +item.spore-pod.description = A pod of synthetic spores, synthesized from atmospheric concentrations for industrial purposes. Used for conversion into oil, explosives and fuel. +item.blast-compound.description = An unstable compound used in bombs and explosives. Synthesized from spore pods and other volatile substances. Use as fuel is not advised. +item.pyratite.description = An extremely flammable substance used in incendiary weapons. +liquid.water.description = The most useful liquid. Commonly used for cooling machines and waste processing. +liquid.slag.description = Various different types of molten metal mixed together. Can be separated into its constituent minerals, or sprayed at enemy units as a weapon. +liquid.oil.description = A liquid used in advanced material production. Can be converted into coal as fuel, or sprayed and set on fire as a weapon. +liquid.cryofluid.description = An inert, non-corrosive liquid created from water and titanium. Has extremely high heat capacity. Extensively used as coolant. +mech.alpha-mech.description = The standard control mech. Based on a Dagger unit, with upgraded armor and building capabilities. Has more damage output than a Dart ship. +mech.delta-mech.description = A fast, lightly-armored mech made for hit-and-run attacks. Does little damage against structures, but can kill large groups of enemy units very quickly with its arc lightning weapons. +mech.tau-mech.description = The support mech. Heals allied blocks by shooting at them. Can heal allies in a radius with its repair ability. +mech.omega-mech.description = A bulky and well-armored mech, made for front-line assaults. Its armor can block up to 90% of incoming damage. +mech.dart-ship.description = The standard control ship. Reasonably fast and light, but has little offensive capability and low mining speed. +mech.javelin-ship.description = A hit-and-run strike ship. While initially slow, it can accelerate to great speeds and fly by enemy outposts, dealing large amounts of damage with its lightning and missiles. +mech.trident-ship.description = A heavy bomber, built for construction and destroying enemy fortifications. Reasonably well armored. +mech.glaive-ship.description = A large, well-armored gunship. Equipped with an incendiary repeater. Highly maneuverable. +unit.draug.description = A primitive mining drone. Cheap to produce. Expendable. Automatically mines copper and lead in the vicinity. Delivers mined resources to the closest core. +unit.spirit.description = A modified draug drone, designed for repair instead of mining. Automatically fixes any damaged blocks in the area. +unit.phantom.description = An advanced drone unit. Follows users. Assists in block construction. +unit.dagger.description = The most basic ground mech. Cheap to produce. Overwhelming when used in swarms. +unit.crawler.description = A ground unit consisting of a stripped-down frame with high explosives strapped on top. Not particular durable. Explodes on contact with enemies. +unit.titan.description = An advanced, armored ground unit. Attacks both ground and air targets. Equipped with two miniature Scorch-class flamethrowers. +unit.fortress.description = A heavy artillery mech. Equipped with two modified Hail-type cannons for long-range assault on enemy structures and units. +unit.eruptor.description = A heavy mech designed to take down structures. Fires a stream of slag at enemy fortifications, melting them and setting volatiles on fire. +unit.wraith.description = A fast, hit-and-run interceptor unit. Targets power generators. +unit.ghoul.description = A heavy carpet bomber. Rips through enemy structures, targeting critical infrastructure. +unit.revenant.description = A heavy, hovering missile array. +block.graphite-press.description = Compresses chunks of coal into pure sheets of graphite. +block.multi-press.description = An upgraded version of the graphite press. Employs water and power to process coal quickly and efficiently. +block.silicon-smelter.description = Reduces sand with pure coal. Produces silicon. +block.kiln.description = Smelts sand and lead into the compound known as metaglass. Requires small amounts of power to run. +block.plastanium-compressor.description = Produces plastanium from oil and titanium. +block.phase-weaver.description = Synthesizes phase fabric from radioactive thorium and sand. Requires massive amounts of power to function. +block.alloy-smelter.description = Combines titanium, lead, silicon and copper to produce surge alloy. +block.cryofluidmixer.description = Mixes water and fine titanium powder into cryofluid. Essential for thorium reactor usage. +block.blast-mixer.description = Crushes and mixes clusters of spores with pyratite to produce blast compound. +block.pyratite-mixer.description = Mixes coal, lead and sand into highly flammable pyratite. +block.melter.description = Melts down scrap into slag for further processing or usage in wave turrets. +block.separator.description = Separates slag into its mineral components. Outputs the cooled result. +block.spore-press.description = Compresses spore pods under extreme pressure to synthesize oil. +block.pulverizer.description = Crushes scrap into fine sand. +block.coal-centrifuge.description = Solidifes oil into chunks of coal. +block.incinerator.description = Vaporizes any excess item or liquid it receives. +block.power-void.description = Voids all power inputted into it. Sandbox only. +block.power-source.description = Infinitely outputs power. Sandbox only. +block.item-source.description = Infinitely outputs items. Sandbox only. +block.item-void.description = Destroys any items. Sandbox only. +block.liquid-source.description = Infinitely outputs liquids. Sandbox only. +block.copper-wall.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves. +block.copper-wall-large.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.\nSpans multiple tiles. +block.titanium-wall.description = A moderately strong defensive block.\nProvides moderate protection from enemies. +block.titanium-wall-large.description = A moderately strong defensive block.\nProvides moderate protection from enemies.\nSpans multiple tiles. +block.thorium-wall.description = A strong defensive block.\nDecent protection from enemies. +block.thorium-wall-large.description = A strong defensive block.\nDecent protection from enemies.\nSpans multiple tiles. +block.phase-wall.description = A wall coated with special phase-based reflective compound. Deflects most bullets upon impact. +block.phase-wall-large.description = A wall coated with special phase-based reflective compound. Deflects most bullets upon impact.\nSpans multiple tiles. +block.surge-wall.description = An extremely durable defensive block.\nBuilds up charge on bullet contact, releasing it randomly. +block.surge-wall-large.description = An extremely durable defensive block.\nBuilds up charge on bullet contact, releasing it randomly.\nSpans multiple tiles. +block.door.description = A small door. Can be opened or closed by tapping. +block.door-large.description = A large door. Can be opened and closed by tapping.\nSpans multiple tiles. +block.mender.description = Periodically repairs blocks in its vicinity. Keeps defenses repaired in-between waves.\nOptionally uses silicon to boost range and efficiency. +block.mend-projector.description = An upgraded version of the Mender. Repairs blocks in its vicinity.\nOptionally uses phase fabric to boost range and efficiency. +block.overdrive-projector.description = Increases the speed of nearby buildings.\nOptionally uses phase fabric to boost range and efficiency. +block.force-projector.description = Creates a hexagonal force field around itself, protecting buildings and units inside from damage.\nOverheats if too much damage is sustained. Optionally uses coolant to prevent overheating. Phase fabric can be used to increase shield size. +block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy. +block.conveyor.description = Basic item transport block. Moves items forward and automatically deposits them into blocks. Rotatable. +block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors. +block.junction.description = Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations. +block.bridge-conveyor.description = Advanced item transport block. Allows transporting items over up to 3 tiles of any terrain or building. +block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles. +block.sorter.description = Sorts items. If an item matches the selection, it is allowed to pass. Otherwise, the item is outputted to the left and right. +block.router.description = Accepts items, then outputs them to up to 3 other directions equally. Useful for splitting the materials from one source to multiple targets.\n\n[scarlet]Never use next to production inputs, as they will get clogged by output.[] +block.distributor.description = An advanced router. Splits items to up to 7 other directions equally. +block.overflow-gate.description = A combination splitter and router. Only outputs to the left and right if the front path is blocked. +block.mass-driver.description = The ultimate item transport block. Collects several items and then shoots them to another mass driver over a long range. Requires power to operate. +block.mechanical-pump.description = A cheap pump with slow output, but no power consumption. +block.rotary-pump.description = An advanced pump. Pumps more liquid, but requires power. +block.thermal-pump.description = The ultimate pump. +block.conduit.description = Basic liquid transport block. Moves liquids forward. Used in conjunction with pumps and other conduits. +block.pulse-conduit.description = An advanced liquid transport block. Transports liquids faster and stores more than standard conduits. +block.liquid-router.description = Accepts liquids from one direction and outputs them to up to 3 other directions equally. Can also store a certain amount of liquid. Useful for splitting the liquids from one source to multiple targets. +block.liquid-tank.description = Stores a large amount of liquids. Use for creating buffers in situations with non-constant demand of materials or as a safeguard for cooling vital blocks. +block.liquid-junction.description = Acts as a bridge for two crossing conduits. Useful in situations with two different conduits carrying different liquids to different locations. +block.bridge-conduit.description = Advanced liquid transport block. Allows transporting liquids over up to 3 tiles of any terrain or building. +block.phase-conduit.description = Advanced liquid transport block. Uses power to teleport liquids to a connected phase conduit over several tiles. +block.power-node.description = Transmits power to connected nodes. The node will receive power from or supply power to any adjacent blocks. +block.power-node-large.description = An advanced power node with greater range and more connections. +block.surge-tower.description = An extremely long-range power node with fewer available connections. +block.battery.description = Stores power as a buffer in times of surplus energy. Outputs power in times of deficit. +block.battery-large.description = Stores much more power than a regular battery. +block.combustion-generator.description = Generates power by burning flammable materials, such as coal. +block.thermal-generator.description = Generates power when placed in hot locations. +block.turbine-generator.description = An advanced combustion generator. More efficient, but requires additional water for generating steam. +block.differential-generator.description = Generates large amounts of energy. Utilizes the temperature difference between cryofluid and burning pyratite. +block.rtg-generator.description = A simple, reliable generator. Uses the heat of decaying radioactive compounds to produce energy at a slow rate. +block.solar-panel.description = Provides a small amount of power from the sun. +block.solar-panel-large.description = A significantly more efficient version of the standard solar panel. +block.thorium-reactor.description = Generates significant amounts of power from thorium. Requires constant cooling. Will explode violently if insufficient amounts of coolant are supplied. Power output depends on fullness, with base power generated at full capacity. +block.impact-reactor.description = An advanced generator, capable of creating massive amounts of power at peak efficiency. Requires a significant power input to kickstart the process. +block.mechanical-drill.description = A cheap drill. When placed on appropriate tiles, outputs items at a slow pace indefinitely. Only capable of mining basic resources. +block.pneumatic-drill.description = An improved drill, capable of mining titanium. Mines at a faster pace than a mechanical drill. +block.laser-drill.description = Allows drilling even faster through laser technology, but requires power. Capable of mining thorium. +block.blast-drill.description = The ultimate drill. Requires large amounts of power. +block.water-extractor.description = Extracts groundwater. Used in locations with no surface water available. +block.cultivator.description = Cultivates tiny concentrations of spores in the atmosphere into industry-ready pods. +block.oil-extractor.description = Uses large amounts of power, sand and water to drill for oil. +block.core-shard.description = The first iteration of the core capsule. Once destroyed, all contact to the region is lost. Do not let this happen. +block.core-foundation.description = The second version of the core. Better armored. Stores more resources. +block.core-nucleus.description = The third and final iteration of the core capsule. Extremely well armored. Stores massive amounts of resources. +block.vault.description = Stores a large amount of items of each type. An unloader block can be used to retrieve items from the vault. +block.container.description = Stores a small amount of items of each type. An unloader block can be used to retrieve items from the container. +block.unloader.description = Unloads items from a container, vault or core onto a conveyor or directly into an adjacent block. The type of item to be unloaded can be changed by tapping. +block.launch-pad.description = Launches batches of items without any need for a core launch. +block.launch-pad-large.description = An improved version of the launch pad. Stores more items. Launches more frequently. +block.duo.description = A small, cheap turret. Useful against ground units. +block.scatter.description = An essential anti-air turret. Sprays clumps of lead or scrap flak at enemy units. +block.scorch.description = Burns any ground enemies close to it. Highly effective at close range. +block.hail.description = A small, long-range artillery turret. +block.wave.description = A medium-sized turret. Shoots streams of liquid at enemies. Automatically extinguishes fires when supplied with water. +block.lancer.description = A medium-sized anti-ground laser turret. Charges and fires powerful beams of energy. +block.arc.description = A small close-range electric turret. Fires arcs of electricity at enemies. +block.swarmer.description = A medium-sized missile turret. Attacks both air and ground enemies. Fires homing missiles. +block.salvo.description = A larger, more advanced version of the Duo turret. Fires quick salvos of bullets at the enemy. +block.fuse.description = A large, close-range energy turret. Fires three piercing beams at nearby enemies. +block.ripple.description = An extremely powerful artillery turret. Shoots clusters of shells at enemies over long distances. +block.cyclone.description = A large anti-air and anti-ground turret. Fires explosive clumps of flak at nearby units. +block.spectre.description = A massive dual-barreled cannon. Shoots large armor-piercing bullets at air and ground targets. +block.meltdown.description = A massive laser cannon. Charges and fires a persistent laser beam at nearby enemies. Requires coolant to operate. +block.draug-factory.description = Produces Draug mining drones. +block.spirit-factory.description = Produces Spirit structural repair drones. +block.phantom-factory.description = Produces advanced construction drones. +block.wraith-factory.description = Produces fast, hit-and-run interceptor units. +block.ghoul-factory.description = Produces heavy carpet bombers. +block.revenant-factory.description = Produces heavy missile-based units. +block.dagger-factory.description = Produces basic ground units. +block.crawler-factory.description = Produces fast self-destructing swarm units. +block.titan-factory.description = Produces advanced, armored ground units. +block.fortress-factory.description = Produces heavy artillery ground units. +block.repair-point.description = Continuously heals the closest damaged unit in its vicinity. +block.dart-mech-pad.description = Provides transformation into a basic attack mech.\nUse by tapping while standing on it. +block.delta-mech-pad.description = Provides transformation into a lightly armored hit-and-run attack mech.\nUse by tapping while standing on it. +block.tau-mech-pad.description = Provides transformation into an advanced support mech.\nUse by tapping while standing on it. +block.omega-mech-pad.description = Provides transformation into a heavily-armored missile mech.\nUse by tapping while standing on it. +block.javelin-ship-pad.description = Provides transformation into a quick, lightly-armored interceptor.\nUse by tapping while standing on it. +block.trident-ship-pad.description = Provides transformation into a heavy support bomber.\nUse by tapping while standing on it. +block.glaive-ship-pad.description = Provides transformation into a large, well-armored gunship.\nUse by tapping while standing on it. \ No newline at end of file diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index 68f8ca7b64..f4464dd977 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -10,6 +10,7 @@ link.dev-builds.description = Versions instables du jeu link.trello.description = Trello officiel pour les ajouts futurs link.itch.io.description = Page itch.io avec lien de téléchargement pour PC link.google-play.description = Google Play Store +link.f-droid.description = Catalogue F-Droid link.wiki.description = Le wiki officiel de Mindustry linkfail = Erreur lors de l'ouverture du lien !\nL'URL a été copiée dans votre presse papier. screenshot = Capture d'écran sauvegardée à {0} @@ -18,12 +19,14 @@ gameover = Game over gameover.pvp = L'équipe [accent] {0}[] a gagné ! highscore = [accent]Nouveau meilleur score! copied = Copié. + load.sound = Sons load.map = Cartes load.image = Images load.content = Contenu load.system = Système load.mod = Mods + schematic = Schéma schematic.add = Sauvegarder le schéma... schematics = Schémas @@ -40,6 +43,7 @@ schematic.saved = Schéma sauvegardé. schematic.delete.confirm = Ce schéma sera complètement éradiqué. schematic.rename = Renommer le schéma schematic.info = {0}x{1}, {2} blocs + stat.wave = Vagues vaincues:[accent] {0} stat.enemiesDestroyed = Ennemis détruits:[accent] {0} stat.built = Bâtiments construits:[accent] {0} @@ -47,6 +51,7 @@ stat.destroyed = Bâtiments détruits:[accent] {0} stat.deconstructed = Bâtiments déconstruits:[accent] {0} stat.delivered = Ressources transférées: stat.rank = Rang Final: [accent]{0} + launcheditems = [accent]Ressources transférées launchinfo = [unlaunched][[LANCER] votre noyau pour obtenir les objets indiqués en bleu. map.delete = Êtes-vous certain(e) de vouloir supprimer la carte "[accent]{0}[]"? @@ -74,6 +79,7 @@ maps.browse = Parcourir les cartes continue = Continuer maps.none = [lightgray]Aucune carte trouvée! invalid = Invalide +pickcolor = Choisir la Couleur preparingconfig = Préparation de la configuration preparingcontent = Préparation du contenu uploadingcontent = Publication du contenu @@ -81,6 +87,7 @@ uploadingpreviewfile = Publication du fichier d'aperçu committingchanges = Validation des modifications done = Fait feature.unsupported = Votre appareil ne supporte pas cette fonctionnalité. + mods.alphainfo = Gardez à l'esprit que les mods sont en alpha et[scarlet] peuvent être très buggés[].\nMerci de signaler les problèmes que vous rencontrez via le GitHub ou le Discord Mindustry. mods.alpha = [accent](Alpha) mods = Mods @@ -104,6 +111,7 @@ mod.author = [LIGHT_GRAY]Auteur:[] {0} mod.missing = Cette sauvegarde contient des mods que vous avez récemment mis à jour ou que vous avez désinstallés. Votre sauvegarde risque d'être corrompue. Êtes-vous sûr de vouloir l'importer?\n[lightgray]Mods:\n{0} mod.preview.missing = Avant de publier ce mod dans le workshop, vous devez ajouter une image servant d'aperçu.\nPlacez une image nommée[accent] preview.png[] dans le dossier du mod et réessayez. mod.folder.missing = Seuls les mods sous forme de dossiers peuvent être publiés sur l'atelier.\nPour convertir n'importe quel mod en un dossier, dézippez-le tout simplement dans un dossier et supprimez l'ancien zip, puis redémarrez votre jeu ou rechargez vos mods. + about.button = À propos name = Nom: noname = Commencer par choisir un[accent] nom de joueur[]. @@ -271,6 +279,7 @@ publishing = [accent]Publication... publish.confirm = Êtes-vous sûr de vouloir publier ceci ?\n\n[lightgray]Assurez-vous d'être d'abord d'accord avec les CGU du workshop, sinon vos éléments n'apparaîtront pas ! publish.error = Erreur de publication de l'élément: {0} steam.error = Failed to initialize Steam services.\nError: {0} + editor.brush = Pinceau editor.openin = Ouvrir dans l'éditeur editor.oregen = Génération de minerais @@ -347,6 +356,7 @@ editor.overwrite = [accent]Attention!\nCeci écrase une carte existante. editor.overwrite.confirm = [scarlet]Attention![] Une carte avec ce nom existe déjà. Êtes-vous sûr de vouloir l'écraser? editor.exists = Une carte avec ce nom existe déjà. editor.selectmap = Sélectionnez une carte: + toolmode.replace = Remplacer toolmode.replace.description = Dessiner seulement sur les blocs solides. toolmode.replaceall = Tout remplacer @@ -361,6 +371,7 @@ toolmode.fillteams = Remplir les équipes toolmode.fillteams.description = Rempli les équipes au lieu des blocs. toolmode.drawteams = Dessiner les équipes toolmode.drawteams.description = Dessine les équipes au lieu de blocs. + filters.empty = [lightgray]Aucun filtre! Ajoutez-en un avec les boutons ci-dessous. filter.distort = Déformation filter.noise = Bruit @@ -392,6 +403,7 @@ filter.option.floor2 = Sol secondaire filter.option.threshold2 = Seuil secondaire filter.option.radius = Rayon filter.option.percentile = Centile + width = Largeur: height = Hauteur: menu = Menu @@ -407,6 +419,7 @@ tutorial = Tutoriel tutorial.retake = Refaire le Tutoriel editor = Éditeur mapeditor = Éditeur de carte + abandon = Abandonner abandon.text = Cette zone et toutes ses ressources vont être perdues. locked = Verrouillé @@ -437,6 +450,7 @@ zone.objective.survival = Survivre zone.objective.attack = Détruire le noyau ennemi add = Ajouter... boss.health = Santé du Boss + connectfail = [crimson]Échec de la connexion au serveur :\n\n[accent]{0} error.unreachable = Serveur injoignable.\nL'adresse IP est correcte? error.invalidaddress = Adresse invalide. @@ -447,6 +461,7 @@ error.mapnotfound = Carte introuvable! error.io = Erreur de Réseau (I/O) error.any = Erreur réseau inconnue error.bloom = Échec de l'initialisation du flou lumineux.\nVotre appareil peux ne pas le supporter. + zone.groundZero.name = Première Bataille zone.desertWastes.name = Désert Sauvage zone.craters.name = Les Cratères @@ -461,6 +476,7 @@ zone.saltFlats.name = Marais Salants zone.impact0078.name = Impact 0078 zone.crags.name = Rochers zone.fungalPass.name = Passe Fongique + zone.groundZero.description = L'emplacement optimal pour débuter. Faible menace ennemie. Peu de ressources. \nRecueillez autant de plomb et de cuivre que possible.\nRien d'autre à signaler. zone.frozenForest.description = Même ici, plus près des montagnes, les spores se sont propagées. Les températures glaciales ne pourront pas les contenir pour toujours.\n\nFamiliarisez vous avec l'Énergie. Construisez des générateurs a combustion. Apprenez a utiliser les réparateurs. zone.desertWastes.description = Cette étendue désertique est immense, imprévisible. On y croise des structures abandonnées.\nLe charbon est présent dans la région. Brûlez-le pour générer de l'Énergie ou synthétisez-le en graphite.\n\n[lightgray]Ce lieu d'atterisage est imprévisible. @@ -475,6 +491,7 @@ zone.nuclearComplex.description = Une ancienne installation de production et tra zone.fungalPass.description = Une zone de transition entre les hautes montagnes et les basses régions infestées de spores. Une petite base de reconnaissance ennemie s'y trouve.\nDétruisez la.\nUtilisez les unités Poignard et Rampeurs. Détruisez les deux noyaux. zone.impact0078.description = zone.crags.description = + settings.language = Langue settings.data = Données du Jeu settings.reset = Valeurs par Défaut @@ -494,8 +511,8 @@ no = Non info.title = Info error.title = [crimson]Une erreur s'est produite error.crashtitle = Une erreur s'est produite -blocks.input = Input -blocks.output = Output +blocks.input = Entrée +blocks.output = Sortie blocks.booster = Booster block.unknown = [lightgray]??? blocks.powercapacity = Capacité d'énergie @@ -529,9 +546,10 @@ blocks.inaccuracy = Imprécision blocks.shots = Tirs blocks.reload = Tirs/Seconde blocks.ammo = Munitions + bar.drilltierreq = Foreuse Améliorée Requise -bar.drillspeed = Vitesse de forage: {0}/s -bar.pumpspeed = Pump Speed: {0}/s +bar.drillspeed = Vitesse de Forage: {0}/s +bar.pumpspeed = Vitesse de Pompage: {0}/s bar.efficiency = Efficacité: {0}% bar.powerbalance = Énergie: {0}/s bar.powerstored = Stocké: {0}/{1} @@ -544,6 +562,9 @@ bar.heat = Chaleur bar.power = Énergie bar.progress = Progression de la construction bar.spawned = Unités: {0}/{1} +bar.input = Entrée +bar.output = Sortie + bullet.damage = [stat]{0}[lightgray] dégâts bullet.splashdamage = [stat]{0}[lightgray] dégâts de zone ~[stat] {1}[lightgray] blocs bullet.incendiary = [stat]incendiaire @@ -555,6 +576,7 @@ bullet.freezing = [stat]gel bullet.tarred = [stat]goudronné bullet.multiplier = [stat]{0}[lightgray]x multiplicateur de munitions bullet.reload = [stat]{0}[lightgray]x vitesse de tir + unit.blocks = blocs unit.powersecond = énergie/seconde unit.liquidsecond = unité de liquide/seconde @@ -576,9 +598,10 @@ category.shooting = Défense category.optional = Améliorations optionnelles setting.landscape.name = Verrouiller en rotation paysage setting.shadows.name = Ombres -setting.blockreplace.name = Automatic Block Suggestions +setting.blockreplace.name = Suggestions Automatiques de Blocs setting.linear.name = Filtrage Linéaire setting.hints.name = Astuces +setting.buildautopause.name = Pause Automatique de la Construction setting.animatedwater.name = Eau animée setting.animatedshields.name = Boucliers Animés setting.antialias.name = Antialias[lightgray] (redémarrage du jeu nécessaire)[] @@ -599,14 +622,17 @@ setting.difficulty.insane = Extrême setting.difficulty.name = Difficulté: setting.screenshake.name = Tremblement de l'écran setting.effects.name = Afficher les effets -setting.destroyedblocks.name = Display Destroyed Blocks -setting.conveyorpathfinding.name = Conveyor Placement Pathfinding +setting.destroyedblocks.name = Afficher les Blocs Détruits +setting.conveyorpathfinding.name = Recherche de Chemin pour le Placement de Convoyeurs setting.sensitivity.name = Sensibilité de la manette setting.saveinterval.name = Intervalle des sauvegardes auto setting.seconds = {0} secondes +setting.blockselecttimeout.name = Délai d'Attente de Sélection de Bloc +setting.milliseconds = {0} millisecondes setting.fullscreen.name = Plein Écran setting.borderlesswindow.name = Fenêtre sans bords (Borderless)[lightgray] (peut nécessiter le redémarrage du jeu) setting.fps.name = Afficher FPS +setting.blockselectkeys.name = Afficher les Touches de Sélection de Bloc setting.vsync.name = VSync setting.pixelate.name = Pixeliser[lightgray] (désactive les animations) setting.minimap.name = Afficher la Minimap @@ -635,16 +661,36 @@ category.multiplayer.name = Multijoueur command.attack = Attaque command.rally = Rassembler command.retreat = Retraite +placement.blockselectkeys = \n[lightgray]Touche: [{0}, keybind.clear_building.name = Effacer les constructions keybind.press = Appuyer sur une touche... keybind.press.axis = Appuyer sur un axe ou une touche... keybind.screenshot.name = Capture d'écran -keybind.move_x.name = Mouvement x -keybind.move_y.name = Mouvement y +keybind.toggle_power_lines.name = Montrer/Cacher les Connections d'Énergie +keybind.move_x.name = Mouvement X +keybind.move_y.name = Mouvement Y +keybind.mouse_move.name = Suivre la Souris +keybind.dash.name = Sprint keybind.schematic_select.name = Sélectionner une région keybind.schematic_menu.name = Menu des schéma keybind.schematic_flip_x.name = Retourner le schéma sur l'axe X keybind.schematic_flip_y.name = Retourner le schéma sur l'axe Y +keybind.category_prev.name = Catégorie Précédente +keybind.category_next.name = Catégorie Suivante +keybind.block_select_left.name = Sélectionner Bloc de Gauche +keybind.block_select_right.name = Sélectionner Bloc de Droite +keybind.block_select_up.name = Sélectionner Bloc en Haut +keybind.block_select_down.name = Sélectionner Bloc en Bas +keybind.block_select_01.name = Sélectionner Catégorie/Bloc 1 +keybind.block_select_02.name = Sélectionner Catégorie/Bloc 2 +keybind.block_select_03.name = Sélectionner Catégorie/Bloc 3 +keybind.block_select_04.name = Sélectionner Catégorie/Bloc 4 +keybind.block_select_05.name = Sélectionner Catégorie/Bloc 5 +keybind.block_select_06.name = Sélectionner Catégorie/Bloc 6 +keybind.block_select_07.name = Sélectionner Catégorie/Bloc 7 +keybind.block_select_08.name = Sélectionner Catégorie/Bloc 8 +keybind.block_select_09.name = Sélectionner Catégorie/Bloc 9 +keybind.block_select_10.name = Sélectionner Catégorie/Bloc 10 keybind.fullscreen.name = Basculer en Plein Écran keybind.select.name = Sélectionner/Tirer keybind.diagonal_placement.name = Placement en diagonale @@ -658,18 +704,17 @@ keybind.menu.name = Menu keybind.pause.name = Pause keybind.pause_building.name = Pauser/Reprendre la construction keybind.minimap.name = Minimap -keybind.dash.name = Sprint keybind.chat.name = Chat -keybind.player_list.name = Liste des joueurs +keybind.player_list.name = Liste des Joueurs keybind.console.name = Console keybind.rotate.name = Tourner keybind.rotateplaced.name = Tourner existant (maintenir) -keybind.toggle_menus.name = Cacher/afficher les menus -keybind.chat_history_prev.name = Remonter l'historique du chat -keybind.chat_history_next.name = Descendre l'historique du chat -keybind.chat_scroll.name = Défilement du chat +keybind.toggle_menus.name = Cacher/Afficher les Menus +keybind.chat_history_prev.name = Remonter l'Historique du Chat +keybind.chat_history_next.name = Descendre l'Historique du Chat +keybind.chat_scroll.name = Défilement du Chat keybind.drop_unit.name = Larguer l'unité -keybind.zoom_minimap.name = Zoom minimap +keybind.zoom_minimap.name = Zoom Minimap mode.help.title = Description des modes de jeu mode.survival.name = Survie mode.survival.description = Le mode normal. Ressources limitées et vagues automatiques.\n[gray]Nécessite un point d'apparition pour les ennemis. @@ -681,7 +726,9 @@ mode.pvp.description = Battez-vous contre d'autres joueurs en local.\n[gray]Requ mode.attack.name = Attaque mode.attack.description = Pas de vagues, le but étant de détruire la base ennemie.\n[gray]Requiert un noyaux rouge dans la map pour y jouer. mode.custom = Règles personnalisées + rules.infiniteresources = Ressources infinies +rules.reactorexplosions = Explosion des Réacteurs rules.wavetimer = Minuterie pour les vagues rules.waves = Vagues rules.attack = Mode d'Attaque @@ -707,6 +754,10 @@ rules.title.resourcesbuilding = Ressources & Construction rules.title.player = Joueurs rules.title.enemy = Ennemis rules.title.unit = Unités +rules.title.experimental = Expérimental +rules.lighting = Éclairage +rules.ambientlight = Éclairage Ambiant + content.item.name = Objets content.liquid.name = Liquides content.unit.name = Unités @@ -753,6 +804,7 @@ mech.trident-ship.name = Trident mech.trident-ship.weapon = Bombes mech.glaive-ship.name = Glaive mech.glaive-ship.weapon = Mitraille incendiaire +item.corestorable = [lightgray]Stockable dans le Noyau: {0} item.explosiveness = [LIGHT_GRAY]Explosivité: {0} item.flammability = [LIGHT_GRAY]Inflammabilité: {0} item.radioactivity = [LIGHT_GRAY]Radioactivité: {0} @@ -768,6 +820,7 @@ mech.buildspeed = [LIGHT_GRAY]Vitesse de Construction: {0}% liquid.heatcapacity = [LIGHT_GRAY]Capacité Thermique: {0} liquid.viscosity = [LIGHT_GRAY]Viscosité: {0} liquid.temperature = [LIGHT_GRAY]Température: {0} + block.sand-boulder.name = Bloc de Sable block.grass.name = Herbe block.salt.name = Sel @@ -866,6 +919,8 @@ block.distributor.name = Distributeur block.sorter.name = Trieur block.inverted-sorter.name = Trieur Inversé block.message.name = Message +block.illuminator.name = Illuminateur +block.illuminator.description = Une petite source lumineuse compacte et configurable. Nécessite de l'énergie pour fonctionner. block.overflow-gate.name = Barrière de Débordement block.silicon-smelter.name = Fonderie de Silicium block.phase-weaver.name = Tisseur à Phase @@ -879,6 +934,7 @@ block.coal-centrifuge.name = Centrifugeur à Charbon block.power-node.name = Transmetteur Énergétique block.power-node-large.name = Grand Transmetteur Énergétique block.surge-tower.name = Tour de Surtension +block.diode.name = Diode de Batterie block.battery.name = Batterie block.battery-large.name = Grande Batterie block.combustion-generator.name = Générateur à Combustion @@ -931,6 +987,7 @@ block.fortress-factory.name = Usine de Méchas Forteresses block.revenant-factory.name = Usine de Combattants Revenants block.repair-point.name = Point de Réparation block.pulse-conduit.name = Conduit à Impulsion +block.plated-conduit.name = Conduit Plaqué block.phase-conduit.name = Conduit Phasé block.liquid-router.name = Routeur de Liquide block.liquid-tank.name = Réservoir à Liquide @@ -938,7 +995,7 @@ block.liquid-junction.name = Jonction à Liquide block.bridge-conduit.name = Conduit Surélevé block.rotary-pump.name = Pompe Rotative block.thorium-reactor.name = Réacteur à Thorium -block.mass-driver.name = Transporteur de Masses +block.mass-driver.name = Catapulte Électromagnétique block.blast-drill.name = Foreuse à Explosion block.thermal-pump.name = Pompe Thermique block.thermal-generator.name = Générateur Thermique @@ -982,7 +1039,7 @@ unit.eradicator.name = Éradicateur unit.lich.name = Liche unit.reaper.name = Faucheur tutorial.next = [lightgray] -tutorial.intro = Vous venez de commencer le [scarlet]Tutoriel de Mindustry.[]\nUtilisez [[ZQSD] pour vous déplacer.\n[accent]Maintenez [[Ctrl] tout en faisant rouler la molette de la souris[] pour zoomer et dézoomer.\nCommencez en minant du [accent]cuivre[]. Pour cela, rapprochez vous de la veine de minerais de cuivre près de votre noyau et faites un clic gauche dessus.\n\n[accent]{0}/{1} cuivre +tutorial.intro = Vous venez de commencer le [scarlet]Tutoriel de Mindustry.[]\nUtilisez [accent][[ZQSD][] pour vous déplacer.\n[accent]Maintenez [[Ctrl] tout en faisant rouler la molette de la souris[] pour zoomer et dézoomer.\nCommencez en minant du [accent]cuivre[]. Pour cela, rapprochez vous de la veine de minerais de cuivre près de votre noyau et faites un clic gauche dessus.\n\n[accent]{0}/{1} cuivre tutorial.intro.mobile = Vous venez de commencer le [scarlet]Tutoriel de Mindustry.[]\nBalayez l'écran pour vous déplacer.\n[accent] Pincer avec deux doigts [] afin d'agrandir et rétrécir la perspective.\nCommencez en[accent] minant du cuivre[]. Pour cela, appuyez sur une veine de minerai de cuivre près de votre noyau.\n\n[accent]{0}/{1} cuivre tutorial.drill = Miner manuellement est inefficace.\n[accent]Les foreuses []peuvent miner pour vous.\nCliquez sur l'onglet des foreuses en bas à droite.\nSélectionnez la [accent]foreuse mécanique[]. Placez-la sur une veine de cuivre en cliquant.\n[accent]Faite un clique-droit[] pour arrêter la construction. tutorial.drill.mobile = Miner manuellement est inefficace.\n[accent]Les foreuses []peuvent miner pour vous.\nAppuyez sur l'onglet des foreuses en bas à droite.\nSélectionnez la [accent]foreuse mécanique[].\nPlacez-la sur une veine de cuivre en y appuyant, puis en touchant la[accent] coche[] pour confirmer votre placement.\nAppuyez sur le [accent]bouton en forme de croix[] pour annuler le placement. @@ -1002,6 +1059,7 @@ tutorial.deposit = Déposez des ressources dans des blocs en les faisant glisser tutorial.waves = L'[lightgray] ennemi[] approche.\n\nDéfendez le noyau pendant 2 vagues.[accent] Cliquez[] pour tirer.\nConstruisez plus de tourelles et de foreuses. Minez plus de cuivre. tutorial.waves.mobile = L'[lightgray] ennemi[] approche.\n\nDéfendez le noyau pendant 2 vagues. Votre vaisseau tirera automatiquement sur les ennemis.\nConstruisez plus de tourelles et de foreuses. Minez plus de cuivre. tutorial.launch = Une fois que vous aurez atteint une vague spécifique, vous aurez la possibilité de[accent] faire décoller le noyau[], abandonnant vos défenses mais [accent]sécurisant toutes les ressources stockées dans votre noyau.[]\nCes ressources peuvent ensuite être utilisées pour rechercher de nouvelles technologies.\n\n[accent]Appuyez sur le bouton de lancement. + item.copper.description = Le matériau structurel de base. Utilisé intensivement dans tout les blocs. item.lead.description = Un matériau de départ. Utilisé intensivement en électronique et dans les blocs de transport de liquides. item.metaglass.description = Un composé de vitre super-résistant. Utilisé largement pour le transport et le stockage de liquides. @@ -1083,21 +1141,22 @@ block.overdrive-projector.description = Accélère les bâtiments autour de lui, block.force-projector.description = Crée un champ de force hexagonal autour de lui qui protège les bâtiments et les unités à l'intérieur des dégâts.\nSurchauffe si trop de dégâts sont reçus. Peut utiliser du liquide réfrigérant pour éviter la surchauffe. Peut utiliser du tissu phasé pour booster la taille du bouclier. block.shock-mine.description = Blesse les ennemis qui marchent dessus. Quasiment invisible pour l'ennemi. block.conveyor.description = Convoyeur basique servant à transporter des objets. Les objets déplacés en avant sont automatiquement déposés dans les tourelles ou les bâtiments. Peut être tourné. -block.titanium-conveyor.description = Convoyeur avancé . Déplace les objets plus rapidement que les convoyeurs standards. +block.titanium-conveyor.description = Convoyeur avancé. Déplace les objets plus rapidement que les convoyeurs standards. block.junction.description = Agit comme un pont pour deux lignes de convoyeurs se croisant. Utile lorsque deux différents convoyeurs déplacent différents matériaux à différents endroits. block.bridge-conveyor.description = Bloc de transport avancé permettant de traverser jusqu'à 3 blocs de n'importe quel terrain ou bâtiment. -block.phase-conveyor.description = Convoyeur très avancé. Utilise de l'énergie pour téléporter des objets à un convoyeur phasé connecté jusqu'à une longue distance . -block.sorter.description = Trie les articles. Si un article correspond à la sélection, il peut passer. Autrement, l'article est distribué vers la gauche ou la droite. -block.inverted-sorter.description = Trie les articles comme un trieur standard, mais ceux correspondant à la sélection sont envoyés sur les côtés. +block.phase-conveyor.description = Convoyeur très avancé. Utilise de l'énergie pour téléporter des objets à un convoyeur phasé connecté jusqu'à une longue distance. +block.sorter.description = Trie les ressources. Si une ressource correspond à la sélection, elle peut passer. Autrement, elle est distribuée vers la gauche ou la droite. +block.inverted-sorter.description = Trie les ressources comme un trieur standard, mais ceux correspondant à la sélection sont envoyés sur les côtés. block.router.description = Accepte les objets depuis une ou plus directions et le renvoie dans n'importe quelle direction. Utile pour séparer une chaîne de convoyeurs en plusieurs.[accent]Le seul et l'Unique[] block.distributor.description = Un routeur avancé qui sépare les objets jusqu'à 7 autres directions équitablement. -block.overflow-gate.description = C'est la combinaison entre un Routeur et un Diviseur qui peut seulement distribuer à gauche et à droite si le chemin de devant est bloqué. -block.mass-driver.description = bâtiment de transport d'objet [accent]ultime[]. Collecte un grand nombre d'objets puis les tire à un autre transporteur de masse sur une très longue distance. -block.mechanical-pump.description = Une pompe de faible prix pompant lentement, mais ne consomme pas d'énergie. +block.overflow-gate.description = Bloc envoyant les ressources à gauche et à droite si le chemin de devant est bloqué. +block.mass-driver.description = Le moyen de transport de resources ultime. Collecte plusieurs ressources puis les envoie à une autre catapulte sur une longue distance. Nécessite de l'énergie pour fonctionner. +block.mechanical-pump.description = Une pompe de faible prix pompant lentement, mais ne consommant pas d'énergie. block.rotary-pump.description = Une pompe avancée plus rapide mais utilisant de l'énergie. -block.thermal-pump.description = La pompe ultime. Beaucoup plus rapide qu'une pompe mécanique et la seule pompe capable de récupérer de la lave. -block.conduit.description = Tuyau basique permettant le transport de liquide . Marche comme un convoyeur mais avec les liquides. Utile si utilisé avec des extracteurs, des pompes ou d'autres conduits. -block.pulse-conduit.description = Tuyau avancé permettant le transport de liquide . Transporte les liquides plus rapidement et en stocke plus que les tuyaux standards. +block.thermal-pump.description = La pompe ultime. +block.conduit.description = Bloc de transport de liquide de base. Fait avancer les liquides. Utilisé avec des pompes et autres conduits. +block.pulse-conduit.description = Tuyau avancé permettant le transport de liquide. Transporte les liquides plus rapidement et en stocke plus que les tuyaux standards. +block.plated-conduit.description = Déplace les liquides au même rythme que les conduits d'impulsion, mais possède plus d'armure. N'accepte pas de liquides provenant des côtés par autre chose que des conduits.\nFuit moins. block.liquid-router.description = Accepte les liquides en une direction et les rejette de tous les côtés équitablement. Peut aussi stocker une certaine quantité de liquide. Utile pour envoyer un liquide à plusieurs endroits. block.liquid-tank.description = Stocke une grande quantité de liquides . Utile pour réguler la sortie quand la demande est inconstante ou comme sécurité pour refroidir des bâtiments important. block.liquid-junction.description = Agit comme une intersection pour deux conduits se croisant.Utile si deux conduits amènent différents liquides à différents endroits. @@ -1106,11 +1165,12 @@ block.phase-conduit.description = Tuyau très avancé permettant le transport de block.power-node.description = Transmet l'énergie aux transmetteurs énergétiques connectés. Le transmetteur recevra de l'énergie ou la transmettra à n'importe quel bâtiment adjacent. block.power-node-large.description = Possède un rayon plus grand que le transmetteur énergétique standard, connectant d'autant plus de consommateurs ou transmetteurs d'énergie. block.surge-tower.description = Un transmetteur énergétique de très grande portée mais avec moins de connections disponibles. +block.diode.description = La batterie ne peut circuler dans ce bloc que dans un sens, mais uniquement si l’autre côté a moins d’énergie stockée. block.battery.description = Stocke l'énergie quand elle est en abondance et la redistribue si il y a un deficit d'énergie dans la limite des réserves disponibles. block.battery-large.description = Stocke bien plus d'énergie qu'une batterie normale. -block.combustion-generator.description = Génère de l'énergie en brûlant du charbon ou des matériaux inflammables. -block.thermal-generator.description = Génère une grande quantité d'énergie à partir de zone de chaleur . -block.turbine-generator.description = Plus efficace qu'un générateur à combustion, mais requiert de l'eau . +block.combustion-generator.description = Génère de l'énergie en brûlant du charbon ou d'autres matériaux inflammables. +block.thermal-generator.description = Génère une grande quantité d'énergie à partir de zone de chaleur. +block.turbine-generator.description = Plus efficace qu'un générateur à combustion, mais requiert de l'eau. block.differential-generator.description = Génère de grande quantité d'energie. Utilise différence de temperature entre le liquide cryogénique et la pyratite brûlante. block.rtg-generator.description = Un générateur thermo-électrique à radioisotope qui ne demande pas de refroidissement mais produit moins d'énergie qu'un réacteur à Thorium. block.solar-panel.description = Génère une faible quantité d'énergie grace au rayons du soleil. diff --git a/core/assets/bundles/bundle_ja.properties b/core/assets/bundles/bundle_ja.properties index 14a3e7e066..06cc822663 100644 --- a/core/assets/bundles/bundle_ja.properties +++ b/core/assets/bundles/bundle_ja.properties @@ -17,29 +17,29 @@ screenshot.invalid = マップが広すぎます。スクリーンショット gameover = ゲームオーバー gameover.pvp = [accent] {0}[] チームの勝利! highscore = [accent]ハイスコアを更新! -copied = Copied. +copied = コピーしました。 load.sound = サウンド load.map = マップ load.image = 画像 load.content = コンテンツ load.system = システム load.mod = MOD -schematic = Schematic -schematic.add = Save Schematic... -schematics = Schematics -schematic.replace = A schematic by that name already exists. Replace it? -schematic.import = Import Schematic... -schematic.exportfile = Export File -schematic.importfile = Import File -schematic.browseworkshop = Browse Workshop -schematic.copy = Copy to Clipboard -schematic.copy.import = Import from Clipboard -schematic.shareworkshop = Share on Workshop +schematic = 設計図 +schematic.add = 設計図を保存しています... +schematics = 設計図一覧 +schematic.replace = 同じ名前の設計図があるようです。 上書きしますか? +schematic.import = 設計図を読み込んでいます... +schematic.exportfile = ファイルに出力する +schematic.importfile = ファイルから読み込む +schematic.browseworkshop = ワークショップを表示する +schematic.copy = クリップボードにコピーする +schematic.copy.import = クリップボードから読み込む +schematic.shareworkshop = ワークショップで共有する schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Flip Schematic -schematic.saved = Schematic saved. -schematic.delete.confirm = This schematic will be utterly eradicated. -schematic.rename = Rename Schematic -schematic.info = {0}x{1}, {2} blocks +schematic.saved = 設計図を保存しました。 +schematic.delete.confirm = この設計図は完全に削除されます。よろしいですか +schematic.rename = 設計図の名前を変更する。 +schematic.info = {0}x{1}, {2} ブロック stat.wave = 防衛したウェーブ:[accent] {0} stat.enemiesDestroyed = 敵による破壊数:[accent] {0} stat.built = 建設した建造物数:[accent] {0} @@ -64,7 +64,7 @@ customgame = カスタムプレイ newgame = 新しく始める none = <なし> minimap = ミニマップ -position = Position +position = 位置 close = 閉じる website = ウェブサイト quit = 終了 @@ -80,25 +80,25 @@ uploadingcontent = コンテンツをアップロードしています uploadingpreviewfile = プレビューファイルをアップロードしています committingchanges = 変更を適応中 done = 完了 -feature.unsupported = Your device does not support this feature. +feature.unsupported = あなたのデバイスはこの機能をサポートしていません。 mods.alphainfo = Mods機能は実験的なものです。[scarlet] エラーが含まれている可能性があります[]。\n 発見した問題をMindustry GitHubに報告してください。 mods.alpha = [accent](Alpha) mods = Mods mods.none = [LIGHT_GRAY]Modが見つかりませんでした! mods.guide = Modding Guide -mods.report = Report Bug -mods.openfolder = Open Mod Folder +mods.report = バグを報告する +mods.openfolder = MODのフォルダを開く mod.enabled = [lightgray]有効 mod.disabled = [scarlet]無効 mod.disable = 無効化 -mod.delete.error = Unable to delete mod. File may be in use. +mod.delete.error = MODを削除することができませんでした。 mod.missingdependencies = [scarlet]Missing dependencies: {0} mod.nowdisabled = [scarlet]Mod '{0}' is missing dependencies:[accent] {1}\n[lightgray]These mods need to be downloaded first.\nThis mod will be automatically disabled. mod.enable = 有効化 mod.requiresrestart = このModをインストールするためにはゲームの再起動が必要です。 mod.reloadrequired = [scarlet]Modを有効にするには、この画面を開き直してください。 mod.import = Modをインポート -mod.import.github = Import GitHub Mod +mod.import.github = GitHubからMODを読み込む mod.remove.confirm = このModを削除します。 mod.author = [LIGHT_GRAY]著者:[] {0} mod.missing = このセーブには、アップグレードされた可能性があるModsか、ここに存在しないModsが必要です。 メモリのセーブを保存する! ロードしてもよろしいですか?\n[lightgray]MODS:\n{0} @@ -166,7 +166,7 @@ server.version = [lightgray]バージョン: {0} {1} server.custombuild = [yellow]カスタムビルド confirmban = このプレイヤーをBanしてもよろしいですか? confirmkick = このプレイヤーをキックしてもよろしいですか? -confirmvotekick = Are you sure you want to vote-kick this player? +confirmvotekick = このプレイヤーを投票キックしてもよろしいですか? confirmunban = このプレイヤーのBanを解除してもよろしいですか? confirmadmin = このプレイヤーを管理者にしてもよろしいですか? confirmunadmin = このプレイヤーを管理者から削除してもよろしいですか? @@ -202,7 +202,7 @@ save.rename = 名前を変更 save.rename.text = 新しい名前: selectslot = セーブデータを選択してください。 slot = [accent]スロット {0} -editmessage = Edit Message +editmessage = メッセージを編集する save.corrupted = [accent]セーブファイルが無効、または破損しました!\nゲームのアップデート直後の場合、恐らくセーブデータのフォーマットの変更によるもので、バグではありません。 empty = <空> on = オン @@ -237,10 +237,10 @@ quit.confirm.tutorial = チュートリアルを終了しますか?\nチュー loading = [accent]読み込み中... reloading = [accent]Reloading Mods... saving = [accent]保存中... -cancelbuilding = [accent][[{0}][] to clear plan -selectschematic = [accent][[{0}][] to select+copy -pausebuilding = [accent][[{0}][] to pause building -resumebuilding = [scarlet][[{0}][] to resume building +cancelbuilding = [accent][[{0}][] 選択を解除する +selectschematic = [accent][[{0}][] 選択し、コピーする +pausebuilding = [accent][[{0}][] 建築を一時的に中断する +resumebuilding = [scarlet][[{0}][] 建築を再開する wave = [accent]ウェーブ {0} wave.waiting = [lightgray]次のウェーブまで {0} 秒 wave.waveInProgress = [lightgray]ウェーブ進行中 @@ -424,8 +424,8 @@ launch.confirm = すべての資源をコアに搬入し、発射します。\n launch.skip.confirm = スキップすると、次の発射可能なウェーブまで発射できません。 uncover = 開放 configure = 積み荷の設定 -bannedblocks = Banned Blocks -addall = Add All +bannedblocks = 禁止ブロック +addall = すべて追加 configure.locked = [lightgray]ウェーブ {0} を達成すると積み荷を設定できるようになります。 configure.invalid = 値は 0 から {0} の間でなければなりません。 zone.unlocked = [lightgray]{0} がアンロックされました. @@ -509,7 +509,7 @@ blocks.shootrange = 範囲 blocks.size = 大きさ blocks.liquidcapacity = 液体容量 blocks.powerrange = 電力範囲 -blocks.powerconnections = Max Connections +blocks.powerconnections = 最大接続数 blocks.poweruse = 電力使用量 blocks.powerdamage = 電力/ダメージ blocks.itemcapacity = アイテム容量 @@ -531,10 +531,10 @@ blocks.reload = ショット/秒 blocks.ammo = 弾薬 bar.drilltierreq = より良いドリルが必要です bar.drillspeed = 採掘速度: {0}/秒 -bar.pumpspeed = Pump Speed: {0}/s +bar.pumpspeed = ポンプの速度: {0}/s bar.efficiency = 効率: {0}% bar.powerbalance = 電力: {0}/秒 -bar.powerstored = Stored: {0}/{1} +bar.powerstored = 残量: {0}/{1} bar.poweramount = 電力: {0} bar.poweroutput = 電力発電量: {0} bar.items = アイテム: {0} @@ -578,7 +578,7 @@ setting.landscape.name = 横画面で固定 setting.shadows.name = 影 setting.blockreplace.name = Automatic Block Suggestions setting.linear.name = リニアフィルター -setting.hints.name = Hints +setting.hints.name = ヒント setting.animatedwater.name = 水のアニメーション setting.animatedshields.name = シールドのアニメーション setting.antialias.name = アンチエイリアス[lightgray] (再起動が必要)[] @@ -599,7 +599,7 @@ setting.difficulty.insane = クレイジー setting.difficulty.name = 難易度: setting.screenshake.name = 画面の揺れ setting.effects.name = 画面効果 -setting.destroyedblocks.name = Display Destroyed Blocks +setting.destroyedblocks.name = 破壊されたブロックを表示 setting.conveyorpathfinding.name = Conveyor Placement Pathfinding setting.sensitivity.name = 操作感度 setting.saveinterval.name = 自動保存間隔 @@ -610,7 +610,7 @@ setting.fps.name = FPSを表示 setting.vsync.name = VSync setting.pixelate.name = ピクセル化[lightgray] (アニメーションが無効化されます) setting.minimap.name = ミニマップを表示 -setting.position.name = Show Player Position +setting.position.name = プレイヤーの位置表示 setting.musicvol.name = 音楽 音量 setting.ambientvol.name = 環境音 音量 setting.mutemusic.name = 音楽をミュート @@ -620,7 +620,7 @@ setting.crashreport.name = 匿名でクラッシュレポートを送信する setting.savecreate.name = 自動保存 setting.publichost.name = 誰でもゲームに参加できるようにする setting.chatopacity.name = チャットの透明度 -setting.lasersopacity.name = Power Laser Opacity +setting.lasersopacity.name = レーザーの透明度 setting.playerchat.name = ゲーム内にチャットを表示 public.confirm = Do you want to make your game public?\n[accent]Anyone will be able to join your games.\n[lightgray]This can be changed later in Settings->Game->Public Game Visibility. public.beta = Note that beta versions of the game cannot make public lobbies. @@ -843,8 +843,8 @@ block.copper-wall.name = 銅の壁 block.copper-wall-large.name = 巨大な銅の壁 block.titanium-wall.name = チタンの壁 block.titanium-wall-large.name = 巨大なチタンの壁 -block.plastanium-wall.name = Plastanium Wall -block.plastanium-wall-large.name = Large Plastanium Wall +block.plastanium-wall.name = プラスタニウムの壁 +block.plastanium-wall-large.name = 巨大なプラスタニウムの壁 block.phase-wall.name = フェーズファイバーの壁 block.phase-wall-large.name = 巨大なフェーズファイバーの壁 block.thorium-wall.name = トリウムの壁 @@ -864,8 +864,8 @@ block.junction.name = ジャンクション block.router.name = ルーター block.distributor.name = ディストリビューター block.sorter.name = ソーター -block.inverted-sorter.name = Inverted Sorter -block.message.name = Message +block.inverted-sorter.name = 反転ソーター +block.message.name = メッセージブロック block.overflow-gate.name = オーバーフローゲート block.silicon-smelter.name = シリコン溶鉱炉 block.phase-weaver.name = フェーズ織機 @@ -1088,7 +1088,7 @@ block.junction.description = 十字に交差したコンベアーをそれぞれ block.bridge-conveyor.description = 高度な輸送ブロックです。地形や建物を超えて、3ブロック離れた場所にアイテムを輸送することができます。 block.phase-conveyor.description = 改良されたアイテム転送ブロックです。電力を使用して、離れた場所にあるフェーズコンベアーにアイテムを転送することができます。 block.sorter.description = アイテムを分別して搬出します。設定したアイテムは通過させます。他のアイテムが搬入されると側面にアイテムを搬出します。 -block.inverted-sorter.description = Processes items like a standard sorter, but outputs selected items to the sides instead. +block.inverted-sorter.description = アイテムを分別して搬出します。設定したアイテムは側面に搬出されます。他のアイテムが搬入されるとアイテムを通過させます。通常のルーターと反対の動作をします。 block.router.description = 搬入したアイテムをほかの3方向に均等に搬出します。一つの資源から複数に分ける際などに使われます。 block.distributor.description = 高度なルーターです。搬入したアイテムをほかの7方向に均等に分けて搬出します。 block.overflow-gate.description = 搬出先にアイテムを搬入する空きがない場合に左右にアイテムを搬出します。 diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 51ef110c8f..dfe930fee9 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -10,6 +10,7 @@ link.dev-builds.description = 불안정한 개발 빌드들 link.trello.description = 다음 출시될 기능들을 게시한 공식 Trello 보드 link.itch.io.description = PC 버전 다운로드와 HTML5 버전이 있는 itch.io 사이트 link.google-play.description = Google Play 스토어 정보 +link.f-droid.description = F-Droid 카탈로그 link.wiki.description = 공식 Mindustry 위키 linkfail = 링크를 여는 데 실패했습니다!\nURL이 기기의 클립보드에 복사되었습니다. screenshot = 스크린샷이 {0} 경로에 저장되었습니다. @@ -18,12 +19,14 @@ gameover = 게임 오버 gameover.pvp = [accent]{0}[] 팀이 승리했습니다! highscore = [accent]최고점수 달성! copied = 복사됨. + load.sound = 소리 load.map = 맵 load.image = 사진 load.content = 컨텐츠 load.system = 시스템 load.mod = 모드 + schematic = 설계도 schematic.add = 설계도 저장하기 schematics = 설계도 모음 @@ -40,6 +43,7 @@ schematic.saved = 설계도 저장됨. schematic.delete.confirm = 삭제된 설계도는 복구할 수 없습니다. 정말로 삭제하시겠습니까? schematic.rename = 설계도명 변경 schematic.info = 크기 : {0}x{1}, 블럭 수 : {2} + stat.wave = 버틴 단계 수 : [accent]{0} stat.enemiesDestroyed = 파괴한 적 수 : [accent]{0} stat.built = 건설한 건물 수 : [accent]{0} @@ -47,6 +51,7 @@ stat.destroyed = 파괴된 건물 수 : [accent]{0} stat.deconstructed = 파괴한 건물 수 : [accent]{0} stat.delivered = 획득한 자원 : stat.rank = 최종 점수 : [accent]{0} + launcheditems = [accent]창고 launchinfo = [출격되지 않음][[출격]파랑색으로 표시된 자원들을 획득합니다. map.delete = 정말로 "[accent]{0}[]" 맵을 삭제하시겠습니까? @@ -74,6 +79,7 @@ maps.browse = 맵 검색 continue = 계속하기 maps.none = [LIGHT_GRAY]맵을 찾을 수 없습니다! invalid = 오류 +pickcolor = 색 preparingconfig = 설정 사전준비 preparingcontent = 컨텐츠 사전준비 uploadingcontent = 컨텐츠 업로드 @@ -81,13 +87,14 @@ uploadingpreviewfile = 미리보기 파일 업로드 committingchanges = 바뀐 점 적용 done = 완료 feature.unsupported = 당신의 기기는 이 기능을 지원하지 않습니다. + mods.alphainfo = 현재의 모드는 첫 번째 시도이며, 그리고[scarlet] 버그가 매우 많음을 명심하십시오[].\n만약 버그를 발견할경우 Mindustry 깃허브 또는 디스코드로 제보해주세요. mods.alpha = [scarlet](Alpha) mods = 모드 mods.none = [LIGHT_GRAY]추가한 모드가 없습니다! mods.guide = 모드 가이드 mods.report = 버그 신고 -mods.openfolder = Open Mod Folder +mods.openfolder = 모드 폴더 열기 mod.enabled = [firebrick]활성화 mod.disabled = [lightgray]비활성화 mod.disable = 비활성화 @@ -104,6 +111,7 @@ mod.author = [LIGHT_GRAY]제작자 : [] {0} mod.missing = 이 세이브파일에는 설치하지 않은 모드 혹은 이 버전에 속해있지 않은 데이터가 포함되어 있습니다. 이 파일을 불러올 경우 세이브파일의 데이터가 손상될 수 있습니다. 정말로 이 파일을 불러오시겠습니까?\n[lightgray]모드 :\n{0} mod.preview.missing = 워크샵에 당신의 모드를 업로드하기 전에 미리보기 이미지를 먼저 추가해야합니다.\n[accent] preview.png[]라는 이름으로 미리보기 이미지를 당신의 모드 폴더안에 준비한 후 다시 시도해주세요. mod.folder.missing = 워크샵에는 폴더 형태의 모드만 게시할 수 있습니다.\n모드를 폴더 형태로 바꾸려면 파일을 폴더에 압축 해제하고 이전 압축파일을 제거한 후, 게임을 재시작하거나 모드를 다시 로드하십시오. + about.button = 정보 name = 이름 : noname = 먼저 [accent] [] 을 설정하세요. @@ -148,7 +156,7 @@ hosts.none = [lightgray]LAN 게임을 찾을 수 없습니다! host.invalid = [scarlet]서버에 연결할 수 없습니다! trace = 플레이어 정보 보기 trace.playername = 닉네임 : [accent]{0} -trace.ip = IP : [accent]{0}{0} +trace.ip = IP : [accent]{0} trace.id = UUID : [accent]{0} trace.mobile = 모바일 접속 유무 : [accent]{0} trace.modclient = 수정된 클라이언트 : [accent]{0} @@ -173,7 +181,7 @@ confirmunadmin = 이 플레이어를 일반 유저로 만들겠습니까? joingame.title = 게임 참가 joingame.ip = 주소 : disconnect = 서버와 연결이 해제되었습니다. -disconnect.error = 연결 . +disconnect.error = 연결 오류. disconnect.closed = 연결이 끊어졌습니다.. disconnect.timeout = 연결 시간 한계 도달.. disconnect.data = 월드 데이터 로딩 실패.. @@ -183,7 +191,7 @@ connecting.data = [accent]월드 데이터 로딩중... server.port = 포트 : server.addressinuse = 주소가 이미 사용중입니다! server.invalidport = 포트가 올바르지 않습니다! -server.error = [accent]{0}[crimson]서버를 여는 데 오류가 발생했습니다. +server.error = [crimson]서버를 여는 데 오류가 발생했습니다. save.new = 새로 저장 save.overwrite = 이 저장 슬롯을 덮어씌우겠습니까? overwrite = 덮어쓰기 @@ -271,6 +279,7 @@ publishing = [accent]업로드 중... publish.confirm = 맵을 업로드 하시겠습니까?\n\n[lightgray]먼저 워크샵 EULA에 동의하시지 않으면 맵이 표시되지 않습니다! publish.error = 맵 업로드 오류 : {0} steam.error = 스팀 서비스를 초기화하는데 실패했습니다.\n에러 코드 : {0} + editor.brush = 브러쉬 editor.openin = 편집기 열기 editor.oregen = 광물 무작위 생성 @@ -308,8 +317,8 @@ editor.name = 이름 : editor.spawn = 유닛 생성 editor.removeunit = 유닛 삭제 editor.teams = 팀 -editor.errorload = [accent]{0} 파일을 불러오는 데 실패했습니다. -editor.errorsave = [accent]{0} 파일을 저장하는 데 실패했습니다. +editor.errorload = 파일을 불러오지 습니다. +editor.errorsave = 파일을 저장하지 못했습니다. editor.errorimage = 이것은 맵이 아니라 사진입니다.\n\n예전 맵을 가져오려면 편집기의 '예전 맵 가져오기' 버튼을 사용하세요. editor.errorlegacy = 이 맵은 너무 오래되어, 더는 지원하지 않는 맵 형식을 사용합니다. editor.errornot = 선택한 대상이 맵 파일이 아닙니다. @@ -347,6 +356,7 @@ editor.overwrite = [accept]경고!이 명령은 기존 맵을 덮어씌우게 editor.overwrite.confirm = [scarlet]경고![] 이 이름을 가진 맵이 이미 있습니다. 덮어 쓰시겠습니까? editor.exists = 같은 이름의 맵이 이미 존재합니다. editor.selectmap = 불러올 맵 선택 : + toolmode.replace = 재배치 toolmode.replace.description = 블록을 배치합니다. toolmode.replaceall = 모두 재배치 @@ -361,6 +371,7 @@ toolmode.fillteams = 팀 채우기 toolmode.fillteams.description = 블록 대신 팀 건물로 채웁니다. toolmode.drawteams = 팀 그리기 toolmode.drawteams.description = 블록 대신 팀 건물을 배치합니다. + filters.empty = [LIGHT_GRAY]필터가 없습니다!! 아래 버튼을 눌러 추가하세요. filter.distort = 왜곡 filter.noise = 맵 전체에 타일 혹은 블럭 뿌리기 @@ -392,6 +403,7 @@ filter.option.floor2 = 2번째 바닥 filter.option.threshold2 = 2번째 한계점 filter.option.radius = 반경 filter.option.percentile = 백분위수 + width = 넓이 : height = 높이 : menu = 메뉴 @@ -407,6 +419,7 @@ tutorial = 튜토리얼 tutorial.retake = 튜토리얼 editor = 편집기 mapeditor = 맵 편집기 + abandon = 지역 포기 abandon.text = 이 구역의 모든 자원이 적에게 빼앗길 것입니다. locked = 잠김 @@ -428,7 +441,7 @@ bannedblocks = 금지된 블럭들 addall = 모두 추가 configure.locked = [lightgray]{0}시 시작자원 설정이 해금됩니다. configure.invalid = 해당 값은 0 과 {0} 사이여야 합니다. -zone.unlocked = [LIGHT_GRAY] 잠금 해제되었습니다! +zone.unlocked = [LIGHT_GRAY]지역 {0}이 잠금 해제되었습니다! zone.requirement.complete = {0} 단계 달성 성공! \n{1} 지역 요구사항이 충족되었습니다! zone.config.unlocked = 시작자원 설정 해금! : [lightgray]\n{0} zone.resources = 감지된 자원 목록 : @@ -437,6 +450,7 @@ zone.objective.survival = 생존 zone.objective.attack = 적 코어 파괴 add = 추가... boss.health = 보스 체력 + connectfail = [crimson]{0}[accent] 서버에 연결하지 못했습니다.[] error.unreachable = 서버에 연결하지 못했습니다.\n서버 주소가 정확히 입력되었나요? error.invalidaddress = 잘못된 주소입니다. @@ -447,6 +461,7 @@ error.mapnotfound = 맵 파일을 찾을 수 없습니다! error.io = 네트워크 I/O 오류. error.any = 알 수 없는 네트워크 오류. error.bloom = 블룸 그래픽 효과를 적용하지 못했습니다.\n당신의 기기가 이 기능을 지원하지 않는 것일 수도 있습니다. + zone.groundZero.name = 전초기지 zone.desertWastes.name = 쓰레기 사막 zone.craters.name = 크레이터 @@ -461,6 +476,7 @@ zone.saltFlats.name = 소금 사막 zone.impact0078.name = Impact 0078 zone.crags.name = 협곡 zone.fungalPass.name = 포자 지대 + zone.groundZero.description = 이 장소는 다시 시작하기에 최적의 환경을 지닌 장소입니다. 적은 수준의 위협이 있으며 자원의 양은 적습니다.\n가능한 한 많은 양의 구리와 납을 수집하십시오.\n출격합시다! zone.frozenForest.description = 이 지역도 산과 가까운 지역입니다 포자들이 흩뿌려져 있으며 극한의 추위도 포자를 막을 수 있을 것 같지 않습니다.\n화력 발전소를 짓고 전력을 확보하여 채광 드론을 사용하는 법을 배우십시오. zone.desertWastes.description = 이 황무지는 끝을 알 수 없을 정도로 광활하고 십자가 형태의 버려진 구조물이 존재합니다.\n석탄이 존재하며 이를 화력발전에 쓰거나 흑연 정제에 쓰십시오.\n\n[lightgray]이 지역에서의 착륙장소는 확실하지 않습니다. @@ -475,6 +491,7 @@ zone.nuclearComplex.description = 과거 토륨의 생산, 연구와 처리를 zone.fungalPass.description = 고산지대과 포자지대 사이의 지역입니다. 소규모의 적 정찰기지가 있으니 디거와 크롤러를 이용해 적의 코어를 파괴하십시오. zone.impact0078.description = [ROYAL]죄송합니다. 아직 설명이 준비되지 않았습니다. zone.crags.description = [ROYAL]죄송합니다. 아직 설명이 준비되지 않았습니다. + settings.language = 언어 settings.data = 게임 데이터 settings.reset = 설정 초기화 @@ -497,7 +514,7 @@ error.crashtitle = 오류가 발생했습니다. blocks.input = 소모 자원 blocks.output = 출력 자원 blocks.booster = 가속 -block.unknown = [LIGHT_GRAY]??? +block.unknown = [LIGHT_GRAY]OHNO blocks.powercapacity = 전력 용량 blocks.powershot = 1발당 전력 소모량 blocks.damage = 공격력 @@ -509,7 +526,7 @@ blocks.shootrange = 사거리 blocks.size = 크기 blocks.liquidcapacity = 액체 용량 blocks.powerrange = 전력 범위 -blocks.powerconnections = Max Connections +blocks.powerconnections = 최대 연결 수 blocks.poweruse = 전력 사용 blocks.powerdamage = 전력/데미지 blocks.itemcapacity = 저장 용량 @@ -529,14 +546,15 @@ blocks.inaccuracy = 오차각 blocks.shots = 공격 속도 blocks.reload = 재장전 blocks.ammo = 탄약 + bar.drilltierreq = 더 좋은 드릴이 요구됨 -bar.drillspeed = 초당 {0}개 채굴중 -bar.pumpspeed = Pump Speed: {0}/s +bar.drillspeed = 드릴 속도 : {0}개/s +bar.pumpspeed = 펌프 속도 : {0}/s bar.efficiency = 활성화율 : {0}% -bar.powerbalance = 초당 {0} 발전중 +bar.powerbalance = 전력 발전 : {0}/s bar.powerstored = 총 전력 저장량 : {0}/{1} bar.poweramount = 전력 저장량 : {0} -bar.poweroutput = 초당 {0} 발전중 +bar.poweroutput = 전력 출력 : {0} bar.items = 자원량 : {0} bar.capacity = 저장공간 : {0} bar.liquid = 액체 @@ -544,6 +562,9 @@ bar.heat = 발열 bar.power = 전력 bar.progress = 생산 진행도 bar.spawned = 최대 {1}기 중 {0}기 생산됨 +bar.input = 입력 +bar.output = + bullet.damage = [lightgray]피해량 : [stat]{0}[] bullet.splashdamage = [lightgray]범위 피해량 : [stat]{0}[] / [lightgray]피해 범위 : [stat]{1}[lightgray] 타일 bullet.incendiary = [stat]방화 @@ -555,6 +576,7 @@ bullet.freezing = [stat]빙결 bullet.tarred = [stat]타르 bullet.multiplier = 추가 타격 횟수 : [stat]{0}[lightgray] bullet.reload = 공격 속도 : [stat]{0}[lightgray] + unit.blocks = 블록 unit.powersecond = 전력/초 unit.liquidsecond = 액체/초 @@ -574,11 +596,12 @@ category.items = 아이템 category.crafting = 제작 category.shooting = 사격 category.optional = 보조 아이템 -setting.landscape.name = 가로화면으로 고정 +setting.landscape.name = 가로화면 setting.shadows.name = 그림자 setting.blockreplace.name = 블럭 제안 자동화 setting.linear.name = 선형 필터링 setting.hints.name = 힌트 활성화 +setting.buildautopause.name = 건설 자동 일시정지 setting.animatedwater.name = 움직이는 물 setting.animatedshields.name = 움직이는 보호막 setting.antialias.name = 안티 에일리어싱[LIGHT_GRAY] (재시작 필요)[] @@ -599,14 +622,17 @@ setting.difficulty.insane = 미침 setting.difficulty.name = 난이도 : setting.screenshake.name = 화면 흔들기 setting.effects.name = 화면 효과 -setting.destroyedblocks.name = Display Destroyed Blocks -setting.conveyorpathfinding.name = Conveyor Placement Pathfinding +setting.destroyedblocks.name = 부서진 블럭 표시 +setting.conveyorpathfinding.name = 컨베이어 설치 보조 기능 setting.sensitivity.name = 컨트롤러 감도 setting.saveinterval.name = 저장 간격 -setting.seconds = 초 +setting.seconds = {0} 초 +setting.blockselecttimeout.name = 블록 선택 시간 초과 +setting.milliseconds = {0} 밀리초 setting.fullscreen.name = 전체 화면 setting.borderlesswindow.name = 테두리 없는 창모드[LIGHT_GRAY] (재시작이 필요할 수 있습니다) setting.fps.name = FPS 표시 +setting.blockselectkeys.name = 블럭 선택 키 setting.vsync.name = VSync 활성화 setting.pixelate.name = 픽셀화[LIGHT_GRAY] (게임에 렉이 심할 경우 이 옵션을 켜주세요.) setting.minimap.name = 미니맵 보기 @@ -635,16 +661,35 @@ category.multiplayer.name = 멀티플레이 command.attack = 공격 command.rally = 순찰 command.retreat = 후퇴 +placement.blockselectkeys = \n[lightgray]키: [{0}, keybind.clear_building.name = 설계도 초기화 keybind.press = 키를 누르세요... keybind.press.axis = 마우스 휠 또는 키를 누르세요... keybind.screenshot.name = 맵 스크린샷 -keybind.move_x.name = 오른쪽/왼쪽 이동 -keybind.move_y.name = 위 / 아래 중간 +keybind.toggle_power_lines.name = 전력 라인 허용 +keybind.move_x.name = 오른쪽 / 왼쪽 이동 +keybind.move_y.name = 위 / 아래 이동 +keybind.mouse_move.name = 커서를 따라서 이동 keybind.schematic_select.name = 영역 설정 keybind.schematic_menu.name = 설계도 메뉴 keybind.schematic_flip_x.name = 설계도 X축 뒤집기 keybind.schematic_flip_y.name = 설계도 Y축 뒤집기 +keybind.category_prev.name = 이전 목록 +keybind.category_next.name = 다음 목록 +keybind.block_select_left.name = 블럭 Select Left +keybind.block_select_right.name = 블럭 Select Right +keybind.block_select_up.name = 블럭 Select Up +keybind.block_select_down.name = 블럭 Select Down +keybind.block_select_01.name = 카테고리/블럭 선택 1 +keybind.block_select_02.name = 카테고리/블럭 선택 2 +keybind.block_select_03.name = 카테고리/블럭 선택 3 +keybind.block_select_04.name = 카테고리/블럭 선택 4 +keybind.block_select_05.name = 카테고리/블럭 선택 5 +keybind.block_select_06.name = 카테고리/블럭 선택 6 +keybind.block_select_07.name = 카테고리/블럭 선택 7 +keybind.block_select_08.name = 카테고리/블럭 선택 8 +keybind.block_select_09.name = 카테고리/블럭 선택 9 +keybind.block_select_10.name = 카테고리/블럭 선택 10 keybind.fullscreen.name = 전체 화면 keybind.select.name = 선택/공격 keybind.diagonal_placement.name = 대각선 설치 @@ -681,9 +726,11 @@ mode.pvp.description = 실제 플레이어와 PvP를 합니다. 맵에 적어도 mode.attack.name = 공격 mode.attack.description = 적 기지를 파괴하세요. 맵에 빨간팀 코어가 있어야 플레이 가능합니다. mode.custom = 사용자 정의 규칙 + rules.infiniteresources = 무한 자원 -rules.wavetimer = 단계 -rules.waves = 단계 +rules.reactorexplosions = 원자로 폭발 허가여부 +rules.wavetimer = 단계 대기시간 +rules.waves = 단계 활성화 rules.attack = 공격 모드 rules.enemyCheat = 무한한 적 자원 rules.unitdrops = 유닛 처치시 자원 약탈 @@ -692,13 +739,13 @@ rules.unithealthmultiplier = 유닛 체력 배수 rules.playerhealthmultiplier = 플레이어 체력 배수 rules.playerdamagemultiplier = 플레이어 공격력 배수 rules.unitdamagemultiplier = 유닛 공격력 배수 -rules.enemycorebuildradius = 적 코어 건설 금지구역:[LIGHT_GRAY] (타일) -rules.respawntime = 플레이어 부활 대기 시간:[LIGHT_GRAY] (초) +rules.enemycorebuildradius = 적 코어 건설 금지구역 범위 : [LIGHT_GRAY] (타일) +rules.respawntime = 플레이어 부활 대기 시간 : [LIGHT_GRAY] (초) rules.wavespacing = 단계 간격 : [LIGHT_GRAY] (초) rules.buildcostmultiplier = 건설 소모 배수 rules.buildspeedmultiplier = 건설 속도 배수 rules.waitForWaveToEnd = 단계가 끝날때까지 기다리는중 -rules.dropzoneradius = 적 소환 구역 반경 : [LIGHT_GRAY] (타일) +rules.dropzoneradius = 소환 충격파 범위 : [LIGHT_GRAY] (타일) rules.respawns = 단계당 최대 플레이어 부활 횟수 rules.limitedRespawns = 플레이어 부활 제한 rules.title.waves = 단계 @@ -707,6 +754,10 @@ rules.title.resourcesbuilding = 자원 & 건축 rules.title.player = 플레이어들 rules.title.enemy = 적 rules.title.unit = 유닛 +rules.title.experimental = 실험적인 기능 +rules.lighting = 전장의 안개 활성화 +rules.ambientlight = 안개 색 + content.item.name = 아이템 content.liquid.name = 액체 content.unit.name = 유닛 @@ -721,7 +772,7 @@ item.thorium.name = 토륨 item.silicon.name = 실리콘 item.plastanium.name = 플라스터늄 item.phase-fabric.name = 메타 -item.surge-alloy.name = 서지 합금 +item.surge-alloy.name = 설금 item.spore-pod.name = 포자 포드 item.sand.name = 모래 item.blast-compound.name = 폭발물 @@ -768,6 +819,7 @@ mech.buildspeed = [LIGHT_GRAY]건설 속도 : {0}% liquid.heatcapacity = [LIGHT_GRAY]발열 용량 : {0} liquid.viscosity = [LIGHT_GRAY]점도 : {0} liquid.temperature = [LIGHT_GRAY]온도 : {0} + block.sand-boulder.name = 사암 block.grass.name = 잔디 block.salt.name = 소금 @@ -866,6 +918,8 @@ block.distributor.name = 대형 분배기 block.sorter.name = 필터 block.inverted-sorter.name = 반전 필터 block.message.name = 메모 블럭 +block.illuminator.name = 조명 +block.illuminator.description = 작고, 간단한 조명입니다. 색을 변경할 수 있으며 가동하기 위해서 전력이 필요합니다. block.overflow-gate.name = 포화 필터 block.silicon-smelter.name = 실리콘 제련소 block.phase-weaver.name = 메타 합성기 @@ -879,6 +933,7 @@ block.coal-centrifuge.name = 석탄 원심분리기 block.power-node.name = 전력 노드 block.power-node-large.name = 대형 전력 노드 block.surge-tower.name = 설금 타워 +block.diode.name = 배터리 다이오드 block.battery.name = 배터리 block.battery-large.name = 대형 배터리 block.combustion-generator.name = 화력 발전기 @@ -893,8 +948,8 @@ block.cultivator.name = 온실 block.dart-mech-pad.name = 알파 기체 패드 block.delta-mech-pad.name = 델타 기체 패드 block.javelin-ship-pad.name = 재블린 비행선 패드 -block.trident-ship-pad.name = 삼지창 비행선 패드 -block.glaive-ship-pad.name = 글레브 비행선 패드 +block.trident-ship-pad.name = 트라이던트 폭격기 패드 +block.glaive-ship-pad.name = 글레이브 전투기 패드 block.omega-mech-pad.name = 오메가 기체 패드 block.tau-mech-pad.name = 타우 기체 패드 block.conduit.name = 파이프 @@ -930,7 +985,8 @@ block.titan-factory.name = 타이탄 공장 block.fortress-factory.name = 포트리스 공장 block.revenant-factory.name = 망령 전함 공장 block.repair-point.name = 수리 지점 -block.pulse-conduit.name = 퓨즈 파이프 +block.pulse-conduit.name = 펄스 파이프 +block.plated-conduit.name = 도금된 block.phase-conduit.name = 메타 파이프 block.liquid-router.name = 액체 분배기 block.liquid-tank.name = 물탱크 @@ -957,8 +1013,8 @@ block.rtg-generator.name = RTG 발전기 block.spectre.name = 스펙터 block.meltdown.name = 멜트다운 block.container.name = 컨테이너 -block.launch-pad.name = 발사대 -block.launch-pad-large.name = 큰 출격 패드 +block.launch-pad.name = 자원 출격 패드 +block.launch-pad-large.name = 대형 자원 출격 패드 team.blue.name = 파랑색 팀 team.crux.name = 빨강색 팀 team.sharded.name = 주황색 팀 @@ -976,10 +1032,10 @@ unit.ghoul.name = 구울 폭격기 unit.wraith.name = 유령 전투기 unit.fortress.name = 포트리스 unit.revenant.name = 망령 전함 -unit.eruptor.name = 이어럽터 -unit.chaos-array.name = 혼돈의 군대 +unit.eruptor.name = 이럽터 +unit.chaos-array.name = 혼돈 군주 unit.eradicator.name = 파괴자 -unit.lich.name = 사자왕 +unit.lich.name = 시체 군주 unit.reaper.name = 사신 tutorial.next = [lightgray]< 이 곳을 터치해 진행하세요. > tutorial.intro = [scarlet]Mindustry 튜토리얼[]을 시작하겠습니다.\n [WASD] 키를 눌러 이동할 수 있습니다.\n[accent]Ctrl 키를 누르고 마우스 휠을 돌려 확대 또는 축소가 가능합니다.\n[accent]주황색의 광맥[]을 눌러 [accent]구리[]를 채광하세요.\n구리를 채광한 후에는 코어 근처로 이동한 뒤, 당신의 기체에서 코어로 드래그해 구리를 코어에 넣으세요. 코어 근처에서 채광하면 자동으로 옮겨집니다.\n\n임무 : 구리 채광({0}/{1}) @@ -1002,6 +1058,7 @@ tutorial.deposit = 자원을 다시 블록에 넣을 수도 있습니다.\n\n[ac tutorial.waves = [LIGHT_GRAY]적[]이 접근합니다.\n당신의 기체는 적을 클릭하여 공격할 수 있습니다. 또한, 구리를 더 캐내고 포탑을 더 지어서 방어를 강화하세요.\n\n[accent]2단계 동안 코어를 보호하세요.[] tutorial.waves.mobile = [LIGHT_GRAY]적[]이 접근합니다.\n당신의 기체는 적을 자동조준하지만, 원하는 적을 클릭하여 공격하고 싶은 대상을 바꿀 수 있습니다.\n구리를 더 캐내고 포탑을 더 지어서 방어를 강화하세요.\n\n[accent]2단계동안 코어를 방어하세요.[] tutorial.launch = 특정 단계에 도달하면 [accent]출격[]이 가능합니다.\n[accent]출격[]을 하게되면 해당 지역의 코어에 들어있는 자원들을 캠페인의 자원 창고로 보내지만, 해당 지역의 [accent]모든 것들[]은 날라가게 되니 주의하세요. + item.copper.description = 모든 종류의 블록에서 광범위하게 사용되는 자원입니다. item.lead.description = 쉽게 구할 수 있으며, 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다. item.metaglass.description = 초강력 유리 화합물. 액체 분배 및 저장에 광범위하게 사용됩니다.\n\n[royal]액체를 활용하기 위한 필수품입니다. @@ -1088,7 +1145,7 @@ block.junction.description = 2개의 컨베이어 벨트를 교차시키는 다 block.bridge-conveyor.description = 자원 수송 블록.\n지형이나 건물을 넘어 최대 3개 타일을 건너뛰고 자원을 운송할 수 있습니다. block.phase-conveyor.description = 고급 자원 수송 블록.\n지형이나 건물을 넘어 최대 11개 타일을 건너뛰고 자원을 운송할 수 있습니다. 전기를 사용하고, 기본 터널 컨베이어보다 빠릅니다. block.sorter.description = 자원을 넣어서 필터에 설정된 자원일 경우 바로 앞으로 통과하며, 그렇지 않을 경우 옆으로 이동시킵니다. -block.inverted-sorter.description = Processes items like a standard sorter, but outputs selected items to the sides instead. +block.inverted-sorter.description = 필터와 비슷하지만, 대신에 반전 필터는 설정된 자원을 필터의 양 옆으로 보냅니다. block.router.description = 한 방향에서 자원을 넣을 시 최대 3개의 다른 방향으로 균등하게 내보냅니다. 자원을 한 곳에서 여러 방향으로 분배하는 데 유용합니다. block.distributor.description = 자원을 최대 7개의 다른 방향으로 균등하게 분베하는 고급 분배기. block.overflow-gate.description = 평소에는 자원의 들어온 방향으로 자원을 통과시키지만, 정면이 자원으로 꽉 차거나 다른 사유로 막힐 시 옆으로 자원을 내보냅니다. @@ -1098,6 +1155,7 @@ block.rotary-pump.description = 전기를 사용해 빠른 속도로 액체를 block.thermal-pump.description = 가장 강력한 펌프. block.conduit.description = 기본 파이프\n액체를 배치된 방향으로 느리게 운송합니다. block.pulse-conduit.description = 고급 파이프\n기본 파이프보다 액체 운송 속도가 빠릅니다. +block.plated-conduit.description = 펄스 파이프와 같은 속도로 액체를 운송시키지만, 체력이 더 많습니다. 양 옆으로는 파이프 의외의 대상에서 액체를 받지 않습니다. \n파이프 끝 부분이 블럭에 연결되지 않고 노출되었을 때 누수되는 액체의 양이 더 적습니다. block.liquid-router.description = 액체를 다른 방향으로 분배할 수 있게 하는 블럭입니다. block.liquid-tank.description = 액체를 저장할 수 있는 물탱크 입니다. block.liquid-junction.description = 교차기와 같은 기능을 하나 자원 대신에 액체를 교차시킵니다. @@ -1106,6 +1164,7 @@ block.phase-conduit.description = 고급 액체 수송블록\n전기를 사용 block.power-node.description = 전기을 연결된 대상과 연동시킵니다.\n최대 20개의 대상을 연결할 수 있습니다. 노드는 붙어있는 블록으로부터 전기가 연동됩니다. block.power-node-large.description = 전기를 연결된 대상과 연동시킵니다.\n최대 30개의 대상을 연결시킬 수 있고, 범위도 더 넓습니다. block.surge-tower.description = 전기를 연결된 대상과 연동시킵니다.\n2개의 대상만 연결시킬 수 있지만 대신에 범위가 매우 넓습니다. +block.diode.description = 이 블럭을 배터리와 배터리 사이에 놓아 연결할경우 전력은 화살표 방향으로만 이동할 수 있습니다. 화살표의 뒤에 있는 배터리의 전력량이 앞에 있는 배터리보다 많을 경우에만 이동시킵니다. block.battery.description = 전력 생산량에 여유가 있을경우, 생산된 잉여 전력을 여기에 저장합니다.\n\n[ROYAL]이것을 이용해 한순간에 많은 전력을 사용하는 포탑들을 보조가능합니다. block.battery-large.description = 일반 배터리보다 훨씬 많은 량의 전력을 저장합니다.\n\n[ROYAL]배터리 9개를 설치하는 것보다 효율이 좋습니다. block.combustion-generator.description = 인화성 물질을 태워 소량의 전력을 생산합니다. diff --git a/core/assets/bundles/bundle_nl_BE.properties b/core/assets/bundles/bundle_nl_BE.properties index f14e68b7c7..1756cd5135 100644 --- a/core/assets/bundles/bundle_nl_BE.properties +++ b/core/assets/bundles/bundle_nl_BE.properties @@ -17,29 +17,29 @@ screenshot.invalid = Kaart te groot, mogelijks te weinig geheugen voor een scree gameover = Game Over gameover.pvp = Het[accent] {0}[] team heeft gewonnen! highscore = [accent]Nieuw record! -copied = Copied. -load.sound = Sounds -load.map = Maps +copied = Gekopieerd. +load.sound = Geluiden +load.map = Kaarten load.image = Images load.content = Content load.system = System load.mod = Mods -schematic = Schematic -schematic.add = Save Schematic... -schematics = Schematics -schematic.replace = A schematic by that name already exists. Replace it? -schematic.import = Import Schematic... -schematic.exportfile = Export File -schematic.importfile = Import File +schematic = Blauwdruk +schematic.add = Blauwdruk Opslaan... +schematics = Blauwdrukken +schematic.replace = Er bestaat al een blaudruk met deze naam. Vervangen? +schematic.import = Importeer Blauwdruk... +schematic.exportfile = Exporteer Bestand +schematic.importfile = Exporteer Bestand schematic.browseworkshop = Browse Workshop -schematic.copy = Copy to Clipboard -schematic.copy.import = Import from Clipboard -schematic.shareworkshop = Share on Workshop +schematic.copy = Kopieer naar Klembord +schematic.copy.import = Importeer vanaf Klembord +schematic.shareworkshop = Deel op Workshop schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Flip Schematic -schematic.saved = Schematic saved. +schematic.saved = Blauwdruk opgeslagen. schematic.delete.confirm = This schematic will be utterly eradicated. -schematic.rename = Rename Schematic -schematic.info = {0}x{1}, {2} blocks +schematic.rename = Blauwdruk Hernoemen +schematic.info = {0}x{1}, {2} blokken stat.wave = Je overleefde tot aanvalsgolf: [accent]{0}[]. stat.enemiesDestroyed = Vijanden vernietigd:[accent] {0} stat.built = Gebouwen gebouwd:[accent] {0} @@ -48,7 +48,7 @@ stat.deconstructed = Gebouwen afgebroken:[accent] {0} stat.delivered = Gronstoffen meegenomen: stat.rank = Eindresultaat: [accent]{0} launcheditems = [accent]Meegenomen grondstoffen -launchinfo = [unlaunched][[LAUNCH] your core to obtain the items indicated in blue. +launchinfo = [unlaunched][[LAUNCH] je kern om de met blauw aangeduide voorwerpen te verkrijgen. map.delete = Ben je zeker dat je de kaart "[accent]{0}[]" wilt verwijderen? level.highscore = Beste score: [accent]{0} level.select = Selecteer level @@ -57,14 +57,14 @@ showagain = Toon dit volgende keer niet meer. coreattack = < Kern wordt aangevallen! > nearpoint = [[ [scarlet]VERLAAT dit gebied onmiddelijk[] ]\nDirecte vernietiging... database = Kern Database -savegame = opslaan -loadgame = openen +savegame = Opslaan +loadgame = Openen joingame = Multiplayer customgame = Aangepaste versie newgame = Nieuw spel none = minimap = Kaartje -position = Position +position = Positie close = Sluit website = Website quit = Verlaat @@ -74,40 +74,40 @@ maps.browse = Browse Maps continue = Ga verder maps.none = [LIGHT_GRAY]Geen kaarten gevonden! invalid = Invalid -preparingconfig = Preparing Config -preparingcontent = Preparing Content -uploadingcontent = Uploading Content -uploadingpreviewfile = Uploading Preview File -committingchanges = Comitting Changes -done = Done -feature.unsupported = Your device does not support this feature. +preparingconfig = Config Voorbereiden +preparingcontent = Content Voorbereiden +uploadingcontent = Content Uploaden +uploadingpreviewfile = Voorbeeldbestand Uploaden +committingchanges = Veranderingen Toepassen +done = Klaar +feature.unsupported = Uw apparaat ondersteunt deze functie niet. mods.alphainfo = Keep in mind that mods are in alpha, and[scarlet] may be very buggy[].\nReport any issues you find to the Mindustry GitHub or Discord. mods.alpha = [accent](Alpha) mods = Mods -mods.none = [LIGHT_GRAY]No mods found! -mods.guide = Modding Guide -mods.report = Report Bug +mods.none = [LIGHT_GRAY]Geen mods gevonden! +mods.guide = Handleiding tot Modding +mods.report = Bug Rapporteren mods.openfolder = Open Mod Folder -mod.enabled = [lightgray]Enabled -mod.disabled = [scarlet]Disabled -mod.disable = Disable -mod.delete.error = Unable to delete mod. File may be in use. +mod.enabled = [lightgray]Ingeschakeld +mod.disabled = [scarlet]Uitgeschakeld +mod.disable = Schakel uit +mod.delete.error = Kan mod niet verwijderen. Bestand is mogelijk in gebruik. mod.missingdependencies = [scarlet]Missing dependencies: {0} mod.nowdisabled = [scarlet]Mod '{0}' is missing dependencies:[accent] {1}\n[lightgray]These mods need to be downloaded first.\nThis mod will be automatically disabled. mod.enable = Enable mod.requiresrestart = The game will now close to apply the mod changes. -mod.reloadrequired = [scarlet]Reload Required -mod.import = Import Mod -mod.import.github = Import GitHub Mod -mod.remove.confirm = This mod will be deleted. -mod.author = [LIGHT_GRAY]Author:[] {0} -mod.missing = This save contains mods that you have recently updated or no longer have installed. Save corruption may occur. Are you sure you want to load it?\n[lightgray]Mods:\n{0} +mod.reloadrequired = [scarlet]Herladen Vereist +mod.import = Importeer Mod +mod.import.github = Importeer GitHub Mod +mod.remove.confirm = Deze mod zal worden verwijderd. +mod.author = [LIGHT_GRAY]Auteur:[] {0} +mod.missing = Dit opslagbestand bevat mods die zijn geupdate of recentelijk zijn verwijderd. Uw opslagbestand kan beschadigd geraken. Bent u zeker dat u wil verdergaan?\n[lightgray]Mods:\n{0} mod.preview.missing = Before publishing this mod in the workshop, you must add an image preview.\nPlace an image named[accent] preview.png[] into the mod's folder and try again. mod.folder.missing = Only mods in folder form can be published on the workshop.\nTo convert any mod into a folder, simply unzip its file into a folder and delete the old zip, then restart your game or reload your mods. about.button = Extra info name = Naam: noname = Kies eerst[accent] een naam[]. -filename = Bestands naam: +filename = Bestandsnaam: unlocked = Ontgrendeld! completed = [accent]Voltooid techtree = Technische vooruitgang diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index 95914d3862..7e8ddd3812 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -1,4 +1,4 @@ -credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) +credits.text = Stworzone przez [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[] credits = Zasłużeni contributors = Tłumacze i pomocnicy discord = Odwiedź nasz serwer Discord! @@ -10,6 +10,7 @@ link.dev-builds.description = Niestabilne wersje gry link.trello.description = Oficjalna tablica Trello z planowanym funkcjami link.itch.io.description = Strona itch.io z oficjanymi wersjami do pobrania link.google-play.description = Strona na sklepie Google Play +link.f-droid.description = F-Droid catalogue listing link.wiki.description = Oficjana Wiki Mindustry linkfail = Nie udało się otworzyć linku!\nURL został skopiowany. screenshot = Zapisano zdjęcie w {0} @@ -18,12 +19,14 @@ gameover = Koniec Gry gameover.pvp = Zwyciężyła drużyna [accent]{0}[]! highscore = [YELLOW] Nowy rekord! copied = Copied. + load.sound = Dźwięki load.map = Mapy load.image = Obrazy load.content = Treść load.system = System load.mod = Mody + schematic = Schemat schematic.add = Zapisz schemat... schematics = Schematy @@ -40,6 +43,7 @@ schematic.saved = Schemat zapisany. schematic.delete.confirm = Ten schemat zostanie kompletnie wyeliminowany. schematic.rename = Zmień nazwę schematu schematic.info = {0}x{1}, {2} bloków + stat.wave = Fale powstrzymane:[accent] {0} stat.enemiesDestroyed = Przeciwnicy zniszczeni:[accent] {0} stat.built = Budynki zbudowane:[accent] {0} @@ -47,8 +51,9 @@ stat.destroyed = Budynki zniszczone:[accent] {0} stat.deconstructed = Budynki zrekonstruowane:[accent] {0} stat.delivered = Surowce wystrzelone: stat.rank = Ocena: [accent]{0} + launcheditems = [accent]Wystrzelone przedmioty -launchinfo = [unlaunched][[LAUNCH] rdzeń aby uzyskać przedmioty oznaczone na niebiesko. +launchinfo = [unlaunched][[WYSTRZEL] rdzeń aby uzyskać przedmioty oznaczone na niebiesko. map.delete = Jesteś pewny, że chcesz usunąć "[accent]{0}[]"? level.highscore = Rekord: [accent]{0} level.select = Wybrany poziom @@ -72,8 +77,10 @@ save.quit = Zapisz & Wyjdź maps = Mapy maps.browse = Przeglądaj Mapy continue = Kontynuuj -maps.none = [LIGHT_GRAY]Nie znaleziono żadnych map! +maps.none = [lightgray]Nie znaleziono żadnych map! invalid = Nieprawidłowy +pickcolor = Wybierz kolor + preparingconfig = Przygotowywanie Konfiguracji preparingcontent = Przygotowywanie Zawartości uploadingcontent = Przesyłanie Zawartości @@ -81,6 +88,7 @@ uploadingpreviewfile = Przesyłanie Pliku Podglądu committingchanges = Zatwierdzanie Zmian done = Gotowe feature.unsupported = Twoje urządzenie nie wspiera tej funkcji. + mods.alphainfo = Pamiętaj, że mody są wersji alpha, i[scarlet] mogą być pełne błędów[].\nZgłaszaj wszystkie znalezione problemy na Mindustry GitHub lub Discord. mods.alpha = [scarlet](Alpha) mods = Mody @@ -104,16 +112,17 @@ mod.author = [LIGHT_GRAY]Autor:[] {0} mod.missing = Ten zapis zawiera mody, które zostały niedawno zaktualizowane, bądź nie są już zainstalowane. Zapis może zostać uszkodzony. Czy jesteś pewien, że chcesz go załadować?\n[lightgray]Mody:\n{0} mod.preview.missing = Przed opublikowaniem tego moda na Warsztacie musisz dodać zdjęcie podglądowe.\nDodaj zdjęcie o nazwie[accent] preview.png[] do folderu moda i spróbuj jeszcze raz. mod.folder.missing = Jedynie mody w formie folderów mogą się znaleźć na Warsztacie.\nBy zamienić moda w folder, wyciągnij go z archiwum, umieść w folderze i usuń archiwum. Później uruchom ponownie grę bądź załaduj ponownie mody. + about.button = O Grze name = Nazwa: -noname = Najpierw wybierz [accent]nazwę gracza[] +noname = Najpierw wybierz[accent] nazwę gracza[] filename = Nazwa Pliku: -unlocked = Odblokowano nowy blok! +unlocked = Odblokowano nową zawartość! completed = [accent]Ukończony techtree = Drzewo Technologiczne -research.list = [LIGHT_GRAY]Badania: +research.list = [lightgray]Badania: research = Badaj -researched = [LIGHT_GRAY]{0} zbadane. +researched = [lightgray]{0} zbadane. players = {0} graczy online players.single = {0} gracz online server.closing = [accent] Zamykanie serwera... @@ -129,23 +138,23 @@ server.kicked.playerLimit = Serwer pełny. Poczekaj na wolne miejsce. server.kicked.recentKick = Zostałeś niedawno wyrzucony.\nPoczekaj chwilę przed ponownym połączniem. server.kicked.nameInUse = Ta nazwa jest już zajęta na tym serwerze. server.kicked.nameEmpty = Wybrana przez Ciebie nazwa jest nieprawidłowa. -server.kicked.idInUse = Jesteś już na serwerze! Używanie tego samego konta na 2 urządzeniach jest zabronione. +server.kicked.idInUse = Jesteś już na serwerze! Łączenie się z dwóch kont nie jest dozwolone. server.kicked.customClient = Ten serwer nie wspomaga wersji deweloperskich. Pobierz oficjalną wersję. server.kicked.gameover = Koniec gry! server.versions = Twoja wersja gry:[accent] {0}[]\nWersja gry serwera:[accent] {1}[] -host.info = Przycisk [accent]host[] hostuje serwer na porcie [scarlet]6567[] i [scarlet]6568.[]\nKażdy w tej samej sieci [LIGHT_GRAY]wifi lub hotspocie[] powinien zobaczyć twój serwer.\n\nJeśli chcesz, aby każdy z twoim IP mógł dołączyć, musisz wykonać [accent]przekierowywanie portów[].\n\n[LIGHT_GRAY]Notka:Jeśli ktokolwiek ma problem z dołączeniem do gry, upewnij się, że udostępniłeś Mindustry dostęp do sieci. -join.info = Tutaj możesz wpisać [accent]adres IP serwera[], aby dołączyć lub wyszukać [accent]serwerów w lokalnej sieci[], do których możesz dołączyć .\nGra wieloosobowa na LAN i WAN jest wspomagana.\n\n[LIGHT_GRAY]Notka: Nie ma automatycznej listy wszystkich serwerów; jeśli chcesz dołączyć przez IP, musisz zapytać hosta o IP. +host.info = Przycisk [accent]host[] hostuje serwer na porcie [scarlet]6567[]. \nKażdy w tej samej sieci [lightgray]wifi lub hotspocie[] powinien zobaczyć twój serwer.\n\nJeśli chcesz, aby każdy z twoim IP mógł dołączyć, musisz wykonać [accent]przekierowywanie portów[].\n\n[lightgray]Notka: Jeśli ktokolwiek ma problem z dołączeniem do gry lokalnej, upewnij się, że udostępniłeś Mindustry dostęp do sieci w ustawieniach zapory (firewall). Zauważ, że niektóre sieci publiczne mogą nie zezwalać na wykrycie serwerów. +join.info = Tutaj możesz wpisać [accent]adres IP serwera[], aby dołączyć lub wyszukać [accent]serwerów w lokalnej sieci[], do których możesz dołączyć .\nGra wieloosobowa na LAN i WAN jest wspomagana.\n\n[lightgray]Notka: Nie ma automatycznej listy wszystkich serwerów; jeśli chcesz dołączyć przez IP, musisz zapytać hosta o IP. hostserver = Stwórz Serwer invitefriends = Zaproś Znajomych hostserver.mobile = Hostuj\nGrę host = Hostuj -hosting = [accent] Otwieranie serwera... +hosting = [accent]Otwieranie serwera... hosts.refresh = Odśwież hosts.discovering = Wyszukiwanie gier w sieci LAN hosts.discovering.any = Wyszukiwanie gier server.refreshing = Odświeżanie serwera -hosts.none = [lightgray] Brak serwerów w sieci LAN! -host.invalid = [scarlet] Nie można połączyć się z hostem. +hosts.none = [lightgray]Brak serwerów w sieci LAN! +host.invalid = [scarlet]Nie można połączyć się z hostem. trace = Zlokalizuj Gracza trace.playername = Nazwa gracza: [accent]{0} trace.ip = IP: [accent]{0} @@ -162,8 +171,8 @@ server.delete = Czy na pewno chcesz usunąć ten serwer? server.edit = Edytuj Serwer server.outdated = [crimson]Przestarzały serwer![] server.outdated.client = [crimson]Przestarzały klient![] -server.version = [lightgray]Wersja: {0} -server.custombuild = [yellow]Zmodowany klient +server.version = [gray]Wersja: {0} +server.custombuild = [accent]Zmodowany klient confirmban = Jesteś pewny, że chcesz zbanować tego gracza? confirmkick = Jesteś pewny, że chcesz wyrzucić tego gracza? confirmvotekick = Jesteś pewny, że chcesz głosować za wyrzuceniem tego gracza? @@ -188,14 +197,14 @@ save.new = Nowy zapis save.overwrite = Czy na pewno chcesz nadpisać zapis gry? overwrite = Nadpisz save.none = Nie znaleziono zapisów gry! -saveload = [accent]Zapisywanie... +saveload = Zapisywanie... savefail = Nie udało się zapisać gry! save.delete.confirm = Czy na pewno chcesz usunąć ten zapis gry? save.delete = Usuń save.export = Eksportuj save.import.invalid = [accent]Zapis gry jest niepoprawny! -save.import.fail = [crimson]Nie udało się zaimportować zapisu: [accent] {0} -save.export.fail = [crimson]Nie można wyeksportować zapisu: [accent] {0} +save.import.fail = [crimson]Nie udało się zaimportować zapisu: [accent]{0} +save.export.fail = [crimson]Nie można wyeksportować zapisu: [accent]{0} save.import = Importuj Zapis save.newslot = Zapisz nazwę: save.rename = Zmień Nazwę @@ -203,7 +212,7 @@ save.rename.text = Nowa nazwa: selectslot = Wybierz zapis. slot = [accent]Slot {0} editmessage = Edytuj Wiadomość -save.corrupted = [accent]Zapis gry jest uszkodzony lub nieprawidłowy! Jeżeli aktualizowałeś grę, najprawdopodobniej jest to zmiana w formacie zapisu i [scarlet]nie jest[] to błąd. +save.corrupted = Zapis gry jest uszkodzony lub nieprawidłowy! empty = on = Włączone off = Wyłączone @@ -231,11 +240,11 @@ data.exported = Dane wyeksportowane. data.invalid = Nieprawidłowe dane gry. data.import.confirm = Zaimportowanie zewnętrznych danych usunie[scarlet] wszystkie[] obecne dane gry.\n[accent]Nie można tego cofnąć![]\n\nGdy dane zostaną zimportowane, gra automatycznie się wyłączy. classic.export = Eksportuj Dane Wersji Klasycznej -classic.export.text = [accent]Mindustry[] otrzymało ostatnio ważną aktualizację.\nClassic (v3.5 build 40) zapis albo mapa zostały wykryte. Czy chciałbyś eksportować te zapisy do katalogu domowego swojego telefonu, do użycia w aplikacji Mindustry Classic? +classic.export.text = [accent]Mindustry[] otrzymało ostatnio ważną aktualizację.\nWykryto zapis lub mapę z wersji classic (v3.5 build 40) - czy chciałbyś eksportować te zapisy do katalogu domowego swojego telefonu, do użycia w aplikacji Mindustry Classic? quit.confirm = Czy na pewno chcesz wyjść? -quit.confirm.tutorial = Czy jesteś pewien tego co robisz?\nSamouczek może zostać powtórzony w[accent] Opcje->Gra->Powtórz samouczek.[] +quit.confirm.tutorial = Czy jesteś pewien tego co robisz?\nSamouczek może zostać powtórzony w[accent] Ustawienia->Gra->Ponów samouczek.[] loading = [accent]Ładowanie... -reloading = [accent]Reloading Mods... +reloading = [accent]Przeładowywanie Modów... saving = [accent]Zapisywanie... cancelbuilding = [accent][[{0}][] by wyczyścić plan selectschematic = [accent][[{0}][] by wybrać+skopiować @@ -243,11 +252,11 @@ pausebuilding = [accent][[{0}][] by wtrzymać budowę resumebuilding = [scarlet][[{0}][] by kontynuować budowę wave = [accent]Fala {0} wave.waiting = Fala za {0} -wave.waveInProgress = [LIGHT_GRAY]Fala w trakcie -waiting = [LIGHT_GRAY]Oczekiwanie... +wave.waveInProgress = [lightgray]Fala w trakcie +waiting = [lightgray]Oczekiwanie... waiting.players = Oczekiwanie na graczy... -wave.enemies = Pozostało [LIGHT_GRAY]{0} wrogów -wave.enemy = Pozostał [LIGHT_GRAY]{0} wróg +wave.enemies = Pozostało [lightgray]{0} wrogów +wave.enemy = Pozostał [lightgray]{0} wróg loadimage = Załaduj Obraz saveimage = Zapisz Obraz unknown = Nieznane @@ -255,8 +264,8 @@ custom = Własne builtin = Wbudowane map.delete.confirm = Jesteś pewny, że chcesz usunąć tę mapę? Nie będzie można jej przywrócić. map.random = [accent]Losowa Mapa -map.nospawn = Ta mapa nie zawiera żadnego rdzenia! Dodaj [ROYAL]niebieski[] rdzeń do tej mapy w edytorze. -map.nospawn.pvp = Ta mapa nie ma żadnego rdzenia przeciwnika, aby mogli się zrespić przeciwnicy! Dodaj[SCARLET] inny niż niebieski[] rdzeń do mapy w edytorze. +map.nospawn = Ta mapa nie zawiera żadnego rdzenia! Dodaj [accent]pomarańczowy[] rdzeń do tej mapy w edytorze. +map.nospawn.pvp = Ta mapa nie ma żadnego rdzenia przeciwnika, aby mogli się zrespić przeciwnicy! Dodaj[SCARLET] inny niż pomarańczowy[] rdzeń do mapy w edytorze. map.nospawn.attack = Ta mapa nie ma żadnego rdzenia przeciwnika, aby można było go zaatakować! Dodaj[SCARLET] czerwony[] rdzeń do mapy w edytorze. map.invalid = Błąd podczas ładowania mapy: uszkodzony lub niepoprawny plik mapy. workshop.update = Aktualizuj pozycję @@ -265,12 +274,13 @@ map.publish.confirm = Czy jesteś pewien, że chcesz opublikować tę mapę?\n\n workshop.menu = Wybierz co chcesz zrobić z tą pozycją. workshop.info = Informacja o pozycji changelog = Historia aktualizacji (opcjonalna): -eula = Umowa EULA Steam +eula = Umowa Użytkownika Końcowego (EULA) Steam missing = Ta pozycja została przeniesiona bądź usunięta.\n[lightgray]Pozycja na Warsztacie została automatycznie odłączona. publishing = [accent]Trwa publikowanie... publish.confirm = Czy jesteś pewien, że chcesz to opublikować?\n\n[lightgray]Najpierw upewnij się, że zgadzasz się z umową EULA Warsztatu, w przeciwnym razie twoje pozycje nie będą widoczne! publish.error = Błąd podczas publikowania pozycji: {0} steam.error = Nie udało się zainicjować serwisów Steam.\nBłąd: {0} + editor.brush = Pędzel editor.openin = Otwórz w Edytorze editor.oregen = Generacja Złóż @@ -301,7 +311,7 @@ waves.load = Załaduj Ze Schowka waves.invalid = Nieprawidłowe fale w schowku. waves.copied = Fale zostały skopiowane. waves.none = Brak zdefiniowanych wrogów.\nPamiętaj, że puste układy fal zostaną automatycznie zastąpione układem domyślnym. -editor.default = [LIGHT_GRAY] +editor.default = [lightgray] details = Detale... edit = Edytuj... editor.name = Nazwa: @@ -310,11 +320,11 @@ editor.removeunit = Usuń Jednostkę editor.teams = Drużyny editor.errorload = Błąd podczas ładowania pliku:\n[accent]{0} editor.errorsave = Błąd podczas zapisywania pliku:\n[accent]{0} -editor.errorimage = To obraz, nie mapa. Nie zmieniaj rozszerzenia, spodziewając się, że to coś zmieni.\n\nJeśli chcesz zaimportować starszą mapę, użyj przycisku „importuj starszą mapę” w edytorze. +editor.errorimage = To obraz, nie mapa.\n\nJeśli chcesz zaimportować mapę z wersji 3.5/build 40, użyj przycisku "Importuj starszą mapę" w edytorze. editor.errorlegacy = Ta mapa jest zbyt stara i używa starszego formatu mapy, który nie jest już obsługiwany. editor.errornot = To nie jest plik mapy. editor.errorheader = Ten plik mapy jest nieprawidłowy lub uszkodzony. -editor.errorname = Mapa nie zawiera nazwy. +editor.errorname = Mapa nie zawiera nazwy. Czy próbujesz załadować zapis gry? editor.update = Aktualizuj editor.randomize = Losuj editor.apply = Zastosuj @@ -347,6 +357,7 @@ editor.overwrite = [accent]Uwaga!\nSpowoduje to nadpisanie istniejącej mapy. editor.overwrite.confirm = [scarlet]Uwaga![] Mapa o tej nazwie już istnieje. Jesteś pewny, że chcesz ją nadpisać? editor.exists = Mapa o tej nazwie już istnieje. editor.selectmap = Wybierz mapę do załadowania: + toolmode.replace = Zastąp toolmode.replace.description = Rysuje tylko na stałych blokach. toolmode.replaceall = Zastąp Wszystko @@ -361,7 +372,8 @@ toolmode.fillteams = Wypełnij Drużyny toolmode.fillteams.description = Wypełniaj drużyny zamiast bloków. toolmode.drawteams = Rysuj Drużyny toolmode.drawteams.description = Rysuj drużyny zamiast bloków. -filters.empty = [LIGHT_GRAY]Brak filtrów! Dodaj jeden za pomocą przycisku poniżej. + +filters.empty = [lightgray]Brak filtrów! Dodaj jeden za pomocą przycisku poniżej. filter.distort = Zniekształcanie filter.noise = Szum filter.median = Mediana @@ -391,7 +403,8 @@ filter.option.ore = Ruda filter.option.floor2 = Druga Podłoga filter.option.threshold2 = Drugi Próg filter.option.radius = Zasięg -filter.option.percentile = Percentyl +filter.option.percentile = Procent + width = Szerokość: height = Wysokość: menu = Menu @@ -401,52 +414,56 @@ load = Wczytaj save = Zapisz fps = FPS: {0} ping = Ping: {0}ms + language.restart = Uruchom grę ponownie, aby ustawiony język zaczął funkcjonować. settings = Ustawienia tutorial = Poradnik tutorial.retake = Ponów Samouczek editor = Edytor mapeditor = Edytor Map + abandon = Opuść abandon.text = Ta strefa i wszystkie jej surowce będą przejęte przez przeciwników. locked = Zablokowane -complete = [LIGHT_GRAY]Ukończone: +complete = [lightgray]Ukończone: requirement.wave = Osiągnij falę {0} w {1} requirement.core = Zniszcz Rdzeń wroga w {0} requirement.unlock = Odblokuj {0} -resume = Kontynuuj Strefę:\n[LIGHT_GRAY]{0} -bestwave = [LIGHT_GRAY]Najwyższa fala: {0} +resume = Kontynuuj Strefę:\n[lightgray]{0} +bestwave = [lightgray]Najwyższa fala: {0} launch = < WYSTRZEL > launch.title = Wystrzelenie Udane -launch.next = [LIGHT_GRAY]Następna okazja przy fali {0} +launch.next = [lightgray]Następna okazja przy fali {0} launch.unable2 = [scarlet]WYSTZRZELENIE niedostępne.[] launch.confirm = Spowoduje to wystrzelenie wszystkich surowców w rdzeniu.\nNie będziesz mógł wrócić do tej bazy. -launch.skip.confirm = Jeśli teraz przejdziesz do kolejnej fali, Nie biędziesz miał możliwości wystrzelenia do czasu pokonania dalszych fal. +launch.skip.confirm = Jeśli teraz przejdziesz do kolejnej fali, nie biędziesz miał możliwości wystrzelenia do czasu pokonania dalszych fal. uncover = Odkryj configure = Skonfiguruj Ładunek bannedblocks = Zabronione bloki addall = Dodaj wszystkie -configure.locked = [LIGHT_GRAY]Dotrzyj do fali {0}\nAby skonfigurować ładunek. +configure.locked = [lightgray]Dotrzyj do fali {0},\naby skonfigurować ładunek. configure.invalid = Ilość musi być liczbą pomiędzy 0 a {0}. -zone.unlocked = [LIGHT_GRAY]Strefa {0} odblokowana. +zone.unlocked = [lightgray]Strefa {0} odblokowana. zone.requirement.complete = Fala {0} osiągnięta:\n{1} Wymagania strefy zostały spełnione. zone.config.unlocked = Ładunek odblokowany:[lightgray]\n{0} -zone.resources = Wykryte Zasoby: +zone.resources = [lightgray]Wykryte Zasoby: zone.objective = [lightgray]Cel: [accent]{0} zone.objective.survival = Przeżyj zone.objective.attack = Zniszcz Rdzeń Wroga add = Dodaj... boss.health = Zdrowie Bossa + connectfail = [crimson]Nie można połączyć się z serwerem:\n\n[accent]{0} error.unreachable = Serwer niedostępny.\nCzy adres jest wpisany poprawnie? error.invalidaddress = Niepoprawny adres. -error.timedout = Przekroczono limit czasu!/nUpewnij się, że host ma ustawione przekierowanie portu oraz, czy adres jest poprawny! +error.timedout = Przekroczono limit czasu!/nUpewnij się, że host ma ustawione przekierowanie portu oraz poprawność wpisanego adresu! error.mismatch = Błąd pakietu:\nprawdopodobne niedopasowanie klienta/serwera.\nUpewnij się, że ty i host macie najnowszą wersję Mindustry! error.alreadyconnected = Jesteś już połączony. error.mapnotfound = Plik mapy nie został znaleziony! error.io = Błąd siecowy I/O. error.any = Nieznany błąd sieci. error.bloom = Nie udało się załadować bloom.\nTwoje urządzenie może nie wspierać tej funkcji. + zone.groundZero.name = Wybuch Lądowy zone.desertWastes.name = Pustynne Pustkowia zone.craters.name = Kratery @@ -461,6 +478,7 @@ zone.saltFlats.name = Solne Równiny zone.impact0078.name = Uderzenie 0078 zone.crags.name = Urwisko zone.fungalPass.name = Grzybowa Przełęcz + zone.groundZero.description = Optymalna lokalizacja, aby rozpocząć jeszcze raz. Niskie zagrożenie. Niewiele zasobów.\nZbierz jak najwięcej miedzi i ołowiu, tyle ile jest możliwe.\nPrzejdź do następnej strefy jak najszybciej. zone.frozenForest.description = Nawet tutaj, bliżej gór, zarodniki rozprzestrzeniły się. Niskie temperatury nie mogą ich zatrzymać na zawsze.\n\nRozpocznij przedsięwzięcie od władzy. Buduj generatory spalinowe. Naucz się korzystać z naprawiaczy. zone.desertWastes.description = Te pustkowia są rozległe, nieprzewidywalne, i znajdują się na nich opuszczone struktury.\nWęgiel jest obecny w tym regionie. Użyj go do produkcji energii, lub do stworzenia grafitu.\n\n[lightgray]Miejsce lądowania nie jest pewne. @@ -472,7 +490,7 @@ zone.overgrowth.description = Obszar ten jest zarośnięty, bliżej źródła za zone.tarFields.description = Obrzeża strefy produkcji ropy, między górami a pustynią. Jeden z niewielu obszarów z rezerwami użytecznej smoły.\nMimo że ta strefa jest opuszczona, w pobliżu znajdują się niebezpieczne siły wroga. Nie lekceważ ich.\n\n[lightgray]Jeśli to możliwe, zbadaj technologię przetwarzania oleju. zone.desolateRift.description = Strefa wyjątkowo niebezpieczna. Obfita w zasoby ale mało miejsca. Wysokie ryzyko zniszczenia. Opuść tę strefe jak najszybciej. Nie daj się zwieść długiemu odstępowi między atakami wroga. zone.nuclearComplex.description = Dawny zakład produkcji i przetwarzania toru, zredukowny do ruin.\n[lightgray]Zbadaj tor i jego zastosowania.\n\nWróg jest tutaj obecny w dużej ilości, nieustannie poszukuje napastników. -zone.fungalPass.description = Przejściowy obszar pomiędzy wysokimi górami a nisko znajdującymi się, ogarniętymi przez zarodniki równinami. Znajduje się tu mała postawiona przez wrogów baza zwiadowcza.\nZniszcz ją.\nUżyj jednostek Nóż i Pełzak. Zniszcz oba rdżenie. +zone.fungalPass.description = Przejściowy obszar pomiędzy wysokimi górami a nisko znajdującymi się, ogarniętymi przez zarodniki równinami. Znajduje się tu mała postawiona przez wrogów baza zwiadowcza.\nZniszcz ją.\nUżyj jednostek Nóż i Pełzak. Zniszcz oba rdzenie. zone.impact0078.description = zone.crags.description = settings.language = Język @@ -497,7 +515,7 @@ error.crashtitle = Wystąpił błąd blocks.input = Wejście blocks.output = Wyjście blocks.booster = Wzmacniacz -block.unknown = [LIGHT_GRAY]??? +block.unknown = [lightgray]??? blocks.powercapacity = Pojemność mocy blocks.powershot = moc/strzał blocks.damage = Obrażenia @@ -509,7 +527,7 @@ blocks.shootrange = Zasięg blocks.size = Rozmiar blocks.liquidcapacity = Pojemność cieczy blocks.powerrange = Zakres mocy -blocks.powerconnections = Max Connections +blocks.powerconnections = Maksymalna ilość połączeń blocks.poweruse = Zużycie prądu blocks.powerdamage = Moc/Zniszczenia blocks.itemcapacity = Pojemność przedmiotów @@ -529,9 +547,10 @@ blocks.inaccuracy = Niedokładność blocks.shots = Strzały blocks.reload = Strzałów/sekundę blocks.ammo = Amunicja + bar.drilltierreq = Wymagane Lepsze Wiertło bar.drillspeed = Prędkość wiertła: {0}/s -bar.pumpspeed = Pump Speed: {0}/s +bar.pumpspeed = Prędkość pompy: {0}/s bar.efficiency = Efektywność: {0}% bar.powerbalance = Moc: {0} bar.powerstored = Zmagazynowano: {0}/{1} @@ -544,6 +563,9 @@ bar.heat = Ciepło bar.power = Prąd bar.progress = Postęp Budowy bar.spawned = Jednostki: {0}/{1} +bar.input = Input +bar.output = Output + bullet.damage = [stat]{0}[lightgray] Obrażenia bullet.splashdamage = [stat]{0}[lightgray] Obrażenia obszarowe ~[stat] {1}[lightgray] kratki bullet.incendiary = [stat]zapalający @@ -555,6 +577,7 @@ bullet.freezing = [stat]zamrażający bullet.tarred = [stat]smolny bullet.multiplier = [stat]{0}[lightgray]x mnożnik amunicji bullet.reload = [stat]{0}[lightgray]x szybkość ataku + unit.blocks = bloki unit.powersecond = jednostek prądu na sekundę unit.liquidsecond = jednostek płynów na sekundę @@ -576,12 +599,13 @@ category.shooting = Strzelanie category.optional = Dodatkowe ulepszenia setting.landscape.name = Zablokuj tryb panoramiczny setting.shadows.name = Cienie -setting.blockreplace.name = Automatic Block Suggestions +setting.blockreplace.name = Automatyczne sugestie bloków setting.linear.name = Filtrowanie Liniowe -setting.hints.name = Hints +setting.hints.name = Podpowiedzi +setting.buildautopause.name = Automatycznie zatrzymaj budowanie setting.animatedwater.name = Animowana woda setting.animatedshields.name = Animowana Tarcza -setting.antialias.name = Antyaliasing[LIGHT_GRAY] (wymaga restartu)[] +setting.antialias.name = Antyaliasing[lightgray] (wymaga restartu)[] setting.indicators.name = Wskaźniki Przyjaciół setting.autotarget.name = Automatyczne Celowanie setting.keyboard.name = Sterowanie - Myszka+Klawiatura @@ -599,18 +623,21 @@ setting.difficulty.insane = Szalony setting.difficulty.name = Poziom trudności setting.screenshake.name = Wstrząsy ekranu setting.effects.name = Wyświetlanie efektów -setting.destroyedblocks.name = Display Destroyed Blocks +setting.destroyedblocks.name = Wyświetl zniszczone bloki setting.conveyorpathfinding.name = Conveyor Placement Pathfinding setting.sensitivity.name = Czułość kontrolera setting.saveinterval.name = Interwał automatycznego zapisywania -setting.seconds = {0} Sekundy +setting.seconds = {0} sekund +setting.blockselecttimeout.name = Block Select Timeout +setting.milliseconds = {0} millisekund setting.fullscreen.name = Pełny ekran -setting.borderlesswindow.name = Bezramkowe okno[LIGHT_GRAY] (może wymagać restartu) -setting.fps.name = Pokazuj FPS +setting.borderlesswindow.name = Bezramkowe okno[lightgray] (może wymagać restartu) +setting.fps.name = Pokazuj FPS oraz ping +setting.blockselectkeys.name = Show Block Select Keys setting.vsync.name = Synchronizacja pionowa -setting.pixelate.name = Pikselacja [LIGHT_GRAY](wyłącza animacje) +setting.pixelate.name = Pikselacja [lightgray](wyłącza animacje) setting.minimap.name = Pokaż Minimapę -setting.position.name = Show Player Position +setting.position.name = Pokazuj położenie gracza setting.musicvol.name = Głośność muzyki setting.ambientvol.name = Głośność otoczenia setting.mutemusic.name = Wycisz muzykę @@ -622,7 +649,7 @@ setting.publichost.name = Widoczność Gry Publicznej setting.chatopacity.name = Przezroczystość czatu setting.lasersopacity.name = Przezroczystość laserów zasilających setting.playerchat.name = Wyświetlaj czat w grze -public.confirm = Czy chcesz ustawić swoją grę jako publiczną?\n[lightgray]Można to później zmienić w Ustawienia->Gra->Widoczność Gry Publicznej. +public.confirm = Czy chcesz ustawić swoją grę jako publiczną?\n[accent]Każdy będzie mógł dołączyć do twojej gry.\n[lightgray]Można to później zmienić w Ustawienia->Gra->Widoczność Gry Publicznej. public.beta = Wersje beta gry nie mogą tworzyć publicznych pokoi. uiscale.reset = Skala interfejsu uległa zmianie.\nNaciśnij "OK" by potwierdzić zmiany.\n[scarlet]Cofanie zmian i wyjście z gry za[accent] {0}[] uiscale.cancel = Anuluj i Wyjdź @@ -635,16 +662,36 @@ category.multiplayer.name = Wielu graczy command.attack = Atakuj command.rally = Zbierz command.retreat = Wycofaj +placement.blockselectkeys = \n[lightgray]Key: [{0}, keybind.clear_building.name = Wyczyść budynek keybind.press = Naciśnij wybrany klawisz... keybind.press.axis = Naciśnij oś lub klawisz... keybind.screenshot.name = Zrzut ekranu mapy +keybind.toggle_power_lines.name = Toggle Power Lines keybind.move_x.name = Poruszanie w poziomie keybind.move_y.name = Poruszanie w pionie +keybind.mouse_move.name = Follow Mouse +keybind.dash.name = Dash keybind.schematic_select.name = Wybierz region keybind.schematic_menu.name = Menu schematów keybind.schematic_flip_x.name = Obróć schemat horyzontalnie keybind.schematic_flip_y.name = Obróć schemat wertykalnie +keybind.category_prev.name = Poprzednia kategoria +keybind.category_next.name = Następna kategoria +keybind.block_select_left.name = Block Select Left +keybind.block_select_right.name = Block Select Right +keybind.block_select_up.name = Block Select Up +keybind.block_select_down.name = Block Select Down +keybind.block_select_01.name = Category/Block Select 1 +keybind.block_select_02.name = Category/Block Select 2 +keybind.block_select_03.name = Category/Block Select 3 +keybind.block_select_04.name = Category/Block Select 4 +keybind.block_select_05.name = Category/Block Select 5 +keybind.block_select_06.name = Category/Block Select 6 +keybind.block_select_07.name = Category/Block Select 7 +keybind.block_select_08.name = Category/Block Select 8 +keybind.block_select_09.name = Category/Block Select 9 +keybind.block_select_10.name = Category/Block Select 10 keybind.fullscreen.name = Przełącz Pełny Ekran keybind.select.name = Zaznacz keybind.diagonal_placement.name = Budowa po skosie @@ -658,7 +705,6 @@ keybind.menu.name = Menu keybind.pause.name = Pauza keybind.pause_building.name = Wstrzymaj/kontynuuj budowę keybind.minimap.name = Minimapa -keybind.dash.name = Przyspieszenie keybind.chat.name = Czat keybind.player_list.name = Lista graczy keybind.console.name = Konsola @@ -672,16 +718,18 @@ keybind.drop_unit.name = Wyrzucanie przedmiot keybind.zoom_minimap.name = Powiększenie mapy mode.help.title = Opis trybów mode.survival.name = Przeżycie -mode.survival.description = Zwykły tryb. Limitowane surowce i fale przeciwników. +mode.survival.description = Zwykły tryb. Limitowane surowce i fale przeciwników.\n[gray]Wymaga spawnów wroga na mapie, aby móc grać na tym trybie. mode.sandbox.name = Piaskownica mode.sandbox.description = Nieskończone surowce i fale bez odliczania. mode.editor.name = Edytor mode.pvp.name = PvP -mode.pvp.description = Walcz przeciwko innym graczom. +mode.pvp.description = Walcz przeciwko innym graczom.\n[gray]Wymaga co najmniej dwóch rdzeniów o róźnych kolorach na mapie, aby móc grać na tym trybie mode.attack.name = Atak -mode.attack.description = Brak fal. Celem jest zniszczenie bazy przeciwnika. +mode.attack.description = Brak fal. Celem jest zniszczenie bazy przeciwnika.\n[gray]Wymaga czerwonego rdzenia na mapie, aby móc grać na tym trybie. mode.custom = Własny tryb + rules.infiniteresources = Nieskończone zasoby +rules.reactorexplosions = Eksplozje reaktorów rules.wavetimer = Zegar fal rules.waves = Fale rules.attack = Tryb ataku @@ -692,13 +740,13 @@ rules.unithealthmultiplier = Mnożnik życia jednostek rules.playerhealthmultiplier = Mnożnik życia gracza rules.playerdamagemultiplier = Mnożnik obrażeń gracza rules.unitdamagemultiplier = Mnożnik obrażeń jednostek -rules.enemycorebuildradius = Zasięg blokady budowy przy rdżeniu wroga:[LIGHT_GRAY] (kratki) -rules.respawntime = Czas odrodzenia:[LIGHT_GRAY] (sek) -rules.wavespacing = Odstępy między falami:[LIGHT_GRAY] (sek) +rules.enemycorebuildradius = Zasięg blokady budowy przy rdzeniu wroga:[lightgray] (kratki) +rules.respawntime = Czas odrodzenia:[lightgray] (sek) +rules.wavespacing = Odstępy między falami:[lightgray] (sek) rules.buildcostmultiplier = Mnożnik kosztów budowania rules.buildspeedmultiplier = Mnożnik prędkości budowania rules.waitForWaveToEnd = Fale czekają na przeciwników -rules.dropzoneradius = Zasięg strefy zrzutu:[LIGHT_GRAY] (kratki) +rules.dropzoneradius = Zasięg strefy zrzutu:[lightgray] (kratki) rules.respawns = Maksymalna ilośc odrodzeń na falę rules.limitedRespawns = Ogranicz Odrodzenia rules.title.waves = Fale @@ -707,6 +755,10 @@ rules.title.resourcesbuilding = Zasoby i Budowanie rules.title.player = Gracze rules.title.enemy = Przeciwnicy rules.title.unit = Jednostki +rules.title.experimental = Eksperymentalne +rules.lighting = Oświetlenie +rules.ambientlight = Światła otoczenia + content.item.name = Przedmioty content.liquid.name = Płyny content.unit.name = Jednostki @@ -753,21 +805,22 @@ mech.trident-ship.name = Trójząb mech.trident-ship.weapon = Wnęka bombowa mech.glaive-ship.name = Glewia mech.glaive-ship.weapon = Zapalający Karabin -item.explosiveness = [LIGHT_GRAY]Wybuchowość: {0} -item.flammability = [LIGHT_GRAY]Palność: {0} -item.radioactivity = [LIGHT_GRAY]Promieniotwórczość: {0} -unit.health = [LIGHT_GRAY]Zdrowie: {0} -unit.speed = [LIGHT_GRAY]Prędkość: {0} -mech.weapon = [LIGHT_GRAY]Broń: {0} -mech.health = [LIGHT_GRAY]Zdrowie: {0} -mech.itemcapacity = [LIGHT_GRAY]Pojemność przedmiotów: {0} -mech.minespeed = [LIGHT_GRAY]Prędkość kopania: {0} -mech.minepower = [LIGHT_GRAY]Moc kopania: {0} -mech.ability = [LIGHT_GRAY]Umiejętność: {0} -mech.buildspeed = [LIGHT_GRAY]Szybkość Budowy: {0}% -liquid.heatcapacity = [LIGHT_GRAY]Wytrzymałość na przegrzewanie: {0} -liquid.viscosity = [LIGHT_GRAY]Lepkość: {0} -liquid.temperature = [LIGHT_GRAY]Temperatura: {0} +item.explosiveness = [lightgray]Wybuchowość: {0} +item.flammability = [lightgray]Palność: {0} +item.radioactivity = [lightgray]Promieniotwórczość: {0} +unit.health = [lightgray]Zdrowie: {0} +unit.speed = [lightgray]Prędkość: {0} +mech.weapon = [lightgray]Broń: {0} +mech.health = [lightgray]Zdrowie: {0} +mech.itemcapacity = [lightgray]Pojemność przedmiotów: {0} +mech.minespeed = [lightgray]Prędkość kopania: {0} +mech.minepower = [lightgray]Moc kopania: {0} +mech.ability = [lightgray]Umiejętność: {0} +mech.buildspeed = [lightgray]Szybkość Budowy: {0}% +liquid.heatcapacity = [lightgray]Wytrzymałość na przegrzewanie: {0} +liquid.viscosity = [lightgray]Lepkość: {0} +liquid.temperature = [lightgray]Temperatura: {0} + block.sand-boulder.name = Piaskowy Głaz block.grass.name = Trawa block.salt.name = Sól @@ -794,7 +847,7 @@ block.thruster.name = Silnik block.kiln.name = Wypalarka block.graphite-press.name = Grafitowa Prasa block.multi-press.name = Multi-Prasa -block.constructing = {0} [LIGHT_GRAY](Budowa) +block.constructing = {0} [lightgray](Budowa) block.spawn.name = Spawn wrogów block.core-shard.name = Rdzeń: Odłamek block.core-foundation.name = Rdzeń: Podstawa @@ -843,8 +896,8 @@ block.copper-wall.name = Miedziana Ściana block.copper-wall-large.name = Duża Miedziana Ściana block.titanium-wall.name = Tytanowa Ściana block.titanium-wall-large.name = Duża Tytanowa Ściana -block.plastanium-wall.name = Plastanium Wall -block.plastanium-wall-large.name = Large Plastanium Wall +block.plastanium-wall.name = Ściana z Plastanu +block.plastanium-wall-large.name = Duża Ściana z Plastanu block.phase-wall.name = Fazowa Ściana block.phase-wall-large.name = Duża Fazowa Ściana block.thorium-wall.name = Torowa Ściana @@ -866,6 +919,8 @@ block.distributor.name = Dystrybutor block.sorter.name = Sortownik block.inverted-sorter.name = Odwrotny Sortownik block.message.name = Wiadomość +block.illuminator.name = Illuminator +block.illuminator.description = Małe, kompaktowe i konfigurowane źródło światła. Wymaga energii do funkcjonowania. block.overflow-gate.name = Brama Przepełnieniowa block.silicon-smelter.name = Huta Krzemu block.phase-weaver.name = Fazowa Fabryka @@ -879,6 +934,7 @@ block.coal-centrifuge.name = Wirówka węglowa block.power-node.name = Węzeł Prądu block.power-node-large.name = Duży Węzeł Prądu block.surge-tower.name = Wieża Energetyczna +block.diode.name = Dioda baterii block.battery.name = Bateria block.battery-large.name = Duża Bateria block.combustion-generator.name = Generator Spalinowy @@ -931,6 +987,7 @@ block.fortress-factory.name = Fabryka Mechów Forteca block.revenant-factory.name = Fabryka Krążowników Zjawa block.repair-point.name = Punkt Napraw block.pulse-conduit.name = Rura Pulsacyjna +block.plated-conduit.name = Opancerzona rura block.phase-conduit.name = Rura Fazowa block.liquid-router.name = Rozdzielacz Płynów block.liquid-tank.name = Zbiornik Płynów @@ -982,8 +1039,8 @@ unit.eradicator.name = Niszczyciel unit.lich.name = Obudzony unit.reaper.name = Żniwiarz tutorial.next = [lightgray] -tutorial.intro = Wszedłeś do[scarlet] Samouczka Mindustry.[]\nZacznij od[accent] wydobycia miedzi[]. Aby to zrobić, dotknij żyły rudy miedzi w pobliżu rdzenia.\n\n[accent]{0}/{1} miedź -tutorial.intro.mobile = You have entered the[scarlet] Mindustry Tutorial.[]\nSwipe the screen to move.\n[accent]Pinch with 2 fingers [] to zoom in and out.\nBegin by[accent] mining copper[]. Move close to it, then tap a copper ore vein near your core to do this.\n\n[accent]{0}/{1} copper +tutorial.intro = Wszedłeś do[scarlet] Samouczka Mindustry.[]\nUżyj [accent][[WASD][], aby poruszyć się.\n[accent]Przytrzymaj [[Ctrl] podczas przewijania[], aby przybliżyć i oddalić widok.\nZacznij od[accent] wydobycia miedzi[]. W tym celu przybliż się, a następnie dotknij żyły rudy miedzi w pobliżu rdzenia.\n\n[accent]{0}/{1} miedź +tutorial.intro.mobile = Wszedłeś do[scarlet] Samouczka Mindustry.[]\nPrzesuń palcem po ekranie, aby poruszyć się.\n[accent]Użyj dwóch palcy[], aby przybliżyć i oddalić widok.\nZacznij od[accent] wydobycia miedzi[]. W tym celu przybliż się, a następnie dotknij żyły rudy miedzi w pobliżu rdzenia.\n\n[accent]{0}/{1} miedź tutorial.drill = Wydobywanie ręczne nie jest efektywne.\n[accent]Wiertła []mogą kopać automatycznie.\nKliknij zakładkę wiertła w prawym dolnym rogu.\nWybierz[accent] wiertło mechaniczne[]. Umieść go na złożu miedzi, klikając.\n[accent]Kliknij prawym przyciskiem myszy[], aby przestać budować. tutorial.drill.mobile = Wydobywanie ręczne jest nieefektywne.\n[accent]Wiertła []mogą kopać automatycznie.\nDotknij zakładkę wiertła w prawym dolnym rogu.\nWybierz[accent] wiertło mechaniczne[].\nUmieść go na złożu miedzi poprzez Stuknięcie, potem wciśnij[accent] ptaszek[] na dole by potwierdzić wybór.\nNaciśnij przycisk[accent] X[] by anulować budowe. tutorial.blockinfo = Każdy blok ma inne statystyki. Każde wiertło może kopać tylko wybrane rudy.\nBy sprawdzić informacje i statystyki bloku,[accent] kliknij przycisk "?" podczas jego wyboru w menu budowy.[]\n\n[accent]Sprawdź teraz statystyki mechanicznego wiertła.[] @@ -1002,12 +1059,13 @@ tutorial.deposit = Włóż przedmioty do bloków poprzez przeciągnięcie z twoj tutorial.waves = [lightgray] Wrogowie[] nadchodzą.\n\nBroń swój rdżeń przez 2 fale.[accent] Kliknij[] by strzelać.\nZbuduj wiecej działek i wierteł. Wydobądź więcej miedzi. tutorial.waves.mobile = [lightgray] Wrogowie[] nadchodzą.\n\nBroń swój rdzeń przez 2 fale. Twój statek będzie automatycznie atakował wrogów.\nZbuduj wiecej działek i wierteł. Wydobądź więcej miedzi. tutorial.launch = Kiedy dotrzesz do określonej fali, masz możliwość[accent] wystrzelenia rdzenia[], pozostawiając struktury obronne za sobą i[accent] otrzymując wszystkie surowce znajdujące się w rdzeniu.[]\nSurowce te mogą potem zostać użyte do odkrywania nowych technologii.\n\n[accent]Naciśnij przycisk Wystrzału. + item.copper.description = Przydatny materiał budowlany. Szeroko używany w prawie każdej konstrukcji. -item.lead.description = Podstawowy matriał. Używany w przesyle przemiotów i płynów. Nie jest on przypadkiem szkodliwy? +item.lead.description = Podstawowy materiał. Używany w przesyle przemiotów i płynów. Nie jest on przypadkiem szkodliwy? item.metaglass.description = Wyjątkowo wytrzymały stop szkła. Szeroko używany w transporcie i przechowywaniu płynów. item.graphite.description = Zmineralizowany węgiel, wykorzystywany do amunicji i izolacji elektrycznej. -item.sand.description = Zwykły materiał używany pospolicie w przepalaniu, stopach i jako topnik. Dostanie piaskiem po oczach nie jest przyjemne. -item.coal.description = Zwykły i łatwo dostępny materiał energetyczny. +item.sand.description = Zwykły materiał używany pospolicie w przepalaniu, stopach i jako topnik. Dostanie piaskiem po oczach nie jest przyjemne. +item.coal.description = Zwykły i łatwo dostępny materiał energetyczny. Używany powszechnie jako paliwo oraz w produkcji surowców. item.titanium.description = Rzadki i bardzo lekki materiał. Używany w bardzo zaawansowanym przewodnictwie, wiertłach i samolotach. Poczuj się jak Tytan! item.thorium.description = Zwarty i radioaktywny materiał używany w strukturach i paliwie nuklearnym. Nie trzymaj go w rękach! item.scrap.description = Pozostałości starych budynków i jednostek. Składa się z małej ilości wszystkiego. @@ -1021,7 +1079,7 @@ item.pyratite.description = Niesamowicie palny związek używany w zbrojeniu. Ni liquid.water.description = Powszechnie używana do schładzania budowli i przetwarzania odpadów. liquid.slag.description = Wiele różnych metali stopionych i zmieszanych razem. Może zostać rozdzielony na jego metale składowe, albo wystrzelony w wrogie jednostki i użyty jako broń. liquid.oil.description = Używany w do produkcji złożonych materiałów. Może zostać przetworzony na węgiel, lub wystrzelony w wrogów przez wieżyczke. -liquid.cryofluid.description = Najefektywniejsza ciecz do schładzania budowli. +liquid.cryofluid.description = Obojętna, niekorozyjna ciecz utworzona z wody i tytanu mech.alpha-mech.description = Standardowy mech. Bazuje na jednostce Nóż, z ulepszonym pancerzem i zdolnością budowania. Zadaje więcej obrażeń niż Strzałka. mech.delta-mech.description = Szybki, lekko opancerzony mech stworzony do ataków typu uderz i uciekaj. Zadaje niewielkie obrażenia strukturom, lecz może bardzo szybko niszczyć spore grupy jednostek wroga przy pomocy jego działek tesli. mech.tau-mech.description = Mech wsparcia. Naprawia budynki drużyny, strzelając w nie. Potrafi wygasić niedalekie pożary i uleczyć bliskich przyjaciół. @@ -1038,7 +1096,7 @@ unit.crawler.description = Jednostka naziemna składająca się z rozebranej ram unit.titan.description = Zaawansowana, opancerzona jednostka naziemna. Atakuje zarówno cele naziemne, jak i powietrzne. Wyposażony w dwa miniaturowe miotacze ognia typu Płomień. unit.fortress.description = Ciężki mech artyleryjski. Wyposażony w dwa zmodyfikowane działa typu gradowego do ataku na dalekie odległości na konstrukcje i jednostki wroga. unit.eruptor.description = Ciężki mech stworzony do niszczenia struktur. Strzela wiązką żużlu w kierunku fortyfikacji wroga, Topiąc je oraz podpalając łatwopalne przedmioty. -unit.wraith.description = Szybka jednostka, stosuje taktyke uderz-uciekaj Namierza jakiekolwiek źródło prądu. +unit.wraith.description = Szybka jednostka, stosuje taktykę uderz-uciekaj. Namierza jakiekolwiek źródło prądu. unit.ghoul.description = Ciężki bombowiec dywanowy. Rozdziera struktury wroga, atakując krytyczną infrastrukturę. unit.revenant.description = Ciężka, unosząca sie platforma z rakietami. block.message.description = Przechowuje wiadomość. Wykorzystywane do komunikacji pomiędzy sojusznikami. @@ -1078,8 +1136,8 @@ block.surge-wall-large.description = Ekstremalnie wytrzymały blok obronny.\nMa block.door.description = Małe drzwi, które można otwierać i zamykać, klikając na nie.\nJeśli są otwarte, wrogowie mogą strzelać i się przemieszczać przez nie. block.door-large.description = Duże drzwi, które można otwierać i zamykać, klikając na nie.\nJeśli są otwarte, wrogowie mogą strzelać i się przemieszczać przez nie.\nObejmuje wiele kratek. block.mender.description = Co jakiś czas naprawia bloki w zasięgu. Utrzymuje struktury obronne w dobrym stanie.\nOpcjonalnie używa silikonu do zwiększenia zasięgu i szybkości naprawy. -block.mend-projector.description = Co jakiś czas naprawia bloki w zasięgu. Lepsza wersja naprawiacza. -block.overdrive-projector.description = Zwiększa szybkość budynków w zasięgu takich jak wiertła czy przenośniki. +block.mend-projector.description = Ulepszona wersja Naprawiacza. Naprawia bloki w jego otoczeniu.\nMoże wykorzystywać włókno fazowe, aby zwiększyć efektywność budowli. +block.overdrive-projector.description = Zwiększa szybkość budynków w zasięgu takich jak wiertła czy przenośniki. Może wykorzystywać włókno fazowe, aby zwiększyć zasięg i efektywność budowli. block.force-projector.description = Wytwarza pole siłowe w kształcie sześciokąta wokół siebie, chroniąc budynki i jednostki wewnątrz od obrażeń zadanych przez pociski. block.shock-mine.description = Zadaje obrażenia jednostkom wroga którzy na nią wejdą. Ledwo widoczne dla wrogów. block.conveyor.description = Podstawowy blok transportowy dla przedmiotów. Automatycznie przesyła przedmioty naprzód do działek oraz maszyn. Można obrócić. @@ -1088,7 +1146,7 @@ block.junction.description = Używany jako most dla dwóch krzyżujących się p block.bridge-conveyor.description = Zaawansowany blok transportujący. Pozwala na przenoszenie przedmiotów nawet do 3 bloków na każdym terenie, przez każdy budynek. block.phase-conveyor.description = Zaawansowany blok transportowy dla przedmiotów. Używa energii do teleportacji przedmiotów do połączonego transportera fazowego na spore odległości. block.sorter.description = Sortuje przedmioty. Jeśli przedmiot pasuje to przechodzi dalej, jeśli nie - to przechodzi na boki. -block.inverted-sorter.description = Processes items like a standard sorter, but outputs selected items to the sides instead. +block.inverted-sorter.description = Sortuje przedmioty jak zwykły sortownik, ale odpowiednie surowce wyciągane są na boki. block.router.description = Akceptuje przedmioty z jednego miejsca i rozdziela je do trzech innych kierunków. Przydatne w rozdzielaniu materiałów z jednego źródła do wielu celów. block.distributor.description = Zaawansowany rozdzielacz, rozdzielający przedmioty do 7 innych kierunków. block.overflow-gate.description = Rozdzielacz, który przerzuca przedmioty, kiedy główna droga jest przepełniona @@ -1098,6 +1156,7 @@ block.rotary-pump.description = Zaawansowana pompa. Pompuje więcej cieczy, ale block.thermal-pump.description = Najlepsza pompa. Trzy razy szybsza od mechanicznej pompy i jedyna, która może wypompować lawę. block.conduit.description = Podstawowy blok do transportowania cieczy. Używany w połączeniu z pompami i innymi rurami. block.pulse-conduit.description = Zaawansowany blok do transportowania cieczy. Transportuje je szybciej i magazynuje więcej niż standardowe rury. +block.plated-conduit.description = Przesyła ciecze z taką samą szybkością co rura tytanowa, ale jest bardziej odporna. Wejściami bocznymi mogą być tylko inne rury.\nWycieka z niej mniej cieczy. block.liquid-router.description = Akceptuje płyny z jednego kierunku i wyprowadza je po równo do trzech innych kierunków. Może również przechowywać pewną ilość płynu. Przydatne do dzielenia płynów z jednego źródła do wielu celów. block.liquid-tank.description = Magazynuje duże ilości cieczy. Użyj go do stworzenia buforu, gdy występuje różne zapotrzebowanie na materiały lub jako zabezpieczenie dla chłodzenia ważnych bloków. block.liquid-junction.description = Działa jak most dla dwóch krzyżujących się rur. Przydatne w sytuacjach, kiedy dwie rury mają różne ciecze do różnych lokacji. @@ -1106,6 +1165,7 @@ block.phase-conduit.description = Zaawansowany blok do przenoszenia cieczy. Uży block.power-node.description = Przesyła moc do połączonych węzłów. Można podłączyć do czterech źródeł zasilania, zlewów lub węzłów. Zasila też bloki które go dotykają. block.power-node-large.description = Posiada większy zasięg niż zwykły węzeł prądu. Można podłączyć do sześciu źródeł zasilania, zlewów lub węzłów. block.surge-tower.description = Węzęł prądu z bardzo dużym zasięgiem, posiadający mniej możliwych podłączeń. +block.diode.description = Battery power can flow through this block in only one direction, but only if the other side has less power stored. block.battery.description = Przechowuje energię przy nadwyżce produkcji oraz dostarcza energię kiedy jest jej brak, dopóki jest w niej miejsce. block.battery-large.description = Przechowuje o wiele wiecej prądu niż standardowa bateria. block.combustion-generator.description = Wytwarza energię poprzez spalanie łatwopalnych materiałów. @@ -1121,14 +1181,14 @@ block.mechanical-drill.description = Tanie wiertło. Kiedy zostanie zbudowane na block.pneumatic-drill.description = Ulepszone wiertło, które jest szybsze i może wykopywać twardsze surowce przy użyciu ciśnienia. block.laser-drill.description = Pozwala kopać jeszcze szybciej poprzez technologię laserową, ale wymaga energii. Zdolne do wydobywania toru. block.blast-drill.description = Najlepsze wiertło. Wymaga dużych ilości energii. -block.water-extractor.description = Wydobywa wodę z ziemi. Użyj go, gdy w pobliżu nie ma jeziora. +block.water-extractor.description = Wydobywa wodę z ziemi. Użyj go, gdy w pobliżu brakuje wody. block.cultivator.description = Uprawia małe skupiska zarodników i umieszcza je w gotowych do dalszego przetwarzania kapsułach. block.oil-extractor.description = Używa bardzo dużych ilości energii do ekstrakcji ropy z piasku. Używaj go w sytuacji kiedy nie ma bezpośredniego źródła ropy w okolicy. block.core-shard.description = Pierwsza wersja rdzenia. Gdy zostaje zniszczony, wszelki kontakt do regionu zostaje utracony. Nie pozwól na to. block.core-foundation.description = Druga wersja rdzenia. Lepiej opancerzony. Przechowuje więcej surowców. block.core-nucleus.description = Trzecia i ostatnia wersja rdzenia. Bardzo dobrze opanczerzony. Przechowuje ogromne ilości surowców. -block.vault.description = Przechowuje duże ilości przedmiotów każdego rodzaju. [LIGHT_GRAY] Ekstraktor[] może zostać użyty do rozładowania magazynu. -block.container.description = Przechowuje małe ilości przedmiotów każdego rodzaju. [LIGHT_GRAY] ekstraktor[] może zostać użyty do rozładowania kontenera. +block.vault.description = Przechowuje duże ilości przedmiotów każdego rodzaju. Użyj ekstraktora, aby rozładować magazyn. +block.container.description = Przechowuje małe ilości przedmiotów każdego rodzaju. Użyj ekstraktora, aby rozładować kontener. block.unloader.description = Wyciąga przedmioty z kontenera, magazynu oraz rdżenia na przenośniki lub bezpośrednio na przyległe bloki. Typ przedmiotu jaki zostanie wyciągniety może zostać zmieniony poprzez kliknięcie. block.launch-pad.description = Wysyła pakiety przedmiotów bez potrzeby wystrzeliwania rdżenia. Niedokończona. block.launch-pad-large.description = Ulepszona wersja wyrzutni. Magazynuje więcej przedmiotów. Wysyła częściej. diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index ea74cce62e..e2d775ff53 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -10,20 +10,23 @@ link.dev-builds.description = Desenvolvimentos instáveis link.trello.description = Trello oficial para atualizações planejadas link.itch.io.description = Página da Itch.io com os downloads link.google-play.description = Página da google play store +link.f-droid.description = F-Droid catalogue listing link.wiki.description = Wiki oficial do Mindustry -linkfail = Falha ao abrir o link\nO Url foi copiado +linkfail = Falha ao abrir o link\nO Url foi copiado para a área de transferência. screenshot = Screenshot salvo para {0} screenshot.invalid = Mapa grande demais, Potencialmente sem memória suficiente para captura de tela. gameover = O núcleo foi destruído. gameover.pvp = O time[accent] {0}[] ganhou! highscore = [YELLOW]Novo recorde! copied = Copiado + load.sound = Sons load.map = Mapas load.image = Imagens load.content = Conteúdo load.system = Sistema load.mod = Mods + schematic = Esquema schematic.add = Salvar Esquema... schematics = Esquemas @@ -40,6 +43,7 @@ schematic.saved = Esquema salvo. schematic.delete.confirm = Esse Esquema será totalmente erradicado. schematic.rename = Rename Schematic schematic.info = {0}x{1}, {2} blocks + stat.wave = Hordas derrotadas:[accent] {0} stat.enemiesDestroyed = Inimigos Destruídos:[accent] {0} stat.built = Construções construídas:[accent] {0} @@ -47,6 +51,7 @@ stat.destroyed = Construções destruídas:[accent] {0} stat.deconstructed = Construções desconstruídas:[accent] {0} stat.delivered = Recursos lançados: stat.rank = Classificação Final: [accent]{0} + launcheditems = [accent]Itens lançados launchinfo = [unlaunched][[LANCE] seu núcleo para obter os itens indicados em azul. map.delete = Certeza que quer deletar o mapa "[accent]{0}[]"? @@ -74,6 +79,7 @@ maps.browse = Pesquisar mapas continue = Continuar maps.none = [LIGHT_GRAY]Nenhum Mapa Encontrado! invalid = Inválido +pickcolor = Escolher Cor preparingconfig = Preparando configuração preparingcontent = Preparando conteúdo uploadingcontent = Fazendo upload do conteúdo @@ -81,6 +87,7 @@ uploadingpreviewfile = Fazendo upload do arquivo de pré-visualização committingchanges = Enviando mudanças done = Feito feature.unsupported = Seu dispositivo não suporta essa função. + mods.alphainfo = Mantenha em mente que os mods estão em Alpha, e[scarlet] talvez sejam bem bugados[].\nReporte quaisquer problemas no Discord ou GitHub do Mindustry. mods.alpha = [accent](Alpha) mods = Mods @@ -90,10 +97,11 @@ mods.report = Reportar um Bug mods.openfolder = Abrir pasta de Mods mod.enabled = [lightgray]Ativado mod.disabled = [scarlet]Desativado -mod.disable = Desativar +mod.disable = Desati-\nvar mod.delete.error = Incapaz de deletar o Mod. O arquivo talvez esteja em uso. +mod.requiresversion = [scarlet]Requer versão [accent]{0} [scarlet]do jogo. mod.missingdependencies = [scarlet]Dependências ausentes: {0} -mod.nowdisabled = [scarlet]O Mod '{0}' está com dependências ausentes :[accent] {1}\n[lightgray]Esses Mods precisam ser baixados primeiro.\nEsse Mod será desativado automaticamente. +mod.nowdisabled = [scarlet]O Mod '{0}' está com dependências ausentes:[accent] {1}\n[lightgray]Esses Mods precisam ser baixados primeiro.\nEsse Mod será desativado automaticamente. mod.enable = Ativar mod.requiresrestart = O jogo irá fechar para aplicar as mudanças do Mod. mod.reloadrequired = [scarlet]Recarregamento necessário @@ -104,6 +112,7 @@ mod.author = [LIGHT_GRAY]Author:[] {0} mod.missing = Esse jogo salvo foi criado antes de você atualizar ou desinstalar um mod. O jogo salvo pode se corromper. Você tem certeza que quer carregar?\n[lightgray]Mods:\n{0} mod.preview.missing = Antes de publicar esse mod na Oficina, você deve adicionar uma imagem de pré-visualização.\nColoque uma imagem com o nome[accent] preview.png[] na pasta do Mod e tente novamente. mod.folder.missing = Somente Mods no formato de pasta serão publicados na Oficina.\nPara converter qualquer Mod em uma pasta, Simplesmente descompacte seu arquivo numa pasta e delete a compactação antiga, então reinicie seu jogo ou recarregue os Mods. + about.button = Sobre name = Nome: noname = Escolha[accent] um nome[] primeiro. @@ -271,6 +280,7 @@ publishing = [accent]Publishing... publish.confirm = você tem certeza de que quer publicar isso?\n\n[lightgray]Primeiramente tenha certeza de que você concorda com o EULA da Oficina, ou seus itens não irão aparecer! publish.error = Erro publicando o Item: {0} steam.error = Falha em iniciar os serviços da Steam.\nError: {0} + editor.brush = Pincel editor.openin = Abrir no Editor editor.oregen = Geração de minério @@ -347,6 +357,7 @@ editor.overwrite = [accent]Aviso!\nIsso Substitui um mapa existente. editor.overwrite.confirm = [scarlet]Aviso![] Um mapa com esse nome já existe. Tem certeza que deseja substituir? editor.exists = Já existe um mapa com este nome. editor.selectmap = Selecione uma mapa para carregar: + toolmode.replace = Substituir toolmode.replace.description = Desenha apenas em blocos sólidos. toolmode.replaceall = Substituir tudo @@ -361,6 +372,7 @@ toolmode.fillteams = Encher times toolmode.fillteams.description = Muda o time do qual todos os blocos pertencem. toolmode.drawteams = Desenhar times toolmode.drawteams.description = Muda o time do qual o bloco pertence. + filters.empty = [LIGHT_GRAY]Sem filtro! Adicione um usando o botão abaixo. filter.distort = Distorcedor filter.noise = Geração aleatória @@ -392,6 +404,7 @@ filter.option.floor2 = Chão secundário filter.option.threshold2 = Margem secundária filter.option.radius = Raio filter.option.percentile = Percentual + width = Largura: height = Altura: menu = Menu @@ -407,6 +420,7 @@ tutorial = Tutorial tutorial.retake = Refazer Tutorial editor = Editor mapeditor = Editor de mapa + abandon = Abandonar abandon.text = Esta zona e todos os seus recursos serão perdidos para o inimigo. locked = Trancado @@ -437,6 +451,7 @@ zone.objective.survival = Sobreviver zone.objective.attack = Destruir o núcleo inimigo add = Adicionar... boss.health = Vida do chefe + connectfail = [crimson]Falha ao entrar no servidor: [accent]{0} error.unreachable = Servidor inalcançável. error.invalidaddress = Endereço inválido. @@ -447,6 +462,7 @@ error.mapnotfound = Arquivo de mapa não encontrado! error.io = Erro I/O de internet. error.any = Erro de rede desconhecido. error.bloom = Falha ao inicializar bloom.\nSeu dispositivo talvez não o suporte. + zone.groundZero.name = Marco zero zone.desertWastes.name = Ruínas do Deserto zone.craters.name = As crateras @@ -461,6 +477,7 @@ zone.saltFlats.name = Planícies de sal zone.impact0078.name = Impacto 0078 zone.crags.name = Penhascos zone.fungalPass.name = Passagem Fúngica + zone.groundZero.description = Uma ótima localização para começar de novo. Baixa ameaça inimiga. Poucos recursos.\nColete o máximo de chumbo e cobre possível.\nContinue! zone.frozenForest.description = Até aqui, perto das montanhas, os esporos se espalharam. As baixas temperaturas não podem contê-los para sempre.\n\nComeçe a busca por energia. Construa geradores à combustão. Aprenda a usar os reparadores (menders). zone.desertWastes.description = Estas ruínas são vastas, imprevisíveis, e cruzadas por estruturas abandonadas.\nCarvão está presente na região. O queime por energia, ou sintetize grafite.\n\n[lightgray]Este local de pouso não pode ser garantido. @@ -475,17 +492,19 @@ zone.nuclearComplex.description = Uma antiga instalação para produção e proc zone.fungalPass.description = Uma area de transição entre montanhas altas e baixas, terras cheias de esporos. Uma pequena base de reconhecimento inimiga está localizada aqui.\nDestrua-a.\nUse as unidades crawler e dagger. Destrua os dois núcleos. zone.impact0078.description = zone.crags.description = + settings.language = Idioma settings.data = Dados do jogo settings.reset = Restaurar Padrões settings.rebind = Religar +settings.resetKey = Resetar settings.controls = Controles settings.game = Jogo settings.sound = Som settings.graphics = Gráficos settings.cleardata = Apagar dados... settings.clear.confirm = Certeza que quer limpar a os dados?\nOque é feito não pode ser desfeito! -settings.clearall.confirm = [scarlet]Aviso![]\nIsso vai limpar todo os arquivos, Incluindo jogos salvos, mapas, Keybinds e desbloqueados.\nQuando apertar 'ok' todos os arquivos serão apagados e o jogo irá sair automaticamente. +settings.clearall.confirm = [scarlet]Aviso![]\nIsso vai limpar todo os arquivos, incluindo jogos salvos, mapas, teclas personalizadas e desbloqueados.\nQuando apertar 'ok' todos os arquivos serão apagados e o jogo irá sair automaticamente. paused = Pausado clear = Clear banned = [scarlet]Banido @@ -529,6 +548,7 @@ blocks.inaccuracy = Imprecisão blocks.shots = Tiros blocks.reload = Tiros por segundo blocks.ammo = Munição + bar.drilltierreq = Broca melhor necessária. bar.drillspeed = Velocidade da Broca: {0}/s bar.pumpspeed = Velocidade da Bomna: {0}/s @@ -544,8 +564,11 @@ bar.heat = Aquecimento bar.power = Poder bar.progress = Progresso da construção bar.spawned = Unidades: {0}/{1} -bullet.damage = [stat]{0}[lightgray] Dano -bullet.splashdamage = [stat]{0}[lightgray] Dano em área ~[stat] {1}[lightgray] Blocos +bar.input = Entrando +bar.output = Saindo + +bullet.damage = [stat]{0}[lightgray] de dano +bullet.splashdamage = [stat]{0}[lightgray] de dano em área ~[stat] {1}[lightgray] bloco(s) bullet.incendiary = [stat]Incendiário bullet.homing = [stat]Guiado bullet.shock = [stat]Choque @@ -555,6 +578,7 @@ bullet.freezing = [stat]Congelamento bullet.tarred = [stat]Grudento bullet.multiplier = [stat]{0}[lightgray]x multiplicador de munição bullet.reload = [stat]{0}[lightgray]x cadência de tiro + unit.blocks = Blocos unit.powersecond = Unidades de energia/segundo unit.liquidsecond = Unidades de líquido/segundo @@ -576,13 +600,14 @@ category.shooting = Atirando category.optional = Melhoras opcionais setting.landscape.name = Travar panorama setting.shadows.name = Sombras -setting.blockreplace.name = Automatic Block Suggestions +setting.blockreplace.name = Sugestões automáticas de blocos setting.linear.name = Filtragem linear setting.hints.name = Dicas +setting.buildautopause.name = Pausar construções automaticamente setting.animatedwater.name = Água animada setting.animatedshields.name = Escudos animados setting.antialias.name = Filtro suavizante[LIGHT_GRAY] (reinicialização requerida)[] -setting.indicators.name = Indicador de aliados +setting.indicators.name = Indicador de aliados/inimigos setting.autotarget.name = Alvo automatico setting.keyboard.name = Controles de mouse e teclado setting.touchscreen.name = Controles de Touchscreen @@ -600,13 +625,16 @@ setting.difficulty.name = Dificuldade setting.screenshake.name = Balanço da Tela setting.effects.name = Efeitos setting.destroyedblocks.name = Mostrar Blocos Destruídos -setting.conveyorpathfinding.name = Posicionamento do localizador do Transportador +setting.conveyorpathfinding.name = Esteiras Encontram Caminho setting.sensitivity.name = Sensibilidade do Controle setting.saveinterval.name = Intervalo de Auto Salvamento -setting.seconds = {0} Segundos +setting.seconds = {0} segundos +setting.blockselecttimeout.name = Tempo limite de seleção de blocos +setting.milliseconds = {0} milissegundos setting.fullscreen.name = Tela Cheia setting.borderlesswindow.name = Janela sem borda[LIGHT_GRAY] (Pode precisar reiniciar) -setting.fps.name = Mostrar FPS +setting.fps.name = Mostrar FPS e Ping +setting.blockselectkeys.name = Mostrar teclas de seleção de blocos setting.vsync.name = VSync setting.pixelate.name = Pixelizado [LIGHT_GRAY](Pode diminuir a performace) setting.minimap.name = Mostrar minimapa @@ -635,16 +663,36 @@ category.multiplayer.name = Multijogador command.attack = Atacar command.rally = Reunir command.retreat = Recuar -keybind.clear_building.name = Clear Building +placement.blockselectkeys = \n[lightgray]Tecla: [{0}, +keybind.clear_building.name = Limpar construção keybind.press = Pressione uma tecla... keybind.press.axis = Pressione uma Axis ou tecla... keybind.screenshot.name = Captura do mapa -keybind.move_x.name = mover_x -keybind.move_y.name = mover_y +keybind.toggle_power_lines.name = Mudar lasers +keybind.move_x.name = Mover no eixo x +keybind.move_y.name = Mover no eixo Y +keybind.mouse_move.name = Seguir Mouse +keybind.dash.name = Arrancada keybind.schematic_select.name = Selecionar região keybind.schematic_menu.name = Menu de Esquemas -keybind.schematic_flip_x.name = girar o Esquema X -keybind.schematic_flip_y.name = girar o Esquema Y +keybind.schematic_flip_x.name = Girar o Esquema no eixo X +keybind.schematic_flip_y.name = Girar o Esquema no eixo Y +keybind.category_prev.name = Categoria anterior +keybind.category_next.name = Próxima categoria +keybind.block_select_left.name = Selecionar bloco à esquerda +keybind.block_select_right.name = Selecionar bloco à direita +keybind.block_select_up.name = Selecionar bloco acima +keybind.block_select_down.name = Selecionar bloco abaixo +keybind.block_select_01.name = Categoria/Selecionar bloco 1 +keybind.block_select_02.name = Categoria/Selecionar bloco 2 +keybind.block_select_03.name = Categoria/Selecionar bloco 3 +keybind.block_select_04.name = Categoria/Selecionar bloco 4 +keybind.block_select_05.name = Categoria/Selecionar bloco 5 +keybind.block_select_06.name = Categoria/Selecionar bloco 6 +keybind.block_select_07.name = Categoria/Selecionar bloco 7 +keybind.block_select_08.name = Categoria/Selecionar bloco 8 +keybind.block_select_09.name = Categoria/Selecionar bloco 9 +keybind.block_select_10.name = Categoria/Selecionar bloco 10 keybind.fullscreen.name = Alterar tela cheia keybind.select.name = selecionar keybind.diagonal_placement.name = Colocação diagonal @@ -658,7 +706,6 @@ keybind.menu.name = Menu keybind.pause.name = Pausar keybind.pause_building.name = Parar/Resumir a construção keybind.minimap.name = Minimapa -keybind.dash.name = Correr keybind.chat.name = Conversa keybind.player_list.name = Lista_de_jogadores keybind.console.name = Console @@ -666,7 +713,7 @@ keybind.rotate.name = Girar keybind.rotateplaced.name = Girar (Segure) keybind.toggle_menus.name = Ativar menus keybind.chat_history_prev.name = Historico do chat anterior -keybind.chat_history_next.name = Historico do proximo chat +keybind.chat_history_next.name = Historico do próximo chat keybind.chat_scroll.name = Rolar chat keybind.drop_unit.name = Soltar unidade keybind.zoom_minimap.name = Zoom do minimapa @@ -681,12 +728,14 @@ mode.pvp.description = Lutar contra outros jogadores locais. mode.attack.name = Ataque mode.attack.description = Sem hordas, com o objetivo de destruir a base inimiga. mode.custom = Regras personalizadas + rules.infiniteresources = Recursos infinitos +rules.reactorexplosions = Reatores explodem rules.wavetimer = Tempo de horda rules.waves = Hordas rules.attack = Modo de ataque rules.enemyCheat = Recursos de IA Infinitos -rules.unitdrops = Unidade solta +rules.unitdrops = Inimigos dropam itens rules.unitbuildspeedmultiplier = Multiplicador de velocidade de criação de unidade rules.unithealthmultiplier = Multiplicador de vida de unidade rules.playerhealthmultiplier = Multiplicador da vida de jogador @@ -694,10 +743,10 @@ rules.playerdamagemultiplier = Multiplicador do dano de jogador rules.unitdamagemultiplier = Multiplicador de dano de Unidade rules.enemycorebuildradius = Raio de "Não-criação" de core inimigo:[LIGHT_GRAY] (blocos) rules.respawntime = Tempo de renascimento:[LIGHT_GRAY] (seg) -rules.wavespacing = Espaço entre hordas:[LIGHT_GRAY] (seg) +rules.wavespacing = Espaço de tempo entre hordas:[LIGHT_GRAY] (seg) rules.buildcostmultiplier = Multiplicador de custo de construção rules.buildspeedmultiplier = Multiplicador de velocidade de construção -rules.waitForWaveToEnd = hordas esperam inimigos +rules.waitForWaveToEnd = Hordas esperam inimigos rules.dropzoneradius = Raio da zona de spawn:[LIGHT_GRAY] (blocos) rules.respawns = Respawn maximos por horda rules.limitedRespawns = Respawn limitados @@ -707,6 +756,10 @@ rules.title.resourcesbuilding = Recursos e Construções rules.title.player = Jogadores rules.title.enemy = Inimigos rules.title.unit = Unidades +rules.title.experimental = Experimental +rules.lighting = Iluminação +rules.ambientlight = Luz ambiente + content.item.name = Itens content.liquid.name = Líquidos content.unit.name = Unidades @@ -768,6 +821,7 @@ mech.buildspeed = [LIGHT_GRAY]Velocidade de construção: {0}% liquid.heatcapacity = [LIGHT_GRAY]Capacidade de aquecimento: {0} liquid.viscosity = [LIGHT_GRAY]Viscosidade: {0} liquid.temperature = [LIGHT_GRAY]Temperatura: {0} + block.sand-boulder.name = Pedregulho de areia block.grass.name = Grama block.salt.name = Sal @@ -843,7 +897,7 @@ block.copper-wall.name = Muro de Cobre block.copper-wall-large.name = Muro de Cobre Grande block.titanium-wall.name = Muro de Titânio block.titanium-wall-large.name = Muro de Titânio grande -block.plastanium-wall.name = Muro de Plastânio Grande +block.plastanium-wall.name = Muro de Plastânio block.plastanium-wall-large.name = Muro de Plastânio Grande block.phase-wall.name = Muro de Fase block.phase-wall-large.name = Muro de Fase Grande @@ -866,6 +920,8 @@ block.distributor.name = Distribuidor block.sorter.name = Ordenador block.inverted-sorter.name = Ordenador Invertido block.message.name = Mensagem +block.illuminator.name = Iluminador +block.illuminator.description = Uma pequena, compacta e configurável fonte de luz. Precisa de energia para funcionar. block.overflow-gate.name = Portão Sobrecarregado block.silicon-smelter.name = Fundidora de silicio block.phase-weaver.name = Palheta de fase @@ -875,14 +931,15 @@ block.melter.name = Aparelho de fusão block.incinerator.name = Incinerador block.spore-press.name = Prensa de Esporo block.separator.name = Separador -block.coal-centrifuge.name = Centrifuga de carvão -block.power-node.name = Célula de energia -block.power-node-large.name = Célula de energia Grande +block.coal-centrifuge.name = Centrífuga de carvão +block.power-node.name = Célula de Energia +block.power-node-large.name = Célula de Energia Grande block.surge-tower.name = Torre de surto +block.diode.name = Bateria de Diodo block.battery.name = Bateria block.battery-large.name = Bateria Grande -block.combustion-generator.name = Gerador a combustão -block.turbine-generator.name = Gerador de Turbina +block.combustion-generator.name = Gerador à combustão +block.turbine-generator.name = Gerador à vapor block.differential-generator.name = Gerador diferencial block.impact-reactor.name = Reator De Impacto block.mechanical-drill.name = Broca Mecânica @@ -931,6 +988,7 @@ block.fortress-factory.name = Fábrica de mech Fortress block.revenant-factory.name = Fábrica de lutadores Revenant block.repair-point.name = Ponto de Reparo block.pulse-conduit.name = Cano de Pulso +block.plated-conduit.name = Cano Chapeado block.phase-conduit.name = Cano de Fase block.liquid-router.name = Roteador de Líquido block.liquid-tank.name = Tanque de Líquido @@ -939,12 +997,12 @@ block.bridge-conduit.name = Cano Ponte block.rotary-pump.name = Bomba Rotatória block.thorium-reactor.name = Reator a Tório block.mass-driver.name = Catapulta Eletromagnética -block.blast-drill.name = Broca de Explosão +block.blast-drill.name = Broca de Jato de Ar block.thermal-pump.name = Bomba térmica block.thermal-generator.name = Gerador Térmico block.alloy-smelter.name = Fundidora de Liga block.mender.name = Reparador -block.mend-projector.name = Projetor de reparo +block.mend-projector.name = Projetor de Reparo block.surge-wall.name = Parede de liga de surto block.surge-wall-large.name = Parede de liga de surto grande block.cyclone.name = Ciclone @@ -960,10 +1018,10 @@ block.container.name = Contâiner block.launch-pad.name = Plataforma de lançamento block.launch-pad-large.name = Plataforma de lançamento grande team.blue.name = Azul -team.crux.name = Vermelha -team.sharded.name = Estilhaçada -team.orange.name = Laranja -team.derelict.name = Abandonada +team.crux.name = Vermelho +team.sharded.name = Fragmentado +team.orange.name = Alaranjado +team.derelict.name = Abandonado team.green.name = Verde team.purple.name = Roxa unit.spirit.name = Drone Spirit @@ -1002,6 +1060,7 @@ tutorial.deposit = Deposite itens em blocos arrastando da sua nave até o bloco. tutorial.waves = O[LIGHT_GRAY] inimigo[] se aproxima.\n\nDefenda seu núcleo por 2 hordas. Construa mais torretas. tutorial.waves.mobile = O[lightgray] inimigo[] se aproxima.\n\nDefenda seu núcleo por 2 hordas. Seu drone vai atirar nos inimigos automaticamente.\nConstrua mais torretas e brocas. Minere mais cobre. tutorial.launch = Quando você atinge uma horda específica, Você é capaz de[accent] lançar o núcleo[], deixando suas defesas para trás e[accent] obtendo todos os recursos em seu núcleo.[]\nEstes recursos podem ser usados para pesquisar novas tecnologias.\n\n[accent]Pressione o botão lançar. + item.copper.description = O material mais básico. Usado em todos os tipos de blocos. item.lead.description = Material de começo basico. usado extensivamente em blocos de transporte de líquidos e eletrônicos. item.metaglass.description = Composto de vidro super resistente. Extensivamente usado para distribuição e armazenagem de líquidos. @@ -1051,7 +1110,7 @@ block.phase-weaver.description = Produz tecido de fase usando tório radioativo block.alloy-smelter.description = Combina titânio, chumbo, silicio e cobre para produzir liga de surto. block.cryofluidmixer.description = Mistura água e pó fino de titânio para produzir criofluido. Essencial para o uso do reator a tório. block.blast-mixer.description = Quebra e mistura aglomerados de esporos com piratita para produzir composto de explosão. -block.pyratite-mixer.description = Mistura carvão, cobre e areia em piratita altamente inflamável +block.pyratite-mixer.description = Mistura carvão, cobre e areia em piratita altamente inflamável. block.melter.description = Derrete sucata em escória para processamento posterior ou uso em torretas. block.separator.description = Separa escória em seus minerais componentes, oferece o resultado refriado. block.spore-press.description = Comprime cápsulas de esporos em petróleo. @@ -1067,10 +1126,10 @@ block.copper-wall.description = Um bloco defensivo e barato.\nUtil para proteger block.copper-wall-large.description = Um bloco defensivo e barato.\nUtil para proteger o núcleo e torretas no começo.\nOcupa múltiplos blocos. block.titanium-wall.description = Um bloco defensivo moderadamente forte.\nProvidencia defesa moderada contra inimigos. block.titanium-wall-large.description = Um bloco defensivo moderadamente forte.\nProvidencia defesa moderada contra inimigos.\nOcupa múltiplos blocos. -block.plastanium-wall.description = A special type of wall that absorbs electric arcs and blocks automatic power node connections. -block.plastanium-wall-large.description = A special type of wall that absorbs electric arcs and blocks automatic power node connections.\nSpans multiple tiles. +block.plastanium-wall.description = Um tipo especial de muro que absorve arcos elétricos e bloqueia conexões automáticas de células de energia. +block.plastanium-wall-large.description = Um tipo especial de muro que absorve arcos elétricos e bloqueia conexões automáticas de células de energia.\nOcupa múltiplos blocos. block.thorium-wall.description = Um bloco defensivo forte.\nBoa proteção contra inimigos. -block.thorium-wall-large.description = Um bloco grande e defensivo.\nBoa proteção contra inimigos.\nOcupa multiplos blocos. +block.thorium-wall-large.description = Um bloco defensivo forte.\nBoa proteção contra inimigos.\nOcupa múltiplos blocos. block.phase-wall.description = Um muro revestido com um composto especial baseado em tecido de fase. Desvia a maioria das balas no impacto. block.phase-wall-large.description = Um muro revestido com um composto especial baseado em tecido de fase. Desvia a maioria das balas no impacto.\nSOcupa múltiplos blocos. block.surge-wall.description = Um bloco defensivo extremamente durável.\nSe carrega com eletricidade no contato com as balas, soltando-s aleatoriamente. @@ -1098,7 +1157,8 @@ block.rotary-pump.description = Uma bomba avançada. Bombeia mais líquido, mas block.thermal-pump.description = A bomba final. block.conduit.description = Bloco básico de transporte de líquidos. Move líquidos para a frente. Usado em conjunto com bombas e outros canos. block.pulse-conduit.description = Bloco avancado de transporte de liquido. Transporta liquidos mais rápido e armazena mais que os canos padrões. -block.liquid-router.description = Aceita liquidos de uma direcão e os joga em 3 direções igualmente. Pode armazenar uma certa quantidade de liquido. Util para espalhar liquidos de uma fonte para multiplos alvos. +block.plated-conduit.description = Move líquidos na mesma velocidade que canos de pulso, mas possui mais blindagem. Não aceita fluidos dos lados de nada além de outros canos.\nVaza menos. +block.liquid-router.description = Aceita liquidos de uma direcão e os joga em 3 direções igualmente. Pode armazenar uma certa quantidade de liquido. Útil para espalhar líquidos de uma fonte para múltiplos alvos. block.liquid-tank.description = Armazena grandes quantidades de liquido. Use quando a demanda de materiais não for constante ou para guardar itens para resfriar blocos vitais. block.liquid-junction.description = Age como uma ponte para dois canos que se cruzam. Útil em situações em que há dois cano carregando liquidos diferentes até localizações diferentes. block.bridge-conduit.description = Bloco de transporte de liquidos avancados. Possibilita o transporte de liquido sobre 3 blocos acima de construções ou paredes @@ -1106,15 +1166,16 @@ block.phase-conduit.description = Bloco avancado de transporte de liquido. Usa e block.power-node.description = Transmite energia para células conectadas. A célula vai receber energia ou alimentar qualquer bloco adjacente. block.power-node-large.description = Uma célula de energia avançada com maior alcance e mais conexões. block.surge-tower.description = Uma célula de energia com um extremo alcance mas com menos conexões disponíveis. +block.diode.description = A energia de baterias pode fluir através desse bloco em apenas uma direção, mas apenas se o outro lado possuir menos energia armazenada. block.battery.description = Armazena energia em tempos de energia excedente. Libera energia em tempos de déficit. -block.battery-large.description = Guarda muito mais energia que uma beteria comum. -block.combustion-generator.description = Gera energia usando combustível ou petróleo. -block.thermal-generator.description = Gera uma quantidade grande de energia usando lava. -block.turbine-generator.description = Mais eficiente que o gerador de Combustão, Mas requer agua adicional. -block.differential-generator.description = Gera grandes quantidades de Energia. Utiliza a diferença de temperatura entre o Fluído Criogênico e a Piratita. +block.battery-large.description = Guarda muito mais energia que uma bateria comum. +block.combustion-generator.description = Gera energia queimando materiais inflamáveis, como carvão. +block.thermal-generator.description = Gera energia quando colocado em lugares quentes. +block.turbine-generator.description = Mais eficiente que o gerador à combustão, mas requer água adicional para a geração de vapor. +block.differential-generator.description = Gera grandes quantidades de energia. Utiliza a diferença de temperatura entre o Fluido Criogênico e a Piratita. block.rtg-generator.description = Um Gerador termoelétrico de radioisótopos que não precisa de refriamento mas dá muito menos energia que o reator de tório. block.solar-panel.description = Gera pequenas quantidades de energia do sol. -block.solar-panel-large.description = Dá muito mais energia que o painel solar comum, Mas sua produção é mais cara. +block.solar-panel-large.description = Uma versão significantemente mais eficiente que o painel solar padrão. block.thorium-reactor.description = Gera altas quantidades de energia do torio radioativo. Requer resfriamento constante. Vai explodir violentamente Se resfriamento insuficiente for fornecido. block.impact-reactor.description = An advanced generator, capable of creating massive amounts of power at peak efficiency. Requires a significant power input to kickstart the process. block.mechanical-drill.description = Uma broca barata. Quando colocado em blocos apropriados, retira itens em um ritmo lento e indefinitavamente. @@ -1123,9 +1184,9 @@ block.laser-drill.description = Possibilita a mineração ainda mais rapida usan block.blast-drill.description = A melhor mineradora. Requer muita energia. block.water-extractor.description = Extrai água do chão. Use quando não tive nenhum lago proximo block.cultivator.description = Cultiva o solo com agua para pegar bio materia. -block.oil-extractor.description = Usa altas quantidades de energia Para extrair oleo da areia. Use quando não tiver fontes de oleo por perto -block.core-shard.description = Primeira iteração da cápsula do núcleo. Uma vez destruida, o controle da região inteira é perdido. Não deixe isso acontecer. -block.core-foundation.description = A segunda versão do núcleo. Melhor armadura. Guarda mais recursos. +block.water-extractor.description = Extrai água subterrânea. Usado em locais sem água superficial disponível. +block.cultivator.description = Cultiva pequenas concentrações de esporos na atmosfera em cápsulas prontas. +block.oil-extractor.description = Usa altas quantidades de energia para extrair petróleo da areia. Use quando não tiver fontes de petróleo por perto. block.core-nucleus.description = A terceira e ultima iteração do núcleo. Extremamente bem armadurada. Guarda quantidades massivas de recursos. block.vault.description = Carrega uma alta quantidade de itens. Usado para criar fontes Quando não tem uma necessidade constante de materiais. Um[LIGHT_GRAY] Descarregador[] pode ser usado para recuperar esses itens do container. block.container.description = Carrega uma baixa quantidade de itens. Usado para criar fontes Quando não tem uma necessidade constante de materiais. Um[LIGHT_GRAY] Descarregador[] pode ser usado para recuperar esses itens do container. diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index 5170552cb7..d3f2b919ce 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -6,10 +6,11 @@ link.discord.description = Официальный Discord-сервер Mindustry link.reddit.description = Сабреддит Mindustry link.github.description = Исходный код игры link.changelog.description = Список изменений -link.dev-builds.description = Нестабильные версии +link.dev-builds.description = Нестабильные разрабатываемые версии link.trello.description = Официальная доска Trello для запланированных функций link.itch.io.description = Страница itch.io с загрузками игры link.google-play.description = Скачать для Android с Google Play +link.f-droid.description = Скачать для Android с F-Droid link.wiki.description = Официальная вики linkfail = Не удалось открыть ссылку!\nURL-адрес был скопирован в буфер обмена. screenshot = Cкриншот сохранён в {0} @@ -18,12 +19,14 @@ gameover = Игра окончена gameover.pvp = [accent]{0}[] команда победила! highscore = [accent]Новый рекорд! copied = Скопировано. + load.sound = Звуки load.map = Карты load.image = Изображения load.content = Содержимое load.system = Система load.mod = Модификации + schematic = Схема schematic.add = Сохранить схему... schematics = Схемы @@ -40,6 +43,7 @@ schematic.saved = Схема сохранена. schematic.delete.confirm = Эта схема будет поджарена Испепелителем. schematic.rename = Переименовать схему schematic.info = {0}x{1}, {2} блоков + stat.wave = Волн отражено:[accent] {0} stat.enemiesDestroyed = Врагов уничтожено:[accent] {0} stat.built = Строений построено:[accent] {0} @@ -47,6 +51,7 @@ stat.destroyed = Строений уничтожено:[accent] {0} stat.deconstructed = Строений деконструировано:[accent] {0} stat.delivered = Ресурсов запущено: stat.rank = Финальный ранг: [accent]{0} + launcheditems = [accent]Запущенные предметы launchinfo = [unlaunched]Нажмите на кнопку [ЗАПУСК], чтобы получить предметы, которые отмечены синим цветом. map.delete = Вы действительно хотите удалить карту «[accent]{0}[]»? @@ -55,7 +60,7 @@ level.select = Выбор карты level.mode = Режим игры: showagain = Не показывать снова до следующей сессии coreattack = < Ядро находится под атакой! > -nearpoint = [[ [scarlet]ПОКИНЬТЕ ТОЧКУ ВЫСАДКИ НЕМЕДЛЕННО[] ]\nАннигиляция неизбежна +nearpoint = [[ [scarlet]ПОКИНЬТЕ ТОЧКУ ВЫСАДКИ НЕМЕДЛЕННО[] ]\nаннигиляция неизбежна database = База данных ядра savegame = Сохранить игру loadgame = Загрузить игру @@ -64,7 +69,7 @@ customgame = Пользовательская игра newgame = Новая игра none = <ничего> minimap = Мини-карта -position = Позиция +position = Координаты close = Закрыть website = Веб-сайт quit = Выход @@ -74,27 +79,29 @@ maps.browse = Просмотр карт continue = Продолжить maps.none = [lightgray]Карты не найдены! invalid = Недопустимый +pickcolor = Выбрать цвет preparingconfig = Подготовка конфигурации preparingcontent = Подготовка содержимого uploadingcontent = Выгрузка содержимого uploadingpreviewfile = Выгрузка файла предпросмотра committingchanges = Внесение изменений done = Готово -feature.unsupported = Your device does not support this feature. -mods.alphainfo = Имейте в виду, что модификации находятся в альфа-версии и могут содержать много ошибок[]. Докладывайте о любых проблемах, которые Вы найдете в Mindustry GitHub или Discord. +feature.unsupported = Ваше устройство не поддерживает эту возможность. + +mods.alphainfo = Имейте в виду, что модификации находятся в альфа-версии и [scarlet]могут содержать много ошибок[]. Докладывайте о любых проблемах, которые Вы найдете в Mindustry Github или Discord. mods.alpha = [accent](Альфа) mods = Модификации mods.none = [LIGHT_GRAY]Модификации не найдены! mods.guide = Руководство по созданию модификаций mods.report = Доложить об ошибке -mods.openfolder = Open Mod Folder +mods.openfolder = Открыть папку с модификациями mod.enabled = [lightgray]Включён mod.disabled = [scarlet]Выключен -mod.disable = Выключить -mod.delete.error = Unable to delete mod. File may be in use. +mod.disable = Выкл. +mod.delete.error = Невозможно удалить модификацию. Возможно, файл используется. mod.missingdependencies = [scarlet]Не найдены родительские модификации: {0} mod.nowdisabled = [scarlet]Модификации '{0}' требуются родительские модификации:[accent] {1}\n[lightgray]Сначала нужно загрузить их.\nЭта модификация будет автоматически отключена. -mod.enable = Включить +mod.enable = Вкл. mod.requiresrestart = Теперь игра закроется, чтобы применить изменения в модификациях. mod.reloadrequired = [scarlet]Необходим перезапуск mod.import = Импортировать модификацию @@ -104,6 +111,7 @@ mod.author = [LIGHT_GRAY]Автор:[] {0} mod.missing = Это сохранение содержит модификацию, которое Вы недавно обновили или оно больше не установлено. Может случиться повреждение сохранения. Вы уверены, что хотите загрузить его?\n[lightgray]Модификации:\n{0} mod.preview.missing = Перед публикацией этой модификации в Мастерской, Вы должны добавить изображение предпросмотра.\nРазместите изображение с именем[accent] preview.png[] в папке модификации и попробуйте снова. mod.folder.missing = Модификации могут быть опубликованы в Мастерской только в виде папки.\nЧтобы конвертировать любой мод в папку, просто извлеките его из архива и удалите старый архив .zip, затем перезапустите игру или перезагрузите модификации. + about.button = Об игре name = Имя: noname = Для начала, придумайте[accent] себе имя[]. @@ -111,8 +119,8 @@ filename = Имя файла: unlocked = Новый контент разблокирован! completed = [accent]Завершено techtree = Дерево технологий -research.list = [lightgray]Исследование: -research = Исследование +research.list = [lightgray]Исследуйте: +research = Исследовать researched = [lightgray]{0} исследовано. players = Игроков: {0} players.single = {0} игрок @@ -133,7 +141,7 @@ server.kicked.idInUse = Вы уже на этом сервере! Соедине server.kicked.customClient = Этот сервер не поддерживает пользовательские сборки. Загрузите официальную версию. server.kicked.gameover = Игра окончена! server.versions = Ваша версия:[accent] {0}[]\nВерсия сервера:[accent] {1}[] -host.info = Кнопка [accent]Сервер[] запускает сервер на порте [scarlet]6567[]. \nЛюбой пользователь в той же [lightgray]локальной сети или WiFi[] должен увидеть ваш сервер в своём списке серверов.\n\nЕсли Вы хотите, чтобы люди могли подключаться откуда угодно по IP, то требуется [accent]переадресация (проброс) портов[] и наличие [red]ВНЕШНЕГО[] WAN адреса (WAN адрес [red]НЕ должен[] начинаться с [red]10[][lightgray].x.x.x[], [red]100.64[][lightgray].x.x[], [red]172.16[][lightgray].x.x[], [red]192.168[][lightgray].x.x[], [red]127[][lightgray].x.x.x[])!\nКлиентам мобильных операторов нужно уточнять информацию в личном кабинете на сайте вашего оператора!\n\n[lightgray]Примечание: Если у кого-то возникают проблемы с подключением к вашей игре по локальной сети, убедитесь, что Вы разрешили доступ Mindustry к вашей локальной сети в настройках брандмауэра. Обратите внимание, что публичные сети иногда не позволяют обнаружение сервера. +host.info = Кнопка [accent]Открыть сервер[] запускает сервер на порте [scarlet]6567[].\nЛюбой пользователь в той же [lightgray]локальной сети или WiFi[] должен увидеть ваш сервер в своём списке серверов.\n\nЕсли Вы хотите, чтобы люди могли подключаться откуда угодно по IP, то требуется [accent]переадресация (проброс) портов[] и наличие [red]ВНЕШНЕГО[] WAN адреса (WAN адрес [red]НЕ должен[] начинаться с [red]10[][lightgray].x.x.x[], [red]100.64[][lightgray].x.x[], [red]172.16[][lightgray].x.x[], [red]192.168[][lightgray].x.x[], [red]127[][lightgray].x.x.x[])!\nКлиентам мобильных операторов нужно уточнять информацию в личном кабинете на сайте вашего оператора!\n\n[lightgray]Примечание: Если у кого-то возникают проблемы с подключением к вашей игре по локальной сети, убедитесь, что Вы разрешили доступ Mindustry к вашей локальной сети в настройках брандмауэра. Обратите внимание, что публичные сети иногда не позволяют обнаружение сервера. join.info = Здесь Вы можете ввести [accent]IP-адрес сервера[] для подключения или открыть [accent]локальную сеть[] для подключения к другим серверам.\nПоддерживаются оба многопользовательских режима: LAN и WAN.\n\n[lightgray]Примечание: это НЕ автоматический глобальный список серверов; если Вы хотите подключиться к кому-то по IP, вам нужно спросить у хоста его IP-адрес. hostserver = Запустить многопользовательский сервер invitefriends = Пригласить друзей @@ -152,7 +160,7 @@ trace.ip = IP: [accent]{0} trace.id = ID: [accent]{0} trace.mobile = Мобильный клиент: [accent]{0} trace.modclient = Пользовательский клиент: [accent]{0} -invalidid = Недопустимый уникальный идентификатор клиента! Отправьте отчёт об ошибке. +invalidid = Недопустимый ID клиента! Отправьте отчёт об ошибке. server.bans = Блокировки server.bans.none = Заблокированных игроков нет! server.admins = Администраторы @@ -175,7 +183,7 @@ joingame.ip = Адрес: disconnect = Отключено. disconnect.error = Ошибка соединения. disconnect.closed = Соединение закрыто. -disconnect.timeout = Время истекло. +disconnect.timeout = Время ожидания истекло. disconnect.data = Ошибка при загрузке данных мира! cantconnect = Не удаётся присоединиться к игре ([accent]{0}[]). connecting = [accent]Подключение… @@ -229,7 +237,7 @@ data.export = Экспортировать данные data.import = Импортировать данные data.exported = Данные экспортированы. data.invalid = Эти игровые данные являются недействительными. -data.import.confirm = Импорт внешних данных сотрёт[scarlet] все[] ваши игровые данные.\n[accent]Это не может быть отменено![]\n\nКак только данные импортированы, ваша игра немедленно закроется. +data.import.confirm = Импорт внешних данных сотрёт[scarlet] все[] Ваши игровые данные.\n[accent]Это не может быть отменено![]\n\nКак только данные импортированы, Ваша игра немедленно закроется. classic.export = Экспортировать данные классической версии classic.export.text = [accent]Mindustry[] получил глобальное обновление.\nБыло обнаружено Классическое (версия 3.5 сборка 40) сохранение или карта. Вы хотите экспортировать эти сохранения в домашнюю папку вашего телефона, для использования в приложении Mindustry Classic? quit.confirm = Вы уверены, что хотите выйти? @@ -247,7 +255,7 @@ wave.waveInProgress = [lightgray]Волна продолжается waiting = [lightgray]Ожидание… waiting.players = Ожидание игроков… wave.enemies = Враги: [lightgray]{0} -wave.enemy = Остался [lightgray]{0} враг +wave.enemy = Остался {0} [lightgray]враг[] loadimage = Загрузить изображение saveimage = Сохранить изображение unknown = Неизвестно @@ -270,12 +278,13 @@ missing = Этот предмет был удалён или перемещён. publishing = [accent]Отправка... publish.confirm = Вы уверены, что хотите опубликовать этот предмет?\n\n[lightgray]Убедитесь, что Вы согласны с EULA Мастерской, иначе ваши предметы не будут отображаться! publish.error = Ошибка отправки предмета: {0} -steam.error = Failed to initialize Steam services.\nError: {0} +steam.error = Не удалось инициализировать сервисы Steam.\nОшибка: {0} + editor.brush = Кисть editor.openin = Открыть в редакторе editor.oregen = Генерация руд editor.oregen.info = Генерация руд: -editor.mapinfo = Параметры карты +editor.mapinfo = Информация о карте editor.author = Автор: editor.description = Описание: editor.nodescription = Чтобы опубликовать карту, она должна содержать по крайней мере 4 символа в описании. @@ -340,13 +349,14 @@ editor.exportimage = Экспортировать изображение лан editor.exportimage.description = Экспортировать файл с изображением карты editor.loadimage = Импортировать\nизображение editor.saveimage = Экспортировать\nизображение -editor.unsaved = [scarlet]У вас есть несохранённые изменения![]\nВы уверены, что хотите выйти? +editor.unsaved = [scarlet]У Вас есть несохранённые изменения![]\nВы уверены, что хотите выйти? editor.resizemap = Изменить размер карты editor.mapname = Название карты: -editor.overwrite = [accent]Внимание! \nЭто перезапишет уже существующую карту. +editor.overwrite = [accent]Внимание!\nЭто перезапишет уже существующую карту. editor.overwrite.confirm = [scarlet]Осторожно![] Карта с таким названием уже существует. Вы действительно хотите её перезаписать? editor.exists = Карта с таким именем уже существует. editor.selectmap = Выберите карту для загрузки: + toolmode.replace = Заменить toolmode.replace.description = Рисует только\nна сплошных блоках. toolmode.replaceall = Заменить всё @@ -361,6 +371,7 @@ toolmode.fillteams = Изменить команду блоков toolmode.fillteams.description = Изменяет принадлежность\nблоков к команде. toolmode.drawteams = Изменить команду блока toolmode.drawteams.description = Изменяет принадлежность\nблока к команде. + filters.empty = [lightgray]Нет фильтров! Добавьте один при помощи кнопки ниже. filter.distort = Искажение filter.noise = Шум @@ -392,6 +403,7 @@ filter.option.floor2 = Вторая поверхность filter.option.threshold2 = Вторичный предельный порог filter.option.radius = Радиус filter.option.percentile = Процентиль + width = Ширина: height = Высота: menu = Меню @@ -407,10 +419,11 @@ tutorial = Обучение tutorial.retake = Перепройти обучение editor = Редактор mapeditor = Редактор карт + abandon = Покинуть abandon.text = Эта зона и все её ресурсы будут отданы противнику. locked = Заблокировано -complete = [lightgray]Достигнута: +complete = [lightgray]Выполнить: requirement.wave = Достигните {0} волны в зоне {1} requirement.core = Уничтожьте вражеское ядро в зоне {0} requirement.unlock = Разблокируйте {0} @@ -429,14 +442,15 @@ addall = Добавить всё configure.locked = [lightgray]Разблокировка выгрузки ресурсов: {0}. configure.invalid = Количество должно быть числом между 0 и {0}. zone.unlocked = Зона «[lightgray]{0}» теперь разблокирована. -zone.requirement.complete = Вы достигли {0}-ой волны,\nУсловия для зоны «{1}» выполнены. -zone.config.unlocked = Loadout unlocked:[lightgray]\n{0} +zone.requirement.complete = Условия для зоны «{0}» выполнены:[lightgray]\n{1} +zone.config.unlocked = Выгрузка ресурсов разблокирована:[lightgray]\n{0} zone.resources = [lightgray]Обнаруженные ресурсы: zone.objective = [lightgray]Цель: [accent]{0} zone.objective.survival = Выжить zone.objective.attack = Уничтожить вражеское ядро add = Добавить… boss.health = Здоровье босса + connectfail = [crimson]Ошибка подключения:\n\n[accent]{0} error.unreachable = Сервер недоступен.\nВы уверены, что адрес введён корректно? error.invalidaddress = Некорректный адрес. @@ -446,11 +460,12 @@ error.alreadyconnected = Вы уже подключены. error.mapnotfound = Файл карты не найден! error.io = Сетевая ошибка ввода-вывода. error.any = Неизвестная сетевая ошибка. -error.bloom = Не удалось инициализировать свечение (Bloom).\nВозможно, ваше устройство не поддерживает его. +error.bloom = Не удалось инициализировать свечение (Bloom).\nВозможно, Ваше устройство не поддерживает его. + zone.groundZero.name = Отправная точка zone.desertWastes.name = Покинутые пустоши zone.craters.name = Кратеры -zone.frozenForest.name = Ледяной Лес +zone.frozenForest.name = Ледяной лес zone.ruinousShores.name = Разрушенные берега zone.stainedMountains.name = Окрашенные горы zone.desolateRift.name = Пустынный разлом @@ -461,20 +476,22 @@ zone.saltFlats.name = Соляные равнины zone.impact0078.name = Воздействие 0078 zone.crags.name = Скалы zone.fungalPass.name = Грибной перевал + zone.groundZero.description = Оптимальная локация для повторных игр. Низкая вражеская угроза. Немного ресурсов.\nСоберите как можно больше свинца и меди.\nДвигайтесь дальше. zone.frozenForest.description = Даже здесь, ближе к горам, споры распространились. Холодные температуры не могут сдерживать их вечно.\n\nНачните вкладываться в энергию. Постройте генераторы внутреннего сгорания. Научитесь пользоваться регенератором. zone.desertWastes.description = Эти пустоши огромны, непредсказуемы и пронизаны заброшенными секторальными структурами.\nВ регионе присутствует уголь. Сожгите его для получения энергии, или синтезируйте графит.\n\n[lightgray]Место посадки здесь может не быть гарантировано. zone.saltFlats.description = На окраине пустыни лежат соляные равнины. В этой местности можно найти немного ресурсов.\n\nВраги возвели здесь комплекс хранения ресурсов. Искорените их ядро. Не оставьте камня на камне. -zone.craters.description = Вода скопилась в этом кратере, реликвии времён старых войн. Восстановите область. Соберите песок. Выплавите метастекло. Качайте воду для охлаждения турелей и буров. +zone.craters.description = Вода скопилась в этом кратере, реликвии времён старых войн. Восстановите область. Соберите песок. Выплавьте метастекло. Качайте воду для охлаждения турелей и буров. zone.ruinousShores.description = Мимо пустошей проходит береговая линия. Когда-то здесь располагался массив береговой обороны. Не так много от него осталось. Только самые базовые оборонительные сооружения остались невредимыми, всё остальное превратилось в металлолом.\nПродолжайте экспансию вовне. Переоткройте для себя технологии. -zone.stainedMountains.description = Дальше, вглубь местности, лежат горы, еще не запятнанные спорами.\nИзвлеките изобилие титана в этой области. Узнайте, как его использовать.\n\nВражеское присутствие здесь сильнее. Не дайте им времени для отправки своих сильнейших боевых единиц. +zone.stainedMountains.description = Дальше, вглубь местности, лежат горы, еще не запятнанные спорами.\nИзвлеките изобилие титана в этой области. Научитесь им пользоваться.\n\nВражеское присутствие здесь сильнее. Не дайте им времени для отправки своих сильнейших боевых единиц. zone.overgrowth.description = Эта заросшая область находится ближе к источнику спор.\nВраг организовал здесь форпост. Постройте боевые единицы «Титан». Уничтожьте его. Верните то, что было потеряно. -zone.tarFields.description = Окраина зоны нефтедобычи, между горами и пустыней. Один из немногих районов с полезными запасами дёгтя.\nХотя область заброшенна, в этой области присутствуют поблизости некоторые опасные вражеские силы. Не стоит их недооценивать.\n\n[lightgray]Исследуйте технологию переработки нефти, если возможно. +zone.tarFields.description = Окраина зоны нефтедобычи, между горами и пустыней. Один из немногих районов с полезными запасами дёгтя.\nХотя эта область заброшенна, в ней поблизости присутствуют некоторые опасные вражеские силы. Не стоит их недооценивать.\n\n[lightgray]Исследуйте технологию переработки нефти, если возможно. zone.desolateRift.description = Чрезвычайно опасная зона. Обилие ресурсов, но мало места. Высокий риск разрушения. Эвакуироваться нужно как можно скорее. Не расслабляйтесь во время больших перерывов между вражескими атаками. zone.nuclearComplex.description = Бывший завод по производству и переработке тория, превращенный в руины.\n[lightgray]Исследуйте торий и варианты его многочисленного применения.\n\nВраг присутствует здесь в большом числе, постоянно разведывая нападающих. zone.fungalPass.description = Переходная область между высокими горами и более низкими, покрытыми спорами землями. Здесь расположена небольшая разведывательная база противника.\nУничтожьте ее.\nИспользуйте единицы «Кинжал» и «Камикадзе». Достаньте до обоих ядер. zone.impact0078.description = <вставить описание здесь> zone.crags.description = <вставить описание здесь> + settings.language = Язык settings.data = Игровые данные settings.reset = Сбросить по умолчанию @@ -508,8 +525,8 @@ blocks.launchtime = Интервал запусков blocks.shootrange = Радиус действия blocks.size = Размер blocks.liquidcapacity = Вместимость жидкости -blocks.powerrange = Диапазон передачи энергии -blocks.powerconnections = Max Connections +blocks.powerrange = Дальность передачи энергии +blocks.powerconnections = Количество соединений blocks.poweruse = Потребляет энергии blocks.powerdamage = Энергия/урон blocks.itemcapacity = Вместимость предметов @@ -529,9 +546,10 @@ blocks.inaccuracy = Разброс blocks.shots = Выстрелы blocks.reload = Выстрелы/секунду blocks.ammo = Боеприпасы -bar.drilltierreq = Требуется лучший бур -bar.drillspeed = Скорость бурения: {0}/s -bar.pumpspeed = Pump Speed: {0}/s + +bar.drilltierreq = Требуется бур получше +bar.drillspeed = Скорость бурения: {0}/с +bar.pumpspeed = Скорость выкачивания: {0}/с bar.efficiency = Эффективность: {0}% bar.powerbalance = Энергия: {0}/с bar.powerstored = Накоплено: {0}/{1} @@ -544,6 +562,9 @@ bar.heat = Нагрев bar.power = Энергия bar.progress = Прогресс строительства bar.spawned = Единицы: {0}/{1} +bar.input = Вход +bar.output = Выход + bullet.damage = [stat]{0}[lightgray] урона bullet.splashdamage = [stat]{0}[lightgray] урона в радиусе ~[stat] {1}[lightgray] блоков bullet.incendiary = [stat]зажигательный @@ -555,6 +576,7 @@ bullet.freezing = [stat]замораживающий bullet.tarred = [stat]замедляющий, горючий bullet.multiplier = [stat]{0}[lightgray]x множитель боеприпасов bullet.reload = [stat]{0}[lightgray]x скорость стрельбы + unit.blocks = блоки unit.powersecond = единиц энергии/секунду unit.liquidsecond = жидкостных единиц/секунду @@ -567,6 +589,8 @@ unit.persecond = /сек unit.timesspeed = x скорость unit.percent = % unit.items = предметов +unit.thousands = тыс +unit.millions = мил category.general = Основные category.power = Энергия category.liquids = Жидкости @@ -576,9 +600,10 @@ category.shooting = Стрельба category.optional = Дополнительные улучшения setting.landscape.name = Только альбомный (горизонтальный) режим setting.shadows.name = Тени -setting.blockreplace.name = Automatic Block Suggestions +setting.blockreplace.name = Автоматическая замена блоков setting.linear.name = Линейная фильтрация setting.hints.name = Подсказки +setting.buildautopause.name = Автоматическая приостановка строительства setting.animatedwater.name = Анимированная вода setting.animatedshields.name = Анимированные щиты setting.antialias.name = Сглаживание[lightgray] (требует перезапуска)[] @@ -599,14 +624,17 @@ setting.difficulty.insane = Безумная setting.difficulty.name = Сложность: setting.screenshake.name = Тряска экрана setting.effects.name = Эффекты -setting.destroyedblocks.name = Display Destroyed Blocks -setting.conveyorpathfinding.name = Conveyor Placement Pathfinding +setting.destroyedblocks.name = Отображать уничтоженные блоки +setting.conveyorpathfinding.name = Поиск пути для установки конвейеров setting.sensitivity.name = Чувствительность контроллера setting.saveinterval.name = Интервал сохранения setting.seconds = {0} секунд +setting.blockselecttimeout.name = Тайм-аут выбора блока +setting.milliseconds = {0} миллисекунд setting.fullscreen.name = Полноэкранный режим setting.borderlesswindow.name = Безрамочное окно[lightgray] (может потребоваться перезапуск) -setting.fps.name = Показывать FPS +setting.fps.name = Показывать FPS и пинг +setting.blockselectkeys.name = Показать клавиши выбора блока setting.vsync.name = Вертикальная синхронизация setting.pixelate.name = Пикселизация[lightgray] (отключает анимации) setting.minimap.name = Отображать мини-карту @@ -635,17 +663,36 @@ category.multiplayer.name = Сетевая игра command.attack = Атаковать command.rally = Точка сбора command.retreat = Отступить +placement.blockselectkeys = \n[lightgray]Клавиша: [{0}, keybind.clear_building.name = Очистить план строительства keybind.press = Нажмите клавишу… keybind.press.axis = Нажмите оси или клавишу… keybind.screenshot.name = Скриншот карты -keybind.move_x.name = Движение по оси x -keybind.move_y.name = Движение по оси y +keybind.toggle_power_lines.name = Отображение линий энергоснабжения +keybind.move_x.name = Движение по оси X +keybind.move_y.name = Движение по оси Y +keybind.category_prev.name = Предыдущая категория +keybind.category_next.name = Следующая категория +keybind.block_select_left.name = Выбор левого блока +keybind.block_select_right.name = Выбор правого блока +keybind.block_select_up.name = Выбор верхнего блока +keybind.block_select_down.name = Выбор нижнего блока +keybind.block_select_01.name = Категория/Выбор блока 1 +keybind.block_select_02.name = Категория/Выбор блока 2 +keybind.block_select_03.name = Категория/Выбор блока 3 +keybind.block_select_04.name = Категория/Выбор блока 4 +keybind.block_select_05.name = Категория/Выбор блока 5 +keybind.block_select_06.name = Категория/Выбор блока 6 +keybind.block_select_07.name = Категория/Выбор блока 7 +keybind.block_select_08.name = Категория/Выбор блока 8 +keybind.block_select_09.name = Категория/Выбор блока 9 +keybind.block_select_10.name = Категория/Выбор блока 10 +keybind.mouse_move.name = Следовать за курсором keybind.schematic_select.name = Выбрать область keybind.schematic_menu.name = Меню схем keybind.schematic_flip_x.name = Отразить схему по оси X keybind.schematic_flip_y.name = Отразить схему по оси Y -keybind.fullscreen.name = Полноэкранный режим +keybind.fullscreen.name = Переключение полноэкранного режима keybind.select.name = Выбор/Выстрел keybind.diagonal_placement.name = Диагональное размещение keybind.pick.name = Выбрать блок @@ -681,7 +728,9 @@ mode.pvp.description = Боритесь против других игроков mode.attack.name = Атака mode.attack.description = Уничтожьте вражескую базу. Никаких волн.\n[gray]Для игры требуется красное ядро на карте. mode.custom = Пользовательские правила + rules.infiniteresources = Бесконечные ресурсы (Игрок) +rules.reactorexplosions = Взрывы реакторов rules.wavetimer = Интервал волн rules.waves = Волны rules.attack = Режим атаки @@ -707,6 +756,10 @@ rules.title.resourcesbuilding = Ресурсы & строительство rules.title.player = Игроки rules.title.enemy = Враги rules.title.unit = Боев. ед. +rules.title.experimental = Эксперементально +rules.lighting = Освещение +rules.ambientlight = Окружающий свет + content.item.name = Предметы content.liquid.name = Жидкости content.unit.name = Боевые единицы @@ -768,6 +821,7 @@ mech.buildspeed = [lightgray]Скорость строительства: {0}% liquid.heatcapacity = [lightgray]Теплоёмкость: {0} liquid.viscosity = [lightgray]Вязкость: {0} liquid.temperature = [lightgray]Температура: {0} + block.sand-boulder.name = Песчаный валун block.grass.name = Трава block.salt.name = Соль @@ -866,6 +920,8 @@ block.distributor.name = Распределитель block.sorter.name = Сортировщик block.inverted-sorter.name = Инвертированный сортировщик block.message.name = Сообщение +block.illuminator.name = Осветитель +block.illuminator.description = Маленький, компактный, настраиваемый источник света. Требуется энергия для работы. block.overflow-gate.name = Избыточный затвор block.silicon-smelter.name = Кремниевый плавильный завод block.phase-weaver.name = Фазовый ткач @@ -879,6 +935,7 @@ block.coal-centrifuge.name = Угольная центрифуга block.power-node.name = Силовой узел block.power-node-large.name = Большой силовой узел block.surge-tower.name = Кинетическая вышка +block.diode.name = Диод block.battery.name = Аккумулятор block.battery-large.name = Большой аккумулятор block.combustion-generator.name = Генератор внутреннего сгорания @@ -931,6 +988,7 @@ block.fortress-factory.name = Завод мехов «Крепость» block.revenant-factory.name = Завод крейсеров «Мститель» block.repair-point.name = Ремонтный пункт block.pulse-conduit.name = Импульсный трубопровод +block.plated-conduit.name = Укреплённый трубопровод block.phase-conduit.name = Фазовый трубопровод block.liquid-router.name = Жидкостный маршрутизатор block.liquid-tank.name = Жидкостный бак @@ -982,37 +1040,38 @@ unit.eradicator.name = Искоренитель unit.lich.name = Лич unit.reaper.name = Жнец tutorial.next = [lightgray]<Нажмите для продолжения> -tutorial.intro = Вы начали[scarlet] обучение по Mindustry.[]\nНачните с [accent]добычи меди[]. Нажмите на медную жилу возле Вашего ядра, чтобы сделать это.\n\n[accent]{0}/{1} меди -tutorial.intro.mobile = Вы начали[scarlet] обучение по Mindustry.[]\nПроведите по экрану, чтобы двигаться.\n[accent] Сведите или разведите 2 пальца для []изменения масштаба.\nНачните с [accent]добычи меди[]. Приблизьтесь к ней, затем нажмите на медную жилу возле Вашего ядра, чтобы сделать это.\n\n[accent]{0}/{1} меди -tutorial.drill = Ручная добыча не является эффективной.\n[accent]Буры []могут добывать автоматически.\nНажмите на вкладку с изображением сверла снизу справа.\nВыберите[accent] механический бур[]. Разместите его на медной жиле нажатием.\n[accent]Нажатие по правой кнопке[] прервёт строительство. [accent]Зажмите Ctrl и покрутите колесо мыши[]для приближения или отдаления камеры. -tutorial.drill.mobile = Ручная добыча не является эффективной.\n[accent]Буры []могут добывать автоматически.\nНажмите на вкладку с изображением сверла снизу справа.\nВыберите[accent] механический бур[]. \nРазместите его на медной жиле нажатием, затемм нажмите [accent] белую галку[] ниже, чтобы подтвердить построение выделенного.\nНажмите [accent] кнопку X[], чтобы отменить размещение. +tutorial.intro = Вы начали[scarlet] обучение по Mindustry.[]\nИспользуйте кнопки [accent][[WASD][] для передвижения.\n[accent]Зажмите [[Ctrl] и покрутите колесо мыши[]для приближения или отдаления камеры.\nНачните с [accent]добычи меди[]. Приблизьтесь к ней, затем нажмите на медную жилу возле Вашего ядра, чтобы сделать это.\n\n[accent]{0}/{1} меди +tutorial.intro.mobile = Вы начали[scarlet] обучение по Mindustry.[]\nПроведите по экрану, чтобы двигаться.\n[accent]Сведите или разведите 2 пальца[] для изменения масштаба.\nНачните с [accent]добычи меди[]. Приблизьтесь к ней, затем нажмите на медную жилу возле Вашего ядра, чтобы сделать это.\n\n[accent]{0}/{1} меди +tutorial.drill = Ручная добыча не является эффективной.\n[accent]Буры[] могут добывать автоматически.\nНажмите на вкладку с изображением сверла снизу справа.\nВыберите[accent] механический бур[]. Разместите его на медной жиле нажатием.\n[accent]Нажатие по правой кнопке[] прервёт строительство. +tutorial.drill.mobile = Ручная добыча не является эффективной.\n[accent]Буры []могут добывать автоматически.\nНажмите на вкладку с изображением сверла снизу справа.\nВыберите[accent] механический бур[].\nРазместите его на медной жиле нажатием, затем нажмите [accent] белую галку[] ниже, чтобы подтвердить построение выделенного.\nНажмите [accent] кнопку X[], чтобы отменить размещение. tutorial.blockinfo = Каждый блок имеет разные характеристики. Каждая дрель может добывать определенные руды.\nЧтобы узнать информацию о блоке и о его характеристиках,[accent] нажмите на «?», когда он выбран в меню строительства.[]\n\n[accent]Сейчас, узнайте характеристики механического бура.[] tutorial.conveyor = [accent]Конвейеры[] используются для транспортировки ресуров в ядро.\nСделайте линию конвейеров от бура к ядру\n[accent]Удерживайте левую кнопку мыши, чтобы разместить в линию.[]\nУдерживайте[accent] CTRL[] при постройке линии блоков, чтобы сделать её диагональной\n\n[accent]Разместите 2 конвейера в линию и доставьте предметы в ядро. tutorial.conveyor.mobile = [accent]Конвейеры[] используются для транспортировки ресурсов в ядро\nСделайте линию конвейеров от бура к ядру\n[accent]Сделайте линию, удерживая палец несколько секунд в том месте, в котором Вы хотите начать линию,[] и перетяните его в нужном направлении.[accent]Разместите 2 конвейера в линию и доставьте предметы в ядро. tutorial.turret = Как только предмет попадает в ядро, его можно использовать в строительстве.\nИмейте в виду, что не все предметы могут быть использованы в строительстве.\nПредметы, которые нелья использовать для стоительства, такие как[accent] уголь[] или[accent] металлолом[], не могут быть транспортированы в ядро.\nЗащитные структуры нужно строить для отражения[lightgray] противников[].\nПостройте[accent] двойную турель[] возле Вашей базы. -tutorial.drillturret = Двойным турелям нужна [accent]медь []в качестве боеприпасов.\nРазместите бур рядом с турелью.\nПроведите конвейеры к турели, чтобы снабдить её медью.\n\n[accent]Боеприпасов доставлено: 0/1 -tutorial.pause = Во время битвы Вы можете[accent] приостановить игру.[]\nВы можете планировать строительство, когда игра стоит на паузе.\n\n[accent]Нажмите ПРОБЕЛ для приостановки игры. +tutorial.drillturret = Двойным турелям нужна [accent]медные боеприпасы[] для стрельбы.\nРазместите бур рядом с турелью.\nПроведите конвейеры к турели, чтобы снабдить её медью.\n\n[accent]Боеприпасов доставлено: 0/1 +tutorial.pause = Во время битвы, Вы можете[accent] приостановить игру.[]\nВы можете планировать строительство, когда игра стоит на паузе.\n\n[accent]Нажмите ПРОБЕЛ для приостановки игры. tutorial.pause.mobile = Во время битвы, Вы можете[accent] приостановить игру.[]\nВы можеть планировать строительство, когда игра стоит на паузе.\n\n[accent]Нажмите кнопку вверху слева, чтобы поставить игру на паузу. tutorial.unpause = Снова нажмите пробел для снятия паузы. tutorial.unpause.mobile = Снова нажмите туда для снятия паузы. tutorial.breaking = Зачастую, блоки приходится разрушать\n[accent]Зажмите ПКМ[], чтобы разрушить блоки в выбранной зоне.[]\n\n[accent]Разрушьте все стены из металлолома слева от Вашего ядра. -tutorial.breaking.mobile = Зачастую, блоки приходится разрушить.\n[accent]Выберите режим деконструкции[], после чего нажмите на нужный блок, чтобы разрушить его.\nРазрушьте блоки в выбранной зоне, зажав палец на несколько секунд[], и проведя его в нужном направлении.\nНажмите на галочку, чтобы подтвердить разрушение.\n\n[accent]Разрушьте все стены из металлолома слева от Вашего ядра. +tutorial.breaking.mobile = Зачастую, блоки приходится разрушать.\n[accent]Выберите режим деконструкции[], после чего нажмите на нужный блок, чтобы разрушить его.\nРазрушьте блоки в выбранной зоне, зажав палец на несколько секунд[], и проведя его в нужном направлении.\nНажмите на галочку, чтобы подтвердить разрушение.\n\n[accent]Разрушьте все стены из металлолома слева от Вашего ядра. tutorial.withdraw = В некоторых ситуациях, необходимо забрать предметы из блоков вручную.\nЧтобы сделать это, [accent]нажмите на блок[], в котором находятся предметы, затем [accent]нажмите на предмет[] в инвентаре.\nМожно забрать несколько предметов [accent]нажатием с зажимом[].\n\n[accent]Заберите немного меди из ядра[] -tutorial.deposit = Положить предметы в блоки можно перетащив от своего корабля к нужному блоку.\n\n[accent]Перенесите медь обратно в ядро[] +tutorial.deposit = Положите предметы в блок, перетащив их от своего корабля в нужный блок.\n\n[accent]Перенесите медь обратно в ядро[] tutorial.waves = [lightgray]Противники[] приближаются.\n\nЗащитите ядро от двух волн. Используйте[accent] левую кнопку мыши[] для стрельбы.\nПостройте больше турелей и буров. Добудьте больше меди. tutorial.waves.mobile = [lightgray]Противники[] приближаются.\n\nЗащитите ядро от двух волн. Ваш корабль будет автоматически атаковать противника.\nПостройте больше турелей и буров. Добудьте больше меди. tutorial.launch = Когда Вы достигаете определенной волны, Вы можете осуществить[accent] запуск ядра[], оставив базу и[accent] перенести ресурсы из ядра.[]\nЭти ресурсы могут быть использованы для изучения новых технологий.\n\n[accent]Нажмите кнопку запуска. + item.copper.description = Самый основной строительный материал. Широко используется во всех типах блоков. item.lead.description = Основной стартовый материал. Широко используется в электронике и блоках для транспортировки жидкостей. item.metaglass.description = Сверхпрочный сплав стекла. Широко используется для распределения и хранения жидкости. item.graphite.description = Минерализованный углерод, используемый для боеприпасов и электроизоляции. -item.sand.description = Обычный материал, который широко используется при выплавке, как при легировании, так и в качестве отходов. +item.sand.description = Обычный материал, который широко используется при выплавке, как при легировании, так и в качестве флюса. item.coal.description = Окаменелое растительное вещество, образовавшееся задолго до посева. Широко используется для производства топлива и ресурсов. item.titanium.description = Редкий сверхлёгкий металл, широко используемый для транспортировки жидкостей, буров и авиации. item.thorium.description = Плотный радиоактивный металл, используемый в качестве структурной опоры и ядерного топлива. item.scrap.description = Остатки старых сооружений и подразделений. Содержит небольшие количества многих различных металлов. item.silicon.description = Чрезвычайно полезный полупроводник. Применяется в солнечных панелях, сложной электронике и самонаводящихся боеприпасах. -item.plastanium.description = Лёгкий, пластичный материал, используемый в современных авиационных и осколочных боеприпасах. +item.plastanium.description = Лёгкий, пластичный материал, используемый в продвинутой авиации и осколочных боеприпасах. item.phase-fabric.description = Практически невесомое вещество, используемое в передовой электронике и технологиях самовосстановления. item.surge-alloy.description = Современный сплав с уникальными электрическими свойствами. item.spore-pod.description = Стручок синтетических спор, синтезированных из атмосферных концентраций для промышленных целей. Используется для превращения в нефть, взрывчатые вещества и топливо. @@ -1024,9 +1083,9 @@ liquid.oil.description = Жидкость, используемая в прои liquid.cryofluid.description = Инертная, неедкая жидкость, созданная из воды и титана. Обладает чрезвычайно высокой теплоёмкостью. Широко используется в качестве охлаждающей жидкости. mech.alpha-mech.description = Стандартный управляемый мех. Основан на «Кинжале», с улучшенной броней и строительными возможностями. Имеет больший урон, чем «Дротик». mech.delta-mech.description = Быстрый, легко бронированный мех, созданный для ударов «атакуй и беги». Наносит мало урона по строениям, но может очень быстро убить большие группы вражеских орудий с помощью дуговых молний. -mech.tau-mech.description = Мех поддержки. Ремонтирует союзные блоки просто стреляя в них. Может лечить союзников в радиусе его ремонтирующей способности. +mech.tau-mech.description = Мех поддержки. Ремонтирует союзные блоки, просто стреляя в них. Может лечить союзников в радиусе его ремонтирующей способности. mech.omega-mech.description = Громоздкий и хорошо бронированный мех, созданный для передовых атак. Его броня может блокировать до 90% входящего урона. -mech.dart-ship.description = Стандартный управляемый корабль. Достаточно быстрый и легкий, но мало атакующий и обладает низкой скоростью добычи. +mech.dart-ship.description = Стандартный управляемый корабль. Достаточно быстрый и легкий, но обладает слабым вооружением и низкой скоростью добычи. mech.javelin-ship.description = Корабль для тактики «атакуй и беги». Сначала он медленный, но позже может разгоняться до огромных скоростей и летать над аванпостами противника, нанося большой урон молниями и ракетами. mech.trident-ship.description = Тяжёлый бомбардировщик, построенный для строительства и уничтожения вражеских укреплений. Достаточно хорошо бронированный. mech.glaive-ship.description = Большой хорошо бронированный боевой корабль. Оборудован зажигательным повторителем. Очень манёвренный. @@ -1045,14 +1104,14 @@ block.message.description = Сохраняет сообщение. Исполь block.graphite-press.description = Сжимает куски угля в чистые листы графита. block.multi-press.description = Обновлённая версия графитовой печати. Использует воду и энергию для быстрой и эффективной переработки угля. block.silicon-smelter.description = Соединяет песок с чистым углем. Производит кремний. -block.kiln.description = Выплавляет песок и свинец в соединение, известному как метастекло. Требуется небольшое количество энергии для запуска. +block.kiln.description = Выплавляет песок и свинец в соединение, известное как метастекло. Требуется небольшое количество энергии для работы. block.plastanium-compressor.description = Производит пластаний из нефти и титана. -block.phase-weaver.description = Синтезирует фазовую ткань из радиоактивного тория и песка. Требуется огромное количество энергии. +block.phase-weaver.description = Синтезирует фазовую ткань из радиоактивного тория и песка. Требуется огромное количество энергии для работы. block.alloy-smelter.description = Объединяет титан, свинец, кремний и медь для производства кинетического сплава. block.cryofluidmixer.description = Смешивает воду и мелкий титановый порошок титана в криогеннную жидкость. Неотъемлемая часть при использования ториевого реактора block.blast-mixer.description = Раздавливает и смешивает скопления спор с пиротитом для получения взрывчатого вещества. block.pyratite-mixer.description = Смешивает уголь, свинец и песок в легковоспламеняющийся пиротит. -block.melter.description = Плавит металлолом в шлак для дальнейшей обработки или использования в башнях «Волна». +block.melter.description = Плавит металлолом в шлак для дальнейшей обработки или использования в турелях «Волна». block.separator.description = Разделяет шлак на его минеральные компоненты. Выводит охлажденный результат. block.spore-press.description = Сжимает капсулы спор под сильным давлением для синтеза масла. block.pulverizer.description = Измельчает металлолом в мелкий песок. @@ -1063,12 +1122,12 @@ block.power-source.description = Бесконечно вводит энерги block.item-source.description = Бесконечно выводит элементы. Только песочница. block.item-void.description = Уничтожает любые предметы. Только песочница. block.liquid-source.description = Бесконечно выводит жидкости. Только песочница. -block.copper-wall.description = Дешёвый защитный блок.\nПолезно для защиты ядра и турелей в первые несколько волн. -block.copper-wall-large.description = Дешёвый защитный блок.\nПолезно для защиты ядра и турелей в первые несколько волн.\nРазмещается на нескольких плитках. +block.copper-wall.description = Дешёвый защитный блок.\nПолезен для защиты ядра и турелей в первые несколько волн. +block.copper-wall-large.description = Дешёвый защитный блок.\nПолезен для защиты ядра и турелей в первые несколько волн.\nРазмещается на нескольких плитках. block.titanium-wall.description = Умеренно сильный защитный блок.\nОбеспечивает умеренную защиту от врагов. block.titanium-wall-large.description = Умеренно сильный защитный блок.\nОбеспечивает умеренную защиту от врагов.\nРазмещается на нескольких плитках. -block.plastanium-wall.description = Специальный тип стены, который поглощает электрические разряды и блокирует автоматическое соединение между силовыми узлами.\nРазмещается на нескольких плитках. -block.plastanium-wall-large.description = A special type of wall that absorbs electric arcs and blocks automatic power node connections.\nSpans multiple tiles. +block.plastanium-wall.description = Специальный тип стены, который поглощает электрические разряды и блокирует автоматическое соединение между силовыми узлами. +block.plastanium-wall-large.description = Специальный тип стены, который поглощает электрические разряды и блокирует автоматическое соединение между силовыми узлами.\nРазмещается на нескольких плитках. block.thorium-wall.description = Сильный защитный блок.\nХорошая защита от врагов. block.thorium-wall-large.description = Сильный защитный блок.\nХорошая защита от врагов.\nРазмещается на нескольких плитках. block.phase-wall.description = Стена, покрытая специальным фазовым отражающим составом. Отражает большинство пуль при ударе. @@ -1077,37 +1136,39 @@ block.surge-wall.description = Очень прочный защитный бло block.surge-wall-large.description = Очень прочный защитный блок.\nНакапливает заряд при контакте с пулей, выпуская его случайным образом.\nРазмещается на нескольких плитках. block.door.description = Маленькая дверь. Можно открыть или закрыть нажатием. block.door-large.description = Большая дверь. Можно открыть и закрыть нажатием.\nРазмещается на нескольких плитках. -block.mender.description = Периодически ремонтирует блоки в непосредственной близости. Сохраняет средства защиты, восстановленные между волнами.\nОпционально использует кремний для увеличения дальности и эффективности. -block.mend-projector.description = Обновлённая версия Регенератора. Ремонт блоков в непосредственной близости.\nОпционально использует фазовую ткань для увеличения дальности и эффективности. +block.mender.description = Периодически ремонтирует блоки в непосредственной близости. Сохраняет средства защиты в целостности между волнами.\nОпционально использует кремний для увеличения дальности и эффективности. +block.mend-projector.description = Обновлённая версия Регенератора. Ремонтирует блоки в непосредственной близости.\nОпционально использует фазовую ткань для увеличения дальности и эффективности. block.overdrive-projector.description = Увеличивает скорость близлежащих зданий.\nОпционально использует фазовую ткань для увеличения дальности и эффективности. -block.force-projector.description = Создает вокруг себя шестиугольное силовое поле, защищая здания и подразделения внутри от повреждений.\nПерегревается, если нанесено слишком большое количество повреждений. Опционально требуется охлаждающая жидкость для предотвращения перегрева. Фазовая ткань может быть использована для увеличения размера щита. +block.force-projector.description = Создает вокруг себя шестиугольное силовое поле, защищая здания и подразделения внутри от повреждений.\nПерегревается, если нанесено слишком большое количество повреждений. Опционально использует охлаждающую жидкость для предотвращения перегрева. Фазовая ткань может быть использована для увеличения размера щита. block.shock-mine.description = Наносит урон врагам, наступающим на мину. Почти невидима для врага. block.conveyor.description = Базовый элемент транспортного блока. Перемещает предметы вперед и автоматически складывает их в блоки. Можно повернуть. -block.titanium-conveyor.description = Расширенный транспортный блок. Перемещает предметы быстрее, чем стандартные конвейеры. -block.junction.description = Действует как мост для двух пересекающихся конвейерных лент. Полезно в ситуациях, когда два разных конвейера перевозят разные материалы в разные места. -block.bridge-conveyor.description = Улучшенный транспортный блок. Позволяет транспортировать предметы по 3 плиткам любой местности или здания. -block.phase-conveyor.description = Улучшенный транспортный блок. Использует энергию для телепортации предметов на подключенный фазовый конвейер по нескольким плиткам. +block.titanium-conveyor.description = Улучшенный транспортный блок. Перемещает предметы быстрее, чем стандартные конвейеры. +block.junction.description = Действует как мост для двух пересекающихся конвейерных лент. Полезен в ситуациях, когда два разных конвейера перевозят разные материалы в разные места. +block.bridge-conveyor.description = Улучшенный транспортный блок. Позволяет транспортировать предметы над 3 плитками любой местности или здания. +block.phase-conveyor.description = Улучшенный транспортный блок. Использует энергию для телепортации предметов на подключенный фазовый конвейер над несколькими плитками. block.sorter.description = Сортирует предметы. Если предмет соответствует выбору, он может пройти. В противном случае предмет выводится слева и справа. block.inverted-sorter.description = Работает с предметами так же, как и стандартный сортировщик, но выводит выбранный предмет по бокам, а не прямо. -block.router.description = Принимает предмет в одном направлении и выводит их до 3 других направлений в равной степени. Полезно для разделения материалов из одного источника на несколько целей.\n\n[scarlet]Никогда не используйте рядом с заводами и т.п., так как маршрутизатор будет забит выходными предметами.[] -block.distributor.description = Расширенный маршрутизатор. Разделение элементов до 7 других направлений в равной степени. -block.overflow-gate.description = Комбинированный разделитель и маршрутизатор. Выводит только влево и вправо, если передний путь заблокирован. -block.mass-driver.description = Конечный транспортный блок. Собирает несколько предметов и затем стреляет ими в другую катапульту на большом расстоянии. Требуется энергия для работы. +block.router.description = Принимает предмет в одном направлении и выводит их до 3 других направлений в равной степени. Полезен для разделения материалов из одного источника на несколько целей.\n\n[scarlet]Никогда не используйте рядом с заводами и т.п., так как маршрутизатор будет забит выходными предметами.[] +block.distributor.description = Расширенный маршрутизатор. Разделяет предметы до 7 других направлений в равной степени. +block.overflow-gate.description = Выводит предметы влево и вправо, только если передний путь заблокирован. +block.mass-driver.description = Самый продвинутый транспортного блока. Собирает несколько предметов и затем стреляет ими в другую катапульту на большом расстоянии. Требуется энергия для работы. block.mechanical-pump.description = Дешёвый насос с низкой производительностью, но без энергопотребления. block.rotary-pump.description = Продвинутый насос. Качает больше жидкости, но требуют энергию. block.thermal-pump.description = Наилучший насос. block.conduit.description = Основной блок транспортировки жидкости. Перемещает жидкости вперед. Используется совместно с насосами и другими трубопроводами. -block.pulse-conduit.description = Расширенный блок транспортировки жидкости. Транспортирует жидкости быстрее и хранит больше, чем стандартные трубопроводы. -block.liquid-router.description = Принимает жидкости из одного направления и выводит их до 3 других направлений в равной степени. Можно также хранить определенное количество жидкости. Полезно для разделения жидкостей из одного источника на несколько целей. +block.pulse-conduit.description = Улучшенный блок транспортировки жидкости. Транспортирует жидкости быстрее и хранит больше, чем стандартные трубопроводы. +block.plated-conduit.description = Перемещает жидкости с той же скоростью, что и импульсные трубопроводы, но обладает большей прочностью. Не принимает жидкости со сторон, кроме как от других трубопроводов.\nПротекает меньше. +block.liquid-router.description = Принимает жидкости из одного направления и выводит их до 3 других направлений в равной степени. Также может хранить определенное количество жидкости. Полезен для разделения жидкостей из одного источника на несколько целей. block.liquid-tank.description = Хранит большое количество жидкости. Используется для создания буферов в ситуациях с непостоянной потребностью в материалах или в качестве защиты для охлаждения жизненно важных блоков. -block.liquid-junction.description = Действует как мост для двух пересекающихся каналов. Полезно в ситуациях, когда два разных трубопровода переносят разные жидкости в разные места. +block.liquid-junction.description = Действует как мост для двух пересекающихся каналов. Полезен в ситуациях, когда два разных трубопровода переносят разные жидкости в разные места. block.bridge-conduit.description = Расширенный блок транспортировки жидкости. Позволяет транспортировать жидкости над 3 плитками любой местности или здания. block.phase-conduit.description = Расширенный блок транспортировки жидкости. Использует энергию для телепортации жидкостей в подключенный фазовый канал над несколькими плиткам. block.power-node.description = Передает питание на подключенные узлы. Узел будет получать питание или поставлять питание на любые соседние блоки. -block.power-node-large.description = Усовершенствованный силовой узел с большей дальностью и большим количеством соединений. +block.power-node-large.description = Усовершенствованный силовой узел с большей дальностью. block.surge-tower.description = Силовой узел с очень большим радиусом действия, но меньшим количеством доступных соединений. +block.diode.description = Энергия из аккумуляторов имеет возможность перемещаться через этот блок в одну сторону, если на выходе имеется меньше энергии в запасе, чем на входе. block.battery.description = Накапливает энергию как буфер во времена избытка энергии. Выводит энергию во времена дефицита. -block.battery-large.description = Хранит гораздо больше энергии, чем обычная батарея. +block.battery-large.description = Хранит гораздо больше энергии, чем обычный аккумулятор. block.combustion-generator.description = Вырабатывает энергию путём сжигания легковоспламеняющихся материалов, таких как уголь. block.thermal-generator.description = Генерирует энергию, когда находится в горячих местах. block.turbine-generator.description = Усовершенствованный генератор сгорания. Более эффективен, но дополнительно требует воду для выработки пара. @@ -1116,28 +1177,28 @@ block.rtg-generator.description = Простой, надежный генера block.solar-panel.description = Обеспечивает небольшое количество энергии от солнца. block.solar-panel-large.description = Значительно более эффективный вариант стандартной солнечной панели. block.thorium-reactor.description = Генерирует значительное количество энергии из тория. Требует постоянного охлаждения. Взорвётся с большой силой при недостаточном количестве охлаждающей жидкости. Выходная энергия зависит от наполненности, при этом базовая энергия генерируется на полную мощность. -block.impact-reactor.description = Усовершенствованный генератор, способный создавать огромное количество энергии с максимальной эффективностью. Требуется значительное количество энергии для запуска процесса. -block.mechanical-drill.description = Дешёвый бур. При размещении на соответствующих плитках, предметы бесконечно выводятся в медленном темпе. Способен добывать только медь, свинец и уголь. +block.impact-reactor.description = Усовершенствованный генератор, способный создавать огромное количество энергии на пике эффективности. Требуется значительное количество энергии для запуска процесса. +block.mechanical-drill.description = Дешёвый бур. При размещении на соответствующих плитках, предметы бесконечно выводятся в медленном темпе. Способен добывать только базовые ресурсы. block.pneumatic-drill.description = Улучшенный бур, способный добывать титан. Добывает быстрее, чем механический бур. block.laser-drill.description = Позволяет сверлить еще быстрее с помощью лазерной технологии, но требует энергии. Способен добывать торий. -block.blast-drill.description = Конечный бур. Требует большое количества энергии. +block.blast-drill.description = Самый продвинутый бура. Требует большое количества энергии. block.water-extractor.description = Выкачивает подземные воды. Используется в местах, где нет поверхностных вод. block.cultivator.description = Выращивает крошечные концентрации спор в атмосфере в готовые к использованию споры. block.oil-extractor.description = Использует большое количество энергии, песка и воды для бурения, добывая нефть. -block.core-shard.description = Первая итерация капсулы ядра. После уничтожения весь контакт с регионом теряется. Не позволяйте этому случиться. +block.core-shard.description = Первая итерация капсулы ядра. После уничтожения, весь контакт с регионом теряется. Не позволяйте этому случиться. block.core-foundation.description = Вторая версия ядра. Лучше бронировано. Хранит больше ресурсов. block.core-nucleus.description = Третья и последняя итерация капсулы ядра. Очень хорошо бронировано. Хранит огромное количество ресурсов. block.vault.description = Хранит большое количество предметов каждого типа. Блок разгрузчика может быть использован для извлечения предметов из хранилища. block.container.description = Хранит небольшое количество предметов каждого типа. Блок разгрузчика может быть использован для извлечения элементов из контейнера. -block.unloader.description = Выгружает предметы из контейнера, хранилища или ядра на конвейер или непосредственно в соседний блок. Тип элемента, который необходимо Выгрузить, можно изменить, коснувшись. +block.unloader.description = Выгружает предметы из любого нетранспортного блока. Тип предмета, который необходимо выгрузить, можно изменить нажатием. block.launch-pad.description = Запускает партии предметов без необходимости запуска ядра. block.launch-pad-large.description = Улучшенная версия стартовой площадки. Хранит больше предметов. Запускается чаще. block.duo.description = Маленькая, дешёвая турель. Полезна против наземных юнитов. block.scatter.description = Основная противовоздушная турель. Распыляет куски свинца или металлолома на вражеские подразделения. -block.scorch.description = Сжигает любых наземных врагов рядом с ним. Высокоэффективна на близком расстоянии. +block.scorch.description = Сжигает любых наземных врагов рядом с ним. Высокоэффективен на близком расстоянии. block.hail.description = Маленькая дальнобойная артиллерийская турель. block.wave.description = Турель среднего размера. Стреляет потоками жидкости по врагам. Автоматически тушит пожары при подаче воды. -block.lancer.description = Лазерная турель среднего размера. Заряжает и стреляет мощными лучами энергии. +block.lancer.description = Лазерная турель среднего размера. Заряжает и стреляет мощными лучами энергии по наземным целям. block.arc.description = Небольшая электрическая турель ближнего радиуса действия. Выстреливает дуги электричества по врагам. block.swarmer.description = Ракетная турель среднего размера. Атакует как воздушных, так и наземных врагов. Запускает самонаводящиеся ракеты. block.salvo.description = Большая, более продвинутая версия двойной турели. Выпускает быстрые залпы из пуль по врагу. @@ -1147,21 +1208,21 @@ block.cyclone.description = Большая противовоздушная и block.spectre.description = Массивная двуствольная пушка. Стреляет крупными бронебойными пулями по воздушным и наземным целям. block.meltdown.description = Массивная лазерная пушка. Заряжает и стреляет постоянным лазерным лучом в ближайших врагов. Требуется охлаждающая жидкость для работы. block.command-center.description = Командует перемещениями боевых единиц по всей карте.\nУказывает подразделениям [accent]собираться[] вокруг командного центра, [accent]атаковать[] вражеское ядро или [accent]отступать[] к ядру/фабрике. Если вражеское ядро отсутствует, единицы будут патрулировать при команде [accent]атаки[]. -block.draug-factory.description = Производит добывающих дронов. -block.spirit-factory.description = Производит дронов, которые ремонтируют постройки. +block.draug-factory.description = Производит добывающих дронов «Драугр». +block.spirit-factory.description = Производит дронов «Дух», которые ремонтируют постройки. block.phantom-factory.description = Производит улучшенных дронов, которые помогают в строительстве. block.wraith-factory.description = Производит быстрые и летающие боевые единицы. -block.ghoul-factory.description = Производит тяжёлых ковровых бомбардировщиков. -block.revenant-factory.description = Производит тяжёлые летающие боевые единицы. -block.dagger-factory.description = Производит основных наземных боевые единиц. -block.crawler-factory.description = Производит быстрых саморозрушающихся боевые единиц. +block.ghoul-factory.description = Производит тяжёлые ковровые бомбардировщики. +block.revenant-factory.description = Производит тяжёлые летающие боевые единицы, вооружённые ракетами. +block.dagger-factory.description = Производит основные наземные боевые единицы. +block.crawler-factory.description = Производит быстрые саморазрушающиеся боевые единицы. block.titan-factory.description = Производит продвинутые бронированные боевые единицы. block.fortress-factory.description = Производит тяжёлые артиллерийские боевые единицы. -block.repair-point.description = Непрерывно лечит ближайший поврежденную боевую единицу или мех, находящийся рядом. -block.dart-mech-pad.description = Обеспечивает превращение в базовый атакующий мех. \nИспользуйте, нажав, стоя на нём. +block.repair-point.description = Непрерывно лечит ближайшую поврежденную боевую единицу или мех в своём радиусе. +block.dart-mech-pad.description = Обеспечивает превращение в базовый атакующий мех.\nИспользуйте, нажав, стоя на нём. block.delta-mech-pad.description = Обеспечивает превращение в легкобронированный атакующий мех.\nИспользуйте, нажав, стоя на нём. -block.tau-mech-pad.description = Обеспечивает превращение в улучшенный мех поддержки.\nИспользуйте, нажав, стоя на нём. +block.tau-mech-pad.description = Обеспечивает превращение в продвинутый мех поддержки.\nИспользуйте, нажав, стоя на нём. block.omega-mech-pad.description = Обеспечивает превращение в тяжелобронированный ракетный мех.\nИспользуйте, нажав, стоя на нём. block.javelin-ship-pad.description = Обеспечивает превращение в быстрый перехватчик в лёгкой броне.\nИспользуйте, нажав, стоя на нём. -block.trident-ship-pad.description = Обеспечивает превращение в тяжёлый бомбардировщик.\nИспользуйте, нажав, стоя на нём. +block.trident-ship-pad.description = Обеспечивает превращение в тяжёлый бомбардировщик поддержки.\nИспользуйте, нажав, стоя на нём. block.glaive-ship-pad.description = Обеспечивает превращение в большой, хорошо бронированный боевой корабль.\nИспользуйте, нажав, стоя на нём. diff --git a/core/assets/bundles/bundle_uk_UA.properties b/core/assets/bundles/bundle_uk_UA.properties index 1d188a100b..07cbede5c6 100644 --- a/core/assets/bundles/bundle_uk_UA.properties +++ b/core/assets/bundles/bundle_uk_UA.properties @@ -10,6 +10,7 @@ link.dev-builds.description = Нестабільні версії link.trello.description = Офіційна дошка Trello для запланованих функцій link.itch.io.description = Itch.io сторінка, на якій можна завантажити гру link.google-play.description = Завантажити для Android з Google Play +link.f-droid.description = Перелік каталогу F-Droid link.wiki.description = Офіційна Mindustry wiki linkfail = Не вдалося відкрити посилання!\nURL-адреса скопійована в буфер обміну. screenshot = Зняток мапи збережено в {0} @@ -74,14 +75,23 @@ maps.browse = Перегляд мап continue = Продовжити maps.none = [lightgray]Мап не знайдено! invalid = Недійсне +pickcolor = Вибрати колір preparingconfig = Підготовка конфігурації preparingcontent = Підготовка вмісту uploadingcontent = Вивантаження вмісту uploadingpreviewfile = Вивантаження файлу передперегляду committingchanges = Здійснення змін done = Зроблено -feature.unsupported = Ваш пристрій не підтримує цю особливість. -mods.alphainfo = Майте на увазі, що модифікації знаходяться в альфі, і [scarlet]можуть бути дуже глючними[].\nПовідомте про будь-які проблеми, які ви знайдете до Mindustry GitHub або Discord. +mods = Модифікації +mods.alphainfo = Майте на увазі, що модифікації знаходяться в альфі, і [scarlet]може бути дуже глючними[].\nПовідомте про будь-які проблеми, які ви знайдете до Mindustry Github або Discord. +mods.alpha = [scarlet](Альфа) +mods.none = [LIGHT_GRAY]Модифікацій не знайдено! +mod.enabled = [lightgray]Увімкнено +mod.disabled = [scarlet]Вимкнено +mod.requiresrestart = А тепер гра закриється, щоб застосувати зміни модифікацій. +mod.import = Імпортувати модифікацію +mod.remove.confirm = Цю модифікацію буде видалено. +mod.author = [LIGHT_GRAY]Автор:[] {0} mods.alpha = [scarlet](Альфа) mods = Модифікації mods.none = [LIGHT_GRAY]Модифікацій не знайдено! @@ -92,6 +102,7 @@ mod.enabled = [lightgray]Увімкнено mod.disabled = [scarlet]Вимкнено mod.disable = Вимкнути mod.delete.error = Неможливо видалити модифікацію. Файл, можливо, використовується. +mod.requiresversion = [scarlet]Необхідна версія гри: [accent]{0} mod.missingdependencies = [scarlet]Відсутні залежності: {0} mod.nowdisabled = [scarlet]Модифікації '{0}' не вистачає залежностей:[accent] {1}\n[lightgray]Ці модифікації потрібно завантажити спочатку.\nЦя модифікація буду автоматично вимкнена. mod.enable = Увімкнути @@ -237,10 +248,10 @@ quit.confirm.tutorial = Ви впевнені, що хочете вийти з loading = [accent]Завантаження… reloading = [accent]Перезавантаження модифікацій… saving = [accent]Збереження… -cancelbuilding = [accent][[{0}][] to clear plan -selectschematic = [accent][[{0}][] to select+copy -pausebuilding = [accent][[{0}][] to pause building -resumebuilding = [scarlet][[{0}][] to resume building +cancelbuilding = [accent][[{0}][], щоб очистити план +selectschematic = [accent][[{0}][], щоб вибрати та скопіювати +pausebuilding = [accent][[{0}][], щоб призупинити будування +resumebuilding = [scarlet][[{0}][], щоб продовжити будування wave = [accent]Хвиля {0} wave.waiting = Хвиля через {0} wave.waveInProgress = [lightgray]Хвиля триває @@ -411,9 +422,9 @@ abandon = Покинути abandon.text = Ця зона і всі її ресурси будуть втрачені. locked = Заблоковано complete = [lightgray]Досягнута: -requirement.wave = Reach Wave {0} in {1} -requirement.core = Destroy Enemy Core in {0} -requirement.unlock = Unlock {0} +requirement.wave = Досягніть хвилі {0} у {1} +requirement.core = Знишьте вороже ядро у {0} +requirement.unlock = Розблокуйте {0} resume = Відновити зону:\n[lightgray]{0} bestwave = [lightgray]Найкраща хвиля: {0} launch = < ЗАПУСК > @@ -424,8 +435,8 @@ launch.confirm = Це видалить всі ресурси у Вашому я launch.skip.confirm = Якщо Ви пропустите зараз, Ви не зможете не запускати до більш пізніх хвиль. uncover = Розкрити configure = Вивантажити конфігурацію -bannedblocks = Banned Blocks -addall = Add All +bannedblocks = Заборонені блоки +addall = Додати все configure.locked = [lightgray]Можливість розблокувати вивантаження ресурсів буде доступна на {0}-тій хвилі. configure.invalid = Кількість повинна бути числом між 0 та {0}. zone.unlocked = Зона «[lightgray]{0}» тепер розблокована. @@ -479,6 +490,7 @@ settings.language = Мова settings.data = Ігрові дані settings.reset = Скинути за замовчуванням settings.rebind = Зміна +settings.resetKey = Скинути settings.controls = Керування settings.game = Гра settings.sound = Звук @@ -487,8 +499,8 @@ settings.cleardata = Очистити дані… settings.clear.confirm = Ви впевнені, що хочете очистити ці дані?\nЦя дія не може бути скасовано! settings.clearall.confirm = [scarlet]УВАГА![]\nЦе очистить всі дані, включаючи збереження, мапи, розблоковане та налаштування керування.\nПісля того, як ви натиснете ОК, гра видалить усі дані та автоматично закриється. paused = Пауза -clear = Clear -banned = [scarlet]Banned +clear = Очистити +banned = [scarlet]Заблоковано yes = Так no = Ні info.title = Інформація @@ -544,6 +556,8 @@ bar.heat = Нагрівання bar.power = Енергія bar.progress = Хід будування bar.spawned = Бойов. од.: {0}/{1} +bar.input = Ввід +bar.output = Вивід bullet.damage = [stat]{0}[lightgray] шкода bullet.splashdamage = [stat]{0}[lightgray] шкода по ділянці ~[stat] {1}[lightgray] блок. bullet.incendiary = [stat]запальний @@ -559,6 +573,8 @@ unit.blocks = блоки unit.powersecond = одиниць енергії за секунду unit.liquidsecond = одиниць рідини за секунду unit.itemssecond = предметів за секунду +unit.thousands = тис +unit.millions = млн unit.liquidunits = одиниць рідини unit.powerunits = одиниць енергії unit.degrees = град. @@ -578,7 +594,8 @@ setting.landscape.name = Тільки альбомний(гозинтальни setting.shadows.name = Тіні setting.blockreplace.name = Пропозиції щодо автоматичної заміни блоків setting.linear.name = Лінійна фільтрація -setting.hints.name = Hints +setting.hints.name = Підказки +setting.buildautopause.name = Автоматичне призупинення будування setting.animatedwater.name = Анімована вода setting.animatedshields.name = Анімовані щити setting.antialias.name = Згладжування[lightgray] (потребує перезапуску)[] @@ -600,16 +617,19 @@ setting.difficulty.name = Складність: setting.screenshake.name = Тряска екрану setting.effects.name = Ефекти setting.destroyedblocks.name = Показувати зруйновані блоки -setting.conveyorpathfinding.name = Пошук шляху для встановлення конвейерівConveyor Placement Pathfinding +setting.conveyorpathfinding.name = Пошук шляху для встановлення конвейерів setting.sensitivity.name = Чутливість контролера setting.saveinterval.name = Інтервал збереження setting.seconds = {0} с +setting.blockselecttimeout.name = Час вибору блока +setting.milliseconds = {0} мілісекунд setting.fullscreen.name = Повноекранний режим setting.borderlesswindow.name = Вікно без полів[lightgray] (може потребувати перезапуску) setting.fps.name = Показувати FPS і затримку до сервера +setting.blockselectkeys.name = Показувати клавіші вибору блока setting.vsync.name = Вертикальна синхронізація setting.pixelate.name = Пікселізація[lightgray] (вимикає анімації) -setting.minimap.name = Показувати міні-мапу +setting.minimap.name = Показувати мінімапу setting.position.name = Показувати координати гравця setting.musicvol.name = Гучність музики setting.ambientvol.name = Звуки навколишнього середовища @@ -620,10 +640,10 @@ setting.crashreport.name = Відсилати анонімні звіти про setting.savecreate.name = Автоматичне створення збережень setting.publichost.name = Загальнодоступність гри setting.chatopacity.name = Непрозорість чату -setting.lasersopacity.name = Power Laser Opacity +setting.lasersopacity.name = Непрозорість лазерів енергопостачання setting.playerchat.name = Відображати хмару чата над гравцями -public.confirm = Ви хочете зробити цю гру загальнодоступною?\n[lightgray]Це можна змінити у Налаштування->Гра->Public Game Visibility. -public.beta = Note that beta versions of the game cannot make public lobbies. +public.confirm = Ви хочете зробити цю гру загальнодоступною?\n[lightgray]Це можна змінити у Налаштування→Гра→Загальнодоступність гри +public.beta = Зауважте, що в бета-версії гри ви не можете робити публічні ігри. uiscale.reset = Масштаб користувальницького інтерфейсу було змінено.\nНатисніть «ОК» для підтверждення цього масшатабу.\n[scarlet]Повернення налаштувань і вихід через[accent] {0}[] … uiscale.cancel = Скасувати & Вийти setting.bloom.name = Світіння @@ -635,17 +655,37 @@ category.multiplayer.name = Мережева гра command.attack = Атакувати command.rally = Точка збору command.retreat = Відступити +placement.blockselectkeys = \n[lightgray]Ключ: [{0}, keybind.clear_building.name = Очистити план будування keybind.press = Натисніть клавішу… keybind.press.axis = Натисніть клавішу… keybind.screenshot.name = Зняток мапи +keybind.toggle_power_lines.name = Показувати лазери енергопостачання keybind.move_x.name = Рух по осі X keybind.move_y.name = Рух по осі Y +keybind.mouse_move.name = Слідкувати за мишею +keybind.dash.name = Прискорення keybind.schematic_select.name = Вибрати ділянку keybind.schematic_menu.name = Меню схем keybind.schematic_flip_x.name = Відобразити по осі X keybind.schematic_flip_y.name = Відобразити по осі Y -keybind.fullscreen.name = Повноекранний +keybind.category_prev.name = Попередня категорія +keybind.category_next.name = Наступна категорія +keybind.block_select_left.name = Вибрати блок ліворуч +keybind.block_select_right.name = Вибрати блок ліворуч праворуч +keybind.block_select_up.name = Вибрати блок зверху +keybind.block_select_down.name = Вибрати блок знизу +keybind.block_select_01.name = Категорія/Вибрати перший блок +keybind.block_select_02.name = Категорія/Вибрати другий блок +keybind.block_select_03.name = Категорія/Вибрати третій блок +keybind.block_select_04.name = Категорія/Вибрати четвертий блок +keybind.block_select_05.name = Категорія/Вибрати п’ятий блок +keybind.block_select_06.name = Категорія/Вибрати шостий блок +keybind.block_select_07.name = Категорія/Вибрати сьомий блок +keybind.block_select_08.name = Категорія/Вибрати восьмий блок +keybind.block_select_09.name = Категорія/Вибрати дев’ятий блок +keybind.block_select_10.name = Категорія/Вибрати десятий блок +keybind.fullscreen.name = Повноекранний режим keybind.select.name = Вибір/Постріл keybind.diagonal_placement.name = Діагональне розміщення keybind.pick.name = Вибрати блок @@ -658,7 +698,6 @@ keybind.menu.name = Меню keybind.pause.name = Пауза keybind.pause_building.name = Призупинити/Продовжити будування keybind.minimap.name = Мінімапа -keybind.dash.name = Прискоритися & летіітати keybind.chat.name = Чат keybind.player_list.name = Список гравців keybind.console.name = Консоль @@ -682,6 +721,7 @@ mode.attack.name = Атака mode.attack.description = Зруйнуйте ворожу базу.\n[gray]Потрібно червоне ядро на мапі для гри. mode.custom = Користувацькі правила rules.infiniteresources = Нескінченні ресурси +rules.reactorexplosions = Вибухи реактора rules.wavetimer = Таймер хвиль rules.waves = Хвилі rules.attack = Режим атаки @@ -707,6 +747,9 @@ rules.title.resourcesbuilding = Ресурси & будування rules.title.player = Гравці rules.title.enemy = Вороги rules.title.unit = Бойов. од. +rules.title.experimental = Есперементальне! +rules.lighting = Світлотінь +rules.ambientlight = Навколишнє світло content.item.name = Предмети content.liquid.name = Рідини content.unit.name = Бойові одиниці @@ -719,7 +762,7 @@ item.graphite.name = Графіт item.titanium.name = Титан item.thorium.name = Торій item.silicon.name = Кремній -item.plastanium.name = Пластиній +item.plastanium.name = Пластаній item.phase-fabric.name = Фазова тканина item.surge-alloy.name = Кінетичний сплав item.spore-pod.name = Споровий стручок @@ -753,6 +796,7 @@ mech.trident-ship.name = Тризубець mech.trident-ship.weapon = Бомби mech.glaive-ship.name = Спис mech.glaive-ship.weapon = Вогняний кулемет +item.corestorable = [lightgray]Зберігання в ядрі: {0} item.explosiveness = [lightgray]Вибухонебезпечність: {0}% item.flammability = [lightgray]Вогненебезпечність: {0}% item.radioactivity = [lightgray]Радіоактивність: {0}% @@ -864,8 +908,10 @@ block.junction.name = Перехрестя block.router.name = Маршрутизатор block.distributor.name = Розподілювач block.sorter.name = Сортувальник -block.inverted-sorter.name = Inverted Sorter +block.inverted-sorter.name = Зворотній сортувальник block.message.name = Повідомлення +block.illuminator.name = Освітлювач +block.illuminator.description = Невелике, компактне, джерело світла, яку можна налаштувати. Для функціонування потрібна енергія. block.overflow-gate.name = Надмірний затвор block.silicon-smelter.name = Кремнієвий плавильний завод block.phase-weaver.name = Фазовий ткач @@ -879,6 +925,7 @@ block.coal-centrifuge.name = Вугільна центрифуга block.power-node.name = Енергійний вузол block.power-node-large.name = Великий енергетичний вузол block.surge-tower.name = Кінетична вежа +block.diode.name = Діод block.battery.name = Акумулятор block.battery-large.name = Великий акумулятор block.combustion-generator.name = Генератор горіння @@ -931,6 +978,7 @@ block.fortress-factory.name = Завод мехів «Фортеця» block.revenant-factory.name = Завод бомбардувальників «Потойбічний вбивця» block.repair-point.name = Ремонтний пункт block.pulse-conduit.name = Імпульсний водопровід +block.plated-conduit.name = Зміцнений водопровід block.phase-conduit.name = Фазовий водопровід block.liquid-router.name = Рідкий маршрутизатор block.liquid-tank.name = Рідкий резервуар @@ -984,8 +1032,8 @@ unit.reaper.name = Жнець tutorial.next = [lightgray]<Натисніть для продовження> tutorial.intro = Ви розпочали[scarlet] навчання по Mindustry.[]\nРозпочніть з[accent] видобування міді[]. Використовуйте [[WASD] для руху.\n[accent] Утримуйте [[Ctrl] під час прокрутки миші[] для приближення і віддалення. Наблизьтесь, а потім натисність на мідну жилу біля вашого ядра, щоб зробити це.\n\n[accent]{0}/{1} міді tutorial.intro.mobile = Ви розпочали[scarlet] навчання по Mindustry.[]\nПроведіть екраном, щоб рухатися.\n[accent] Зведіть або розведіть 2 пальця [] для приближення і віддалення відповідно.\nз[accent] видобування міді.[] Наблизьтесь, а потім натисність на мідну жилу біля вашого ядра, щоб зробити це.\n\n[accent]{0}/{1} міді -tutorial.drill = Добування вручну неефективне.\n[accent]Бури []можуть добувати автоматично.\nНатисніть на вкладку свердла знизу зправа.\nВиберіть[accent] механічний бур[]. Розмістіть його на мідній жилі натисканням.\n[accent]Натисніть ПКМ[], щоб зупинити будування. -tutorial.drill.mobile = Добування вручну неефективне.\n[accent]Бури []можуть добувати автоматично.\nНатисність на вкладку сведла знизу зправа.\nВиберіть[accent] механічний бур[]. Розмістіть його на мідній жилі натисканням, потім натисність на [accent] галочку[] нижче, щоб підтвердити розміщення to confirm your selection.\nPress the[accent] X button[] to cancel placement. +tutorial.drill = Добування вручну неефективне.\n[accent]Бури []можуть добувати автоматично.\nНатисніть на вкладку свердла знизу зправа.\nВиберіть[accent] механічний бур[]. Розмістіть його на мідній жилі натисканням.\nВи також можете вибрати бур, натиснувши [accent][[2][], а потім натиснути [accent][[1][] швидко, незалежно від того, яка вкладка відкрита.\n[accent]Натисніть ПКМ[], щоб зупинити будування.tutorial.drill.mobile = Добування вручну неефективне.\n[accent]Бури []можуть добувати автоматично.\nНатисність на вкладку сведла знизу зправа.\nВиберіть[accent] механічний бур[]. Розмістіть його на мідній жилі натисканням, потім натисність на [accent] галочку[] нижче, щоб підтвердити розміщення .\nНатисніть[accent] клавішу X[], щоб скасувати розміщення. +tutorial.drill.mobile = Добування вручну неефективне.\n[accent]Бури []можуть добувати автоматично.\nНатисність на вкладку сведла знизу зправа.\nВиберіть[accent] механічний бур[]. Розмістіть його на мідній жилі натисканням, потім натисність на [accent] галочку[] нижче, щоб підтвердити розміщення.\nPress the[accent] X button[] to cancel placement. tutorial.blockinfo = Кожен блок має різні характеристики. Кожний бур може видобувати тільки певні руди.\nЩоб переглянути інформацію та характеристики блока,[accent] натисність на кнопку «?», коли Ви вибрали блок у меню будування.[]\n\n[accent]Перегляньте характеристику Механічного бура прямо зараз.[] tutorial.conveyor = [accent]Конвеєри[] використовуються для транспортування предметів до ядра.\nЗробіть лінію конвеєрів від бура до ядра.\n[accent]Утримуйте миш, щоб розмістити у лінію.[]\nУтримуйте[accent] CTRL[] під час вибору лінії для розміщення по діагоналі.\n\n[accent]{0}/{1} конвеєрів, які розміщені в лінію\n[accent]0/1 предмет доставлено tutorial.conveyor.mobile = [accent]Конвеєри[] використовується для транспортування предметів до ядра.\nЗробіть лінію конвеєрів від бура до ядра.\n[accent] Розмістить у лінію, утримуючи палець кілька секунд[] і тягніть у напрямку, який Ви вибрали.\nВикористовуйте колесо прокрутки, щоб обертати блоки перед їх розміщенням\n[accent]{0}/{1} конвеєрів, які розміщені в лінію\n[accent]0/1 предмет доставлено @@ -1026,7 +1074,7 @@ mech.alpha-mech.description = Стандартний керований мех. mech.delta-mech.description = Швидкий, легкоброньований мех, зроблений для тактики «атакуй і біжи». Наносить мало шкоди будівлям, але може дуже швидко вбити великі групи підрозділів противника своєю дуговою блискавкою. mech.tau-mech.description = Мех підтримки. Ремонтує союзні блоки, стріляючи по них. Може зцілювати союзників у радіусі його ремонтної здатності. mech.omega-mech.description = Об’ємний і добре броньований мех, зроблений для фронтових штурмів. Його броня може перекрити до 90% пошкоджень, що надходять. -mech.dart-ship.description = Стандартний корабель управління. Розумно швидкий і легкий, але має мало наступальних можливостей і низьку швидкість видобутку. +mech.dart-ship.description = Стандартний корабель управління. Швидко видобуває ресурси. Достатньо швидкий і легкий, але має мало наступальних можливостей. mech.javelin-ship.description = Корабель для стратегії атакуй та біжи». Хоча спочатку він повільний, потім вже може розганятися до великих швидкостей і літати над ворожими форпостами, завдаючи великої кількості шкоди своїми блискавками та ракетами. mech.trident-ship.description = Важкий бомбардувальник, побудований для будування та знищення ворожих укріплень. Дуже добре броньований. mech.glaive-ship.description = Великий, добре броньований бойовий корабель. Оснащений запальним ретранслятором. Високо маневрений. @@ -1046,7 +1094,7 @@ block.graphite-press.description = Стискає шматки вугілля в block.multi-press.description = Модернізована версія графітового преса. Використовує воду та енергію для швидкої та ефективної переробки вугілля. block.silicon-smelter.description = Змішує пісок з чистим вугіллям. Виробляє кремній. block.kiln.description = Виплавляє пісок та свинець у сполуку, відому як метаскло. Для запуску потрібна невелика кількість енергії. -block.plastanium-compressor.description = Виробляє пластиній з нафти і титану. +block.plastanium-compressor.description = Виробляє пластаній з нафти і титану. block.phase-weaver.description = Синтезує фазову тканину з радіоактивного торію та піску. Для функціонування потрібна велика кількість енергії. block.alloy-smelter.description = Поєднує титан, свинець, кремній і мідь для отримання кінетичного сплаву. block.cryofluidmixer.description = Змішує воду і дрібний порошок титану титану в кріогенну рідину. Основне використання у торієвому реактору. @@ -1091,13 +1139,14 @@ block.sorter.description = Сортує предмети. Якщо елемен block.inverted-sorter.description = Обробляє елементи, як звичайний сортувальник, але виводить обрані елементи на сторони. block.router.description = Приймає елементи з одного напрямку та виводить їх до трьох інших напрямків порівну. Корисно для поділу матеріалів від одного джерела до кількох цілей.\n\n[scarlet]Ніколи не використовуйте поруч із входами до механізмів, оскільки вони будуть забиті вихідними предметами.[] block.distributor.description = Розширений маршрутизатор. Розділяє предмети до 7 інших напрямків порівну. -block.overflow-gate.description = Комбінований розгалужувач і маршрутизатор. Виходи лише вліво і вправо, якщо передній шлях заблокований. +block.overflow-gate.description = Виходи лише вліво і вправо, якщо передній шлях заблокований. block.mass-driver.description = Кінцевий елемент транспортного блоку. Збирає кілька предметів, а потім вистрілює їх до іншої електромагнитної катапульти на великій відстані. Для роботи потрібна енергія. block.mechanical-pump.description = Недорогий насос з повільним виходом, але без енергоспоживання. block.rotary-pump.description = Удосконалений насос. Насоси більше викачують, але потребують енергію. block.thermal-pump.description = Найкращий насос. block.conduit.description = Основний блок транспортування рідини. Пересуває рідини вперед. Застосовується спільно з насосами та іншими трубопроводами. block.pulse-conduit.description = Вдосконалений блок транспортування рідини. Транспортує рідини швидше і зберігає більше, ніж стандартні трубопроводи. +block.plated-conduit.description =Переміщує рідини з тією ж швидкістю, як і імпульсні трубопроводи, але має більше міцності. Не приймає рідин з боків окрім інших трубопроводів.\nПротікає менше. block.liquid-router.description = Приймає рідини з одного напрямку та виводить їх до трьох інших напрямків порівну. Також можна зберігати певну кількість рідини. Корисно для розщеплення рідин від одного джерела до кількох мішеней. block.liquid-tank.description = Зберігає велику кількість рідини. Використовуйте для створення буферів у ситуаціях з непостійним попитом на матеріали або як гарантію охолодження життєво важливих блоків. block.liquid-junction.description = Діє як міст для двох каналів перетину. Корисно в ситуаціях, коли два різні трубопроводи перевозять різні рідини в різні місця. @@ -1106,6 +1155,7 @@ block.phase-conduit.description = Розширений блок транспор block.power-node.description = Передає живлення на підключені вузли. Вузол буде отримувати живлення від будь-яких сусідніх блоків або подавати живлення до них. block.power-node-large.description = Удосконалений вузол живлення з більшим діапазоном. block.surge-tower.description = Надзвичайно дальний вузол живлення з меншою кількістю доступних з’єднань. +block.diode.description = Живлення акумулятора може протікати через цей блок лише в одному напрямку, але лише в тому випадку, якщо інша сторона має менше енергії. block.battery.description = Зберігає енергію як буфер в часи надлишкової енергії. Виводить енергію у періоди дефіциту. block.battery-large.description = Зберігає набагато більше енергії, ніж звичайний акумулятор. block.combustion-generator.description = Виробляє енергію, спалюючи легкозаймисті матеріали, такі як вугілля. diff --git a/core/assets/bundles/bundle_zh_CN.properties b/core/assets/bundles/bundle_zh_CN.properties index a70c0b9f18..b2ae9cdc24 100644 --- a/core/assets/bundles/bundle_zh_CN.properties +++ b/core/assets/bundles/bundle_zh_CN.properties @@ -1,37 +1,40 @@ -credits.text = 由[ROYAL]Anuken[]开发 - [SKY]anukendev@gmail.com[] +credits.text = 作者[ROYAL]Anuken[] - [SKY]anukendev@gmail.com[] credits = 致谢 -contributors = 译者和贡献者 -discord = 加入 Mindustry 的 Discord! -link.discord.description = 官方 Mindustry Discord 聊天室 -link.reddit.description = The Mindustry subreddit -link.github.description = 游戏源码 -link.changelog.description = 更新列表 -link.dev-builds.description = 不稳定开发版 -link.trello.description = Trello board 上的官方计划表 -link.itch.io.description = PC版下载和网页版(itch.io) -link.google-play.description = 从谷歌商店获取安卓版 -link.wiki.description = 官方 Mindustry 维基 -linkfail = 打开链接失败!\n网址已经复制到剪贴板。 -screenshot = 屏幕截图已放在 {0} +contributors = 翻译者和贡献者 +discord = 加入 Mindustry 的 Discord! +link.discord.description = Mindustry 官方的 Discord 聊天室 +link.reddit.description = Mindustry 的 reddit 板块 +link.github.description = 游戏源代码 +link.changelog.description = 更新日志 +link.dev-builds.description = 不稳定的开发版本 +link.trello.description = 官方列于 Trello 的功能计划表 +link.itch.io.description = itch.io 上的 PC 版下载 +link.google-play.description = Google Play 页面 +link.f-droid.description = F-Droid 页面 +link.wiki.description = Mindustry 官方 Wiki +linkfail = 打开链接失败!\n网址已复制到您的剪贴板。 +screenshot = 屏幕截图已保存到 {0} screenshot.invalid = 地图太大,可能没有足够的内存用于截图。 gameover = 你的核心被摧毁了! -gameover.pvp = [accent] {0}[]队获胜! +gameover.pvp = [accent] {0}[]队获胜! highscore = [accent]新纪录! copied = 已复制。 + load.sound = 音乐加载中 load.map = 地图加载中 load.image = 图片加载中 load.content = 内容加载中 load.system = 系统加载中 load.mod = 模组加载中 + schematic = 蓝图 -schematic.add = 保存蓝图中…… +schematic.add = 保存蓝图… schematics = 蓝图 -schematic.replace = A schematic by that name already exists. Replace it? -schematic.import = 导入蓝图中…… +schematic.replace = 此名称的蓝图已存在,是否覆盖? +schematic.import = 导入蓝图… schematic.exportfile = 导出文件 schematic.importfile = 导入蓝图 -schematic.browseworkshop = 流览创意工坊 +schematic.browseworkshop = 浏览创意工坊 schematic.copy = 复制蓝图到剪贴板 schematic.copy.import = 从剪贴板导入蓝图 schematic.shareworkshop = 在创意工坊上分享蓝图 @@ -39,23 +42,25 @@ schematic.flip = [accent][[{0}][]/[accent][[{1}][]:翻转蓝图 schematic.saved = 蓝图已保存。 schematic.delete.confirm = 确认删除蓝图? schematic.rename = 重命名蓝图 -schematic.info = {0}x{1}, {2} 方块 -stat.wave = 战胜的波数:[accent]{0} -stat.enemiesDestroyed = 消灭的敌人:[accent]{0} -stat.built = 建造的建筑:[accent]{0} -stat.destroyed = 摧毁的建筑:[accent]{0} -stat.deconstructed = 拆除的建筑:[accent]{0} -stat.delivered = 发射的资源: -stat.rank = 最终等级:[accent]{0} -launcheditems = [accent]发射的资源 -launchinfo = [unlaunched][[LAUNCH] 你的核心将会获得用蓝色标识出来的资源. -map.delete = 确定要删除名为 "[accent]{0}[]" 的地图吗? +schematic.info = {0}x{1},{2} 个方块 + +stat.wave = 防守波数:[accent]{0} +stat.enemiesDestroyed = 消灭敌人:[accent]{0} +stat.built = 建造建筑:[accent]{0} +stat.destroyed = 被毁建筑:[accent]{0} +stat.deconstructed = 拆除建筑:[accent]{0} +stat.delivered = 装运资源: +stat.rank = 最终评级:[accent]{0} + +launcheditems = [accent]装运的资源 +launchinfo = [unlaunched]发射你的核心后,你将获得用蓝字标识的资源。 +map.delete = 确定要删除“[accent]{0}[]”地图吗? level.highscore = 最高分:[accent]{0} level.select = 选择关卡 level.mode = 游戏模式: showagain = 下次不再显示 coreattack = < 核心正在受到攻击!> -nearpoint = [[ [scarlet]立即离开敌人出生点[] ]\n将被全部清除 +nearpoint = [[ [scarlet]立即离开敌人出生点[] ]\n摧毁在即 database = 核心数据库 savegame = 保存游戏 loadgame = 载入游戏 @@ -68,32 +73,35 @@ position = 位置 close = 关闭 website = 官网 quit = 退出 -save.quit = Save & Quit +save.quit = 保存并退出 maps = 地图 maps.browse = 浏览地图 continue = 继续 -maps.none = [LIGHT_GRAY]没有找到地图! +maps.none = [lightgray]没有找到任何地图! invalid = 无效 +pickcolor = 选择颜色 preparingconfig = 正在准备配置 preparingcontent = 正在准备内容 uploadingcontent = 正在上传内容 uploadingpreviewfile = 正在上传预览文件 -committingchanges = 提交更改 +committingchanges = 正在提交更改 done = 已完成 -feature.unsupported = Your device does not support this feature. -mods.alphainfo = 请注意在测试版本中的模组[scarlet]可能有缺陷[]。\n在 Mindustry GitHub 或 Discord上报告你发现的问题。 -mods.alpha = [accent](测试版) +feature.unsupported = 您的设备不支持此功能。 + +mods.alphainfo = 请注意,测试版本(alpha)中的模组(mods)[scarlet]很容易存在缺陷[]。\n在 Mindustry 的 GitHub 或 Discord 上报告你发现的问题。 +mods.alpha = [accent](Alpha) mods = 模组 -mods.none = [LIGHT_GRAY]无模组! +mods.none = [LIGHT_GRAY]没有找到模组! mods.guide = 模组教程 mods.report = 报告 Bug -mods.openfolder = Open Mod Folder +mods.openfolder = 打开模组文件夹 mod.enabled = [lightgray]已启用 mod.disabled = [scarlet]已禁用 mod.disable = 禁用 -mod.delete.error = Unable to delete mod. File may be in use. -mod.missingdependencies = [scarlet]Missing dependencies: {0} -mod.nowdisabled = [scarlet]Mod '{0}' is missing dependencies:[accent] {1}\n[lightgray]These mods need to be downloaded first.\nThis mod will be automatically disabled. +mod.delete.error = 无法删除模组。可能文件被占用。 +mod.requiresversion = [scarlet]所需的游戏版本:[accent]{0} +mod.missingdependencies = [scarlet]缺少依赖条件:{0} +mod.nowdisabled = [scarlet]“{0}”模组缺少依赖条件:[accent] {1}\n[lightgray]需要先下载上述模组。\n此模组现在将自动禁用。 mod.enable = 启用 mod.requiresrestart = 需要重启使模组生效。 mod.reloadrequired = [scarlet]需要重启 @@ -101,22 +109,23 @@ mod.import = 导入模组 mod.import.github = 导入 GitHub 模组 mod.remove.confirm = 此模组将被删除。 mod.author = [LIGHT_GRAY]作者:[] {0} -mod.missing = 此存档包含更新后的模组或不再使用的模组。存档可能会损坏。确定要加载它吗?\n[lightgray]模组:\n{0} -mod.preview.missing = 在创意工坊中发布此模组之前,必须添加图像预览。\n请将名为[accent] preview.png[] 的图像放入模组文件夹,然后重试。 -mod.folder.missing = 只有文件夹形式的模组才能在创意工坊上发布。\n若要将任何模组转换为文件夹,只需将其文件解压缩到文件夹中并删除旧压缩包,然后重新启动游戏或重新加载模组。 +mod.missing = 此存档包含您最近已更新或者现在未安装的模组。存档可能会损坏。确定要加载它吗?\n[lightgray]模组:\n{0} +mod.preview.missing = 在创意工坊中发布此模组前,您必须添加一则预览图像。\n请将名为[accent] preview.png[] 的图像放入模组文件夹,然后重试。 +mod.folder.missing = 只有文件夹形式的模组能在创意工坊上发布。\n若要将任何模组转换为文件夹,只需将其文件解压缩到文件夹中并删除旧压缩包,然后重新启动游戏或重新加载模组。 + about.button = 关于 name = 名字: noname = 先取一个[accent]玩家名[]。 filename = 文件名: -unlocked = 新方块已解锁! +unlocked = 解锁了新内容! completed = [accent]己研究 techtree = 科技树 -research.list = [LIGHT_GRAY]研究: +research.list = [lightgray]研究: research = 研究 -researched = [LIGHT_GRAY]{0}己研究。 -players = {0} 玩家在线 -players.single = {0}玩家在线 -server.closing = [accent]正在关闭服务器…… +researched = [lightgray]{0}己研究。 +players = {0} 位玩家在线 +players.single = {0} 位玩家在线 +server.closing = [accent]服务器关闭… server.kicked.kick = 你被踢出了服务器。 server.kicked.whitelist = 你不在白名单中。 server.kicked.serverClose = 服务器已关闭。 @@ -133,13 +142,13 @@ server.kicked.idInUse = 你已在这个服务器上!不允许用两个账号 server.kicked.customClient = 这个服务器不支持自定义版本。请下载官方版本。 server.kicked.gameover = 游戏结束! server.versions = 客户端版本:[accent] {0}[]\n服务器版本:[accent] {1}[] -host.info = [accent]创建局域网游戏[]按钮会在[scarlet] 6567 []端口运行一个服务器。[]\n任何在同一个[LIGHT_GRAY] Wi-Fi 或本地网络[]下的人应该都可以在服务器列表中看到你的服务器。\n\n如果你想让别人在任何地方都能通过 IP 地址连接,你需要设定[accent]端口转发[]。\n\n[LIGHT_GRAY]注意:如果某人无法连接到你的局域网游戏,请确保你在防火墙设置里允许了 Mindustry 访问本地网络。 -join.info = 此时,可以输入[accent]服务器的 IP 地址[]来连接,或寻找[accent]本地网络[]中的服务器来连接。\n局域网或广域网多人游戏都支持。\n\n[LIGHT_GRAY]注意:没有全球服务器列表;如果你想通过 IP 地址连接某个服务器,你需要向房主询问 IP 地址。 +host.info = [accent]创建局域网游戏[]按钮会在[scarlet] 6567 []端口运行一个服务器。[]\n任何在同一个[lightgray] Wi-Fi 或本地网络[]下的人应该都可以在服务器列表中看到你的服务器。\n\n如果你想让别人在任何地方都能通过 IP 地址连接,你需要设定[accent]端口转发[]。\n\n[lightgray]注意:如果某人无法连接到你的局域网游戏,请确保你在防火墙设置里允许了 Mindustry 访问本地网络。 +join.info = 您可以输入[accent]服务器的 IP 地址[]来连接,或寻找[accent]本地网络[]中的服务器来连接。\n支持局域网或广域网的多人游戏。\n\n[lightgray]注意:没有全球服务器列表;如果你想通过 IP 地址连接某个服务器,你需要向房主询问 IP 地址。 hostserver = 创建服务器 invitefriends = 邀请朋友 hostserver.mobile = 创建\n服务器 host = 创建 -hosting = [accent]正在打开服务器…… +hosting = [accent]正在开启服务器… hosts.refresh = 刷新 hosts.discovering = 正在搜索局域网服务器 hosts.discovering.any = 正在搜索服务器 @@ -178,8 +187,8 @@ disconnect.closed = 连接关闭。 disconnect.timeout = 连接超时。 disconnect.data = 读取服务器数据失败! cantconnect = 无法加入([accent]{0}[])。 -connecting = [accent]连接中…… -connecting.data = [accent]加载中…… +connecting = [accent]连接中… +connecting.data = [accent]加载中… server.port = 端口: server.addressinuse = 地址已在使用! server.invalidport = 无效的端口! @@ -188,7 +197,7 @@ save.new = 新存档 save.overwrite = 你确定你要覆盖这个存档吗? overwrite = 覆盖 save.none = 没有找到存档! -saveload = [accent]正在保存…… +saveload = [accent]正在保存… savefail = 保存失败! save.delete.confirm = 你确定你要删除这个存档吗? save.delete = 删除 @@ -202,7 +211,7 @@ save.rename = 重命名 save.rename.text = 新名称: selectslot = 选择一个存档。 slot = [accent]存档位 {0} -editmessage = Edit Message +editmessage = 编辑消息 save.corrupted = [accent]存档损坏或无效!\n如果你刚刚升级了游戏,那么这可能是因为存档格式改变了,而[scarlet]不是[] bug 。 empty = < 空 > on = 开 @@ -233,21 +242,21 @@ data.import.confirm = 导入外部游戏数据将覆盖本地[scarlet]全部[] classic.export = 导出老版本数据 classic.export.text = [accent]Mindustry []已经有了一个重要的更新。\n检测到此为老版本(v3.5 build 40)的存档或地图。是否要将这些保存导出到手机的主文件夹中,以便在 Mindustry 老版本应用程序中使用? quit.confirm = 确定退出? -quit.confirm.tutorial = 你确定要跳过教程?\n教程可以通过[accent]设置->游戏->重新游玩教程[]来再次游玩。 -loading = [accent]加载中…… -reloading = [accent]重载模组中…… -saving = [accent]保存中…… +quit.confirm.tutorial = 确定要跳过教程?\n您可以通过[accent]设置->游戏->重玩教程[]来重玩教程。 +loading = [accent]加载中… +reloading = [accent]重载模组中… +saving = [accent]保存中… cancelbuilding = [accent][[{0}][]来清除规划 selectschematic = [accent][[{0}][]来选择复制 pausebuilding = [accent][[{0}][]来暂停建造 resumebuilding = [scarlet][[{0}][]来恢复建造 -wave = [accent]波次{0} -wave.waiting = [LIGHT_GRAY]下一波将在{0}秒后到来 -wave.waveInProgress = [LIGHT_GRAY]波次进行中 -waiting = [LIGHT_GRAY]等待中…… -waiting.players = 等待玩家中…… -wave.enemies = [LIGHT_GRAY]剩余 {0} 个敌人 -wave.enemy = [LIGHT_GRAY]剩余 {0} 个敌人 +wave = [accent]第{0}波 +wave.waiting = [lightgray]下一波倒计时:{0}秒 +wave.waveInProgress = [lightgray]波次袭来 +waiting = [lightgray]等待中… +waiting.players = 等待玩家中… +wave.enemies = [lightgray]剩余 {0} 个敌人 +wave.enemy = [lightgray]剩余 {0} 个敌人 loadimage = 加载图片 saveimage = 保存图片 unknown = 未知 @@ -256,21 +265,22 @@ builtin = 内建的 map.delete.confirm = 你确定你想要删除这张地图吗?这个操作无法撤销! map.random = [accent]随机地图 map.nospawn = 这个地图没有核心!请在编辑器中添加一个[ROYAL]己方[]的核心。 -map.nospawn.pvp = 这个地图没有敌人的核心!请在编辑器中添加一个[ROYAL]敌方[]的核心。 -map.nospawn.attack = 这个地图没有敌人的核心!请在编辑中向地图添加一个[SCARLET]敌方[]的核心。 +map.nospawn.pvp = 这个地图没有敌人的核心!请在编辑器中添加一个[ROYAL]敌人[]的核心。 +map.nospawn.attack = 这个地图没有敌人的核心!请在编辑中向地图添加一个[SCARLET]敌人[]的核心。 map.invalid = 地图载入错误:地图文件可能已经损坏。 workshop.update = 更新地图 workshop.error = 获取创意工坊详细信息时出错:{0} map.publish.confirm = 确定上传此地图?\n\n[lightgray]确定你同意 Steam 创意工坊的最终用户许可协议,否则你的地图将不会被展示! -workshop.menu = Select what you would like to do with this item. -workshop.info = Item Info -changelog = Changelog (optional): +workshop.menu = 选择此项目的目的。 +workshop.info = 项目信息 +changelog = 更新日志(可选): eula = Steam 最终用户许可协议 -missing = 地图已被删除或移动。\n[lightgray]链接已在创意工坊中被删除。 -publishing = [accent]Publishing... -publish.confirm = Are you sure you want to publish this?\n\n[lightgray]Make sure you agree to the Workshop EULA first, or your items will not show up! -publish.error = Error publishing item: {0} -steam.error = Failed to initialize Steam services.\nError: {0} +missing = 此项目已被删除或转移。\n[lightgray]链接已在创意工坊中被删除。 +publishing = [accent]正在发布... +publish.confirm = 确定发布?\n\n[lightgray]请确认您已经同意创意工坊的最终用户许可协议,否则您的项目不会展示! +publish.error = 发布项目出错:{0} +steam.error = 初始化 Steam 服务失败。\n错误:{0} + editor.brush = 笔刷 editor.openin = 在编辑器中打开 editor.oregen = 矿石的生成 @@ -278,7 +288,7 @@ editor.oregen.info = 矿石的生成: editor.mapinfo = 地图信息 editor.author = 作者: editor.description = 描述: -editor.nodescription = 地图必须要有不少于4个字符的描述才能上传。 +editor.nodescription = 地图发布前,描述不得少于4个字符。 editor.waves = 波数: editor.rules = 规则: editor.generation = 筛选器: @@ -295,26 +305,26 @@ waves.perspawn = 每次生成 waves.to = 至 waves.boss = BOSS waves.preview = 预览 -waves.edit = 编辑…… +waves.edit = 编辑… waves.copy = 复制到剪贴板 waves.load = 从剪贴板读取 -waves.invalid = 剪贴板中无效的波次信息。 +waves.invalid = 剪贴板中的波次信息无效。 waves.copied = 波次信息已复制。 -waves.none = 无自定义敌人。\n请注意,空布局将自动替换为默认布局。 -editor.default = [LIGHT_GRAY]<默认> -details = 详情…… -edit = 编辑…… +waves.none = 没有定义敌人。\n请注意,空布局将自动替换为默认布局。 +editor.default = [lightgray]<默认> +details = 详情… +edit = 编辑… editor.name = 名称: editor.spawn = 生成单位 editor.removeunit = 移除单位 editor.teams = 队伍 -editor.errorload = 读取文件时出现错误:\n[accent]{0} -editor.errorsave = 保存文件时出现错误:\n[accent]{0} -editor.errorimage = 这是一幅图片,不是地图。请不要更改文件的扩展名来导入。\n\n如果你想导入地图,请在编辑器中使用“导入地图”这一按钮。 -editor.errorlegacy = 此地图太旧,而旧的地图格式不再受支持了。 +editor.errorload = 读取文件出错:\n[accent]{0} +editor.errorsave = 保存文件出错:\n[accent]{0} +editor.errorimage = 这是一幅图片,不是地图。请不要更改文件的扩展名来导入。\n\n如果你想导入地图,请在编辑器中使用“导入地图”按钮。 +editor.errorlegacy = 此地图太旧了,旧的地图格式已不再支持。 editor.errornot = 这不是地图文件。 -editor.errorheader = 此地图文件已失效或损坏。 -editor.errorname = 地图没有被定义的名称。是否需要加载存档文件? +editor.errorheader = 此地图文件无效或已损坏。 +editor.errorname = 地图没有定义名称。是否要加载一个存档文件? editor.update = 更新 editor.randomize = 随机化 editor.apply = 应用 @@ -324,16 +334,16 @@ editor.loadmap = 载入地图 editor.savemap = 保存地图 editor.saved = 已保存! editor.save.noname = 你的地图没有名字!在“地图信息”菜单里设置一个。 -editor.save.overwrite = 你的地图覆盖了一个内建的地图!在“地图信息”菜单里重新设置一个不同的名称。 -editor.import.exists = [scarlet]无法导入:[]名为‘{0}’的内建地图已存在! -editor.import = 导入…… +editor.save.overwrite = 你的地图覆盖了一个内置的地图!在“地图信息”菜单里重新设置一个不同的名称。 +editor.import.exists = [scarlet]无法导入:[]存在名为“{0}”的内置地图! +editor.import = 导入… editor.importmap = 导入地图 editor.importmap.description = 导入一个已经存在的地图 editor.importfile = 导入文件 editor.importfile.description = 导入一个外置的地图文件 editor.importimage = 导入地形图像 editor.importimage.description = 导入一个外置的地图图像文件 -editor.export = 导出…… +editor.export = 导出… editor.exportfile = 导出文件 editor.exportfile.description = 导出一个地图文件 editor.exportimage = 导出一个地形文件 @@ -347,6 +357,7 @@ editor.overwrite = [accent]警告!\n这将会覆盖一个已经存在的地图 editor.overwrite.confirm = [scarlet]警告![]存在同名地图。你确定你想要覆盖? editor.exists = 已经存在同名地图。 editor.selectmap = 选择一个地图加载: + toolmode.replace = 替换 toolmode.replace.description = 仅在实心块上绘制。 toolmode.replaceall = 全部替换 @@ -361,7 +372,8 @@ toolmode.fillteams = 填充团队 toolmode.fillteams.description = 填充团队而不是方块。 toolmode.drawteams = 绘制团队 toolmode.drawteams.description = 绘制团队而不是方块。 -filters.empty = [LIGHT_GRAY]没有筛选器!用下方的按钮添加一个。 + +filters.empty = [lightgray]没有筛选器!用下方的按钮添加一个。 filter.distort = 扭曲程度 filter.noise = 波动程度 filter.median = 平均数 @@ -392,6 +404,7 @@ filter.option.floor2 = 二重地面 filter.option.threshold2 = 二重阈值 filter.option.radius = 半径大小 filter.option.percentile = 百分比 + width = 宽度: height = 高度: menu = 菜单 @@ -404,49 +417,52 @@ ping = 延迟:{0}毫秒 language.restart = 为了使语言设置生效请重启游戏。 settings = 设置 tutorial = 教程 -tutorial.retake = 重新游玩教程 +tutorial.retake = 重玩教程 editor = 编辑器 mapeditor = 地图编辑器 + abandon = 放弃 abandon.text = 这个区域及其资源会被敌人重置。 locked = 已锁定 -complete = [LIGHT_GRAY]完成: -requirement.wave = Reach Wave {0} in {1} +complete = [lightgray]完成: +requirement.wave = {1}中的第{0}波次 requirement.core = 在{0}中摧毁敌方核心 requirement.unlock = 解锁{0} -resume = 暂停:\n[LIGHT_GRAY]{0} -bestwave = [LIGHT_GRAY]最高波次:{0} +resume = 暂停:\n[lightgray]{0} +bestwave = [lightgray]最高波次:{0} launch = < 发射 > launch.title = 发射成功 -launch.next = [LIGHT_GRAY]下一个发射机会在第 {0} 波 +launch.next = [lightgray]下个发射窗口在第{0}波 launch.unable2 = [scarlet]无法发射[] -launch.confirm = 您将发射核心中所有资源。\n此地图将重置。 -launch.skip.confirm = 如果你现在跳过,在后来的波次前你将无法发射。 +launch.confirm = 您将装载并发射核心中的所有资源。\n此地图将重置,无法回到此基地。 +launch.skip.confirm = 如果现在跳过,在下一个发射窗口到来前,您都无法发射。 uncover = 解锁 -configure = 设定发射资源数量 +configure = 设定装运的数量 bannedblocks = 禁用方块 addall = 添加所有 -configure.locked = [LIGHT_GRAY]到达第{0}波\n才能设定发射资源。 +configure.locked = [lightgray]完成{0}\n解锁装运配置。 configure.invalid = 数量必须是0到{0}之间的数字。 -zone.unlocked = [LIGHT_GRAY]{0} 已解锁。 -zone.requirement.complete = 已达到第{0}波。\n达到解锁{1}的需求。 -zone.config.unlocked = Loadout unlocked:[lightgray]\n{0} +zone.unlocked = [lightgray]{0} 已解锁。 +zone.requirement.complete = 完成{0}。\n已达成解锁{1}的要求。 +zone.config.unlocked = 资源装运已解锁:[lightgray]\n{0} zone.resources = 地图中的资源: zone.objective = [lightgray]目标:[accent]{0} zone.objective.survival = 生存 zone.objective.attack = 摧毁敌方核心 -add = 添加…… +add = 添加… boss.health = BOSS 生命值 + connectfail = [crimson]服务器连接失败:[accent]{0} -error.unreachable = 服务器无法访问。\n确定输对地址了吗? +error.unreachable = 无法访问服务器。\n确定输对地址了吗? error.invalidaddress = 地址无效。 -error.timedout = 连接超时!\n确保服务器设置了端口转发,并且地址正确! -error.mismatch = 不匹配。\n可能是客户端/服务器版本不匹配。\n请确保客户端和服务器都是最新的版本! +error.timedout = 连接超时!\n请确认服务器设置了端口转发且地址无误! +error.mismatch = 数据包错误。\n可能是客户端/服务器的版本不匹配。\n请确保客户端和服务器都是最新的版本! error.alreadyconnected = 已连接。 -error.mapnotfound = 找不到地图文件! +error.mapnotfound = 找不到地图文件! error.io = 网络 I/O 错误。 error.any = 未知网络错误。 -error.bloom = 未能初始化特效。\n您的设备可能不支持它。 +error.bloom = 未能初始化特效。\n您的设备可能不支持。 + zone.groundZero.name = 零号地区 zone.desertWastes.name = 荒芜沙漠 zone.craters.name = 陨石带 @@ -456,36 +472,38 @@ zone.stainedMountains.name = 绵延群山 zone.desolateRift.name = 荒芜裂谷 zone.nuclearComplex.name = 核裂阵 zone.overgrowth.name = 增生区 -zone.tarFields.name = 石油田 +zone.tarFields.name = 油田 zone.saltFlats.name = 盐碱荒滩 zone.impact0078.name = 0078号冲击 zone.crags.name = 悬崖 zone.fungalPass.name = 真菌通道 -zone.groundZero.description = 重新开始的最佳位置。这儿敌人威胁很小,资源少。\n尽可能收集多的铅和铜。\n行动。 -zone.frozenForest.description = 即使在这里,靠近山脉的地方,孢子也已经扩散。寒冷的温度不可能永远容纳它们。\n\n此行动须投入电力。建造燃烧发电机并学会使用修理者。 -zone.desertWastes.description = 这些废料规模巨大,难以预测,并且与废弃的结构交错在一起。\n此地区有煤矿存在,燃烧它以获取动力或合成石墨。\n\n[lightgray]无法保证此着陆位置。 + +zone.groundZero.description = 踏上旅程的最佳位置。这儿的敌人威胁很小,但资源也少。\n收集尽可能多的铅和铜。\n出发吧! +zone.frozenForest.description = 即使是靠近山脉的这里,孢子也已经扩散。他们不能长期停留在寒冷的温度中。\n\n开始运用电力。建造火力发电机并学会使用修理者。 +zone.desertWastes.description = 这里的废料规模庞大、难以预测,并与废弃的结构交织在一起。\n此地区有煤矿存在,点燃它以获取动力,或者将其合成为石墨。\n\n[lightgray]无法保证此着陆位置。 zone.saltFlats.description = 在沙漠的郊区有盐滩。在这个地方几乎找不到资源。\n\n敌人在这里建立了一个资源存储区。摧毁他们的核心。不要留下任何东西。 zone.craters.description = 水在这个火山口积聚,这是旧战争的遗迹。夺下该区域。收集沙子来冶炼玻璃。用水泵抽水来加速炮塔和钻头。 zone.ruinousShores.description = 穿过荒地,就是海岸线。这个地方曾经建造了一个海岸防御线。但现在所剩无几,只有最基本的防御结构仍然毫发无损,其他一切都被摧毁了。\n继续向外扩展。继续研究科技。 -zone.stainedMountains.description = 在更远的内陆地区是山脉,但这里没有被孢子污染。\n在这一地区分布着丰富的钛,学习如何使用它。\n\n这里敌人的存在更大。不要给他们时间派出最强的部队。 +zone.stainedMountains.description = 在更远的内陆地区是山脉,但这里没有被孢子污染。\n这一地区分布着丰富的钛,学习如何使用它。\n\n这里的敌人势力更大,不要给他们时间派出最强的部队。 zone.overgrowth.description = 这个地区靠近孢子的来源,因此生长过度。\n敌人在这里建立了一个前哨站。建造尖刀单位来摧毁它并找回丢失的东西。 -zone.tarFields.description = 位于山脉和沙漠之间的产油区的郊区是少数几个有可用石油储量的地区之一。\n尽管被废弃,但附近仍有一些危险的敌军。不要低估它们。\n\n[lightgray]如果可能,研究石油加工技术。 -zone.desolateRift.description = 非常危险的区域。这儿资源丰富但空间小。敌人十分危险。尽快离开,不要被敌人的攻击间隔太长所愚弄。 +zone.tarFields.description = 产油区边缘,位于山脉和沙漠之间。它少数几个有石油储量的地区之一。\n尽管被废弃,这附近仍有一些危险的敌方单位。不要低估他们。\n\n[lightgray]如果可能,研究石油加工技术。 +zone.desolateRift.description = 非常危险的区域。这儿的资源丰富但空间很小。敌人十分危险。尽快离开,不要被敌人的攻击间隔太长所愚弄。 zone.nuclearComplex.description = 以前生产和加工钍的设施已变成废墟。\n[lightgray]研究钍及其多种用途。\n\n敌人在这里大量存在,不断消灭入侵者。 zone.fungalPass.description = 介于高山和低矮孢子丛生的土地之间的过渡地带。这里有一个小型的敌方侦察基地。\n侦察它。\n使用尖刀和爬行者单位来摧毁两个核心。 -zone.impact0078.description = <在此处插入说明> -zone.crags.description = <在此处插入说明> +zone.impact0078.description = <描述空缺> +zone.crags.description = <描述空缺> + settings.language = 语言 settings.data = 游戏数据 -settings.reset = 恢复默认 +settings.reset = 恢复默认设置 settings.rebind = 重新绑定 settings.controls = 控制 settings.game = 游戏 settings.sound = 声音 settings.graphics = 图像 -settings.cleardata = 清除游戏数据…… -settings.clear.confirm = 您确定要清除数据吗?\n这个操作无法撤销! -settings.clearall.confirm = [scarlet]警告![]\n这将清除所有数据,包括存档、地图、解锁和绑定键。\n按「是」后,游戏将删除所有数据并自动退出。 +settings.cleardata = 清除游戏数据… +settings.clear.confirm = 您确定要清除此数据?\n此操作无法撤销! +settings.clearall.confirm = [scarlet]警告![]\n这将清除所有数据,包括存档、地图、解锁和按键绑定。\n按「是」后,游戏将删除所有数据并自动退出。 paused = [accent]< 暂停 > clear = 清除 banned = [scarlet]已禁止 @@ -496,8 +514,8 @@ error.title = [crimson]发生了一个错误 error.crashtitle = 发生了一个错误 blocks.input = 输入 blocks.output = 输出 -blocks.booster = 加成物品/液体 -block.unknown = [LIGHT_GRAY]??? +blocks.booster = 增强物品/液体 +block.unknown = [lightgray]??? blocks.powercapacity = 能量容量 blocks.powershot = 能量/发射 blocks.damage = 伤害 @@ -509,8 +527,8 @@ blocks.shootrange = 范围 blocks.size = 尺寸 blocks.liquidcapacity = 液体容量 blocks.powerrange = 能量范围 -blocks.powerconnections = Max Connections -blocks.poweruse = 能量使用 +blocks.powerconnections = 最多连接 +blocks.poweruse = 使用能量 blocks.powerdamage = 功率/损伤 blocks.itemcapacity = 物品容量 blocks.basepowergeneration = 基础能源输出 @@ -520,7 +538,7 @@ blocks.speedincrease = 提速 blocks.range = 范围 blocks.drilltier = 可钻探矿物 blocks.drillspeed = 基础钻探速度 -blocks.boosteffect = 加成影响 +blocks.boosteffect = 增强效果 blocks.maxunits = 最大单位数量 blocks.health = 生命值 blocks.buildtime = 建造时间 @@ -528,22 +546,26 @@ blocks.buildcost = 建造花费 blocks.inaccuracy = 误差 blocks.shots = 发射数 blocks.reload = 每秒发射数 -blocks.ammo = 子弹 +blocks.ammo = 弹药 + bar.drilltierreq = 需要更好的钻头 -bar.drillspeed = 挖掘速度:{0}/s -bar.pumpspeed = Pump Speed: {0}/s +bar.drillspeed = 挖掘速度:{0}/秒 +bar.pumpspeed = 泵压速度:{0}/秒 bar.efficiency = 效率:{0}% bar.powerbalance = 能量:{0}/秒 bar.powerstored = 储能:{0}/{1} bar.poweramount = 能量:{0} bar.poweroutput = 能量输出:{0} -bar.items = 物体:{0} +bar.items = 物品:{0} bar.capacity = 容量:{0} bar.liquid = 液体 bar.heat = 热量 bar.power = 电力 bar.progress = 制造进度 bar.spawned = 单位数量:{0}/{1} +bar.input = 输入 +bar.output = 输出 + bullet.damage = [stat]{0}[lightgray] 伤害 bullet.splashdamage = [stat]{0}[lightgray] 范围伤害 ~[stat] {1}[lightgray] 格 bullet.incendiary = [stat] 燃烧 @@ -553,18 +575,19 @@ bullet.frag = [stat] 分裂 bullet.knockback = [stat]{0}[lightgray] 击退 bullet.freezing = [stat] 冰冻 bullet.tarred = [stat] 减速 -bullet.multiplier = [stat]{0}[lightgray]x 子弹数量 +bullet.multiplier = [stat]{0}[lightgray]x 弹药数量 bullet.reload = [stat]{0}[lightgray]x 装弹 + unit.blocks = 方块 -unit.powersecond = 能量单位/秒 -unit.liquidsecond = 液体单位/秒 +unit.powersecond = 能量/秒 +unit.liquidsecond = 液体/秒 unit.itemssecond = 物品/秒 -unit.liquidunits = 液体单位 -unit.powerunits = 能量单位 +unit.liquidunits = 液体 +unit.powerunits = 能量 unit.degrees = 度 unit.seconds = 秒 unit.persecond = /秒 -unit.timesspeed = x 速度 +unit.timesspeed = 倍 速度 unit.percent = % unit.items = 物品 category.general = 普通 @@ -573,15 +596,16 @@ category.liquids = 液体 category.items = 物品 category.crafting = 制造 category.shooting = 发射 -category.optional = 可选的增强物品 +category.optional = 可选的增强 setting.landscape.name = 锁定横屏 setting.shadows.name = 影子 -setting.blockreplace.name = Automatic Block Suggestions +setting.blockreplace.name = 自动推荐块 setting.linear.name = 抗锯齿 setting.hints.name = 提示 +setting.buildautopause.name = 自动暂停建造 setting.animatedwater.name = 流动的水 setting.animatedshields.name = 动态画面 -setting.antialias.name = 抗锯齿[LIGHT_GRAY](需要重新启动)[] +setting.antialias.name = 抗锯齿[lightgray](需要重新启动)[] setting.indicators.name = 队友指示器 setting.autotarget.name = 自动射击 setting.keyboard.name = 鼠标+键盘操控 @@ -589,7 +613,7 @@ setting.touchscreen.name = 触屏操控 setting.fpscap.name = 最大FPS setting.fpscap.none = 无 setting.fpscap.text = {0} FPS -setting.uiscale.name = UI缩放比例[lightgray](需要重新启动)[] +setting.uiscale.name = UI缩放比例[lightgray](需要重新启动)[] setting.swapdiagonal.name = 自动铺设 setting.difficulty.training = 训练 setting.difficulty.easy = 简单 @@ -599,106 +623,130 @@ setting.difficulty.insane = 疯狂 setting.difficulty.name = 难度: setting.screenshake.name = 屏幕抖动 setting.effects.name = 显示效果 -setting.destroyedblocks.name = Display Destroyed Blocks -setting.conveyorpathfinding.name = Conveyor Placement Pathfinding +setting.destroyedblocks.name = 显示摧毁的块 +setting.conveyorpathfinding.name = 传送带放置寻路 setting.sensitivity.name = 控制器灵敏度 setting.saveinterval.name = 自动保存间隔 setting.seconds = {0} 秒 +setting.blockselecttimeout.name = 块选择超时 +setting.milliseconds = {0} 毫秒 setting.fullscreen.name = 全屏 -setting.borderlesswindow.name = 无边框窗口[LIGHT_GRAY] (可能需要重启) -setting.fps.name = 显示 FPS +setting.borderlesswindow.name = 无边框窗口[lightgray](可能需要重启) +setting.fps.name = 显示 FPS 和网络延迟 +setting.blockselectkeys.name = 显示块选择按键 setting.vsync.name = 垂直同步 -setting.pixelate.name = 像素画面 [LIGHT_GRAY](禁用动画) +setting.pixelate.name = 像素画面 [lightgray](禁用动画) setting.minimap.name = 显示小地图 setting.position.name = 显示玩家坐标 setting.musicvol.name = 音乐音量 -setting.ambientvol.name = 环境体积 -setting.mutemusic.name = 静音 +setting.ambientvol.name = 环境音量 +setting.mutemusic.name = 无音乐 setting.sfxvol.name = 音效音量 -setting.mutesound.name = 静音 -setting.crashreport.name = 发送匿名崩溃报告 +setting.mutesound.name = 无音效 +setting.crashreport.name = 发送匿名的崩溃报告 setting.savecreate.name = 自动创建存档 -setting.publichost.name = 公共游戏旁观 -setting.chatopacity.name = 聊天界面透明度 +setting.publichost.name = 游戏公开可见 +setting.chatopacity.name = 聊天界面不透明度 setting.lasersopacity.name = 能量激光不透明度 -setting.playerchat.name = 显示游戏内聊天界面 -public.confirm = 确定开启旁观?\n[lightgray]可在设置->游戏->公共游戏旁观中修改。 -public.beta = 请注意,测试版的游戏不能公共旁观。 -uiscale.reset = UI缩放比例已经改变。\n按下“确定”来确定缩放比例\n[accent]{0}[]秒后[scarlet]退出并恢复设定。 +setting.playerchat.name = 显示玩家聊天气泡 +public.confirm = 确定使您的游戏公开可见?\n[accent]其他人将可以加入到您的游戏。\n[lightgray]您之后可以在 设置->游戏->游戏公开可见 更改。 +public.beta = 请注意,测试版的游戏不能公开可见。 +uiscale.reset = UI 缩放比例已更改。\n按下“确定”来执行缩放比例的更改。\n[accent]{0}[]秒后[scarlet]将自动退出并还原设置。 uiscale.cancel = 取消并退出 setting.bloom.name = 特效 keybind.title = 重新绑定按键 -keybinds.mobile = [scarlet]这里的大多数键绑定在移动设备上都不起作用。仅支持基本运动。 -category.general.name = 普通 -category.view.name = 查看 +keybinds.mobile = [scarlet]这里的大多数按键绑定在移动设备上都不能用。仅支持基本的移动。 +category.general.name = 常规 +category.view.name = 视图 category.multiplayer.name = 多人 command.attack = 攻击 -command.rally = 集合 +command.rally = 团体 command.retreat = 撤退 +placement.blockselectkeys = \n[lightgray]按键:[{0}, keybind.clear_building.name = 清除建筑 -keybind.press = 按一下键…… -keybind.press.axis = 按一下轴或键…… +keybind.press = 请按一个键… +keybind.press.axis = 请按一个轴或键… keybind.screenshot.name = 地图截图 +keybind.toggle_power_lines.name = 显隐能量标识线 keybind.move_x.name = 水平移动 keybind.move_y.name = 竖直移动 +keybind.mouse_move.name = 跟随鼠标 +keybind.dash.name = 冲刺 keybind.schematic_select.name = 选择区域 keybind.schematic_menu.name = 蓝图目录 keybind.schematic_flip_x.name = 水平翻转 keybind.schematic_flip_y.name = 竖直翻转 +keybind.category_prev.name = 上一分类 +keybind.category_next.name = 下一分类 +keybind.block_select_left.name = 块选择向左 +keybind.block_select_right.name = 块选择向右 +keybind.block_select_up.name = 块选择向上 +keybind.block_select_down.name = 块选择向下 +keybind.block_select_01.name = 分类/块选择 1 +keybind.block_select_02.name = 分类/块选择 2 +keybind.block_select_03.name = 分类/块选择 3 +keybind.block_select_04.name = 分类/块选择 4 +keybind.block_select_05.name = 分类/块选择 5 +keybind.block_select_06.name = 分类/块选择 6 +keybind.block_select_07.name = 分类/块选择 7 +keybind.block_select_08.name = 分类/块选择 8 +keybind.block_select_09.name = 分类/块选择 9 +keybind.block_select_10.name = 分类/块选择 10 keybind.fullscreen.name = 切换全屏 keybind.select.name = 选择/射击 keybind.diagonal_placement.name = 自动铺设 keybind.pick.name = 选择方块 keybind.break_block.name = 破坏方块 -keybind.deselect.name = 取消 +keybind.deselect.name = 取消选择 keybind.shoot.name = 射击 -keybind.zoom_hold.name = 保持缩放 +keybind.zoom_hold.name = 按住调整缩放 keybind.zoom.name = 缩放 keybind.menu.name = 菜单 keybind.pause.name = 暂停 keybind.pause_building.name = 暂停/继续建造 keybind.minimap.name = 小地图 -keybind.dash.name = 冲刺 keybind.chat.name = 聊天 keybind.player_list.name = 玩家列表 keybind.console.name = 控制台 keybind.rotate.name = 旋转 keybind.rotateplaced.name = 旋转全部(长按) -keybind.toggle_menus.name = 切换菜单 -keybind.chat_history_prev.name = 前面的聊天记录 -keybind.chat_history_next.name = 后面的聊天记录 +keybind.toggle_menus.name = 显隐选项 +keybind.chat_history_prev.name = 聊天记录向前 +keybind.chat_history_next.name = 聊天记录向后 keybind.chat_scroll.name = 聊天记录滚动 -keybind.drop_unit.name = 释放单位 +keybind.drop_unit.name = 松开单位 keybind.zoom_minimap.name = 小地图缩放 mode.help.title = 模式说明 mode.survival.name = 生存 -mode.survival.description = 正常的游戏模式,有限的资源和自动波次。\n[gray]需要敌人出生点。 +mode.survival.description = 正常的游戏模式,有限的资源,自动的波次。\n[gray]需要击退周期性出现的敌人。 mode.sandbox.name = 沙盒 mode.sandbox.description = 无限的资源,不会自动生成敌人。 -mode.editor.name = 编辑 +mode.editor.name = 编辑器 mode.pvp.name = PvP -mode.pvp.description = 和本地玩家对战。\n[gray]需要不同队伍的核心。 +mode.pvp.description = 与本地玩家对战。\n[gray]需要地图中有不同队伍(颜色)的核心。 mode.attack.name = 攻击 -mode.attack.description = 没有波数,但是有摧毁敌人基地的任务。\n[gray]需要姨妈红队核心。 +mode.attack.description = 没有波次,但需要摧毁敌人的基地。\n[gray]需要地图中有红色的核心。 mode.custom = 自定义模式 + rules.infiniteresources = 无限资源 +rules.reactorexplosions = 反应堆爆炸 rules.wavetimer = 波次计时器 rules.waves = 波次 rules.attack = 攻击模式 -rules.enemyCheat = 敌人无限资源 +rules.enemyCheat = 敌人(红队)无限资源 rules.unitdrops = 敌人出生点 rules.unitbuildspeedmultiplier = 单位生产速度倍数 rules.unithealthmultiplier = 单位生命倍数 rules.playerhealthmultiplier = 玩家生命倍数 rules.playerdamagemultiplier = 玩家伤害倍数 rules.unitdamagemultiplier = 单位伤害倍数 -rules.enemycorebuildradius = 敌对核心非建设区半径:[LIGHT_GRAY](格) -rules.respawntime = 重生时间:[LIGHT_GRAY](秒) -rules.wavespacing = 波次间隔时间:[LIGHT_GRAY](秒) +rules.enemycorebuildradius = 敌对核心非建设区半径:[lightgray](格) +rules.respawntime = 重生时间:[lightgray](秒) +rules.wavespacing = 波次间隔时间:[lightgray](秒) rules.buildcostmultiplier = 建设花费倍数 rules.buildspeedmultiplier = 建设时间倍数 rules.waitForWaveToEnd = 等待敌人时间 -rules.dropzoneradius = 敌人出生点毁灭大小:[LIGHT_GRAY](格) +rules.dropzoneradius = 敌人出生点禁区大小:[lightgray](格) rules.respawns = 每波最大重生次数 rules.limitedRespawns = 重生限制次数 rules.title.waves = 波次 @@ -707,6 +755,10 @@ rules.title.resourcesbuilding = 资源和建造 rules.title.player = 玩家 rules.title.enemy = 敌人 rules.title.unit = 单位 +rules.title.experimental = 实验性 +rules.lighting = 光照 +rules.ambientlight = 环境光 + content.item.name = 物品 content.liquid.name = 液体 content.unit.name = 部队 @@ -753,21 +805,22 @@ mech.trident-ship.name = Trident mech.trident-ship.weapon = 炸弹 mech.glaive-ship.name = Glaive mech.glaive-ship.weapon = 火焰机枪 -item.explosiveness = [LIGHT_GRAY]爆炸性:{0} -item.flammability = [LIGHT_GRAY]易燃性:{0} -item.radioactivity = [LIGHT_GRAY]放射性:{0} -unit.health = [LIGHT_GRAY]生命值:{0} -unit.speed = [LIGHT_GRAY]速度:{0} -mech.weapon = [LIGHT_GRAY]武器:{0} -mech.health = [LIGHT_GRAY]生命值:{0} -mech.itemcapacity = [LIGHT_GRAY]物品容量:{0} -mech.minespeed = [LIGHT_GRAY]采矿速度:{0} -mech.minepower = [LIGHT_GRAY]采矿力量:{0} -mech.ability = [LIGHT_GRAY]能力:{0} -mech.buildspeed = [LIGHT_GRAY]建造速度:{0}% -liquid.heatcapacity = [LIGHT_GRAY]热容量:{0} -liquid.viscosity = [LIGHT_GRAY]粘度:{0} -liquid.temperature = [LIGHT_GRAY]温度:{0} +item.explosiveness = [lightgray]爆炸性:{0}% +item.flammability = [lightgray]易燃性:{0}% +item.radioactivity = [lightgray]放射性:{0}% +unit.health = [lightgray]生命值:{0} +unit.speed = [lightgray]速度:{0} +mech.weapon = [lightgray]武器:{0} +mech.health = [lightgray]生命值:{0} +mech.itemcapacity = [lightgray]物品容量:{0} +mech.minespeed = [lightgray]采矿速度:{0}% +mech.minepower = [lightgray]采矿强度:{0} +mech.ability = [lightgray]能力:{0} +mech.buildspeed = [lightgray]建造速度:{0}% +liquid.heatcapacity = [lightgray]热容量:{0} +liquid.viscosity = [lightgray]粘度:{0} +liquid.temperature = [lightgray]温度:{0} + block.sand-boulder.name = 沙砂巨石 block.grass.name = 草地 block.salt.name = 盐碱地 @@ -790,11 +843,11 @@ block.scrap-wall.name = 废墙 block.scrap-wall-large.name = 大型废墙 block.scrap-wall-huge.name = 巨型废墙 block.scrap-wall-gigantic.name = 超巨型废墙 -block.thruster.name = 助力器 -block.kiln.name = 熔炉 +block.thruster.name = 推进器残骸 +block.kiln.name = 窑炉 block.graphite-press.name = 石墨压缩机 block.multi-press.name = 多重压缩机 -block.constructing = {0}\n[LIGHT_GRAY](建造中) +block.constructing = {0}\n[lightgray](建造中) block.spawn.name = 敌人出生点 block.core-shard.name = 小型核心 block.core-foundation.name = 中型核心 @@ -853,19 +906,21 @@ block.door.name = 门 block.door-large.name = 大门 block.duo.name = 双管炮 block.scorch.name = 火焰炮 -block.scatter.name = 分裂炮 +block.scatter.name = 散射炮 block.hail.name = 冰雹炮 block.lancer.name = 蓝瑟炮 block.conveyor.name = 传送带 block.titanium-conveyor.name = 钛传送带 block.armored-conveyor.name = 装甲传送带 -block.armored-conveyor.description = 向钛传送带一样运物品,但有更好的装甲。除其他传送带,不接受任何边的输入。 -block.junction.name = 连接点 +block.armored-conveyor.description = 运送物品,与钛传送带一样的速度,但有更强的装甲。除其他传送带,不接受任何边的输入。 +block.junction.name = 交叉器 block.router.name = 路由器 block.distributor.name = 分配器 block.sorter.name = 分类器 block.inverted-sorter.name = 反向分类器 block.message.name = 信息板 +block.illuminator.name = 照明器 +block.illuminator.description = 小型、紧凑、可配置的光源。需要能量运行。 block.overflow-gate.name = 溢流门 block.silicon-smelter.name = 硅冶炼厂 block.phase-weaver.name = 相织布编织器 @@ -878,12 +933,13 @@ block.separator.name = 分离机 block.coal-centrifuge.name = 煤炭离心机 block.power-node.name = 能量节点 block.power-node-large.name = 大型能量节点 -block.surge-tower.name = 巨浪塔 +block.surge-tower.name = 大型能量塔 +block.diode.name = 二极管 block.battery.name = 电池 block.battery-large.name = 大型电池 -block.combustion-generator.name = 燃烧发电机 +block.combustion-generator.name = 火力发电机 block.turbine-generator.name = 涡轮发电机 -block.differential-generator.name = 差动发电机 +block.differential-generator.name = 温差发电机 block.impact-reactor.name = 冲击反应堆 block.mechanical-drill.name = 机械钻头 block.pneumatic-drill.name = 气动钻头 @@ -899,30 +955,30 @@ block.omega-mech-pad.name = Omega 机甲平台 block.tau-mech-pad.name = Tau 机甲平台 block.conduit.name = 导管 block.mechanical-pump.name = 机械泵 -block.item-source.name = 物品源 +block.item-source.name = 无限物品 block.item-void.name = 物品黑洞 -block.liquid-source.name = 液体源 +block.liquid-source.name = 无限液体 block.power-void.name = 能源黑洞 block.power-source.name = 无限能源 block.unloader.name = 装卸器 block.vault.name = 仓库 -block.wave.name = 波浪 +block.wave.name = 波浪炮 block.swarmer.name = 蜂群 -block.salvo.name = 齐射炮 -block.ripple.name = 浪涌 +block.salvo.name = 连射炮 +block.ripple.name = 浪涌炮 block.phase-conveyor.name = 相织布传送带桥 block.bridge-conveyor.name = 传送带桥 block.plastanium-compressor.name = 塑钢压缩机 block.pyratite-mixer.name = 硫混合器 block.blast-mixer.name = 爆炸混合器 -block.solar-panel.name = 太阳能电池 -block.solar-panel-large.name = 大型太阳能电池 +block.solar-panel.name = 太阳能板 +block.solar-panel-large.name = 大型太阳能板 block.oil-extractor.name = 石油钻井 block.command-center.name = 指挥中心 block.draug-factory.name = 德鲁格采矿机工厂 block.spirit-factory.name = 幽灵修理机工厂 -block.phantom-factory.name = 鬼怪建造机工厂 -block.wraith-factory.name = 幻影战机工厂 +block.phantom-factory.name = 幻影建造机工厂 +block.wraith-factory.name = 幽灵战机工厂 block.ghoul-factory.name = 食尸鬼轰炸机工厂 block.dagger-factory.name = 尖刀机甲工厂 block.crawler-factory.name = 爬行者机甲工厂 @@ -931,12 +987,13 @@ block.fortress-factory.name = 堡垒机甲工厂 block.revenant-factory.name = 亡魂战机工厂 block.repair-point.name = 维修点 block.pulse-conduit.name = 脉冲导管 +block.plated-conduit.name = 电镀导管 block.phase-conduit.name = 相织布导管桥 block.liquid-router.name = 液体路由器 block.liquid-tank.name = 储液罐 -block.liquid-junction.name = 液体连接点 +block.liquid-junction.name = 液体交叉器 block.bridge-conduit.name = 导管桥 -block.rotary-pump.name = 回旋泵 +block.rotary-pump.name = 回转泵 block.thorium-reactor.name = 钍反应堆 block.mass-driver.name = 质量驱动器 block.blast-drill.name = 爆破钻头 @@ -948,32 +1005,32 @@ block.mend-projector.name = 修理投影器 block.surge-wall.name = 波动墙 block.surge-wall-large.name = 大型波动墙 block.cyclone.name = 气旋炮 -block.fuse.name = 融合炮 +block.fuse.name = 雷光炮 block.shock-mine.name = 脉冲地雷 block.overdrive-projector.name = 超速投影器 block.force-projector.name = 力墙投影器 -block.arc.name = 电弧 +block.arc.name = 电弧炮 block.rtg-generator.name = RTG 发电机 -block.spectre.name = 幽灵 -block.meltdown.name = 熔毁 +block.spectre.name = 幽灵炮 +block.meltdown.name = 熔毁炮 block.container.name = 容器 block.launch-pad.name = 发射台 block.launch-pad-large.name = 大型发射台 -team.blue.name = 胖次蓝 -team.crux.name = 姨妈红 -team.sharded.name = 哲学黄 -team.orange.name = 太阳橙 -team.derelict.name = 高冷灰 -team.green.name = 原谅绿 -team.purple.name = 基佬紫 +team.blue.name = 蓝 +team.crux.name = 红 +team.sharded.name = 黄 +team.orange.name = 橙 +team.derelict.name = 灰 +team.green.name = 绿 +team.purple.name = 紫 unit.spirit.name = 幽灵修理机 unit.draug.name = 德鲁格采矿机 -unit.phantom.name = 鬼怪建造机 +unit.phantom.name = 幻影建造机 unit.dagger.name = 尖刀 unit.crawler.name = 爬行者 unit.titan.name = 泰坦 unit.ghoul.name = 食尸鬼轰炸机 -unit.wraith.name = 幻影战机 +unit.wraith.name = 幽灵战机 unit.fortress.name = 堡垒 unit.revenant.name = 亡魂 unit.eruptor.name = 暴君 @@ -982,174 +1039,177 @@ unit.eradicator.name = 根除者 unit.lich.name = 尸鬼 unit.reaper.name = 死神 tutorial.next = [lightgray]<点击以继续> -tutorial.intro = 你进入了[scarlet] Mindustry 教程[]。\n[accent]采集铜矿[]以开始。点击附近的一处铜矿。\n\n[accent]{0}/{1} 铜 -tutorial.intro.mobile = You have entered the[scarlet] Mindustry Tutorial.[]\nSwipe the screen to move.\n[accent]Pinch with 2 fingers [] to zoom in and out.\nBegin by[accent] mining copper[]. Move close to it, then tap a copper ore vein near your core to do this.\n\n[accent]{0}/{1} copper -tutorial.drill = 手动采矿效率低。\n[accent]钻头[]可以自动采矿。\n放一个在铜矿上吧。\n点击右下角的钻头菜单。\n选择[accent]机械钻头[]。\n单击将其放置在铜矿上。\n[accent]右键单击[]来停止。 -tutorial.drill.mobile = 手动采矿效率低。\n[accent]钻头[]可以自动采矿。\n点击右下角的钻头菜单。\n选择[accent]机械钻头[]。\n点击将其放在铜矿上,点击[accent]对号[]来确定。\n点击[accent]叉号[]来取消。 -tutorial.blockinfo = 每个方块具有不同的数据。每个钻头只能开采某些矿石。\n要检查块的信息和统计信息,[accent]在菜单中点击问号。[]\n\n[accent]现在查看机械钻头的数据吧。[] -tutorial.conveyor = [accent]传送带[]可以把物资传送到核心。\n请从钻头到核心间造一条传送带。 -tutorial.conveyor.mobile = [accent]传送带[]可以把物资传送到核心。\n请从钻头到核心间造一条传送带。\n[accent]长按数秒[]并向一个方向拖动来直线放置。\n\n[accent]{0}/{1} 条传送带\n[accent]0/1 物品 -tutorial.turret = 必须建造防御建筑来击退[LIGHT_GRAY]敌人[]。\n请在核心附近造一个双管炮。 +tutorial.intro = 您已进入[scarlet] Mindustry 教程[]。[]\n使用[accent][[WASD][]键移动主角和视角。\n[accent]按住[[Ctrl]并转动鼠标滚轮[]缩放视野。\n让我们从[accent]采集铜矿[]开始。先移动到铜矿旁边,然后点按矿脉附近散落的矿物。\n\n[accent]{0}/{1} 铜 +tutorial.intro.mobile = 您已进入[scarlet] Mindustry 教程[]。\n在屏幕上滑动来继续。\n[accent]双指捏合[] 来缩小和放大。\n让我们从[accent]采集铜矿[]开始。先移动到铜矿旁边,然后点按矿脉附近散落的矿物。\n\n[accent]铜 {0}/{1} +tutorial.drill = 手动采矿效率不高。\n[accent]钻头[]可以自动采矿。\n让我们在在铜矿上放一个。\n点击右下角的钻头菜单。\n选择[accent]机械钻头[]。\n单击将其放置在铜矿上。\n[accent]右键单击[]来停止。 +tutorial.drill.mobile = 手动采矿效率不高。\n[accent]钻头[]可以自动采矿。\n点右下角的钻头菜单。\n选择[accent]机械钻头[]。\n点一下将其放在铜矿上,点[accent]对号[]来确定。\n点[accent]叉号[]来取消。 +tutorial.blockinfo = 每种方块都有其独特的数据。每个钻头只能开采部分矿石。\n若要查看块的信息和统计信息,[accent]在菜单中点击问号。[]\n\n[accent]现在查看机械钻头的数据吧。[] +tutorial.conveyor = [accent]传送带[]可以把物资传送到核心。\n请在钻头到核心间建造一条传送带。 +tutorial.conveyor.mobile = [accent]传送带[]可以把物资传送到核心。\n请在钻头到核心间建造一条传送带。\n[accent]长按数秒[]并向一个方向拖动来直线放置。\n\n[accent]{0}/{1} 条传送带\n[accent]0/1 物品 +tutorial.turret = 必须建造防御建筑来击退[lightgray]敌人[]。\n请在核心附近造一个双管炮。 tutorial.drillturret = 双管炮需要[accent]铜[]作弹药来射击。\n可以放一个钻头在炮塔附近供应铜。 tutorial.pause = 在战斗中,您可以[accent]暂停游戏[]。\n暂停时您可以规划建筑物。\n\n按[accent]空格[]暂停。 tutorial.pause.mobile = 在战斗中,您可以[accent]暂停游戏[]。\n暂停时您可以规划建筑物。\n\n[accent]点击左上角的按钮以暂停。 tutorial.unpause = 现在再次按空格以继续。 -tutorial.unpause.mobile = 现在再次点击以继续。 +tutorial.unpause.mobile = 现在再次点按以继续。 tutorial.breaking = 方块经常需要拆除。\n[accent]按住鼠标右键[]来拆除选中的方块。[]\n\n[accent]使用范围拆除来拆除核心左侧的废墙。 tutorial.breaking.mobile = 方块经常需要拆除。\n[accent]选择拆除模式[],点击方块以拆除。\n[accent]长按几秒[]并拖动来范围拆除。\n点击对号来确定。\n\n[accent]使用范围拆除来拆除核心左侧的废墙。 tutorial.withdraw = 有时,从方块中取出物品是必要的。\n[accent]点击有物品的方块[],然后[accent]点击在方框中的物品[]。\n可以通过[accent]点击或长按[]来取出物品。\n\n[accent]从核心中取出一些铜[]。 tutorial.deposit = 将物品从机甲拖向方块来放下物品。\n\n[accent]将铜放回核心[]。 -tutorial.waves = [lightgray]敌人[]来了。\n\n保护核心,防御2波攻击。造更多的炮塔。[accent]点击[]以射击。\n建造更多的炮塔和钻头,并采更多的矿。 -tutorial.waves.mobile = [lightgray]敌人[]来了。\n\n保护核心,防御2波攻击。造更多的炮塔。你的机甲将对敌人自动开火。\n建造更多的炮塔和钻头,并采更多的矿。 -tutorial.launch = 特定波次中,你可以[accent]发射核心[],[accent]携带核心中所有资源[]离开所有的建筑。\n资源可用来研究科技。\n\n[accent]点击发射按钮。 -item.copper.description = 一种有用的结构材料。在各种类型的方块中广泛使用。 -item.lead.description = 一种基本的起始材料。广泛用于电子设备和液体运输。 -item.metaglass.description = 一种超级强硬的复合玻璃。通常用来传送和收藏液体。 -item.graphite.description = 一种用于弹药和电路绝缘的矿化碳。 +tutorial.waves = [lightgray]敌人[]来了。\n\n保护核心,防御两波攻击。造更多的炮塔。[accent]点击[]以射击。\n建造更多的炮塔和钻头,并采更多的矿。 +tutorial.waves.mobile = [lightgray]敌人[]来了。\n\n保护核心,防御两波攻击。造更多的炮塔。你的机甲将对敌人自动开火。\n建造更多的炮塔和钻头,并采更多的矿。 +tutorial.launch = 进入特定波次后,你可以[accent]发射核心(起飞)[],[accent]带走核心中的所有资源[]并抛下所有的建筑。\n装运的资源可用于研究科技。\n\n[accent]点击发射按钮。 + +item.copper.description = 最基本的的结构材料。在各种类型的方块中被广泛使用。 +item.lead.description = 一种基本的电力材料。广泛用于电子设备和液体输送模块。 +item.metaglass.description = 一种致密坚硬的复合玻璃。广泛用于液体输送和存储。 +item.graphite.description = 矿化碳,用于弹药和电路绝缘。 item.sand.description = 一种常见的材料,广泛用于冶炼,包括制作合金和助熔剂。 -item.coal.description = 一种常见并容易获得的燃料。 +item.coal.description = 植物的化石,常见且容易获得,常用作燃料或其他资源的生产。 item.titanium.description = 一种罕见的超轻金属,被广泛运用于液体运输、钻头和飞机。 item.thorium.description = 一种致密的放射性金属,用作结构支撑和核燃料。 item.scrap.description = 一种废弃的建筑物及废弃单位的残骸,富含多种金属元素。 item.silicon.description = 一种非常有用的半导体,被用于太阳能电池板和很多复杂的电子设备。 -item.plastanium.description = 一种轻质,可延展的材料,用于高级的飞机和碎片弹药。 -item.phase-fabric.description = 一种接近0重量的物质,用于先进的电子技术和自我修复技术。 -item.surge-alloy.description = 一种具有独特电气性能的高级合金。 -item.spore-pod.description = 一种用于制造石油,炸药及燃料的生物质。 -item.blast-compound.description = 一种用于炸弹和炸药的挥发性混合物。虽然它可以作为燃料燃烧,但不建议这样做。 -item.pyratite.description = 一种燃烧武器中使用的极易燃物质。 -liquid.water.description = 最有用的液体。常用于冷却和废物处理。 -liquid.slag.description = 各种不同类型的熔融金属混合在一起的液体。可以被分解成其组成矿物,或作为武器喷向敌方单位。 +item.plastanium.description = 一种轻质、可延展的材料,用于高级的飞机和碎片弹药。 +item.phase-fabric.description = 一种近乎无重量的物质,用于先进的电子技术和自我修复技术。 +item.surge-alloy.description = 一种先进的合金,具有独特的电气性能。 +item.spore-pod.description = 一种用于制造石油、炸药及燃料的生物质。 +item.blast-compound.description = 一种用于炸弹和炸药的挥发性混合物。虽然它可以作为燃料,但不建议这样做。 +item.pyratite.description = 一种在燃烧武器中使用的极易燃物质。 +liquid.water.description = 最有用的液体。常用于冷却机器和废物处理。 +liquid.slag.description = 各种不同类型的熔融金属混合在一起的液体。可以被分解成其矿物成分,或作为武器喷向敌方单位。 liquid.oil.description = 用于先进材料生产的液体。可以转换成煤作为燃料,或作为武器喷射和放火。 liquid.cryofluid.description = 一种由水和钛制成的惰性、无腐蚀性的液体。具有极高的热容量。广泛用作冷却剂。 mech.alpha-mech.description = 标准控制机甲。基于尖刀单位,具有升级的装甲和建筑能力。比 Dart 有更多的伤害输出。 -mech.delta-mech.description = 一种快速,轻便的机甲,一击即退。对结构造成的伤害很小,但可以用弧形闪电武器快速杀死大量敌方单位。 +mech.delta-mech.description = 一种快速、轻便的机甲,一击即退。对结构造成的伤害很小,但可以使用弧形闪电武器快速杀死大量敌方单位。 mech.tau-mech.description = 后勤机甲。治疗友军。可以熄灭火焰并治疗一定范围内的友军。 mech.omega-mech.description = 一种装甲厚重的机甲,用于在前线攻击。它的护甲可以阻挡高达90%的伤害。 mech.dart-ship.description = 标准飞船。快速轻便,但攻击能力低,采矿速度慢。 mech.javelin-ship.description = 一艘一击即退的攻击船。虽然最初很慢,但它可以加速到很快的速度,并飞过敌人的前哨,利用其闪电能力和导弹造成大量伤害。 mech.trident-ship.description = 为建造和摧毁敌人防御工事而建造的重型轰炸机。有相当好的装甲。 -mech.glaive-ship.description = 一种大型,装甲厚重的武装直升机。配备燃烧机枪。有优秀的加速能力和最快的速度。 +mech.glaive-ship.description = 一种大型的装甲厚重的武装直升机。配备火焰机枪。有优秀的加速能力和最快的速度。 unit.draug.description = 一种原始的采矿机。生产成本低,消耗品。在附近自动开采铜和铅。将开采的资源输送到最近的核心。 unit.spirit.description = 一种改进的德鲁格无人机,设计用于维修而不是采矿。自动修复该区域中任何损坏的块。 unit.phantom.description = 一种先进的无人机。跟随玩家并协助建造。 -unit.dagger.description = 一种最基本的地面机甲。生产成本低。在蜂群中使用时很有用。 +unit.dagger.description = 一种最基本的地面机甲。生产成本低。集群使用时比较有用。 unit.crawler.description = 一种地面装置,由一个框架和绑在上面的烈性炸药组成。不是特别耐用。与敌人接触后爆炸。 -unit.titan.description = 一种先进的装甲地面部队。攻击地面和空中目标。配备两个微型灼烧级火焰喷射器。 +unit.titan.description = 一种先进的地面装甲部队。攻击地面和空中目标。配备两个微型灼烧级火焰喷射器。 unit.fortress.description = 一种重型炮兵机甲。装备两门改进型冰雹炮,用于对敌军建筑物和部队进行远程攻击。 unit.eruptor.description = 一种用来拆除建筑物的重型机甲。在敌人的防御工事上发射矿渣,将它们熔化并点燃挥发物。 unit.wraith.description = 一种快速、一击即退的拦截器机甲。目标是发电机。 -unit.ghoul.description = 一种地毯式轰炸机。通过敌人的结构进行攻击,并瞄准关键的基础设施。 +unit.ghoul.description = 一种重型地毯式轰炸机。瞄准关键的基础设施来击溃敌人的基地。 unit.revenant.description = 一种发射导弹的重型飞行机甲。 -block.message.description = 储存一条信息。用于在盟军之间交流。 -block.graphite-press.description = 把大块的煤压缩成纯石墨片。 +block.message.description = 储存一条消息。用于盟友间的交流。 +block.graphite-press.description = 将煤块压缩成纯石墨片材料。 block.multi-press.description = 石墨压缩机的升级版。利用水和电力快速高效地处理煤炭。 block.silicon-smelter.description = 用高纯度的焦炭来加工沙子以生产硅。 block.kiln.description = 将铅和沙子熔炼成钢化玻璃,需要少量电力。 block.plastanium-compressor.description = 用石油和钛生产塑钢。 block.phase-weaver.description = 用放射性钍和大量沙子生产相织物。 -block.alloy-smelter.description = 用钛,铅,硅和铜生产浪涌合金。 -block.cryofluidmixer.description = 水和钛结合到低温流体中,冷却效率更高。 -block.blast-mixer.description = 用油将硫转化为不易燃但更具爆炸性的爆炸化合物。 -block.pyratite-mixer.description = 将煤,铅和沙子混合成高度易燃的硫。 -block.melter.description = 将废料熔化成矿渣,以便进一步加工或用于炮塔子弹。 +block.alloy-smelter.description = 用钛、铅、硅和铜生产浪涌合金。 +block.cryofluidmixer.description = 将水和细的钛粉混成冷却液。钍反应堆的必备之物。 +block.blast-mixer.description = 用油料将硫转化为不易燃但更具爆炸性的爆炸化合物。 +block.pyratite-mixer.description = 将煤、铅和沙子混合成高度易燃的硫。 +block.melter.description = 将废料熔化成矿渣,以便进一步加工或用于炮塔弹药。 block.separator.description = 从矿渣中提取有用的矿物。 -block.spore-press.description = 压缩孢子荚得到石油。 -block.pulverizer.description = 将废料压碎成沙子。当缺少天然沙子时很有用。 +block.spore-press.description = 以极高压力压缩孢子荚合成油料。 +block.pulverizer.description = 将废料碾成沙。 block.coal-centrifuge.description = 使石油凝固成煤块。 -block.incinerator.description = 用于除掉任何多余的物品或液体。 +block.incinerator.description = 用来接收并除掉多余的物品或液体。 block.power-void.description = 消耗输入的所有能量。仅限沙盒。 block.power-source.description = 无限输出能量。仅限沙盒。 block.item-source.description = 无限输出物品。仅限沙盒。 -block.item-void.description = 在不使用能量的情况下销毁任何进入它的物品。仅限沙盒。 +block.item-void.description = 销毁输入的所有物品。仅限沙盒。 block.liquid-source.description = 无限输出液体。仅限沙盒。 -block.copper-wall.description = 廉价的防守方块。\n用于保护前几波中的核心和炮塔。 -block.copper-wall-large.description = 廉价的防守方块。\n用于保护前几个波浪中的核心和炮塔。\n跨越多个区块。 +block.copper-wall.description = 廉价的防御方块。\n适合在前几个波次中保护核心和炮塔。 +block.copper-wall-large.description = 廉价的防御方块。\n适合在前几个波次中保护核心和炮塔。\n占多个方格。 block.titanium-wall.description = 中等强度的防御方块。\n提供中等强度的防御以抵御敌人。 -block.titanium-wall-large.description = 一个中等强度的防御方块。\n提供中等强度的防御以防敌人攻击。\n跨越多个区块。 -block.plastanium-wall.description = A special type of wall that absorbs electric arcs and blocks automatic power node connections. -block.plastanium-wall-large.description = A special type of wall that absorbs electric arcs and blocks automatic power node connections.\nSpans multiple tiles. -block.thorium-wall.description = 强大的防守方块。\n可以很好的防御敌人。 -block.thorium-wall-large.description = 强大的防守方块。\n很好地防御敌人。\n跨越多个区块。 -block.phase-wall.description = 没有钍墙那样坚固,但是它可以使不太强的子弹发生偏转。 -block.phase-wall-large.description = 没有钍墙那样坚固,但是它可以使不太强的子弹发生偏转。\n跨越多个区块。 -block.surge-wall.description = 强大的防守方块。\n有很小的机会向攻击者发射闪电。 -block.surge-wall-large.description = 强大的防御方块。\n有很小的机会向攻击者发射闪电。\n跨越多个区块。 -block.door.description = 一扇小门,可以通过点击打开和关闭。\n如果打开,敌人可以射击并穿过。 -block.door-large.description = 一扇大门,可以通过点击打开和关闭。\n如果打开,敌人可以射击并穿过。\n跨越多个区块。 -block.mender.description = 会定期修理附近的方块,使防御系统在波与波之间得到修复。\n可以使用硅来提高修复范围和修复效率。 -block.mend-projector.description = 修理者的升级版,会定期修复附近的建筑物。 +block.titanium-wall-large.description = 中等强度的防御方块。\n提供中等强度的防御以防敌人攻击。\n占多个方格。 +block.plastanium-wall.description = 一种特殊的防御方块,能吸收电弧、自动与能量节点连接。 +block.plastanium-wall-large.description = 一种特殊的防御方块,能吸收电弧、自动与能量节点连接。\n占多个方格。 +block.thorium-wall.description = 强大的防御方块。\n可以很好的防御敌人。 +block.thorium-wall-large.description = 强大的防御方块。\n很好地防御敌人。\n占多个方格。 +block.phase-wall.description = 没有钍墙那样坚固,但是它可以使不太强的弹药发生偏转。 +block.phase-wall-large.description = 没有钍墙那样坚固,但是它可以使不太强的弹药发生偏转。\n占多个方格。 +block.surge-wall.description = 强大的防御方块。\n有很小的机会向攻击者发射闪电。 +block.surge-wall-large.description = 强大的防御方块。\n有很小的机会向攻击者发射闪电。\n占多个方格。 +block.door.description = 一扇小门。点按切换它的打开/关闭状态。 +block.door-large.description = 一扇大门。点按切换它的打开/关闭状态。\n占多个方格。 +block.mender.description = 定期修理附近的方块,使防御系统在波次之间得到修复。\n可选使用硅来提高修复范围和修复效率。 +block.mend-projector.description = 修理者的升级版,定期修复附近的建筑物。 block.overdrive-projector.description = 提高附近建筑物的速度,如钻头和传送带。 -block.force-projector.description = 自身周围创建一个六边形力场,使建筑物和内部单位免受子弹的伤害。 +block.force-projector.description = 在自身周围创建一个六角形力场,使里面的建筑物和单位免受伤害。\n持续承受高伤害会导致过热,可以使用冷却液降温。相织物可用于增加屏障大小。 block.shock-mine.description = 伤害踩到它的敌人。敌人几乎看不到它。 -block.conveyor.description = 初级传送带。将物品向前输送并将它们放入炮塔或工厂中。可旋转方向。 -block.titanium-conveyor.description = 高级传送带,比初级传送带更快地输送物品。 -block.junction.description = 两条交叉传送带的桥梁。适用于两条不同方向传送带将不同物品运送到不同位置的情况。 -block.bridge-conveyor.description = 高级物品传输方块。允许跨越任何地形或建筑物上运输物品,最多跨越3个块。 -block.phase-conveyor.description = 高级传送带,使用电力将物品传送到距离几个块的相位传送带上。 -block.sorter.description = 对物品进行分类,如果物品与所选种类相同,则允许其通过。否则,物品将从左边和右边输出。 -block.inverted-sorter.description = Processes items like a standard sorter, but outputs selected items to the sides instead. +block.conveyor.description = 初级物资传送带。将物品向前输送并在可能时运入建筑。可旋转方向。 +block.titanium-conveyor.description = 高级物资传送带。运送物品的速度优于初级传送带。 +block.junction.description = 两条传送带的交叉桥连接。适用于两条不同方向的传送带要分别将不同的物品运送到不同的位置。 +block.bridge-conveyor.description = 先进的物品运输方块。允许跨越任意地形或建筑物运输物品,最多跨越3格。 +block.phase-conveyor.description = 先进的传送带,使用电力将物品传送到距离几个块的相位传送带上。 +block.sorter.description = 对物品进行分类,如果物品与所选种类相同,则允许其通过。否则,物品将从左边和右边输出。 +block.inverted-sorter.description = 同分类器一样分类物品,但所选物品输出到左边和右边。 block.router.description = 从一个方向接受物品,并将它们平均输出到其他3个方向。可以将材料分成多份。 -block.distributor.description = 一个高级路由器,可以将物品向最多7个方向输出。 -block.overflow-gate.description = 分离器和路由器的组合,如果前面被挡住,则向从左和右输出。 -block.mass-driver.description = 终极传送带,收集物品后将它们射向远处的另一个质量驱动器。 -block.mechanical-pump.description = 一种输出速度慢但没有功耗的廉价泵。 -block.rotary-pump.description = 先进的水泵。泵送更多液体,但需要能量。 -block.thermal-pump.description = 终级水泵。 +block.distributor.description = 改进的路由器,可将物品输出到周围的最多7个其他方向。 +block.overflow-gate.description = 仅在前路被阻塞时向左和右输出。 +block.mass-driver.description = 终极传送带,收集若干物品后将其射到远处的另一个质量驱动器。 +block.mechanical-pump.description = 一种廉价泵,输出速度慢,但无需能量。 +block.rotary-pump.description = 先进液泵。泵送更多液体,但需要能量。 +block.thermal-pump.description = 终级液泵。 block.conduit.description = 基本液体传输管道。像传送带一样工作,但仅适用于液体。用于从泵或其他导管中提取液体。 block.pulse-conduit.description = 高级液体传输管道。比普通导管更快地输送液体且能储存更多液体。 -block.liquid-router.description = 接受来自一个方向的液体并将它们平均输出到其他3个方向。同时可以储存一定量的液体。用于将液体从一个源分成多个目标。 -block.liquid-tank.description = 存储大量液体,可用于在材料需求不恒定的时候提供缓冲,或作为供给冷却液体的保障。 -block.liquid-junction.description = 作为两个交叉管道的桥梁。适用于两种不同方向的导管将不同液体输送到不同位置的情况。 -block.bridge-conduit.description = 高级液体传输方块。可以跨越任何地形或建筑物,最多跨越3格来传输液体。 -block.phase-conduit.description = 高级液体传输方块。使用电力将液体传送到多个块上的连接管道。 +block.plated-conduit.description = 转移液体的速度与脉冲导管相同,但护甲更强。两侧只接受通过导管传入液体。\n更少泄漏。 +block.liquid-router.description = 接受一个方向的液体并将它们平均输出到其他3个方向。同时可以储存一定量的液体。用于将液体从一个源分往多个目标。 +block.liquid-tank.description = 存储大量液体,可在材料需求不恒定作为缓冲区,或作为供给冷却液体的保障设施。 +block.liquid-junction.description = 两条管道的交叉桥连接。适用于两条不同方向的导管要将不同的液体输送到不同的位置。 +block.bridge-conduit.description = 先进的液体传输方块。可以跨越任何地形或建筑物,最多跨越3格来传输液体。 +block.phase-conduit.description = 先进的液体传输方块。使用电力将液体传送到多个块上的连接管道。 block.power-node.description = 将电源传输到连接的节点上。节点将接收来自任何方块的能量或向任何方块供给能量。 -block.power-node-large.description = 拥有大范围和多连接点的高级能量节点。 -block.surge-tower.description = 连接点较少,但是距离远的能量节点。 -block.battery.description = 储存能量,当储存有能量时,可在能源短缺时提供能量。 +block.power-node-large.description = 更大范围、更多连接点的高级能量节点。 +block.surge-tower.description = 连接数低但范围很远的能量节点。 +block.diode.description = 此方块上的电能只能单向流动,仅当对方的储能更低时流动。 +block.battery.description = 存储能量作为缓冲,在能源亏空时提供。 block.battery-large.description = 比普通电池容量更大。 block.combustion-generator.description = 燃烧煤等材料发电。 -block.thermal-generator.description = 当放置在热的地方时发电。 -block.turbine-generator.description = 先进的燃烧发电机,效率更高,但需要水来产生蒸汽。 -block.differential-generator.description = 利用低温流体和燃烧的硫之间的温差产生大量的能量。 -block.rtg-generator.description = 简单可靠的发电机。利用衰变放射性化合物的热量以缓慢的速度产生能量。 -block.solar-panel.description = 普通太阳能面板,提供少量电力。 -block.solar-panel-large.description = 高级太阳能面板,提供更多电力,但搭建起来更贵。 -block.thorium-reactor.description = 高放射性钍产生大量电力。需要冷却液来冷却。如果供应的冷却液不足,会导致爆炸。 -block.impact-reactor.description = 一种先进的发电机,能够以最高效率产生大量的电力。但需要大量的能量输入才会启动。 +block.thermal-generator.description = 放置在炽热的地方发电。 +block.turbine-generator.description = 先进的火力发电机,效率更高,但需要水来产生蒸汽。 +block.differential-generator.description = 利用低温流体与燃烧的硫之间的温差产生大量能量。 +block.rtg-generator.description = 一种简单可靠的发电机。利用放射性化合物的衰变产生的热量,以缓慢的速度产生能量。 +block.solar-panel.description = 普通太阳能板,提供少量电力。 +block.solar-panel-large.description = 高级太阳能板,提供更多电力,但成本更高。 +block.thorium-reactor.description = 用高放射性的钍产生大量电力。需要冷却液冷却。如果供应的冷却液不足,会导致爆炸。 +block.impact-reactor.description = 一种先进的发电机,能够以最高效率产生大量的电力。但需要大量的能量输入来启动。 block.mechanical-drill.description = 一种便宜的钻头。放置在合适的方块上时,以缓慢的速度无限期地输出物品。只能开采基本资源。 -block.pneumatic-drill.description = 一种改进的钻头,能开采钛。采矿速度比机械钻快。 -block.laser-drill.description = 通过激光技术更快开采,但需要电力。这种钻头可以开采放射性钍。 -block.blast-drill.description = 终极钻头,需要大量电力。 +block.pneumatic-drill.description = 一种改进的钻头,能开采钛。采矿速度比机械钻头快。 +block.laser-drill.description = 通过激光技术更快地开采,但需要能量。这种钻头可以开采放射性钍。 +block.blast-drill.description = 终极钻头,需要大量能量。 block.water-extractor.description = 从地下提取水。当附近没有水源时使用它。 block.cultivator.description = 将微小的孢子培养成工业用的孢子荚。 -block.oil-extractor.description = 使用大量的电力从沙子中提取石油。当附近没有直接的石油来源时使用它。 -block.core-shard.description = 核心第一代。一旦被摧毁,与该地区的所有连接都将断开。不要让他被摧毁。 -block.core-foundation.description = 核心第二代。血量更高。可以存储更多资源。 -block.core-nucleus.description = 核心第三代,也是最后一代,血量非常高。存储大量资源。 -block.vault.description = 存储大量物品。当存在非恒定的材料需求时,使用它来创建缓冲区。[LIGHT_GRAY]卸载器[]可从仓库中提取物品。 -block.container.description = 存储少量物品。当存在非恒定的材料需求时,使用它来创建缓冲区。[LIGHT_GRAY]卸载器[]可从容器中提取物品。 -block.unloader.description = 物品可以从容器,仓库或核心提取到传送带上或直接提取到相邻的方块中。可以通过点击卸载器来更改要卸载的项目类型。 -block.launch-pad.description = 允许不通过核心发射物体。 -block.launch-pad-large.description = 发射台的改进版,可以存储更多物体的同时启动频率更高。 -block.duo.description = 小而便宜的炮塔,对地有效。 -block.scatter.description = 不可或缺的防空炮塔,向空中敌人发射铅或废料。 -block.scorch.description = 小型炮塔,燃烧任何靠近它的地面敌人。近距离非常有效。 +block.oil-extractor.description = 使用大量能量、沙子和水提炼石油。 +block.core-shard.description = 初代核心。一旦被摧毁,与该地区的所有连接都将断开。不要让它被摧毁。 +block.core-foundation.description = 二代核心。血量更高。可以存储更多资源。 +block.core-nucleus.description = 三代核心,也是最新一代,血量非常高。能存储大量资源。 +block.vault.description = 存储大量物品。当存在非恒定的材料需求时,使用它来创建缓冲区。[lightgray]卸载器[]可从仓库中提取物品。 +block.container.description = 存储少量物品。当存在非恒定的材料需求时,使用它来创建缓冲区。[lightgray]卸载器[]可从容器中提取物品。 +block.unloader.description = 将物品从容器、仓库或你的核心中提取到传送带或直接提取到相邻的方块。点击卸载器本身更改所要卸载的物品类型。 +block.launch-pad.description = 定期发射一批物品,而无需发射核心(离开地图)。 +block.launch-pad-large.description = 发射台的改进版,可以存储更多物品,同时启动频率更高。 +block.duo.description = 小而便宜的炮塔,对地很有效。 +block.scatter.description = 基本型防空炮塔。向空中敌人喷出一团铅或废料。 +block.scorch.description = 小型炮塔,点燃任何靠近它的地面敌人。近距离非常有效。 block.hail.description = 小型远程炮台。 block.wave.description = 中型快速炮塔,射出液体泡泡。有液体输入时自动灭火。 -block.lancer.description = 中型对地炮塔。遇敌时会充能并发射强有力的的能量束。 +block.lancer.description = 中型对地炮塔。会充能并发射强力的的能量束。 block.arc.description = 小型炮塔,发射电弧。 block.swarmer.description = 中型炮塔,对空对地,发射跟踪爆炸导弹。 -block.salvo.description = 双管炮的升级版。中型,齐射射击。 -block.fuse.description = 大型炮塔,发射三道刺穿敌人的短程光束。 +block.salvo.description = 双管炮的升级版。中型,快速射出一串子弹。 +block.fuse.description = 大型近程炮塔,发射三道刺穿敌人的短程光束。 block.ripple.description = 大型远程炮台,非常强力,向远处的敌人投射一簇弹药。 -block.cyclone.description = 大型快速炮塔,对空对地,向周围敌人发射爆炸弹。 -block.spectre.description = 超大型炮塔,对空对地,一次射出两颗强大的穿甲子弹。 +block.cyclone.description = 大型炮塔,对空对地,发射在敌人周围引爆的爆炸物。 +block.spectre.description = 超大型炮塔,对空对地,一次射出两颗强大的穿甲弹药。 block.meltdown.description = 超大型激光炮塔,充能之后持续发射光束,需要冷却剂。 -block.command-center.description = 在地图上向盟军发出移动命令。\n使用部队巡逻、攻击敌军核心或撤退到核心/工厂。当没有敌人核心时,部队默认在攻击命令下巡逻。 +block.command-center.description = 在地图上向联盟单位发出移动命令。\n使部队巡逻、攻击一个敌人核心,或者撤退到核心/工厂。当没有敌人核心时,得到攻击命令的部队默认执行巡逻。 block.draug-factory.description = 生产德鲁格釆矿机。 block.spirit-factory.description = 生产幽灵修理机。 -block.phantom-factory.description = 生产鬼怪建造机。 +block.phantom-factory.description = 生产幻影建造机。 block.wraith-factory.description = 生产快速截击机。 block.ghoul-factory.description = 生产重型地毯轰炸机。 block.revenant-factory.description = 生产重型导弹部队。 @@ -1157,11 +1217,11 @@ block.dagger-factory.description = 生产基本地面单位。 block.crawler-factory.description = 生产快速自毁单元。 block.titan-factory.description = 生产先进的装甲地面单位。 block.fortress-factory.description = 生产重型地面火炮部队。 -block.repair-point.description = 连续治疗附近最近的受损单位。 -block.dart-mech-pad.description = 替换当前的机甲并转换成一个基础的攻击型机甲。\n站在上面时点击切换。 -block.delta-mech-pad.description = 替换当前的机甲并转换成一个快速,轻装甲的机械装置。\n站在上面时点击切换。 -block.tau-mech-pad.description = 替换当前的机甲并转换成一个可以治愈友方建筑物和单位的后勤机甲。\n站在上面时点击切换。 -block.omega-mech-pad.description = 替换当前的机甲并转换成一个笨重但是高护甲的机甲。\n站在上面时点击切换。 -block.javelin-ship-pad.description = 替换当前的机甲并转换成一个强大而快速的截击机,发射电弧。\n站在上面时点击切换。 -block.trident-ship-pad.description = 替换当前的机甲并转换成一个高护甲的重型轰炸机。\n站在上面时点击切换。 -block.glaive-ship-pad.description = 替换当前的机甲并转换成一个高护甲的大型武装直升机。\n站在上面时点击切换。 +block.repair-point.description = 持续治疗其附近伤势最重的单位。 +block.dart-mech-pad.description = 允许将当前的机甲替换为一款基础的攻击型机甲。\n站在上面并点一下执行切换。 +block.delta-mech-pad.description = 允许将当前的机甲替换为一款轻快的攻击型机甲。\n站在上面并点一下执行切换。 +block.tau-mech-pad.description = 允许将当前的机甲替换为一款可以治愈友方建筑物和单位的支援型机甲。\n站在上面并点一下执行切换。 +block.omega-mech-pad.description = 允许将当前的机甲替换为一款笨重、厚装甲的导弹机甲。\n站在上面并点一下执行切换。 +block.javelin-ship-pad.description = 允许将当前的机甲替换为一款快速、轻装甲的截击机,发射电弧。\n站在上面并点一下执行切换。 +block.trident-ship-pad.description = 允许将当前的机甲替换为一款重型的支援轰炸机。\n站在上面并点一下执行切换。 +block.glaive-ship-pad.description = 允许将当前的机甲替换为一款大型的装甲武装直升机。\n站在上面并点一下执行切换。 diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index e264e302c3..d9e7e16abd 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -10,13 +10,14 @@ link.dev-builds.description = 開發中版本 link.trello.description = 官方 Trello 功能規劃看板 link.itch.io.description = itch.io 電腦版下載網頁 link.google-play.description = Google Play 商店頁面 +link.f-droid.description = F-Droid 目錄頁面 link.wiki.description = 官方 Mindustry 維基 linkfail = 無法打開連結!\n我們已將該網址複製到您的剪貼簿。 screenshot = 截圖保存到{0} screenshot.invalid = 地圖太大了,可能沒有足夠的內存用於截圖。 gameover = 遊戲結束 gameover.pvp = [accent]{0}[]隊獲勝! -highscore = [accent]新的高分紀錄! +highscore = [accent]新的高分紀錄! copied = 已複製。 load.sound = 音效載入中 @@ -52,7 +53,7 @@ stat.delivered = 發射的核心資源: stat.rank = 最終排名:[accent]{0} launcheditems = [accent]已發射的物品 -launchinfo = [unlaunched][[LAUNCH]你的核心以獲得藍字部分的物品。 +launchinfo = [unlaunched][[發射]核心以獲得藍字部分的物品。 map.delete = 確認要刪除「[accent]{0}[]」地圖嗎? level.highscore = 最高分:[accent]{0} level.select = 選擇關卡 @@ -78,6 +79,7 @@ maps.browse = 瀏覽地圖 continue = 繼續 maps.none = [lightgray]找不到地圖! invalid = 無效 +pickcolor = 選擇顏色 preparingconfig = 配置準備中 preparingcontent = 內容準備中 uploadingcontent = 內容上傳中 @@ -97,8 +99,9 @@ mod.disabled = [scarlet]已禁用 mod.enable = 啟用 mod.disable = 禁用 mod.delete.error = 無法刪除模組,檔案可能在使用中。 +mod.requiresversion = [scarlet]遊戲版本要求:[accent]{0} mod.missingdependencies = [scarlet]缺少依賴項目: {0} -mod.nowdisabled = [scarlet]「{0}'」模組缺少依賴項目:[accent] {1}\n[lightgray]必須先下載這些模組。\n此模組將被自動禁用。 +mod.nowdisabled = [scarlet]「{0}」模組缺少必須項目:[accent] {1}\n[lightgray]必須先下載這些模組。\n此模組將被自動禁用。 mod.requiresrestart = 遊戲將立即關閉以套用模組變更。 mod.reloadrequired = [scarlet]需要重新載入 mod.import = 匯入模組 @@ -138,7 +141,7 @@ server.kicked.idInUse = 你已經在伺服器中!不允許用兩個帳號。 server.kicked.customClient = 這個伺服器不支持自訂客戶端,請下載官方版本。 server.kicked.gameover = 遊戲結束! server.versions = 您的遊戲版本:[accent] {0}[]\n伺服器遊戲版本:[accent] {1}[] -host.info = 目前伺服器監聽於連接埠[scarlet]6567[]。\n所有跟您在同一個[lightgray]網路或區域網路[]環境的玩家應該能在他們的伺服器清單中找到您的伺服器。\n\n如果您希望網際網路上的玩家透過IP 位址連線到您的伺服器,您必須設定[accent]連接埠轉發[]。\n\n[lightgray]注意:如果區域網路內有玩家無法連線至您的伺服器,請務必確認您已於防火牆設定中開放Mindustry存取您的區域網路。請注意公共網路有時不允許搜尋伺服器。 +host.info = [accent]建立伺服器[]按鍵會在連接埠[scarlet]6567[]建立一個伺服器。\n所有跟您在同一個[lightgray]網路或區域網路[]環境的玩家應該能在他們的伺服器清單中找到您的伺服器。\n\n如果您希望網際網路上的玩家透過IP 位址連線到您的伺服器,您必須設定[accent]連接埠轉發[]。\n\n[lightgray]注意:如果區域網路內有玩家無法連線至您的伺服器,請務必確認您已於防火牆設定中開放Mindustry存取您的區域網路。請注意公共網路有時不允許搜尋伺服器。 join.info = 您可以在此輸入欲連線的[accent]伺服器IP位址[],或尋找[accent]區域網路[]內的伺服器。目前支援區域網路與網際網路連線。\n\n[lightgray]注意:並沒有自動的網際網路伺服器清單,如果您想透過IP位址連線到他人的伺服器,您必須向他們詢問IP位址。 hostserver = 建立伺服器 invitefriends = 邀請好友 @@ -492,6 +495,7 @@ settings.language = 語言 settings.data = 遊戲數據 settings.reset = 重設為預設設定 settings.rebind = 重新綁定 +settings.resetKey = 重設按鍵 settings.controls = 操作 settings.game = 遊戲 settings.sound = 音效 @@ -558,8 +562,8 @@ bar.heat = 熱 bar.power = 能量 bar.progress = 建造進度 bar.spawned = 單位:{0}/{1} -bar.input = 能量輸入 -bar.output = 能量輸出 +bar.input = 輸入 +bar.output = 輸出 bullet.damage = [stat]{0}[lightgray]傷害 bullet.splashdamage = [stat]{0}[lightgray]範圍傷害 ~[stat] {1}[lightgray]格 @@ -585,6 +589,8 @@ unit.persecond = /秒 unit.timesspeed = ×速度 unit.percent = % unit.items = 物品 +unit.thousands = k +unit.millions = mil category.general = 一般 category.power = 能量 category.liquids = 液體 @@ -609,7 +615,7 @@ setting.fpscap.name = 最大FPS setting.fpscap.none = 没有 setting.fpscap.text = {0}FPS setting.uiscale.name = UI縮放[lightgray] (需要重啟遊戲)[] -setting.swapdiagonal.name = 始終對角線放置 +setting.swapdiagonal.name = 預設對角線放置 setting.difficulty.training = 訓練 setting.difficulty.easy = 簡單 setting.difficulty.normal = 普通 @@ -645,19 +651,20 @@ public.confirm = 您想公開遊戲嗎?\n[accent]任何人都可以加入您 public.beta = 請注意,該遊戲的Beta版本無法公開遊戲大廳。 uiscale.reset = UI縮放已變更\n按下"確定"確認這個比例\n[scarlet][accent] {0}[] 秒後...退出並還原設定 uiscale.cancel = 取消並退出 -setting.bloom.name = 特效 +setting.bloom.name = 粒子特效 keybind.title = 重新綁定按鍵 keybinds.mobile = [scarlet]此處的大多數快捷鍵在移動設備上均不起作用。僅支援基本移動。 category.general.name = 一般 category.view.name = 查看 category.multiplayer.name = 多人 command.attack = 攻擊 -command.rally = Rally +command.rally = 集結 command.retreat = 撤退 keybind.clear_building.name = 清除建築物 keybind.press = 按一下按鍵... keybind.press.axis = 按一下軸向或按鍵... keybind.screenshot.name = 地圖截圖 +keybind.toggle_power_lines.name = 顯示能量激光 keybind.move_x.name = 水平移動 keybind.move_y.name = 垂直移動 keybind.schematic_select.name = 選擇區域 @@ -702,6 +709,7 @@ mode.attack.description = 沒有波次,目標是摧毀敵人的基地。 mode.custom = 自訂規則 rules.infiniteresources = 無限資源 +rules.reactorexplosions = 反應爐爆炸 rules.wavetimer = 波次時間 rules.waves = 波次 rules.attack = 攻擊模式 @@ -727,6 +735,9 @@ rules.title.resourcesbuilding = 資源與建築 rules.title.player = 玩家 rules.title.enemy = 敵人 rules.title.unit = 單位 +rules.title.experimental = 實驗中 +rules.lighting = 光照 +rules.ambientlight = 環境光照 content.item.name = 物品 content.liquid.name = 液體 @@ -775,6 +786,7 @@ mech.trident-ship.name = 三叉戟 mech.trident-ship.weapon = 轟炸艙 mech.glaive-ship.name = 偃月刀 mech.glaive-ship.weapon = 火焰機關槍 +item.corestorable = [lightgray]核心可儲存: {0} item.explosiveness = [lightgray]爆炸性:{0} item.flammability = [lightgray]易燃性:{0} item.radioactivity = [lightgray]放射性:{0} @@ -888,6 +900,8 @@ block.distributor.name = 大型分配器 block.sorter.name = 分類器 block.inverted-sorter.name = 反向分類器 block.message.name = 訊息板 +block.illuminator.name = 照明燈 +block.illuminator.description = 小、緊湊而且可調整的光源。需要能源來運作。 block.overflow-gate.name = 溢流器 block.silicon-smelter.name = 煉矽廠 block.phase-weaver.name = 相織布編織器 @@ -954,6 +968,7 @@ block.fortress-factory.name = 要塞機甲工廠 block.revenant-factory.name = 復仇鬼戰鬥機工廠 block.repair-point.name = 維修點 block.pulse-conduit.name = 脈衝管線 +block.plated-conduit.name = 裝甲管線 block.phase-conduit.name = 相織管線 block.liquid-router.name = 液體分配器 block.liquid-tank.name = 液體儲存槽 @@ -1005,9 +1020,9 @@ unit.eradicator.name = 消除者 unit.lich.name = 巫妖 unit.reaper.name = 收掠者 tutorial.next = [lightgray]<按下以繼續> -tutorial.intro = 您已進入[scarlet] Mindustry 教學。[]\n從[accent] 挖掘銅礦[]開始吧。點擊靠近您核心的銅礦脈。\n\n[accent]{0}/{1} 個銅礦 +tutorial.intro = 您已進入[scarlet] Mindustry 教學。[]\n使用[[WASD鍵]來移動.\n在滾動滾輪時[accent]按住 [[Ctrl][]來放大縮小畫面.\n從[accent]開採銅礦[]開始吧靠近它,然後在靠近核心的位置點擊銅礦。\n\n[accent]{0}/{1}銅礦 tutorial.intro.mobile = 您已進入[scarlet] Mindustry 教學。[]\n滑動螢幕即可移動。\n[accent]用兩指捏[]來縮放畫面。\n從[accent]開採銅礦[]開始吧。靠近它,然後在靠近核心的位置點擊銅礦。\n\n[accent]{0}/{1}銅礦 -tutorial.drill = 手動挖掘礦石的效率很低。\n[accent]鑽頭[]能夠自動挖掘礦石。\n在銅脈上放置一個鑽頭。 +tutorial.drill = 手動挖掘礦石的效率很低。\n[accent]鑽頭[]能夠自動挖掘礦石。\n在銅礦脈上放置一個鑽頭。 tutorial.drill.mobile = 手動挖掘礦石的效率很低。\n[accent]鑽頭[]能夠自動挖掘礦石。\n點選右下角的鑽頭選項\n選擇[accent]機械鑽頭[].\n通過點擊將其放置在銅礦上,然後按下下方的[accent]確認標誌[]確認您的選擇\n按下[accent] X 按鈕[] 取消放置. tutorial.blockinfo = 每個方塊都有不同的屬性。每個鑽頭只能開採特定的礦石。\n查看方塊的資訊和屬性,[accent]在建造目錄時按下"?"鈕。[]\n\n[accent]立即訪問機械鑽頭的屬性資料。[] tutorial.conveyor = [accent]輸送帶[]能夠將物品運輸到核心。\n製作一條從鑽頭開始到核心的輸送帶。 @@ -1018,16 +1033,15 @@ tutorial.pause = 在戰鬥中,你可以[accent]暫停遊戲。[]\n您可以在 tutorial.pause.mobile = 在戰鬥中,你可以[accent]暫停遊戲。[]\n您可以在暫停時規劃建築物並加入建造序列。\n\n[accent]按左上角的此按鈕暫停。 tutorial.unpause = 現在再次按空格鍵即可取消暫停。 tutorial.unpause.mobile = 現在再次按空格鍵即可取消暫停。 -tutorial.breaking = 方塊經常需要被銷毀。\n[accent]按住右鍵[]破壞選擇中的所有方塊。[]\n\n[accent]使用區域選擇銷毀核心左側的所有廢料方塊。 -tutorial.breaking.mobile = 方塊經常需要被銷毀。\n[accent]選擇解構模式[],然後點擊一個方塊開始破壞它。\n按住手指幾秒鐘以破壞區域[]並向一個方向拖動。\n按下複選標記按鈕以確認破壞。\n\n[accent]使用區域選擇銷毀核心左側的所有廢料方塊。 -tutorial.withdraw = 在某些情況下,直接從方塊中取出物品是必要的。\n去做這個, [accent]點擊有物品的方塊[],然後[accent]點擊在方框中的物品[]。\n可以通過[accent]點擊或常按[]來取出物品。\n\n[accent]從核心中取出一些銅。[] -tutorial.deposit = 通過將物品從船上拖到目標方塊,將物品放入放塊中。\n\n[accent]將您的銅放到核心中。[] -tutorial.waves = [lightgray]敵人[]來臨。\n\n防衛核心2波。建造更多的砲塔以防衛。 -tutorial.waves.mobile = [lightgray]敵人[]接近。\n\n保護核心抵抗兩波攻擊。您的飛船將自動向敵人開火。\n建造更多的砲塔和鑽頭。開採更多的銅。 +tutorial.breaking = 方塊經常需要被拆除。\n[accent]按住右鍵[]破壞選擇區域中的所有方塊。[]\n\n[accent]使用區域選擇拆除核心左側的所有廢料方塊。 +tutorial.breaking.mobile = 方塊經常需要被拆除。\n[accent]選擇拆除模式[],然後點擊一個方塊以破壞它。\n按住螢幕幾秒鐘並向一個方向拖動以破壞一個範圍內的方塊[]。\n按下確認標記按鈕以確認拆除。\n\n[accent]使用區域選擇拆除核心左側的所有廢料方塊。 +tutorial.withdraw = 在某些情況下,直接從方塊中取出物品是必要的。\n[accent]點擊有物品的方塊[],然後[accent]點擊在方框中的物品[]以將其取出。\n可以通過[accent]點擊或長按[]來取出物品。\n\n[accent]從核心中取出一些銅。[] +tutorial.deposit = 通過將物品從船上拖到目標方塊,將物品放入方塊中。\n\n[accent]將您的銅放到核心中。[] +tutorial.waves = [lightgray]敵人[]來臨。\n\n保護核心抵抗兩波攻擊。\n建造更多的砲塔和鑽頭。開採更多的銅。 tutorial.launch = 一旦您達到特定的波數, 您就可以[accent] 發射核心[],放棄防禦並[accent]獲取核心中的所有資源。[]\n這些資源可以用於研究新科技。\n\n[accent]按下發射按鈕。 -item.copper.description = 一種有用的結構材料。在各種類型的方塊中廣泛使用。 -item.lead.description = 一種基本的起始材料。被廣泛用於電子設備和運輸液體方塊。 -item.metaglass.description = 一種高強度的玻璃。廣泛用於液體分配和存儲。 +item.copper.description = 最基本的結構材料。在各種類型的方塊中廣泛使用。 +item.lead.description = 一種基本的起始材料。被廣泛用於電子設備和液體運輸方塊。 +item.metaglass.description = 一種超高強度的玻璃。廣泛用於液體分配和存儲。 item.graphite.description = 礦化的碳,用於彈藥和電氣絕緣。 item.sand.description = 一種常見的材料,廣泛用於冶煉,包括製作合金和助熔劑。 item.coal.description = 遠在「播種」事件前就形成的植物化石。一種常見並容易獲得的燃料。 @@ -1114,13 +1128,14 @@ block.sorter.description = 對物品進行分類。如果物品與所選種類 block.inverted-sorter.description = 處理物品的方式類似於分類器,但將所選擇的物品輸出到側面。 block.router.description = 接受來自一個方向的物品並將它們平均輸出到最多3個其他方向。用於將物品從一個來源分割為多個目標。 block.distributor.description = 高級的分配器,可將物品均分到最多7個其他方向。 -block.overflow-gate.description = 分離器和分配器的組合。如果前面被擋住,則向從左邊和右邊輸出物品。 +block.overflow-gate.description = 如果前面被擋住,則向左邊和右邊輸出物品。 block.mass-driver.description = 終極物品運輸方塊。收集大量物品,然後將它們射向另一個質量驅動器。需要能源以運作。 block.mechanical-pump.description = 一種便宜的泵,輸出速度慢,但不使用能量。 block.rotary-pump.description = 高級的泵。抽更多液體,但需要能量。 block.thermal-pump.description = 終極的泵。 block.conduit.description = 基本液體運輸方塊。將液體往前輸送。用於提取器、泵或其他管線。 block.pulse-conduit.description = 高級的液體運輸方塊。比標準管線更快地輸送並儲存更多液體。 +block.plated-conduit.description = 用和脈衝管線相同的速率運送液體,但有更強的裝甲。除了其他管線以外,不會接受來自側面的其他液體\n比較不會漏液。 block.liquid-router.description = 接受來自一個方向的液體並將它們平均輸出到最多3個其他方向。可以儲存一定量的液體。用於將液體從一個來源分成多個目標。 block.liquid-tank.description = 存儲大量液體。當液體需求非恆定時,使用它來創建緩衝或作為冷卻重要方塊的保障。 block.liquid-junction.description = 作為兩個交叉管線的橋樑。適用於兩條不同管線將不同液體運送到不同位置的情況。 diff --git a/core/assets/shaders/light.fragment.glsl b/core/assets/shaders/light.fragment.glsl new file mode 100644 index 0000000000..c1a831668a --- /dev/null +++ b/core/assets/shaders/light.fragment.glsl @@ -0,0 +1,18 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +#define steprad 0.13 + +uniform sampler2D u_texture; +uniform vec4 u_ambient; + +varying vec4 v_color; +varying vec2 v_texCoord; + +void main(){ + vec4 color = texture2D(u_texture, v_texCoord.xy); + //color.a = clamp(color.a, 0.0, 0.8); + gl_FragColor = clamp(vec4(mix(u_ambient.rgb, color.rgb, color.a), u_ambient.a - color.a), 0.0, 1.0); +} diff --git a/core/src/io/anuke/mindustry/ClientLauncher.java b/core/src/io/anuke/mindustry/ClientLauncher.java index 9c6248562c..6abff04782 100644 --- a/core/src/io/anuke/mindustry/ClientLauncher.java +++ b/core/src/io/anuke/mindustry/ClientLauncher.java @@ -104,7 +104,7 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform public void resize(int width, int height){ if(assets == null) return; - if(!assets.isFinished()){ + if(!finished){ Draw.proj().setOrtho(0, 0, width, height); }else{ super.resize(width, height); diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 067946698d..731866b521 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -32,8 +32,6 @@ import static io.anuke.arc.Core.settings; public class Vars implements Loadable{ /** Whether to load locales.*/ public static boolean loadLocales = true; - /** Maximum number of broken blocks. TODO implement or remove.*/ - public static final int maxBrokenBlocks = 256; /** Maximum schematic size.*/ public static final int maxSchematicSize = 32; /** All schematic base64 starts with this string.*/ @@ -49,13 +47,15 @@ public class Vars implements Loadable{ /** URL for discord invite. */ public static final String discordURL = "https://discord.gg/mindustry"; /** URL for sending crash reports to */ - public static final String crashReportURL = "http://mins.us.to/report"; + public static final String crashReportURL = "http://192.99.169.18/report"; /** URL the links to the wiki's modding guide.*/ public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/"; + /** URL to the JSON file containing all the global, public servers. */ + public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers.json"; /** URL the links to the wiki's modding guide.*/ public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?template=bug_report.md"; /** list of built-in servers.*/ - public static final Array defaultServers = Array.with(/*"mins.us.to"*/); + public static final Array defaultServers = Array.with(); /** maximum distance between mine and core that supports automatic transferring */ public static final float mineTransferRange = 220f; /** team of the player by default */ diff --git a/core/src/io/anuke/mindustry/content/Blocks.java b/core/src/io/anuke/mindustry/content/Blocks.java index 7e90b010bf..8a0ffcea99 100644 --- a/core/src/io/anuke/mindustry/content/Blocks.java +++ b/core/src/io/anuke/mindustry/content/Blocks.java @@ -19,6 +19,8 @@ import io.anuke.mindustry.world.blocks.*; import io.anuke.mindustry.world.blocks.defense.*; import io.anuke.mindustry.world.blocks.defense.turrets.*; import io.anuke.mindustry.world.blocks.distribution.*; +import io.anuke.mindustry.world.blocks.liquid.Conduit; +import io.anuke.mindustry.world.blocks.liquid.LiquidTank; import io.anuke.mindustry.world.blocks.logic.*; import io.anuke.mindustry.world.blocks.power.*; import io.anuke.mindustry.world.blocks.production.*; @@ -48,18 +50,18 @@ public class Blocks implements ContentList{ melter, separator, sporePress, pulverizer, incinerator, coalCentrifuge, //sandbox - powerSource, powerVoid, itemSource, itemVoid, liquidSource, message, + powerSource, powerVoid, itemSource, itemVoid, liquidSource, message, illuminator, //defense - scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, plastaniumWall, plastaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge, phaseWall, phaseWallLarge, surgeWall, surgeWallLarge, mender, mendProjector, overdriveProjector, forceProjector, shockMine, + scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet //transport conveyor, titaniumConveyor, armoredConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, invertedSorter, router, overflowGate, massDriver, //liquids - mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, liquidRouter, liquidTank, liquidJunction, bridgeConduit, phaseConduit, + mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, platedConduit, liquidRouter, liquidTank, liquidJunction, bridgeConduit, phaseConduit, //power combustionGenerator, thermalGenerator, turbineGenerator, differentialGenerator, rtgGenerator, solarPanel, largeSolarPanel, thoriumReactor, @@ -516,7 +518,7 @@ public class Blocks implements ContentList{ int bottomRegion = reg("-bottom"), weaveRegion = reg("-weave"); - drawIcons = () -> new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name)}; + drawIcons = () -> new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name), Core.atlas.find(name + "-weave")}; drawer = tile -> { GenericCrafterEntity entity = tile.entity(); @@ -721,69 +723,11 @@ public class Blocks implements ContentList{ consumes.power(0.50f); }}; - //endregion - //region sandbox - - powerSource = new PowerSource("power-source"){{ - requirements(Category.power, BuildVisibility.sandboxOnly, ItemStack.with()); - alwaysUnlocked = true; - }}; - powerVoid = new PowerVoid("power-void"){{ - requirements(Category.power, BuildVisibility.sandboxOnly, ItemStack.with()); - alwaysUnlocked = true; - }}; - itemSource = new ItemSource("item-source"){{ - requirements(Category.distribution, BuildVisibility.sandboxOnly, ItemStack.with()); - alwaysUnlocked = true; - }}; - itemVoid = new ItemVoid("item-void"){{ - requirements(Category.distribution, BuildVisibility.sandboxOnly, ItemStack.with()); - alwaysUnlocked = true; - }}; - liquidSource = new LiquidSource("liquid-source"){{ - requirements(Category.liquid, BuildVisibility.sandboxOnly, ItemStack.with()); - alwaysUnlocked = true; - }}; - message = new MessageBlock("message"){{ - requirements(Category.effect, ItemStack.with(Items.graphite, 5)); - }}; - //endregion //region defense int wallHealthMultiplier = 4; - scrapWall = new Wall("scrap-wall"){{ - requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.with()); - health = 60 * wallHealthMultiplier; - variants = 5; - }}; - - scrapWallLarge = new Wall("scrap-wall-large"){{ - requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.with()); - health = 60 * 4 * wallHealthMultiplier; - size = 2; - variants = 4; - }}; - - scrapWallHuge = new Wall("scrap-wall-huge"){{ - requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.with()); - health = 60 * 9 * wallHealthMultiplier; - size = 3; - variants = 3; - }}; - - scrapWallGigantic = new Wall("scrap-wall-gigantic"){{ - requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.with()); - health = 60 * 16 * wallHealthMultiplier; - size = 4; - }}; - - thruster = new Wall("thruster"){{ - health = 55 * 16 * wallHealthMultiplier; - size = 4; - }}; - copperWall = new Wall("copper-wall"){{ requirements(Category.defense, ItemStack.with(Items.copper, 6)); health = 80 * wallHealthMultiplier; @@ -865,6 +809,37 @@ public class Blocks implements ContentList{ size = 2; }}; + scrapWall = new Wall("scrap-wall"){{ + requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.with()); + health = 60 * wallHealthMultiplier; + variants = 5; + }}; + + scrapWallLarge = new Wall("scrap-wall-large"){{ + requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.with()); + health = 60 * 4 * wallHealthMultiplier; + size = 2; + variants = 4; + }}; + + scrapWallHuge = new Wall("scrap-wall-huge"){{ + requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.with()); + health = 60 * 9 * wallHealthMultiplier; + size = 3; + variants = 3; + }}; + + scrapWallGigantic = new Wall("scrap-wall-gigantic"){{ + requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.with()); + health = 60 * 16 * wallHealthMultiplier; + size = 4; + }}; + + thruster = new Wall("thruster"){{ + health = 55 * 16 * wallHealthMultiplier; + size = 4; + }}; + mender = new MendProjector("mender"){{ requirements(Category.effect, ItemStack.with(Items.lead, 30, Items.copper, 25)); consumes.power(0.3f); @@ -929,7 +904,7 @@ public class Blocks implements ContentList{ }}; armoredConveyor = new ArmoredConveyor("armored-conveyor"){{ - requirements(Category.distribution, ItemStack.with(Items.metaglass, 1, Items.thorium, 1)); + requirements(Category.distribution, ItemStack.with(Items.plastanium, 1, Items.thorium, 1, Items.metaglass, 1)); health = 180; speed = 0.08f; }}; @@ -1013,7 +988,7 @@ public class Blocks implements ContentList{ size = 3; }}; - conduit = new Conduit("conduit"){{ + conduit = new io.anuke.mindustry.world.blocks.liquid.Conduit("conduit"){{ requirements(Category.liquid, ItemStack.with(Items.metaglass, 1)); health = 45; }}; @@ -1025,7 +1000,14 @@ public class Blocks implements ContentList{ health = 90; }}; - liquidRouter = new LiquidRouter("liquid-router"){{ + platedConduit = new io.anuke.mindustry.world.blocks.liquid.ArmoredConduit("plated-conduit"){{ + requirements(Category.liquid, ItemStack.with(Items.thorium, 2, Items.metaglass, 1)); + liquidCapacity = 16f; + liquidPressure = 1.025f; + health = 220; + }}; + + liquidRouter = new io.anuke.mindustry.world.blocks.liquid.LiquidRouter("liquid-router"){{ requirements(Category.liquid, ItemStack.with(Items.graphite, 4, Items.metaglass, 2)); liquidCapacity = 20f; }}; @@ -1037,17 +1019,17 @@ public class Blocks implements ContentList{ health = 500; }}; - liquidJunction = new LiquidJunction("liquid-junction"){{ + liquidJunction = new io.anuke.mindustry.world.blocks.liquid.LiquidJunction("liquid-junction"){{ requirements(Category.liquid, ItemStack.with(Items.graphite, 2, Items.metaglass, 2)); }}; - bridgeConduit = new LiquidExtendingBridge("bridge-conduit"){{ + bridgeConduit = new io.anuke.mindustry.world.blocks.liquid.LiquidExtendingBridge("bridge-conduit"){{ requirements(Category.liquid, ItemStack.with(Items.graphite, 4, Items.metaglass, 8)); range = 4; hasPower = false; }}; - phaseConduit = new LiquidBridge("phase-conduit"){{ + phaseConduit = new io.anuke.mindustry.world.blocks.liquid.LiquidBridge("phase-conduit"){{ requirements(Category.liquid, ItemStack.with(Items.phasefabric, 5, Items.silicon, 7, Items.metaglass, 20, Items.titanium, 10)); range = 12; hasPower = true; @@ -1152,7 +1134,7 @@ public class Blocks implements ContentList{ powerProduction = 14f; consumes.item(Items.thorium); heating = 0.02f; - consumes.liquid(Liquids.cryofluid, 0.1f).update(false); + consumes.liquid(Liquids.cryofluid, heating / coolantPower).update(false); }}; impactReactor = new ImpactReactor("impact-reactor"){{ @@ -1821,6 +1803,45 @@ public class Blocks implements ContentList{ consumes.power(1.2f); }}; + //endregion + //region sandbox + + powerSource = new PowerSource("power-source"){{ + requirements(Category.power, BuildVisibility.sandboxOnly, ItemStack.with()); + alwaysUnlocked = true; + }}; + + powerVoid = new PowerVoid("power-void"){{ + requirements(Category.power, BuildVisibility.sandboxOnly, ItemStack.with()); + alwaysUnlocked = true; + }}; + + itemSource = new ItemSource("item-source"){{ + requirements(Category.distribution, BuildVisibility.sandboxOnly, ItemStack.with()); + alwaysUnlocked = true; + }}; + + itemVoid = new ItemVoid("item-void"){{ + requirements(Category.distribution, BuildVisibility.sandboxOnly, ItemStack.with()); + alwaysUnlocked = true; + }}; + + liquidSource = new LiquidSource("liquid-source"){{ + requirements(Category.liquid, BuildVisibility.sandboxOnly, ItemStack.with()); + alwaysUnlocked = true; + }}; + + message = new MessageBlock("message"){{ + requirements(Category.effect, ItemStack.with(Items.graphite, 5)); + }}; + + illuminator = new LightBlock("illuminator"){{ + requirements(Category.effect, BuildVisibility.lightingOnly, ItemStack.with(Items.graphite, 4, Items.silicon, 2)); + brightness = 0.67f; + radius = 120f; + consumes.power(0.05f); + }}; + //endregion } } diff --git a/core/src/io/anuke/mindustry/content/Fx.java b/core/src/io/anuke/mindustry/content/Fx.java index 397f15e67b..d7aeed4c65 100644 --- a/core/src/io/anuke/mindustry/content/Fx.java +++ b/core/src/io/anuke/mindustry/content/Fx.java @@ -13,7 +13,7 @@ import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.ui.Cicon; -import static io.anuke.mindustry.Vars.tilesize; +import static io.anuke.mindustry.Vars.*; public class Fx implements ContentList{ public static Effect @@ -456,6 +456,8 @@ public class Fx implements ContentList{ }); Draw.color(); + + renderer.lights.add(e.x, e.y, 20f * e.fslope(), Pal.lightFlame, 0.5f); }); fireSmoke = new Effect(35f, e -> { diff --git a/core/src/io/anuke/mindustry/content/Liquids.java b/core/src/io/anuke/mindustry/content/Liquids.java index 3dccc3d7e6..bbc934cd16 100644 --- a/core/src/io/anuke/mindustry/content/Liquids.java +++ b/core/src/io/anuke/mindustry/content/Liquids.java @@ -19,6 +19,7 @@ public class Liquids implements ContentList{ temperature = 1f; viscosity = 0.8f; effect = StatusEffects.melting; + lightColor = Color.valueOf("f0511d").a(0.4f); }}; oil = new Liquid("oil", Color.valueOf("313131")){{ @@ -34,6 +35,7 @@ public class Liquids implements ContentList{ heatCapacity = 0.9f; temperature = 0.25f; effect = StatusEffects.freezing; + lightColor = Color.valueOf("0097f5").a(0.2f); }}; } } diff --git a/core/src/io/anuke/mindustry/content/TechTree.java b/core/src/io/anuke/mindustry/content/TechTree.java index e59fc3ab90..8058a4982b 100644 --- a/core/src/io/anuke/mindustry/content/TechTree.java +++ b/core/src/io/anuke/mindustry/content/TechTree.java @@ -199,6 +199,10 @@ public class TechTree implements ContentList{ node(phaseConduit, () -> { }); + + node(platedConduit, () -> { + + }); }); node(rotaryPump, () -> { diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index f900eb7236..42eb33117d 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -5,7 +5,7 @@ import io.anuke.arc.*; import io.anuke.arc.util.*; import io.anuke.mindustry.content.*; import io.anuke.mindustry.core.GameState.*; -import io.anuke.mindustry.ctype.UnlockableContent; +import io.anuke.mindustry.ctype.*; import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.game.EventType.*; @@ -189,6 +189,7 @@ public class Logic implements ApplicationListener{ for(Item item : content.items()){ if(tile == null || tile.entity == null || tile.entity.items == null) continue; data.addItem(item, tile.entity.items.get(item)); + Events.fire(new LaunchItemEvent(item, tile.entity.items.get(item))); } world.removeBlock(tile); } diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 437cb10d57..8de0e91fe4 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -292,7 +292,7 @@ public class NetServer implements ApplicationListener{ } //cooldown between votes - int voteTime = 60 * 5; + int voteTime = 60 * 3; Timekeeper vtime = new Timekeeper(voteTime); //current kick sessions VoteSession[] currentlyKicking = {null}; @@ -484,7 +484,7 @@ public class NetServer implements ApplicationListener{ for(BuildRequest req : requests){ if(req == null) continue; Tile tile = world.tile(req.x, req.y); - if(tile == null) continue; + if(tile == null || (!req.breaking && req.block == null)) continue; //auto-skip done requests if(req.breaking && tile.block() == Blocks.air){ continue; diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 0803cab883..4a50b04275 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -32,6 +32,7 @@ public class Renderer implements ApplicationListener{ public final BlockRenderer blocks = new BlockRenderer(); public final MinimapRenderer minimap = new MinimapRenderer(); public final OverlayRenderer overlays = new OverlayRenderer(); + public final LightRenderer lights = new LightRenderer(); public final Pixelator pixelator = new Pixelator(); public FrameBuffer shieldBuffer = new FrameBuffer(2, 2); @@ -256,6 +257,7 @@ public class Renderer implements ApplicationListener{ drawFlyerShadows(); blocks.drawBlocks(Layer.power); + blocks.drawBlocks(Layer.lights); drawAllTeams(true); @@ -298,6 +300,10 @@ public class Renderer implements ApplicationListener{ playerGroup.draw(p -> !p.isDead(), Player::drawName); + if(state.rules.lighting){ + lights.draw(); + } + drawLanding(); Draw.color(); diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 2e86ba1c33..142481b96d 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -70,6 +70,7 @@ public class UI implements ApplicationListener, Loadable{ public MinimapDialog minimap; public SchematicsDialog schematics; public ModsDialog mods; + public ColorPicker picker; public Cursor drillCursor, unloadCursor; @@ -211,6 +212,7 @@ public class UI implements ApplicationListener, Loadable{ listfrag = new PlayerListFragment(); loadfrag = new LoadingFragment(); + picker = new ColorPicker(); editor = new MapEditorDialog(); controls = new ControlsDialog(); restart = new GameOverDialog(); @@ -427,12 +429,15 @@ public class UI implements ApplicationListener, Loadable{ } - public void showCustomConfirm(String title, String text, String yes, String no, Runnable confirmed){ + public void showCustomConfirm(String title, String text, String yes, String no, Runnable confirmed, Runnable denied){ FloatingDialog dialog = new FloatingDialog(title); dialog.cont.add(text).width(mobile ? 400f : 500f).wrap().pad(4f).get().setAlignment(Align.center, Align.center); dialog.buttons.defaults().size(200f, 54f).pad(2f); dialog.setFillParent(false); - dialog.buttons.addButton(no, dialog::hide); + dialog.buttons.addButton(no, () -> { + dialog.hide(); + denied.run(); + }); dialog.buttons.addButton(yes, () -> { dialog.hide(); confirmed.run(); @@ -456,11 +461,11 @@ public class UI implements ApplicationListener, Loadable{ public String formatAmount(int number){ if(number >= 1000000){ - return Strings.fixed(number / 1000000f, 1) + "[gray]mil[]"; + return Strings.fixed(number / 1000000f, 1) + "[gray]" + Core.bundle.getOrNull("unit.millions") + "[]"; }else if(number >= 10000){ return number / 1000 + "[gray]k[]"; }else if(number >= 1000){ - return Strings.fixed(number / 1000f, 1) + "[gray]k[]"; + return Strings.fixed(number / 1000f, 1) + "[gray]" + Core.bundle.getOrNull("unit.thousands") + "[]"; }else{ return number + ""; } diff --git a/core/src/io/anuke/mindustry/ctype/UnlockableContent.java b/core/src/io/anuke/mindustry/ctype/UnlockableContent.java index b442558f1f..8b02036834 100644 --- a/core/src/io/anuke/mindustry/ctype/UnlockableContent.java +++ b/core/src/io/anuke/mindustry/ctype/UnlockableContent.java @@ -5,6 +5,7 @@ import io.anuke.arc.*; import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.scene.ui.layout.*; import io.anuke.mindustry.*; +import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.ui.Cicon; /** Base interface for an unlockable content type. */ @@ -25,7 +26,7 @@ public abstract class UnlockableContent extends MappableContent{ /** Generate any special icons for this content. Called asynchronously.*/ @CallSuper - public void createIcons(PixmapPacker out, PixmapPacker editor){ + public void createIcons(MultiPacker packer){ } diff --git a/core/src/io/anuke/mindustry/entities/effect/Puddle.java b/core/src/io/anuke/mindustry/entities/effect/Puddle.java index 56d326c41b..e7f1330a10 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Puddle.java +++ b/core/src/io/anuke/mindustry/entities/effect/Puddle.java @@ -237,6 +237,12 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai seeds++; }); Draw.color(); + + if(liquid.lightColor.a > 0.001f && f > 0){ + Color color = liquid.lightColor; + float opacity = color.a * f; + renderer.lights.add(tile.drawx(), tile.drawy(), 30f * f, color, opacity * 0.8f); + } } @Override diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index a4c59b4d53..3459e3b18e 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -35,14 +35,14 @@ public interface BuilderTrait extends Entity, TeamTrait{ float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance; Unit unit = (Unit)this; - //remove already completed build requests - removal.clear(); - removal.addAll(buildQueue()); - - Structs.filter(buildQueue(), req -> { + Iterator it = buildQueue().iterator(); + while(it.hasNext()){ + BuildRequest req = it.next(); Tile tile = world.tile(req.x, req.y); - return tile == null || (req.breaking && tile.block() == Blocks.air) || (!req.breaking && (tile.rotation() == req.rotation || !req.block.rotate) && tile.block() == req.block); - }); + if(tile == null || (req.breaking && tile.block() == Blocks.air) || (!req.breaking && (tile.rotation() == req.rotation || !req.block.rotate) && tile.block() == req.block)){ + it.remove(); + } + } TileEntity core = unit.getClosestCore(); @@ -62,6 +62,8 @@ public interface BuilderTrait extends Entity, TeamTrait{ BuildRequest current = buildRequest(); + if(dst(current.tile()) > finalPlaceDst) return; + Tile tile = world.tile(current.x, current.y); if(!(tile.block() instanceof BuildBlock)){ @@ -113,7 +115,7 @@ public interface BuilderTrait extends Entity, TeamTrait{ /** @return whether this request should be skipped, in favor of the next one. */ default boolean shouldSkip(BuildRequest request, @Nullable TileEntity core){ //requests that you have at least *started* are considered - if(state.rules.infiniteResources || request.breaking || !request.initialized) return false; + if(state.rules.infiniteResources || request.breaking || !request.initialized || core == null) return false; return request.stuck && !core.items.has(request.block.requirements); } @@ -228,7 +230,6 @@ public interface BuilderTrait extends Entity, TeamTrait{ //due to iOS weirdness, this is apparently required class BuildDataStatic{ - static Array removal = new Array<>(); static Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()}; } diff --git a/core/src/io/anuke/mindustry/entities/type/Bullet.java b/core/src/io/anuke/mindustry/entities/type/Bullet.java index a1f4831f66..a5c3d21697 100644 --- a/core/src/io/anuke/mindustry/entities/type/Bullet.java +++ b/core/src/io/anuke/mindustry/entities/type/Bullet.java @@ -11,6 +11,7 @@ import io.anuke.mindustry.entities.bullet.*; import io.anuke.mindustry.entities.effect.*; import io.anuke.mindustry.entities.traits.*; import io.anuke.mindustry.game.*; +import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.world.*; import static io.anuke.mindustry.Vars.*; @@ -294,6 +295,7 @@ public class Bullet extends SolidEntity implements DamageTrait, ScaleTrait, Pool @Override public void draw(){ type.draw(this); + renderer.lights.add(x, y, 16f, Pal.powerLight, 0.3f); } @Override diff --git a/core/src/io/anuke/mindustry/entities/type/Player.java b/core/src/io/anuke/mindustry/entities/type/Player.java index 186c8c8e3a..4e83cd1091 100644 --- a/core/src/io/anuke/mindustry/entities/type/Player.java +++ b/core/src/io/anuke/mindustry/entities/type/Player.java @@ -24,9 +24,7 @@ import io.anuke.mindustry.io.*; import io.anuke.mindustry.net.Administration.*; import io.anuke.mindustry.net.*; import io.anuke.mindustry.type.*; -import io.anuke.mindustry.type.TypeID; import io.anuke.mindustry.ui.*; -import io.anuke.mindustry.ui.Cicon; import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.blocks.*; @@ -352,6 +350,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{ Draw.rect(getPowerCellRegion(), x + Angles.trnsx(rotation, mech.cellTrnsY, 0f), y + Angles.trnsy(rotation, mech.cellTrnsY, 0f), rotation - 90); Draw.reset(); drawBackItems(itemtime, isLocal); + drawLight(); } @Override diff --git a/core/src/io/anuke/mindustry/entities/type/TileEntity.java b/core/src/io/anuke/mindustry/entities/type/TileEntity.java index 3438eac854..947748ffeb 100644 --- a/core/src/io/anuke/mindustry/entities/type/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/type/TileEntity.java @@ -15,6 +15,7 @@ import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.EventType.BlockDestroyEvent; import io.anuke.mindustry.gen.*; import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.consumers.*; import io.anuke.mindustry.world.modules.*; import java.io.*; @@ -89,7 +90,7 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ /** Base efficiency. If this entity has non-buffered power, returns the power %, otherwise returns 1. */ public float efficiency(){ - return power != null && !block.consumes.getPower().buffered ? power.status : 1f; + return power != null && (block.consumes.has(ConsumeType.power) && !block.consumes.getPower().buffered) ? power.status : 1f; } /** Call when nothing is happening to the entity. This increments the internal sleep timer. */ @@ -311,13 +312,17 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ loops.play(block.idleSound, this, block.idleSoundVolume); } - Block previous = block; block.update(tile); - if(block == previous && cons != null){ + + if(liquids != null){ + liquids.update(); + } + + if(cons != null){ cons.update(); } - if(block == previous && power != null){ + if(power != null){ power.graph.update(); } } diff --git a/core/src/io/anuke/mindustry/entities/type/Unit.java b/core/src/io/anuke/mindustry/entities/type/Unit.java index 8211476cef..73dec77656 100644 --- a/core/src/io/anuke/mindustry/entities/type/Unit.java +++ b/core/src/io/anuke/mindustry/entities/type/Unit.java @@ -167,6 +167,8 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } public void writeSave(DataOutput stream, boolean net) throws IOException{ + if(item.item == null) item.item = Items.copper; + stream.writeByte(team.ordinal()); stream.writeBoolean(isDead()); stream.writeFloat(net ? interpolator.target.x : x); @@ -399,6 +401,12 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ Draw.color(); drawBackItems(item.amount > 0 ? 1f : 0f, false); + + drawLight(); + } + + public void drawLight(){ + renderer.lights.add(x, y, 50f, Pal.powerLight, 0.6f); } public void drawBackItems(float itemtime, boolean number){ diff --git a/core/src/io/anuke/mindustry/game/EventType.java b/core/src/io/anuke/mindustry/game/EventType.java index ac56c86b6e..a5319c18e5 100644 --- a/core/src/io/anuke/mindustry/game/EventType.java +++ b/core/src/io/anuke/mindustry/game/EventType.java @@ -37,6 +37,14 @@ public class EventType{ public static class LaunchEvent{} + public static class LaunchItemEvent{ + public final ItemStack stack; + + public LaunchItemEvent(Item item, int amount){ + this.stack = new ItemStack(item, amount); + } + } + public static class MapMakeEvent{} public static class MapPublishEvent{} @@ -138,7 +146,7 @@ public class EventType{ public final Player player; public final Item item; public final int amount; - + public DepositEvent(Tile tile, Player player, Item item, int amount){ this.tile = tile; this.player = player; @@ -146,7 +154,7 @@ public class EventType{ this.amount = amount; } } - + /** Called when the player taps a block. */ public static class TapEvent{ public final Tile tile; @@ -157,7 +165,7 @@ public class EventType{ this.player = player; } } - + /** Called when the player sets a specific block. */ public static class TapConfigEvent{ public final Tile tile; @@ -310,7 +318,7 @@ public class EventType{ /** Called after connecting; when a player recieves world data and is ready to play.*/ public static class PlayerJoin{ public final Player player; - + public PlayerJoin(Player player){ this.player = player; } @@ -327,11 +335,45 @@ public class EventType{ public static class PlayerLeave{ public final Player player; - + public PlayerLeave(Player player){ this.player = player; } } - + + public static class PlayerBanEvent{ + public final Player player; + + public PlayerBanEvent(Player player){ + this.player = player; + } + } + + public static class PlayerUnbanEvent{ + public final Player player; + + public PlayerUnbanEvent(Player player){ + this.player = player; + } + } + + public static class PlayerIpBanEvent{ + public final String ip; + + + public PlayerIpBanEvent(String ip){ + this.ip = ip; + } + } + + public static class PlayerIpUnbanEvent{ + public final String ip; + + + public PlayerIpUnbanEvent(String ip){ + this.ip = ip; + } + } + } diff --git a/core/src/io/anuke/mindustry/game/Rules.java b/core/src/io/anuke/mindustry/game/Rules.java index 94cf4225ad..dbafda9579 100644 --- a/core/src/io/anuke/mindustry/game/Rules.java +++ b/core/src/io/anuke/mindustry/game/Rules.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.game; import io.anuke.annotations.Annotations.*; import io.anuke.arc.collection.*; +import io.anuke.arc.graphics.*; import io.anuke.mindustry.content.*; import io.anuke.mindustry.io.*; import io.anuke.mindustry.type.*; @@ -25,6 +26,8 @@ public class Rules{ public boolean pvp; /** Whether enemy units drop random items on death. */ public boolean unitDrops = true; + /** Whether reactors can explode and damage other blocks. */ + public boolean reactorExplosions = true; /** How fast unit pads build units. */ public float unitBuildSpeedMultiplier = 1f; /** How much health units start with. */ @@ -65,12 +68,16 @@ public class Rules{ public boolean attackMode = false; /** Whether this is the editor gamemode. */ public boolean editor = false; - /** Whether the tutorial is enabled. False by default.*/ + /** Whether the tutorial is enabled. False by default. */ public boolean tutorial = false; /** Starting items put in cores */ public Array loadout = Array.with(ItemStack.with(Items.copper, 100)); /** Blocks that cannot be placed. */ public ObjectSet bannedBlocks = new ObjectSet<>(); + /** Whether everything is dark. Enables lights. Experimental. */ + public boolean lighting = false; + /** Ambient light color, used when lighting is enabled. */ + public Color ambientLight = new Color(0.01f, 0.01f, 0.04f, 0.99f); /** Copies this ruleset exactly. Not very efficient at all, do not use often. */ public Rules copy(){ diff --git a/core/src/io/anuke/mindustry/game/Stats.java b/core/src/io/anuke/mindustry/game/Stats.java index aa152d377c..3c6847712e 100644 --- a/core/src/io/anuke/mindustry/game/Stats.java +++ b/core/src/io/anuke/mindustry/game/Stats.java @@ -9,7 +9,7 @@ import io.anuke.mindustry.type.*; @Serialize public class Stats{ /** Items delivered to global resoure counter. Zones only. */ - public transient ObjectIntMap itemsDelivered = new ObjectIntMap<>(); + public ObjectIntMap itemsDelivered = new ObjectIntMap<>(); /** Enemy (red team) units destroyed. */ public int enemyUnitsDestroyed; /** Total waves lasted. */ diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 6d3a8a5281..1e7fa36982 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -9,11 +9,11 @@ import io.anuke.arc.graphics.glutils.*; import io.anuke.arc.math.*; import io.anuke.arc.util.*; import io.anuke.mindustry.content.*; -import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.Teams.*; -import io.anuke.mindustry.ui.Cicon; +import io.anuke.mindustry.ui.*; import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.blocks.*; import static io.anuke.arc.Core.camera; import static io.anuke.mindustry.Vars.*; @@ -219,6 +219,10 @@ public class BlockRenderer implements Disposable{ addRequest(tile, Layer.block); } + if(state.rules.lighting && tile.block().synthetic() && !(tile.block() instanceof BlockPart)){ + addRequest(tile, Layer.lights); + } + if(block.expanded || !expanded){ if(block.layer != null){ @@ -274,6 +278,9 @@ public class BlockRenderer implements Disposable{ if(block.synthetic() && request.tile.getTeam() != player.getTeam()){ block.drawTeam(request.tile); } + + }else if(request.layer == Layer.lights){ + block.drawLight(request.tile); }else if(request.layer == block.layer){ block.drawLayer(request.tile); }else if(request.layer == block.layer2){ @@ -282,39 +289,6 @@ public class BlockRenderer implements Disposable{ } } - public void drawTeamBlocks(Layer layer, Team team){ - int index = this.iterateidx; - - for(; index < requestidx; index++){ - - if(index < requests.size && requests.get(index).layer.ordinal() > layer.ordinal()){ - break; - } - - BlockRequest req = requests.get(index); - if(req.tile.getTeam() != team) continue; - - Block block = req.tile.block(); - - if(req.layer == Layer.block){ - block.draw(req.tile); - }else if(req.layer == block.layer){ - block.drawLayer(req.tile); - }else if(req.layer == block.layer2){ - block.drawLayer2(req.tile); - } - - } - } - - public void skipLayer(Layer stopAt){ - for(; iterateidx < requestidx; iterateidx++){ - if(iterateidx < requests.size && requests.get(iterateidx).layer.ordinal() > stopAt.ordinal()){ - break; - } - } - } - private void addRequest(Tile tile, Layer layer){ if(requestidx >= requests.size){ requests.add(new BlockRequest()); diff --git a/core/src/io/anuke/mindustry/graphics/Drawf.java b/core/src/io/anuke/mindustry/graphics/Drawf.java index ecbd7eec09..036db1eca0 100644 --- a/core/src/io/anuke/mindustry/graphics/Drawf.java +++ b/core/src/io/anuke/mindustry/graphics/Drawf.java @@ -6,6 +6,8 @@ import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.math.*; import io.anuke.arc.util.*; +import static io.anuke.mindustry.Vars.renderer; + public class Drawf{ public static void dashCircle(float x, float y, float rad, Color color){ @@ -40,15 +42,6 @@ public class Drawf{ square(x, y, radius, Pal.accent); } - /* - public static void square(float x, float y, float radius){ - Lines.stroke(1f, Pal.gray); - Lines.square(x, y - 1f, radius + 1f, 45); - Lines.stroke(1f, Pal.accent); - Lines.square(x, y, radius + 1f, 45); - Draw.reset(); - }*/ - public static void arrow(float x, float y, float x2, float y2, float length, float radius){ float angle = Angles.angle(x, y, x2, y2); float space = 2f; @@ -81,6 +74,8 @@ public class Drawf{ Lines.line(line, x + Tmp.v1.x, y + Tmp.v1.y, x2 - Tmp.v1.x, y2 - Tmp.v1.y, CapStyle.none, 0f); Lines.precise(false); Lines.stroke(1f); + + renderer.lights.line(x, y, x2, y2); } public static void tri(float x, float y, float width, float length, float rotation){ diff --git a/core/src/io/anuke/mindustry/graphics/Layer.java b/core/src/io/anuke/mindustry/graphics/Layer.java index 206da3d6e0..1ba9c76ec6 100644 --- a/core/src/io/anuke/mindustry/graphics/Layer.java +++ b/core/src/io/anuke/mindustry/graphics/Layer.java @@ -10,5 +10,7 @@ public enum Layer{ /** "High" blocks, like turrets. */ turret, /** Power lasers. */ - power + power, + /** Extra layer that's always on top.*/ + lights } diff --git a/core/src/io/anuke/mindustry/graphics/LightRenderer.java b/core/src/io/anuke/mindustry/graphics/LightRenderer.java new file mode 100644 index 0000000000..19ab2ff016 --- /dev/null +++ b/core/src/io/anuke/mindustry/graphics/LightRenderer.java @@ -0,0 +1,199 @@ +package io.anuke.mindustry.graphics; + +import io.anuke.arc.*; +import io.anuke.arc.collection.*; +import io.anuke.arc.graphics.*; +import io.anuke.arc.graphics.g2d.*; +import io.anuke.arc.graphics.glutils.*; +import io.anuke.arc.math.*; +import io.anuke.arc.math.geom.*; +import io.anuke.arc.util.*; + +import static io.anuke.mindustry.Vars.state; + +/** Renders overlay lights. Client only. */ +public class LightRenderer{ + private static final int scaling = 4; + private float[] vertices = new float[24]; + private FrameBuffer buffer = new FrameBuffer(2, 2); + private Array lights = new Array<>(); + + public void add(Runnable run){ + if(!enabled()) return; + + lights.add(run); + } + + public void add(float x, float y, float radius, Color color, float opacity){ + if(!enabled()) return; + + float res = color.toFloatBits(); + add(() -> { + Draw.color(res); + Draw.alpha(opacity); + Draw.rect("circle-shadow", x, y, radius * 2, radius * 2); + }); + } + + public void add(float x, float y, TextureRegion region, Color color, float opacity){ + if(!enabled()) return; + + float res = color.toFloatBits(); + add(() -> { + Draw.color(res); + Draw.alpha(opacity); + Draw.rect(region, x, y); + }); + } + + public void line(float x, float y, float x2, float y2){ + if(!enabled()) return; + + add(() -> { + Draw.color(Color.orange, 0.3f); + + float stroke = 30f; + float rot = Mathf.angleExact(x2 - x, y2 - y); + TextureRegion ledge = Core.atlas.find("circle-end"), lmid = Core.atlas.find("circle-mid"); + + float color = Draw.getColor().toFloatBits(); + float u = lmid.getU(); + float v = lmid.getV2(); + float u2 = lmid.getU2(); + float v2 = lmid.getV(); + + + Vector2 v1 = Tmp.v1.trnsExact(rot + 90f, stroke); + float lx1 = x - v1.x, ly1 = y - v1.y, + lx2 = x + v1.x, ly2 = y + v1.y, + lx3 = x2 + v1.x, ly3 = y2 + v1.y, + lx4 = x2 - v1.x, ly4 = y2 - v1.y; + + vertices[0] = lx1; + vertices[1] = ly1; + vertices[2] = color; + vertices[3] = u; + vertices[4] = v; + vertices[5] = 0; + + vertices[6] = lx2; + vertices[7] = ly2; + vertices[8] = color; + vertices[9] = u; + vertices[10] = v2; + vertices[11] = 0; + + vertices[12] = lx3; + vertices[13] = ly3; + vertices[14] = color; + vertices[15] = u2; + vertices[16] = v2; + vertices[17] = 0; + + vertices[18] = lx4; + vertices[19] = ly4; + vertices[20] = color; + vertices[21] = u2; + vertices[22] = v; + vertices[23] = 0; + + Draw.vert(ledge.getTexture(), vertices, 0, vertices.length); + + + Vector2 v3 = Tmp.v2.trnsExact(rot, stroke); + + u = ledge.getU(); + v = ledge.getV2(); + u2 = ledge.getU2(); + v2 = ledge.getV(); + + vertices[0] = lx4; + vertices[1] = ly4; + vertices[2] = color; + vertices[3] = u; + vertices[4] = v; + vertices[5] = 0; + + vertices[6] = lx3; + vertices[7] = ly3; + vertices[8] = color; + vertices[9] = u; + vertices[10] = v2; + vertices[11] = 0; + + vertices[12] = lx3 + v3.x; + vertices[13] = ly3 + v3.y; + vertices[14] = color; + vertices[15] = u2; + vertices[16] = v2; + vertices[17] = 0; + + vertices[18] = lx4 + v3.x; + vertices[19] = ly4 + v3.y; + vertices[20] = color; + vertices[21] = u2; + vertices[22] = v; + vertices[23] = 0; + + Draw.vert(ledge.getTexture(), vertices, 0, vertices.length); + + vertices[0] = lx2; + vertices[1] = ly2; + vertices[2] = color; + vertices[3] = u; + vertices[4] = v; + vertices[5] = 0; + + vertices[6] = lx1; + vertices[7] = ly1; + vertices[8] = color; + vertices[9] = u; + vertices[10] = v2; + vertices[11] = 0; + + vertices[12] = lx1 - v3.x; + vertices[13] = ly1 - v3.y; + vertices[14] = color; + vertices[15] = u2; + vertices[16] = v2; + vertices[17] = 0; + + vertices[18] = lx2 - v3.x; + vertices[19] = ly2 - v3.y; + vertices[20] = color; + vertices[21] = u2; + vertices[22] = v; + vertices[23] = 0; + + Draw.vert(ledge.getTexture(), vertices, 0, vertices.length); + }); + } + + public boolean enabled(){ + return state.rules.lighting; + } + + public void draw(){ + if(buffer.getWidth() != Core.graphics.getWidth()/scaling || buffer.getHeight() != Core.graphics.getHeight()/scaling){ + buffer.resize(Core.graphics.getWidth()/scaling, Core.graphics.getHeight()/scaling); + } + + Draw.color(); + buffer.beginDraw(Color.clear); + Draw.blend(Blending.normal); + for(Runnable run : lights){ + run.run(); + } + Draw.reset(); + Draw.blend(); + buffer.endDraw(); + + Draw.color(); + Shaders.light.ambient.set(state.rules.ambientLight); + Draw.shader(Shaders.light); + Draw.rect(Draw.wrap(buffer.getTexture()), Core.camera.position.x, Core.camera.position.y, Core.camera.width, -Core.camera.height); + Draw.shader(); + + lights.clear(); + } +} diff --git a/core/src/io/anuke/mindustry/graphics/MultiPacker.java b/core/src/io/anuke/mindustry/graphics/MultiPacker.java new file mode 100644 index 0000000000..578aa677ba --- /dev/null +++ b/core/src/io/anuke/mindustry/graphics/MultiPacker.java @@ -0,0 +1,61 @@ +package io.anuke.mindustry.graphics; + +import io.anuke.arc.graphics.*; +import io.anuke.arc.graphics.Pixmap.*; +import io.anuke.arc.graphics.Texture.*; +import io.anuke.arc.graphics.g2d.*; +import io.anuke.arc.util.*; + +public class MultiPacker implements Disposable{ + private PixmapPacker[] packers = new PixmapPacker[PageType.all.length]; + + public MultiPacker(){ + for(int i = 0; i < packers.length; i++){ + int pageSize = 2048; + packers[i] = new PixmapPacker(pageSize, pageSize, Format.RGBA8888, 2, true); + } + } + + public boolean has(PageType type, String name){ + return packers[type.ordinal()].getRect(name) != null; + } + + public void add(PageType type, String name, PixmapRegion region){ + packers[type.ordinal()].pack(name, region); + } + + public void add(PageType type, String name, Pixmap pix){ + packers[type.ordinal()].pack(name, pix); + } + + public TextureAtlas flush(TextureFilter filter, TextureAtlas atlas){ + for(PixmapPacker p : packers){ + p.updateTextureAtlas(atlas, filter, filter, false, false); + } + return atlas; + } + + @Override + public void dispose(){ + for(PixmapPacker packer : packers){ + packer.dispose(); + } + } + + + //There are several pages for sprites. + //main page (sprites.png) - all sprites for units, weapons, placeable blocks, effects, bullets, etc + //environment page (sprites2.png) - all sprites for things in the environmental cache layer + //editor page (sprites3.png) - all sprites needed for rendering in the editor, including block icons and a few minor sprites + //zone page (sprites4.png) - zone previews + //ui page (sprites5.png) - content icons, white icons and UI elements + public enum PageType{ + main, + environment, + editor, + zone, + ui; + + public static final PageType[] all = values(); + } +} diff --git a/core/src/io/anuke/mindustry/graphics/Shaders.java b/core/src/io/anuke/mindustry/graphics/Shaders.java index 73509ff4a8..fbe6adb0cf 100644 --- a/core/src/io/anuke/mindustry/graphics/Shaders.java +++ b/core/src/io/anuke/mindustry/graphics/Shaders.java @@ -15,6 +15,7 @@ public class Shaders{ public static UnitBuild build; public static FogShader fog; public static MenuShader menu; + public static LightShader light; public static SurfaceShader water, tar, slag; public static void init(){ @@ -30,11 +31,26 @@ public class Shaders{ build = new UnitBuild(); fog = new FogShader(); menu = new MenuShader(); + light = new LightShader(); water = new SurfaceShader("water"); tar = new SurfaceShader("tar"); slag = new SurfaceShader("slag"); } + public static class LightShader extends LoadShader{ + public Color ambient = new Color(0.01f, 0.01f, 0.04f, 0.99f); + + public LightShader(){ + super("light", "default"); + } + + @Override + public void apply(){ + setUniformf("u_ambient", ambient); + } + + } + public static class MenuShader extends LoadShader{ float time = 0f; diff --git a/core/src/io/anuke/mindustry/input/Binding.java b/core/src/io/anuke/mindustry/input/Binding.java index c96b58a1cc..45383cb6ef 100644 --- a/core/src/io/anuke/mindustry/input/Binding.java +++ b/core/src/io/anuke/mindustry/input/Binding.java @@ -24,6 +24,22 @@ public enum Binding implements KeyBind{ schematic_flip_x(KeyCode.Z), schematic_flip_y(KeyCode.X), schematic_menu(KeyCode.T), + category_prev(KeyCode.COMMA), + category_next(KeyCode.PERIOD), + block_select_left(KeyCode.LEFT), + block_select_right(KeyCode.RIGHT), + block_select_up(KeyCode.UP), + block_select_down(KeyCode.DOWN), + block_select_01(KeyCode.NUM_1), + block_select_02(KeyCode.NUM_2), + block_select_03(KeyCode.NUM_3), + block_select_04(KeyCode.NUM_4), + block_select_05(KeyCode.NUM_5), + block_select_06(KeyCode.NUM_6), + block_select_07(KeyCode.NUM_7), + block_select_08(KeyCode.NUM_8), + block_select_09(KeyCode.NUM_9), + block_select_10(KeyCode.NUM_0), zoom_hold(KeyCode.CONTROL_LEFT, "view"), zoom(new Axis(KeyCode.SCROLL)), menu(Core.app.getType() == ApplicationType.Android ? KeyCode.BACK : KeyCode.ESCAPE), diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index ca104342c1..f95f7a2b04 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -455,7 +455,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } protected void drawRequest(BuildRequest request){ - drawRequest(request.x, request.y, request.block, request.rotation); + request.block.drawRequest(request, allRequests(), validPlace(request.x, request.y, request.block, request.rotation)); } /** Draws a placement icon for a specific block. */ diff --git a/core/src/io/anuke/mindustry/io/JsonIO.java b/core/src/io/anuke/mindustry/io/JsonIO.java index 4dc253672b..3635c25bc0 100644 --- a/core/src/io/anuke/mindustry/io/JsonIO.java +++ b/core/src/io/anuke/mindustry/io/JsonIO.java @@ -4,7 +4,7 @@ import io.anuke.arc.util.serialization.*; import io.anuke.arc.util.serialization.Json.*; import io.anuke.mindustry.*; import io.anuke.mindustry.content.*; -import io.anuke.mindustry.ctype.MappableContent; +import io.anuke.mindustry.ctype.*; import io.anuke.mindustry.game.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; @@ -29,8 +29,20 @@ public class JsonIO{ super.writeValue(value, knownType, elementType); } } + + @Override + protected String convertToString(Object object){ + if(object instanceof MappableContent){ + return ((MappableContent)object).name; + } + return super.convertToString(object); + } }; + public static Json json(){ + return json; + } + public static String write(Object object){ return json.toJson(object, object.getClass()); } diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index 86d4a75b58..b855090ea2 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -8,10 +8,12 @@ import io.anuke.arc.collection.IntSet.*; import io.anuke.arc.files.*; import io.anuke.arc.func.*; import io.anuke.arc.graphics.*; +import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.*; import io.anuke.arc.util.async.*; import io.anuke.arc.util.io.*; import io.anuke.arc.util.serialization.*; +import io.anuke.mindustry.*; import io.anuke.mindustry.content.*; import io.anuke.mindustry.ctype.*; import io.anuke.mindustry.game.EventType.*; @@ -34,9 +36,30 @@ public class Maps{ /** Serializer for meta. */ private Json json = new Json(); + private ShuffleMode shuffleMode = ShuffleMode.all; + private @Nullable MapProvider shuffler; + private AsyncExecutor executor = new AsyncExecutor(2); private ObjectSet previewList = new ObjectSet<>(); + public ShuffleMode getShuffleMode(){ + return shuffleMode; + } + + public void setShuffleMode(ShuffleMode mode){ + this.shuffleMode = mode; + } + + /** Set the provider for the map(s) to be played on. Will override the default shuffle mode setting.*/ + public void setMapProvider(MapProvider provider){ + this.shuffler = provider; + } + + /** @return the next map to shuffle to. May be null, in which case the server should be stopped. */ + public @Nullable Map getNextMap(@Nullable Map previous){ + return shuffler != null ? shuffler.next(previous) : shuffleMode.next(previous); + } + /** Returns a list of all maps, including custom ones. */ public Array all(){ return maps; @@ -422,4 +445,37 @@ public class Maps{ return map; } + public interface MapProvider{ + @Nullable Map next(@Nullable Map previous); + } + + public enum ShuffleMode implements MapProvider{ + none(map -> null), + all(prev -> { + Array maps = Array.withArrays(Vars.maps.defaultMaps(), Vars.maps.customMaps()); + maps.shuffle(); + return maps.find(m -> m != prev || maps.size == 1); + }), + custom(prev -> { + Array maps = Array.withArrays(Vars.maps.customMaps().isEmpty() ? Vars.maps.defaultMaps() : Vars.maps.customMaps()); + maps.shuffle(); + return maps.find(m -> m != prev || maps.size == 1); + }), + builtin(prev -> { + Array maps = Array.withArrays(Vars.maps.defaultMaps()); + maps.shuffle(); + return maps.find(m -> m != prev || maps.size == 1); + }); + + private final MapProvider provider; + + ShuffleMode(MapProvider provider){ + this.provider = provider; + } + + @Override + public Map next(@Nullable Map previous){ + return provider.next(previous); + } + } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/mod/ContentParser.java b/core/src/io/anuke/mindustry/mod/ContentParser.java index 286e2d62e0..afe1f2f74f 100644 --- a/core/src/io/anuke/mindustry/mod/ContentParser.java +++ b/core/src/io/anuke/mindustry/mod/ContentParser.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.mod; import io.anuke.arc.*; +import io.anuke.arc.assets.*; import io.anuke.arc.audio.*; import io.anuke.arc.audio.mock.*; import io.anuke.arc.collection.Array; @@ -10,8 +11,6 @@ import io.anuke.arc.func.*; import io.anuke.arc.graphics.*; import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.*; -import io.anuke.arc.util.reflect.Field; -import io.anuke.arc.util.reflect.*; import io.anuke.arc.util.serialization.*; import io.anuke.arc.util.serialization.Json.*; import io.anuke.arc.util.serialization.Jval.*; @@ -71,9 +70,9 @@ public class ContentParser{ String name = "sounds/" + data.asString(); String path = Vars.tree.get(name + ".ogg").exists() && !Vars.ios ? name + ".ogg" : name + ".mp3"; ModLoadingSound sound = new ModLoadingSound(); - Core.assets.load(path, Sound.class).loaded = result -> { - sound.sound = (Sound)result; - }; + AssetDescriptor desc = Core.assets.load(path, Sound.class); + desc.loaded = result -> sound.sound = (Sound)result; + desc.errored = Throwable::printStackTrace; return sound; }); put(Objective.class, (type, data) -> { @@ -106,7 +105,7 @@ public class ContentParser{ return t; } - private T internalRead(Class type, Class elementType, JsonValue jsonData, Class keyType){ + private T internalRead(Class type, Class elementType, JsonValue jsonData, Class keyType){ if(type != null){ if(classParsers.containsKey(type)){ try{ @@ -116,6 +115,29 @@ public class ContentParser{ } } + //try to parse "item/amount" syntax + try{ + if(type == ItemStack.class && jsonData.isString() && jsonData.asString().contains("/")){ + String[] split = jsonData.asString().split("/"); + + return (T)fromJson(ItemStack.class, "{item: " + split[0] + ", amount: " + split[1] + "}"); + } + }catch(Throwable ignored){ + } + + //try to parse "liquid/amount" syntax + try{ + if(jsonData.isString() && jsonData.asString().contains("/")){ + String[] split = jsonData.asString().split("/"); + if(type == LiquidStack.class){ + return (T)fromJson(LiquidStack.class, "{liquid: " + split[0] + ", amount: " + split[1] + "}"); + }else if(type == ConsumeLiquid.class){ + return (T)fromJson(ConsumeLiquid.class, "{liquid: " + split[0] + ", amount: " + split[1] + "}"); + } + } + }catch(Throwable ignored){ + } + if(Content.class.isAssignableFrom(type)){ ContentType ctype = contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName())); String prefix = currentMod != null ? currentMod.name + "-" : ""; @@ -152,6 +174,7 @@ public class ContentParser{ "io.anuke.mindustry.world.blocks.defense", "io.anuke.mindustry.world.blocks.defense.turrets", "io.anuke.mindustry.world.blocks.distribution", + "io.anuke.mindustry.world.blocks.liquid", "io.anuke.mindustry.world.blocks.logic", "io.anuke.mindustry.world.blocks.power", "io.anuke.mindustry.world.blocks.production", @@ -206,6 +229,9 @@ public class ContentParser{ postreads.add(() -> { TechNode parnode = TechTree.all.find(t -> t.block == parent); + if(parnode == null){ + throw new ModLoadException("Block '" + parent.name + "' isn't in the tech tree, but '" + block.name + "' requires it to be researched.", block); + } if(!parnode.children.contains(baseNode)){ parnode.children.add(baseNode); } @@ -343,7 +369,13 @@ public class ContentParser{ init(); } + //remove extra # characters to make it valid json... apparently some people have *unquoted* # characters in their json + if(file.extension().equals("json")){ + json = json.replace("#", "\\#"); + } + JsonValue value = parser.fromJson(null, Jval.read(json).toString(Jformat.plain)); + if(!parsers.containsKey(type)){ throw new SerializationException("No parsers for content type '" + type + "'"); } @@ -361,7 +393,7 @@ public class ContentParser{ private T make(Class type){ try{ - java.lang.reflect.Constructor cons = type.getDeclaredConstructor(); + Constructor cons = type.getDeclaredConstructor(); cons.setAccessible(true); return cons.newInstance(); }catch(Exception e){ @@ -371,7 +403,7 @@ public class ContentParser{ private T make(Class type, String name){ try{ - java.lang.reflect.Constructor cons = type.getDeclaredConstructor(String.class); + Constructor cons = type.getDeclaredConstructor(String.class); cons.setAccessible(true); return cons.newInstance(name); }catch(Exception e){ @@ -381,7 +413,7 @@ public class ContentParser{ private Prov supply(Class type){ try{ - java.lang.reflect.Constructor cons = type.getDeclaredConstructor(); + Constructor cons = type.getDeclaredConstructor(); return () -> { try{ return cons.newInstance(); @@ -457,7 +489,7 @@ public class ContentParser{ Field field = metadata.field; try{ field.set(object, parser.readValue(field.getType(), metadata.elementType, child, metadata.keyType)); - }catch(ReflectionException ex){ + }catch(IllegalAccessException ex){ throw new SerializationException("Error accessing field: " + field.getName() + " (" + type.getName() + ")", ex); }catch(SerializationException ex){ ex.addTrace(field.getName() + " (" + type.getName() + ")"); diff --git a/core/src/io/anuke/mindustry/mod/Mods.java b/core/src/io/anuke/mindustry/mod/Mods.java index 59347e01ab..6188d5c954 100644 --- a/core/src/io/anuke/mindustry/mod/Mods.java +++ b/core/src/io/anuke/mindustry/mod/Mods.java @@ -6,7 +6,6 @@ import io.anuke.arc.collection.*; import io.anuke.arc.files.*; import io.anuke.arc.func.*; import io.anuke.arc.graphics.*; -import io.anuke.arc.graphics.Pixmap.*; import io.anuke.arc.graphics.Texture.*; import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.graphics.g2d.TextureAtlas.*; @@ -14,10 +13,13 @@ import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.*; import io.anuke.arc.util.io.*; import io.anuke.arc.util.serialization.*; +import io.anuke.arc.util.serialization.Jval.*; import io.anuke.mindustry.core.*; import io.anuke.mindustry.ctype.*; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.gen.*; +import io.anuke.mindustry.graphics.*; +import io.anuke.mindustry.graphics.MultiPacker.*; import io.anuke.mindustry.plugin.*; import io.anuke.mindustry.type.*; @@ -33,7 +35,7 @@ public class Mods implements Loadable{ private ObjectSet specialFolders = ObjectSet.with("bundles", "sprites"); private int totalSprites; - private PixmapPacker packer; + private MultiPacker packer; private Array loaded = new Array<>(); private Array disabled = new Array<>(); @@ -50,7 +52,7 @@ public class Mods implements Loadable{ /** @return the loaded mod found by class, or null if not found. */ public @Nullable LoadedMod getMod(Class type){ - return loaded.find(l -> l.mod.getClass() == type); + return loaded.find(l -> l.mod != null && l.mod.getClass() == type); } /** Imports an external mod file.*/ @@ -79,68 +81,71 @@ public class Mods implements Loadable{ if(loaded.isEmpty()) return; Time.mark(); - packer = new PixmapPacker(2048, 2048, Format.RGBA8888, 2, true); + packer = new MultiPacker(); for(LoadedMod mod : loaded){ - int[] packed = {0}; - boolean[] failed = {false}; - mod.root.child("sprites").walk(file -> { - if(failed[0]) return; - if(file.extension().equals("png")){ - try(InputStream stream = file.read()){ - byte[] bytes = Streams.copyStreamToByteArray(stream, Math.max((int)file.length(), 512)); - Pixmap pixmap = new Pixmap(bytes, 0, bytes.length); - packer.pack(mod.name + "-" + file.nameWithoutExtension(), pixmap); - pixmap.dispose(); - packed[0] ++; - totalSprites ++; - }catch(IOException e){ - failed[0] = true; - Core.app.post(() -> { - Log.err("Error packing images for mod: {0}", mod.meta.name); - e.printStackTrace(); - if(!headless) ui.showException(e); - }); - } - } - }); - Log.info("Packed {0} images for mod '{1}'.", packed[0], mod.meta.name); + Array sprites = mod.root.child("sprites").findAll(f -> f.extension().equals("png")); + Array overrides = mod.root.child("sprites-override").findAll(f -> f.extension().equals("png")); + packSprites(sprites, mod, true); + packSprites(overrides, mod, false); + Log.info("Packed {0} images for mod '{1}'.", sprites.size + overrides.size, mod.meta.name); + totalSprites += sprites.size + overrides.size; + } + + for(AtlasRegion region : Core.atlas.getRegions()){ + PageType type = getPage(region); + if(!packer.has(type, region.name)){ + packer.add(type, region.name, Core.atlas.getPixmap(region)); + } } Log.info("Time to pack textures: {0}", Time.elapsed()); } + private void packSprites(Array sprites, LoadedMod mod, boolean prefix){ + for(FileHandle file : sprites){ + try(InputStream stream = file.read()){ + byte[] bytes = Streams.copyStreamToByteArray(stream, Math.max((int)file.length(), 512)); + Pixmap pixmap = new Pixmap(bytes, 0, bytes.length); + packer.add(getPage(file), (prefix ? mod.name + "-" : "") + file.nameWithoutExtension(), new PixmapRegion(pixmap)); + pixmap.dispose(); + }catch(IOException e){ + Core.app.post(() -> { + Log.err("Error packing images for mod: {0}", mod.meta.name); + e.printStackTrace(); + if(!headless) ui.showException(e); + }); + break; + } + } + totalSprites += sprites.size; + } + @Override public void loadSync(){ if(packer == null) return; Time.mark(); - Texture editor = Core.atlas.find("clear-editor").getTexture(); - PixmapPacker editorPacker = new PixmapPacker(2048, 2048, Format.RGBA8888, 2, true); - - for(AtlasRegion region : Core.atlas.getRegions()){ - if(region.getTexture() == editor){ - editorPacker.pack(region.name, Core.atlas.getPixmap(region).crop()); - } - } - //get textures packed if(totalSprites > 0){ TextureFilter filter = Core.settings.getBool("linear") ? TextureFilter.Linear : TextureFilter.Nearest; - packer.updateTextureAtlas(Core.atlas, filter, filter, false); + //flush so generators can use these sprites + packer.flush(filter, Core.atlas); + //generate new icons for(Array arr : content.getContentMap()){ arr.each(c -> { if(c instanceof UnlockableContent && c.mod != null){ UnlockableContent u = (UnlockableContent)c; - u.createIcons(packer, editorPacker); + u.createIcons(packer); } }); } - editorPacker.updateTextureAtlas(Core.atlas, filter, filter, false); - packer.updateTextureAtlas(Core.atlas, filter, filter, false); + Core.atlas = packer.flush(filter, new TextureAtlas()); + Core.atlas.setErrorRegion("error"); + Log.info("Total pages: {0}", Core.atlas.getTextures().size); } packer.dispose(); @@ -148,6 +153,26 @@ public class Mods implements Loadable{ Log.info("Time to update textures: {0}", Time.elapsed()); } + private PageType getPage(AtlasRegion region){ + return + region.getTexture() == Core.atlas.find("white").getTexture() ? PageType.main : + region.getTexture() == Core.atlas.find("stone1").getTexture() ? PageType.environment : + region.getTexture() == Core.atlas.find("clear-editor").getTexture() ? PageType.editor : + region.getTexture() == Core.atlas.find("zone-groundZero").getTexture() ? PageType.zone : + region.getTexture() == Core.atlas.find("whiteui").getTexture() ? PageType.ui : + PageType.main; + } + + private PageType getPage(FileHandle file){ + String parent = file.parent().name(); + return + parent.equals("environment") ? PageType.environment : + parent.equals("editor") ? PageType.editor : + parent.equals("zones") ? PageType.zone : + parent.equals("ui") || file.parent().parent().name().equals("ui") ? PageType.ui : + PageType.main; + } + /** Removes a mod file and marks it for requiring a restart. */ public void removeMod(LoadedMod mod){ if(mod.root instanceof ZipFileHandle){ @@ -172,8 +197,7 @@ public class Mods implements Loadable{ /** Loads all mods from the folder, but does not call any methods on them.*/ public void load(){ for(FileHandle file : modDirectory.list()){ - if(!file.extension().equals("jar") && !file.extension().equals("zip") && !(file.isDirectory() && file.child("mod.json").exists())) continue; - + if(!file.extension().equals("jar") && !file.extension().equals("zip") && !(file.isDirectory() && (file.child("mod.json").exists() || file.child("mod.hjson").exists()))) continue; Log.debug("[Mods] Loading mod {0}", file); try{ @@ -206,6 +230,7 @@ public class Mods implements Loadable{ } resolveDependencies(); + //sort mods to make sure servers handle them properly. loaded.sort(Structs.comparing(m -> m.name)); @@ -213,6 +238,10 @@ public class Mods implements Loadable{ } private void resolveDependencies(){ + Array incompatible = loaded.select(m -> !m.isSupported()); + loaded.removeAll(incompatible); + disabled.addAll(incompatible); + for(LoadedMod mod : Array.withArrays(loaded, disabled)){ updateDependencies(mod); } @@ -354,7 +383,7 @@ public class Mods implements Loadable{ FileHandle folder = contentRoot.child(type.name().toLowerCase() + "s"); if(folder.exists()){ for(FileHandle file : folder.list()){ - if(file.extension().equals("json") || file.extension().equals("hjson") || file.extension().equals("js")){ + if(file.extension().equals("json") || file.extension().equals("hjson")){ runs.add(new LoadRun(type, file, mod)); } } @@ -482,13 +511,13 @@ public class Mods implements Loadable{ zip = zip.list()[0]; } - FileHandle metaf = zip.child("mod.json").exists() ? zip.child("mod.json") : zip.child("plugin.json"); + FileHandle metaf = zip.child("mod.json").exists() ? zip.child("mod.json") : zip.child("mod.hjson").exists() ? zip.child("mod.hjson") : zip.child("plugin.json"); if(!metaf.exists()){ - Log.warn("Mod {0} doesn't have a 'mod.json'/'plugin.json' file, skipping.", sourceFile); + Log.warn("Mod {0} doesn't have a 'mod.json'/'plugin.json'/'mod.js' file, skipping.", sourceFile); throw new IllegalArgumentException("No mod.json found."); } - ModMeta meta = json.fromJson(ModMeta.class, metaf.readString()); + ModMeta meta = json.fromJson(ModMeta.class, Jval.read(metaf.readString()).toString(Jformat.plain)); String camelized = meta.name.replace(" ", ""); String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main; String baseName = meta.name.toLowerCase().replace(" ", "-"); @@ -563,6 +592,18 @@ public class Mods implements Loadable{ return !missingDependencies.isEmpty(); } + /** @return whether this mod is supported by the game verison */ + public boolean isSupported(){ + if(Version.build <= 0 || meta.minGameVersion == null) return true; + if(meta.minGameVersion.contains(".")){ + String[] split = meta.minGameVersion.split("\\."); + if(split.length == 2){ + return Version.build >= Strings.parseInt(split[0], 0) && Version.revision >= Strings.parseInt(split[1], 0); + } + } + return Version.build >= Strings.parseInt(meta.minGameVersion, 0); + } + @Override public String getSteamID(){ return Core.settings.getString(name + "-steamid", null); @@ -632,7 +673,7 @@ public class Mods implements Loadable{ /** Plugin metadata information.*/ public static class ModMeta{ - public String name, author, description, version, main; + public String name, author, description, version, main, minGameVersion; public Array dependencies = Array.with(); /** Hidden mods are only server-side or client-side, and do not support adding new content. */ public boolean hidden; @@ -662,5 +703,13 @@ public class Mods implements Loadable{ this.mod = content.mod; } } + + public ModLoadException(String message, @Nullable Content content){ + super(message); + this.content = content; + if(content != null){ + this.mod = content.mod; + } + } } } diff --git a/core/src/io/anuke/mindustry/net/Administration.java b/core/src/io/anuke/mindustry/net/Administration.java index 0aaeb8542f..f7815e03d2 100644 --- a/core/src/io/anuke/mindustry/net/Administration.java +++ b/core/src/io/anuke/mindustry/net/Administration.java @@ -3,8 +3,11 @@ package io.anuke.mindustry.net; import io.anuke.annotations.Annotations.*; import io.anuke.arc.*; import io.anuke.arc.collection.*; +import io.anuke.mindustry.Vars; + import static io.anuke.mindustry.Vars.headless; +import static io.anuke.mindustry.game.EventType.*; public class Administration{ /** All player info. Maps UUIDs to info. This persists throughout restarts. */ @@ -76,7 +79,7 @@ public class Administration{ bannedIPs.add(ip); save(); - + Events.fire(new PlayerIpBanEvent(ip)); return true; } @@ -88,7 +91,7 @@ public class Administration{ getCreateInfo(id).banned = true; save(); - + Events.fire(new PlayerBanEvent(Vars.playerGroup.find(p -> id.equals(p.uuid)))); return true; } @@ -108,8 +111,10 @@ public class Administration{ bannedIPs.removeValue(ip, false); - if(found) save(); - + if(found){ + save(); + Events.fire(new PlayerIpUnbanEvent(ip)); + } return found; } @@ -126,7 +131,7 @@ public class Administration{ info.banned = false; bannedIPs.removeAll(info.ips, false); save(); - + Events.fire(new PlayerUnbanEvent(Vars.playerGroup.find(p -> id.equals(p.uuid)))); return true; } diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index 0a39de51ef..963ed3c549 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -80,7 +80,7 @@ public class Packets{ buffer.put(mobile ? (byte)1 : 0); buffer.putInt(color); buffer.put(Base64Coder.decode(uuid)); - buffer.putInt(mods.size); + buffer.put((byte)mods.size); for(int i = 0; i < mods.size; i++){ TypeIO.writeString(buffer, mods.get(i)); } @@ -97,7 +97,7 @@ public class Packets{ byte[] idbytes = new byte[8]; buffer.get(idbytes); uuid = new String(Base64Coder.encode(idbytes)); - int totalMods = buffer.getInt(); + int totalMods = buffer.get(); mods = new Array<>(totalMods); for(int i = 0; i < totalMods; i++){ mods.add(TypeIO.readString(buffer)); diff --git a/core/src/io/anuke/mindustry/type/Category.java b/core/src/io/anuke/mindustry/type/Category.java index a22b742345..c75451bc64 100644 --- a/core/src/io/anuke/mindustry/type/Category.java +++ b/core/src/io/anuke/mindustry/type/Category.java @@ -23,4 +23,12 @@ public enum Category{ effect; public static final Category[] all = values(); + + public Category prev(){ + return all[(this.ordinal() - 1 + all.length) % all.length]; + } + + public Category next(){ + return all[(this.ordinal() + 1) % all.length]; + } } diff --git a/core/src/io/anuke/mindustry/type/Liquid.java b/core/src/io/anuke/mindustry/type/Liquid.java index e6c8b3e089..bc97a18990 100644 --- a/core/src/io/anuke/mindustry/type/Liquid.java +++ b/core/src/io/anuke/mindustry/type/Liquid.java @@ -13,6 +13,8 @@ public class Liquid extends UnlockableContent{ /** Color used in bars. */ public @Nullable Color barColor; + /** Color used to draw lights. Note that the alpha channel is used to dictate brightness. */ + public Color lightColor = Color.clear.cpy(); /** 0-1, 0 is completely inflammable, anything above that may catch fire when exposed to heat, 0.5+ is very flammable. */ public float flammability; /** temperature: 0.5 is 'room' temperature, 0 is very cold, 1 is molten hot */ diff --git a/core/src/io/anuke/mindustry/ui/ContentDisplay.java b/core/src/io/anuke/mindustry/ui/ContentDisplay.java index a184e86aaf..e086e4e616 100644 --- a/core/src/io/anuke/mindustry/ui/ContentDisplay.java +++ b/core/src/io/anuke/mindustry/ui/ContentDisplay.java @@ -85,6 +85,9 @@ public class ContentDisplay{ table.left().defaults().fillX(); + table.add(Core.bundle.format("item.corestorable", item.type == ItemType.material ? Core.bundle.format("yes") : Core.bundle.format("no"))); + table.row(); + table.add(Core.bundle.format("item.explosiveness", (int)(item.explosiveness * 100))); table.row(); table.add(Core.bundle.format("item.flammability", (int)(item.flammability * 100))); diff --git a/core/src/io/anuke/mindustry/ui/Links.java b/core/src/io/anuke/mindustry/ui/Links.java index cfdaac40a9..670ca4e76e 100644 --- a/core/src/io/anuke/mindustry/ui/Links.java +++ b/core/src/io/anuke/mindustry/ui/Links.java @@ -17,6 +17,7 @@ public class Links{ new LinkEntry("reddit", "https://www.reddit.com/r/Mindustry/", Color.valueOf("ee593b")), new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Color.valueOf("fa5c5c")), new LinkEntry("google-play", "https://play.google.com/store/apps/details?id=io.anuke.mindustry", Color.valueOf("689f38")), + new LinkEntry("f-droid", "https://f-droid.org/packages/io.anuke.mindustry/", Color.valueOf("026aa7")), new LinkEntry("github", "https://github.com/Anuken/Mindustry/", Color.valueOf("24292e")), new LinkEntry("dev-builds", "https://github.com/Anuken/MindustryBuilds", Color.valueOf("fafbfc")) }; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java index a8e5212307..83d44a97f2 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java @@ -16,7 +16,7 @@ import static io.anuke.mindustry.Vars.*; public class AboutDialog extends FloatingDialog{ private Array contributors = new Array<>(); - private static ObjectSet bannedItems = ObjectSet.with("google-play", "itch.io", "dev-builds"); + private static ObjectSet bannedItems = ObjectSet.with("google-play", "itch.io", "dev-builds", "f-droid"); public AboutDialog(){ super("$about.button"); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ColorPicker.java b/core/src/io/anuke/mindustry/ui/dialogs/ColorPicker.java new file mode 100644 index 0000000000..03454d76e5 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/dialogs/ColorPicker.java @@ -0,0 +1,63 @@ +package io.anuke.mindustry.ui.dialogs; + +import io.anuke.arc.func.*; +import io.anuke.arc.graphics.*; +import io.anuke.arc.scene.ui.*; +import io.anuke.mindustry.gen.*; +import io.anuke.mindustry.graphics.*; + +public class ColorPicker extends FloatingDialog{ + private Cons cons = c -> {}; + private Color current = new Color(); + + public ColorPicker(){ + super("$pickcolor"); + } + + public void show(Color color, Cons consumer){ + show(color, true, consumer); + } + + public void show(Color color, boolean alpha, Cons consumer){ + this.current.set(color); + this.cons = consumer; + show(); + + cont.clear(); + cont.pane(t -> { + t.table(Tex.pane, i -> { + i.stack(new Image(Tex.alphaBg), new Image(){{ + setColor(current); + update(() -> setColor(current)); + }}).size(200f); + }).colspan(2).padBottom(5); + + float w = 150f; + + t.row(); + + t.defaults().padBottom(4); + t.add("R").color(Pal.remove); + t.addSlider(0f, 1f, 0.01f, current.r, current::r).width(w); + t.row(); + t.add("G").color(Color.lime); + t.addSlider(0f, 1f, 0.01f, current.g, current::g).width(w); + t.row(); + t.add("B").color(Color.royal); + t.addSlider(0f, 1f, 0.01f, current.b, current::b).width(w); + t.row(); + if(alpha){ + t.add("A"); + t.addSlider(0f, 1f, 0.01f, current.a, current::a).width(w); + t.row(); + } + }); + + buttons.clear(); + addCloseButton(); + buttons.addImageTextButton("$ok", Icon.checkSmall, () -> { + cons.get(current); + hide(); + }); + } +} diff --git a/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java index b3bea499c3..201e3411f2 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java @@ -116,7 +116,7 @@ public class CustomRulesDialog extends FloatingDialog{ void setup(){ cont.clear(); - cont.pane(m -> main = m); + cont.pane(m -> main = m).get().setScrollingDisabled(true, false); main.margin(10f); main.addButton("$settings.reset", () -> { rules = resetter.get(); @@ -135,13 +135,11 @@ public class CustomRulesDialog extends FloatingDialog{ number("$rules.dropzoneradius", false, f -> rules.dropZoneRadius = f * tilesize, () -> rules.dropZoneRadius / tilesize, () -> true); title("$rules.title.respawns"); - //limited respawns don't work on PvP, commented out until they're fixed - //check("$rules.limitedRespawns", b -> rules.limitedRespawns = b, () -> rules.limitedRespawns); - //number("$rules.respawns", true, f -> rules.respawns = (int)f, () -> rules.respawns, () -> rules.limitedRespawns); number("$rules.respawntime", f -> rules.respawnTime = f * 60f, () -> rules.respawnTime / 60f); title("$rules.title.resourcesbuilding"); check("$rules.infiniteresources", b -> rules.infiniteResources = b, () -> rules.infiniteResources); + check("$rules.reactorexplosions", b -> rules.reactorExplosions = b, () -> rules.reactorExplosions); number("$rules.buildcostmultiplier", false, f -> rules.buildCostMultiplier = f, () -> rules.buildCostMultiplier, () -> !rules.infiniteResources); number("$rules.buildspeedmultiplier", f -> rules.buildSpeedMultiplier = f, () -> rules.buildSpeedMultiplier); @@ -171,6 +169,20 @@ public class CustomRulesDialog extends FloatingDialog{ check("$rules.attack", b -> rules.attackMode = b, () -> rules.attackMode); check("$rules.enemyCheat", b -> rules.enemyCheat = b, () -> rules.enemyCheat); number("$rules.enemycorebuildradius", f -> rules.enemyCoreBuildRadius = f * tilesize, () -> Math.min(rules.enemyCoreBuildRadius / tilesize, 200)); + + title("$rules.title.experimental"); + check("$rules.lighting", b -> rules.lighting = b, () -> rules.lighting); + + main.addButton(b -> { + b.left(); + b.table(Tex.pane, in -> { + in.stack(new Image(Tex.alphaBg), new Image(Tex.whiteui){{ + update(() -> setColor(rules.ambientLight)); + }}).grow(); + }).margin(4).size(50f).padRight(10); + b.add("$rules.ambientlight"); + }, () -> ui.picker.show(rules.ambientLight, rules.ambientLight::set)).left().width(250f); + main.row(); } void number(String text, Floatc cons, Floatp prov){ @@ -200,7 +212,9 @@ public class CustomRulesDialog extends FloatingDialog{ } void title(String text){ - main.add(text).color(Pal.accent).padTop(20).padBottom(20).padRight(100f); + main.add(text).color(Pal.accent).padTop(20).padRight(100f).padBottom(-3); + main.row(); + main.addImage().color(Pal.accent).height(3f).padRight(100f).padBottom(20); main.row(); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java index 5ecb7a3e9a..200986f839 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java @@ -31,7 +31,7 @@ public class HostDialog extends FloatingDialog{ }).grow().pad(8).get().setMaxLength(40); ImageButton button = t.addImageButton(Tex.whiteui, Styles.clearFulli, 40, () -> { - new ColorPickDialog().show(color -> { + new PaletteDialog().show(color -> { player.color.set(color); Core.settings.put("color-0", Color.rgba8888(color)); Core.settings.save(); @@ -74,6 +74,9 @@ public class HostDialog extends FloatingDialog{ ui.showCustomConfirm("$setting.publichost.name", "$public.confirm", "$yes", "$no", () -> { Core.settings.putSave("publichost", true); platform.updateLobby(); + }, () -> { + Core.settings.putSave("publichost", false); + platform.updateLobby(); }); })); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java index ac8c22a0a5..490d2b370f 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java @@ -9,6 +9,7 @@ import io.anuke.arc.math.*; import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.util.*; +import io.anuke.arc.util.serialization.*; import io.anuke.mindustry.*; import io.anuke.mindustry.core.*; import io.anuke.mindustry.gen.*; @@ -247,7 +248,7 @@ public class JoinDialog extends FloatingDialog{ } ImageButton button = t.addImageButton(Tex.whiteui, Styles.clearFulli, 40, () -> { - new ColorPickDialog().show(color -> { + new PaletteDialog().show(color -> { player.color.set(color); Core.settings.put("color-0", Color.rgba8888(color)); Core.settings.save(); @@ -359,6 +360,20 @@ public class JoinDialog extends FloatingDialog{ @SuppressWarnings("unchecked") private void loadServers(){ servers = Core.settings.getObject("server-list", Array.class, Array::new); + + //get servers + Core.net.httpGet(serverJsonURL, result -> { + try{ + Jval val = Jval.read(result.getResultAsString()); + Core.app.post(() -> { + try{ + defaultServers.clear(); + val.asArray().each(child -> defaultServers.add(child.getString("address", ""))); + Log.info("Fetched {0} global servers.", defaultServers.size); + }catch(Throwable ignored){} + }); + }catch(Throwable ignored){} + }, t -> {}); } private void saveServers(){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ModsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ModsDialog.java index 50164a7dff..ed8b3c5670 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ModsDialog.java @@ -132,7 +132,7 @@ public class ModsDialog extends FloatingDialog{ title.addImageTextButton(mod.enabled() ? "$mod.disable" : "$mod.enable", mod.enabled() ? Icon.arrowDownSmall : Icon.arrowUpSmall, Styles.cleart, () -> { mods.setEnabled(mod, !mod.enabled()); setup(); - }).height(50f).margin(8f).width(130f); + }).height(50f).margin(8f).width(130f).disabled(!mod.isSupported()); if(steam && !mod.hasSteamID()){ title.addImageButton(Icon.loadMapSmall, Styles.cleari, () -> { @@ -161,7 +161,10 @@ public class ModsDialog extends FloatingDialog{ t.labelWrap("[lightgray]" + mod.meta.description).growX(); t.row(); } - if(mod.hasUnmetDependencies()){ + if(!mod.isSupported()){ + t.labelWrap(Core.bundle.format("mod.requiresversion", mod.meta.minGameVersion)).growX(); + t.row(); + }else if(mod.hasUnmetDependencies()){ t.labelWrap(Core.bundle.format("mod.missingdependencies", mod.missingDependencies.toString(", "))).growX(); t.row(); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PaletteDialog.java similarity index 93% rename from core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java rename to core/src/io/anuke/mindustry/ui/dialogs/PaletteDialog.java index 5e26f272d3..693a576691 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PaletteDialog.java @@ -10,10 +10,10 @@ import io.anuke.mindustry.ui.*; import static io.anuke.mindustry.Vars.*; -public class ColorPickDialog extends Dialog{ +public class PaletteDialog extends Dialog{ private Cons cons; - public ColorPickDialog(){ + public PaletteDialog(){ super(""); build(); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SchematicsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SchematicsDialog.java index 0109b959e4..e9c6cc18de 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SchematicsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SchematicsDialog.java @@ -62,12 +62,12 @@ public class SchematicsDialog extends FloatingDialog{ t.clear(); int i = 0; - if(!schematics.all().contains(s -> search.isEmpty() || s.name().contains(search))){ + if(!schematics.all().contains(s -> search.isEmpty() || s.name().toLowerCase().contains(search.toLowerCase()))){ t.add("$none"); } for(Schematic s : schematics.all()){ - if(!search.isEmpty() && !s.name().contains(search)) continue; + if(!search.isEmpty() && !s.name().toLowerCase().contains(search.toLowerCase())) continue; Button[] sel = {null}; sel[0] = t.addButton(b -> { diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index a840b2a9fd..28e83c63c8 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -221,6 +221,8 @@ public class SettingsMenuDialog extends SettingsDialog{ game.sliderPref("saveinterval", 60, 10, 5 * 120, 10, i -> Core.bundle.format("setting.seconds", i)); if(!mobile){ + game.sliderPref("blockselecttimeout", 750, 0, 2000, 50, i -> Core.bundle.format("setting.milliseconds", i)); + game.checkPref("crashreport", true); } @@ -251,7 +253,7 @@ public class SettingsMenuDialog extends SettingsDialog{ } }); - graphics.sliderPref("uiscale", 100, 25, 400, 5, s -> { + graphics.sliderPref("uiscale", 100, 25, 300, 25, s -> { if(ui.settings != null){ Core.settings.put("uiscalechanged", true); } @@ -306,6 +308,9 @@ public class SettingsMenuDialog extends SettingsDialog{ graphics.checkPref("minimap", !mobile); graphics.checkPref("position", false); graphics.checkPref("fps", false); + if(!mobile){ + graphics.checkPref("blockselectkeys", true); + } graphics.checkPref("indicators", true); graphics.checkPref("animatedwater", !mobile); if(Shaders.shield != null){ diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java index 1c663f2b4a..1ea3623790 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java @@ -189,9 +189,9 @@ public class BlockInventoryFragment extends Fragment{ private String round(float f){ f = (int)f; if(f >= 1000000){ - return (int)(f / 1000000f) + "[gray]mil[]"; + return (int)(f / 1000000f) + "[gray]" + Core.bundle.getOrNull("unit.millions") + "[]"; }else if(f >= 1000){ - return (int)(f / 1000) + "k"; + return (int)(f / 1000) + Core.bundle.getOrNull("unit.thousands"); }else{ return (int)f + ""; } diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 6afd96619b..3bbce3b1ec 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -64,9 +64,7 @@ public class HudFragment extends Fragment{ select.addImageButton(Icon.menuLargeSmall, style, ui.paused::show); flip = select.addImageButton(Icon.arrowUpSmall, style, this::toggleMenus).get(); - select.addImageButton(Icon.pasteSmall, style, () -> { - ui.schematics.show(); - }); + select.addImageButton(Icon.pasteSmall, style, ui.schematics::show); select.addImageButton(Icon.pauseSmall, style, () -> { if(net.active()){ @@ -347,7 +345,7 @@ public class HudFragment extends Fragment{ @Remote(targets = Loc.both, forward = true, called = Loc.both) public static void setPlayerTeamEditor(Player player, Team team){ - if(state.isEditor()){ + if(state.isEditor() && player != null){ player.setTeam(team); } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index 9229546fe0..b18be4b27e 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -17,7 +17,6 @@ import io.anuke.mindustry.gen.*; import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.ui.*; -import static io.anuke.arc.Core.assets; import static io.anuke.mindustry.Vars.*; public class MenuFragment extends Fragment{ @@ -26,8 +25,6 @@ public class MenuFragment extends Fragment{ private MenuRenderer renderer; public MenuFragment(){ - assets.load("sprites/logo.png", Texture.class); - assets.finishLoading(); Events.on(DisposeEvent.class, event -> { renderer.dispose(); }); @@ -67,7 +64,7 @@ public class MenuFragment extends Fragment{ String versionText = "[#ffffffba]" + ((Version.build == -1) ? "[#fc8140aa]custom build" : (Version.type.equals("official") ? Version.modifier : Version.type) + " build " + Version.build + (Version.revision == 0 ? "" : "." + Version.revision)); parent.fill((x, y, w, h) -> { - Texture logo = Core.assets.get("sprites/logo.png"); + TextureRegion logo = Core.atlas.find("logo"); float logoscl = Scl.scl(1); float logow = Math.min(logo.getWidth() * logoscl, Core.graphics.getWidth() - Scl.scl(20)); float logoh = logow * (float)logo.getHeight() / logo.getWidth(); @@ -76,7 +73,7 @@ public class MenuFragment extends Fragment{ float fy = (int)(Core.graphics.getHeight() - 6 - logoh) + logoh / 2 - (Core.graphics.isPortrait() ? Scl.scl(30f) : 0f); Draw.color(); - Draw.rect(Draw.wrap(logo), fx, fy, logow, logoh); + Draw.rect(logo, fx, fy, logow, logoh); Fonts.def.setColor(Color.white); Fonts.def.draw(versionText, fx, fy - logoh/2f, Align.center); diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java index fd088ae3b6..95bdd5affa 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java @@ -36,6 +36,25 @@ public class PlacementFragment extends Fragment{ Tile hoverTile; Table blockTable, toggler, topTable; boolean lastGround; + boolean blockSelectEnd; + int blockSelectSeq; + long blockSelectSeqMillis; + Binding[] blockSelect = { + Binding.block_select_01, + Binding.block_select_02, + Binding.block_select_03, + Binding.block_select_04, + Binding.block_select_05, + Binding.block_select_06, + Binding.block_select_07, + Binding.block_select_08, + Binding.block_select_09, + Binding.block_select_10, + Binding.block_select_left, + Binding.block_select_right, + Binding.block_select_up, + Binding.block_select_down + }; public PlacementFragment(){ Events.on(WorldLoadEvent.class, event -> { @@ -83,6 +102,78 @@ public class PlacementFragment extends Fragment{ return true; } } + + if(ui.chatfrag.chatOpen()) return false; + for(int i = 0; i < blockSelect.length; i++){ + if(Core.input.keyTap(blockSelect[i])){ + if(i > 9) { //select block directionally + Array blocks = getByCategory(currentCategory); + Block currentBlock = getSelectedBlock(currentCategory); + for(int j = 0; j < blocks.size; j++){ + if(blocks.get(j) == currentBlock){ + switch(i){ + case 10: //left + j = (j - 1 + blocks.size) % blocks.size; + break; + case 11: //right + j = (j + 1) % blocks.size; + break; + case 12: //up + j = (j > 3 ? j - 4 : blocks.size - blocks.size % 4 + j); + j -= (j < blocks.size ? 0 : 4); + break; + case 13: //down + j = (j < blocks.size - 4 ? j + 4 : j % 4); + } + input.block = blocks.get(j); + selectedBlocks.put(currentCategory, input.block); + break; + } + } + }else if(blockSelectEnd || Time.timeSinceMillis(blockSelectSeqMillis) > Core.settings.getInt("blockselecttimeout")){ //1st number of combo, select category + //select only visible categories + if(!getByCategory(Category.all[i]).isEmpty()){ + currentCategory = Category.all[i]; + if(input.block != null){ + input.block = getSelectedBlock(currentCategory); + } + blockSelectEnd = false; + blockSelectSeq = 0; + blockSelectSeqMillis = Time.millis(); + } + }else{ //select block + if(blockSelectSeq == 0){ //2nd number of combo + blockSelectSeq = i + 1; + }else{ //3rd number of combo + //entering "X,1,0" selects the same block as "X,0" + i += (blockSelectSeq - (i != 9 ? 0 : 1)) * 10; + blockSelectEnd = true; + } + Array blocks = getByCategory(currentCategory); + input.block = (i < blocks.size) ? blocks.get(i) : null; + selectedBlocks.put(currentCategory, input.block); + blockSelectSeqMillis = Time.millis(); + } + return true; + } + } + + if(Core.input.keyTap(Binding.category_prev)){ + do{ + currentCategory = currentCategory.prev(); + }while(categoryEmpty[currentCategory.ordinal()]); + input.block = getSelectedBlock(currentCategory); + return true; + } + + if(Core.input.keyTap(Binding.category_next)){ + do{ + currentCategory = currentCategory.next(); + }while(categoryEmpty[currentCategory.ordinal()]); + input.block = getSelectedBlock(currentCategory); + return true; + } + return false; } @@ -109,11 +200,6 @@ public class PlacementFragment extends Fragment{ blockTable.row(); } - if(!unlocked(block)){ - blockTable.add().size(46); - continue; - } - ImageButton button = blockTable.addImageButton(Icon.lockedSmall, Styles.selecti, () -> { if(unlocked(block)){ control.input.block = control.input.block == block ? null : block; @@ -170,9 +256,22 @@ public class PlacementFragment extends Fragment{ lastGround = false; topTable.table(header -> { + String keyCombo = ""; + if(!mobile && Core.settings.getBool("blockselectkeys")){ + Array blocks = getByCategory(currentCategory); + for(int i = 0; i < blocks.size; i++){ + if(blocks.get(i) == lastDisplay){ + keyCombo = Core.bundle.format("placement.blockselectkeys", Core.keybinds.get(blockSelect[currentCategory.ordinal()]).key.toString()) + + (i < 10 ? "" : Core.keybinds.get(blockSelect[(i + 1) / 10 - 1]).key.toString() + ",") + + Core.keybinds.get(blockSelect[i % 10]).key.toString() + "]"; + break; + } + } + } + final String keyComboFinal = keyCombo; header.left(); header.add(new Image(lastDisplay.icon(Cicon.medium))).size(8 * 4); - header.labelWrap(() -> !unlocked(lastDisplay) ? Core.bundle.get("block.unknown") : lastDisplay.localizedName) + header.labelWrap(() -> !unlocked(lastDisplay) ? Core.bundle.get("block.unknown") : lastDisplay.localizedName + keyComboFinal) .left().width(190f).padLeft(5); header.add().growX(); if(unlocked(lastDisplay)){ @@ -265,7 +364,7 @@ public class PlacementFragment extends Fragment{ //update category empty values for(Category cat : Category.all){ Array blocks = getByCategory(cat); - categoryEmpty[cat.ordinal()] = blocks.isEmpty() || !unlocked(blocks.first()); + categoryEmpty[cat.ordinal()] = blocks.isEmpty(); } int f = 0; @@ -280,10 +379,7 @@ public class PlacementFragment extends Fragment{ categories.addImageButton(Core.atlas.drawable("icon-" + cat.name() + "-smaller"), Styles.clearToggleTransi, () -> { currentCategory = cat; if(control.input.block != null){ - if(selectedBlocks.get(currentCategory) == null){ - selectedBlocks.put(currentCategory, getByCategory(currentCategory).find(this::unlocked)); - } - control.input.block = selectedBlocks.get(currentCategory); + control.input.block = getSelectedBlock(currentCategory); } rebuildCategory.run(); }).group(group).update(i -> i.setChecked(currentCategory == cat)).name("category-" + cat.name()); @@ -308,7 +404,7 @@ public class PlacementFragment extends Fragment{ Array getByCategory(Category cat){ returnArray.clear(); for(Block block : content.blocks()){ - if(block.category == cat && block.isVisible()){ + if(block.category == cat && block.isVisible() && unlocked(block)){ returnArray.add(block); } } @@ -320,6 +416,13 @@ public class PlacementFragment extends Fragment{ return returnArray; } + Block getSelectedBlock(Category cat){ + if(selectedBlocks.get(cat) == null){ + selectedBlocks.put(cat, getByCategory(cat).find(this::unlocked)); + } + return selectedBlocks.get(cat); + } + boolean unlocked(Block block){ return !world.isZone() || data.isUnlocked(block); } @@ -359,4 +462,4 @@ public class PlacementFragment extends Fragment{ Block tileDisplayBlock(){ return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.drop() != null ? hoverTile.overlay().itemDrop != null ? hoverTile.overlay() : hoverTile.floor() : null; } -} \ No newline at end of file +} diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 8e733dab1f..e05f047b21 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -24,6 +24,7 @@ import io.anuke.mindustry.entities.traits.BuilderTrait.*; import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.gen.*; import io.anuke.mindustry.graphics.*; +import io.anuke.mindustry.graphics.MultiPacker.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.ui.*; import io.anuke.mindustry.world.blocks.*; @@ -89,6 +90,8 @@ public class Block extends BlockStorage{ public boolean configurable; /** Whether this block consumes touchDown events when tapped. */ public boolean consumesTap; + /** Whether to draw the glow of the liquid for this block, if it has one. */ + public boolean drawLiquidLight = true; /** Whether the config is positional and needs to be shifted. */ public boolean posConfig; /** Whether this block uses conveyor-type placement mode.*/ @@ -137,6 +140,7 @@ public class Block extends BlockStorage{ protected TextureRegion[] cacheRegions = {}; protected Array cacheRegionStrings = new Array<>(); + protected Prov entityType = TileEntity::new; protected Array tempTiles = new Array<>(); protected TextureRegion[] generatedIcons; @@ -292,6 +296,23 @@ public class Block extends BlockStorage{ Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.rotation() * 90 : 0); } + public void drawLight(Tile tile){ + if(tile.entity != null && hasLiquids && drawLiquidLight && tile.entity.liquids.current().lightColor.a > 0.001f){ + drawLiquidLight(tile, tile.entity.liquids.current(), tile.entity.liquids.smoothAmount()); + } + } + + public void drawLiquidLight(Tile tile, Liquid liquid, float amount){ + if(amount > 0.01f){ + Color color = liquid.lightColor; + float fract = 1f; + float opacity = color.a * fract; + if(opacity > 0.001f){ + renderer.lights.add(tile.drawx(), tile.drawy(), size * 30f * fract, color, opacity); + } + } + } + public void drawTeam(Tile tile){ Draw.color(tile.getTeam().color); Draw.rect("block-border", tile.drawx() - size * tilesize / 2f + 4, tile.drawy() - size * tilesize / 2f + 4); @@ -363,6 +384,16 @@ public class Block extends BlockStorage{ return sum; } + public float percentSolid(int x, int y){ + Tile tile = world.tile(x, y); + if(tile == null) return 0; + float sum = 0; + for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){ + sum += !other.floor.isLiquid ? 1f : 0f; + } + return sum / size / size; + } + @Override public String localizedName(){ return localizedName; @@ -596,7 +627,7 @@ public class Block extends BlockStorage{ if(hasLiquids){ - tile.entity.liquids.forEach((liquid, amount) -> { + tile.entity.liquids.each((liquid, amount) -> { float splash = Mathf.clamp(amount / 4f, 0f, 10f); for(int i = 0; i < Mathf.clamp(amount / 5, 0, 30); i++){ @@ -706,10 +737,12 @@ public class Block extends BlockStorage{ Color color = content instanceof Item ? ((Item)content).color : content instanceof Liquid ? ((Liquid)content).color : null; if(color == null) return; + float prev = Draw.scl; + Draw.color(color); Draw.scl *= req.animScale; Draw.rect(region, req.drawx(), req.drawy()); - Draw.scl /= req.animScale; + Draw.scl = prev; Draw.color(); } @@ -723,10 +756,10 @@ public class Block extends BlockStorage{ } @Override - public void createIcons(PixmapPacker packer, PixmapPacker editor){ - super.createIcons(packer, editor); + public void createIcons(MultiPacker packer){ + super.createIcons(packer); - editor.pack(name + "-icon-editor", Core.atlas.getPixmap((AtlasRegion)icon(Cicon.full)).crop()); + packer.add(PageType.editor, name + "-icon-editor", Core.atlas.getPixmap((AtlasRegion)icon(Cicon.full))); if(!synthetic()){ PixmapRegion image = Core.atlas.getPixmap((AtlasRegion)icon(Cicon.full)); @@ -766,7 +799,7 @@ public class Block extends BlockStorage{ } last = out; - packer.pack(name, out); + packer.add(PageType.main, name, out); } if(generatedIcons.length > 1){ @@ -778,7 +811,7 @@ public class Block extends BlockStorage{ base.draw(Core.atlas.getPixmap(generatedIcons[i])); } } - packer.pack("block-" + name + "-full", base); + packer.add(PageType.main, "block-" + name + "-full", base); generatedIcons = null; Arrays.fill(cicons, null); } @@ -825,8 +858,8 @@ public class Block extends BlockStorage{ return destructible || update; } - public TileEntity newEntity(){ - return new TileEntity(); + public final TileEntity newEntity(){ + return entityType.get(); } /** Offset for placing and drawing multiblocks. */ diff --git a/core/src/io/anuke/mindustry/world/BlockStorage.java b/core/src/io/anuke/mindustry/world/BlockStorage.java index 199a82870c..ced126de72 100644 --- a/core/src/io/anuke/mindustry/world/BlockStorage.java +++ b/core/src/io/anuke/mindustry/world/BlockStorage.java @@ -116,9 +116,9 @@ public abstract class BlockStorage extends UnlockableContent{ Tile other = proximity.get((i + dump) % proximity.size); Tile in = Edges.getFacingEdge(tile, other); - other = other.block().getLiquidDestination(other, tile); + other = other.block().getLiquidDestination(other, in, liquid); - if(other.getTeam() == tile.getTeam() && other.block().hasLiquids && canDumpLiquid(tile, other, liquid) && other.entity.liquids != null){ + if(other != null && other.getTeam() == tile.getTeam() && other.block().hasLiquids && canDumpLiquid(tile, other, liquid) && other.entity.liquids != null){ float ofract = other.entity.liquids.get(liquid) / other.block().liquidCapacity; float fract = tile.entity.liquids.get(liquid) / liquidCapacity; @@ -142,10 +142,14 @@ public abstract class BlockStorage extends UnlockableContent{ } public float tryMoveLiquid(Tile tile, Tile next, boolean leak, Liquid liquid){ + return tryMoveLiquid(tile, next, leak ? 1.5f : 100, liquid); + } + + public float tryMoveLiquid(Tile tile, Tile next, float leakResistance, Liquid liquid){ if(next == null) return 0; next = next.link(); - next = next.block().getLiquidDestination(next, tile); + next = next.block().getLiquidDestination(next, tile, liquid); if(next.getTeam() == tile.getTeam() && next.block().hasLiquids && tile.entity.liquids.get(liquid) > 0f){ @@ -175,15 +179,15 @@ public abstract class BlockStorage extends UnlockableContent{ } } } - }else if(leak && !next.block().solid && !next.block().hasLiquids){ - float leakAmount = tile.entity.liquids.get(liquid) / 1.5f; + }else if(leakResistance != 100f && !next.block().solid && !next.block().hasLiquids){ + float leakAmount = tile.entity.liquids.get(liquid) / leakResistance; Puddle.deposit(next, tile, liquid, leakAmount); tile.entity.liquids.remove(liquid, leakAmount); } return 0; } - public Tile getLiquidDestination(Tile tile, Tile from){ + public Tile getLiquidDestination(Tile tile, Tile from, Liquid liquid){ return tile; } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index bb63b8098d..06e6cdca81 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -327,19 +327,19 @@ public class Tile implements Position, TargetTrait{ } // ▲ ▲ ▼ ▼ ◀ ▶ ◀ ▶ B A - public Tile front(){ + public @Nullable Tile front(){ return getNearbyLink((rotation + 4) % 4); } - public Tile right(){ + public @Nullable Tile right(){ return getNearbyLink((rotation + 3) % 4); } - public Tile back(){ + public @Nullable Tile back(){ return getNearbyLink((rotation + 2) % 4); } - public Tile left(){ + public @Nullable Tile left(){ return getNearbyLink((rotation + 1) % 4); } diff --git a/core/src/io/anuke/mindustry/world/blocks/Autotiler.java b/core/src/io/anuke/mindustry/world/blocks/Autotiler.java index 081651d40e..29e99361a4 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Autotiler.java +++ b/core/src/io/anuke/mindustry/world/blocks/Autotiler.java @@ -87,6 +87,12 @@ public interface Autotiler{ return other != null && blends(tile, rotation, other.x, other.y, other.rotation(), other.block()); } + default boolean blendsArmored(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ + return (Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, otherx, othery) + || ((!otherblock.rotate && Edges.getFacingEdge(otherblock, otherx, othery, tile) != null && + Edges.getFacingEdge(otherblock, otherx, othery, tile).relativeTo(tile) == rotation) || (otherblock.rotate && Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y)))); + } + default boolean lookingAt(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ return (Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, otherx, othery) || (!otherblock.rotate || Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y))); diff --git a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java index 799eaffaba..45023deac8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java @@ -42,6 +42,7 @@ public class BuildBlock extends Block{ layer = Layer.placement; consumesTap = true; solidifes = true; + entityType = BuildEntity::new; buildBlocks[size - 1] = this; } @@ -197,11 +198,6 @@ public class BuildBlock extends Block{ } } - @Override - public TileEntity newEntity(){ - return new BuildEntity(); - } - public class BuildEntity extends TileEntity{ /** * The recipe of the block that is being constructed. diff --git a/core/src/io/anuke/mindustry/world/blocks/Floor.java b/core/src/io/anuke/mindustry/world/blocks/Floor.java index 4ddb75ec32..582dc0e520 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/Floor.java @@ -10,8 +10,10 @@ import io.anuke.arc.math.geom.*; import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.mindustry.content.*; import io.anuke.mindustry.entities.Effects.*; +import io.anuke.mindustry.graphics.*; +import io.anuke.mindustry.graphics.MultiPacker.*; import io.anuke.mindustry.type.*; -import io.anuke.mindustry.ui.Cicon; +import io.anuke.mindustry.ui.*; import io.anuke.mindustry.world.*; import static io.anuke.mindustry.Vars.tilesize; @@ -87,9 +89,9 @@ public class Floor extends Block{ } @Override - public void createIcons(PixmapPacker out, PixmapPacker editor){ - super.createIcons(out, editor); - editor.pack("editor-" + name, Core.atlas.getPixmap((AtlasRegion)icon(Cicon.full)).crop()); + public void createIcons(MultiPacker packer){ + super.createIcons(packer); + packer.add(PageType.editor, "editor-" + name, Core.atlas.getPixmap((AtlasRegion)icon(Cicon.full)).crop()); if(blendGroup != this){ return; @@ -98,7 +100,7 @@ public class Floor extends Block{ if(variants > 0){ for(int i = 0; i < variants; i++){ String rname = name + (i + 1); - editor.pack("editor-" + rname, Core.atlas.getPixmap(rname).crop()); + packer.add(PageType.editor, "editor-" + rname, Core.atlas.getPixmap(rname).crop()); } } @@ -115,7 +117,7 @@ public class Floor extends Block{ } } - out.pack(name + "-edge", result); + packer.add(PageType.environment, name + "-edge", result); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java index cf4d45524c..ba74f2db0f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java @@ -4,6 +4,8 @@ import io.anuke.annotations.Annotations.*; import io.anuke.arc.*; import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.g2d.*; +import io.anuke.mindustry.graphics.*; +import io.anuke.mindustry.graphics.MultiPacker.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; @@ -34,7 +36,7 @@ public class OreBlock extends OverlayFloor{ @Override @OverrideCallSuper - public void createIcons(PixmapPacker out, PixmapPacker editor){ + public void createIcons(MultiPacker packer){ for(int i = 0; i < variants; i++){ Pixmap image = new Pixmap(32, 32); PixmapRegion shadow = Core.atlas.getPixmap(itemDrop.name + (i + 1)); @@ -55,12 +57,12 @@ public class OreBlock extends OverlayFloor{ image.draw(shadow); - out.pack(name + (i + 1), image); - editor.pack("editor-" + name + (i + 1), image); + packer.add(PageType.environment, name + (i + 1), image); + packer.add(PageType.editor, "editor-" + name + (i + 1), image); if(i == 0){ - editor.pack("editor-block-" + name + "-full", image); - out.pack("block-" + name + "-full", image); + packer.add(PageType.editor, "editor-block-" + name + "-full", image); + packer.add(PageType.main, "block-" + name + "-full", image); } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java b/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java index de358e7b53..1dff9f636c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java @@ -20,6 +20,7 @@ public class DeflectorWall extends Wall{ public DeflectorWall(String name){ super(name); + entityType = DeflectorEntity::new; } @Override @@ -72,11 +73,6 @@ public class DeflectorWall extends Wall{ ((DeflectorEntity)entity).hit = 1f; } - @Override - public TileEntity newEntity(){ - return new DeflectorEntity(); - } - public static class DeflectorEntity extends TileEntity{ public float hit; } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/Door.java b/core/src/io/anuke/mindustry/world/blocks/defense/Door.java index d10afac6aa..b0c83fba9d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/Door.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/Door.java @@ -31,6 +31,7 @@ public class Door extends Wall{ solid = false; solidifes = true; consumesTap = true; + entityType = DoorEntity::new; } @Remote(called = Loc.server) @@ -89,11 +90,6 @@ public class Door extends Wall{ Call.onDoorToggle(null, tile, !entity.open); } - @Override - public TileEntity newEntity(){ - return new DoorEntity(); - } - public class DoorEntity extends TileEntity{ public boolean open = false; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java index 0ef91424a3..4dce2d9db9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java @@ -54,6 +54,7 @@ public class ForceProjector extends Block{ hasLiquids = true; hasItems = true; consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).boost().update(false); + entityType = ForceEntity::new; } @Override @@ -98,7 +99,7 @@ public class ForceProjector extends Block{ entity.phaseHeat = Mathf.lerpDelta(entity.phaseHeat, Mathf.num(phaseValid), 0.1f); - if(phaseValid && !entity.broken && entity.timer.get(timerUse, phaseUseTime)){ + if(phaseValid && !entity.broken && entity.timer.get(timerUse, phaseUseTime) && entity.efficiency() > 0){ entity.cons.trigger(); } @@ -179,11 +180,6 @@ public class ForceProjector extends Block{ Draw.reset(); } - @Override - public TileEntity newEntity(){ - return new ForceEntity(); - } - class ForceEntity extends TileEntity{ ShieldEntity shield; boolean broken = true; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java index 57488c659a..5ba2461265 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java @@ -38,6 +38,7 @@ public class MendProjector extends Block{ update = true; hasPower = true; hasItems = true; + entityType = MendEntity::new; } @Override @@ -133,8 +134,8 @@ public class MendProjector extends Block{ } @Override - public TileEntity newEntity(){ - return new MendEntity(); + public void drawLight(Tile tile){ + renderer.lights.add(tile.drawx(), tile.drawy(), 50f * tile.entity.efficiency(), color, 0.7f * tile.entity.efficiency()); } class MendEntity extends TileEntity{ diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java index 2b571e04dc..cc8c99a54e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java @@ -37,6 +37,7 @@ public class OverdriveProjector extends Block{ hasPower = true; hasItems = true; canOverdrive = false; + entityType = OverdriveEntity::new; } @Override @@ -66,6 +67,11 @@ public class OverdriveProjector extends Block{ stats.add(BlockStat.boostEffect, (int)((speedBoost + speedBoostPhase) * 100f), StatUnit.percent); } + @Override + public void drawLight(Tile tile){ + renderer.lights.add(tile.drawx(), tile.drawy(), 50f * tile.entity.efficiency(), color, 0.7f * tile.entity.efficiency()); + } + @Override public void update(Tile tile){ OverdriveEntity entity = tile.entity(); @@ -132,11 +138,6 @@ public class OverdriveProjector extends Block{ Draw.reset(); } - @Override - public TileEntity newEntity(){ - return new OverdriveEntity(); - } - class OverdriveEntity extends TileEntity{ float heat; float charge = Mathf.random(reload); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ChargeTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ChargeTurret.java index aa7151df98..3f02328eed 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ChargeTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ChargeTurret.java @@ -1,13 +1,12 @@ package io.anuke.mindustry.world.blocks.defense.turrets; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Effects; -import io.anuke.mindustry.entities.Effects.Effect; -import io.anuke.mindustry.entities.bullet.BulletType; -import io.anuke.mindustry.entities.type.TileEntity; -import io.anuke.mindustry.world.Tile; +import io.anuke.arc.math.*; +import io.anuke.arc.util.*; +import io.anuke.mindustry.content.*; +import io.anuke.mindustry.entities.*; +import io.anuke.mindustry.entities.Effects.*; +import io.anuke.mindustry.entities.bullet.*; +import io.anuke.mindustry.world.*; import static io.anuke.mindustry.Vars.tilesize; @@ -21,6 +20,7 @@ public class ChargeTurret extends PowerTurret{ public ChargeTurret(String name){ super(name); + entityType = LaserTurretEntity::new; } @Override @@ -59,11 +59,6 @@ public class ChargeTurret extends PowerTurret{ return !entity.shooting; } - @Override - public TileEntity newEntity(){ - return new LaserTurretEntity(); - } - public class LaserTurretEntity extends TurretEntity{ public boolean shooting; } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java index 3cce48833e..dca1324e66 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java @@ -28,6 +28,7 @@ public class ItemTurret extends CooledTurret{ public ItemTurret(String name){ super(name); hasItems = true; + entityType = ItemTurretEntity::new; } /** Initializes accepted ammo map. Format: [item1, bullet1, item2, bullet2...] */ @@ -148,11 +149,6 @@ public class ItemTurret extends CooledTurret{ return ammo != null && ammo.get(item) != null && entity.totalAmmo + ammo.get(item).ammoMultiplier <= maxAmmo; } - @Override - public TileEntity newEntity(){ - return new ItemTurretEntity(); - } - public class ItemTurretEntity extends TurretEntity{ @Override public void write(DataOutput stream) throws IOException{ diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java index d6b94f872c..2766e79724 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java @@ -23,6 +23,7 @@ public class LaserTurret extends PowerTurret{ consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.01f)).update(false); coolantMultiplier = 1f; + entityType = LaserTurretEntity::new; } @Override @@ -99,11 +100,6 @@ public class LaserTurret extends PowerTurret{ entity.bulletLife = shootDuration; } - @Override - public TileEntity newEntity(){ - return new LaserTurretEntity(); - } - @Override public boolean shouldActiveSound(Tile tile){ LaserTurretEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java index e0b815d583..05edbe5091 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java @@ -79,6 +79,7 @@ public abstract class Turret extends Block{ group = BlockGroup.turrets; flags = EnumSet.of(BlockFlag.turret); outlineIcon = true; + entityType = TurretEntity::new; } @Override @@ -305,11 +306,6 @@ public abstract class Turret extends Block{ return (tile.entity instanceof TurretEntity); } - @Override - public TileEntity newEntity(){ - return new TurretEntity(); - } - public static abstract class AmmoEntry{ public int amount; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ArmoredConveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ArmoredConveyor.java index fad38034e5..c91c16318b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ArmoredConveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ArmoredConveyor.java @@ -1,6 +1,5 @@ package io.anuke.mindustry.world.blocks.distribution; -import io.anuke.arc.math.geom.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; @@ -16,9 +15,7 @@ public class ArmoredConveyor extends Conveyor{ } @Override - public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ - return otherblock.outputsItems() && (Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, otherx, othery) - || ((!otherblock.rotate && Edges.getFacingEdge(otherblock, otherx, othery, tile) != null && - Edges.getFacingEdge(otherblock, otherx, othery, tile).relativeTo(tile) == rotation) || (otherblock.rotate && Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y)))); + public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock) { + return otherblock.outputsItems() && blendsArmored(tile, rotation, otherx, othery, otherrot, otherblock); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java index 74d47e2c6d..4fc815676d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java @@ -1,10 +1,8 @@ package io.anuke.mindustry.world.blocks.distribution; -import io.anuke.arc.math.Mathf; -import io.anuke.mindustry.entities.type.TileEntity; -import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.world.ItemBuffer; -import io.anuke.mindustry.world.Tile; +import io.anuke.arc.math.*; +import io.anuke.mindustry.type.*; +import io.anuke.mindustry.world.*; import java.io.*; @@ -18,6 +16,7 @@ public class BufferedItemBridge extends ExtendingItemBridge{ super(name); hasPower = false; hasItems = true; + entityType = BufferedItemBridgeEntity::new; } @Override @@ -38,11 +37,6 @@ public class BufferedItemBridge extends ExtendingItemBridge{ } } - @Override - public TileEntity newEntity(){ - return new BufferedItemBridgeEntity(); - } - class BufferedItemBridgeEntity extends ItemBridgeEntity{ ItemBuffer buffer = new ItemBuffer(bufferCapacity, speed); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java index 9a909700e5..e05812d523 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java @@ -43,6 +43,7 @@ public class Conveyor extends Block implements Autotiler{ hasItems = true; itemCapacity = 4; conveyorPlacement = true; + entityType = ConveyorEntity::new; idleSound = Sounds.conveyor; idleSoundVolume = 0.004f; @@ -342,11 +343,6 @@ public class Conveyor extends Block implements Autotiler{ entity.lastInserted = (byte)(entity.convey.size - 1); } - @Override - public TileEntity newEntity(){ - return new ConveyorEntity(); - } - public static class ConveyorEntity extends TileEntity{ LongArray convey = new LongArray(); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java index 89c6d868d9..0d692a504d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java @@ -41,6 +41,7 @@ public class ItemBridge extends Block{ hasItems = true; unloadable = false; group = BlockGroup.transportation; + entityType = ItemBridgeEntity::new; } @Override @@ -174,7 +175,7 @@ public class ItemBridge extends Block{ while(it.hasNext){ int i = it.next(); Tile other = world.tile(i); - if(!linkValid(tile, other, false)){ + if(!linkValid(tile, other, false) || other.entity().link != tile.pos()){ it.remove(); } } @@ -297,7 +298,7 @@ public class ItemBridge extends Block{ @Override public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - if(tile.getTeam() != source.getTeam()) return false; + if(tile.getTeam() != source.getTeam() || !hasLiquids) return false; ItemBridgeEntity entity = tile.entity(); Tile other = world.tile(entity.link); @@ -340,11 +341,6 @@ public class ItemBridge extends Block{ return rel != rel2; } - @Override - public TileEntity newEntity(){ - return new ItemBridgeEntity(); - } - public boolean linkValid(Tile tile, Tile other){ return linkValid(tile, other, true); } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java index e184492864..7877317185 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java @@ -27,6 +27,7 @@ public class Junction extends Block{ instantTransfer = true; group = BlockGroup.transportation; unloadable = false; + entityType = JunctionEntity::new; } @Override @@ -87,11 +88,6 @@ public class Junction extends Block{ return to != null && to.link().entity != null; } - @Override - public TileEntity newEntity(){ - return new JunctionEntity(); - } - class JunctionEntity extends TileEntity{ DirectionalItemBuffer buffer = new DirectionalItemBuffer(capacity, speed); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java index 61caaa5fae..c4a1aba990 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java @@ -42,16 +42,9 @@ public class MassDriver extends Block{ layer = Layer.turret; hasPower = true; outlineIcon = true; + entityType = MassDriverEntity::new; } - /* - @Remote(targets = Loc.both, called = Loc.server, forward = true) - public static void linkMassDriver(Player player, Tile tile, int position){ - if(!Units.canInteract(player, tile)) return; - MassDriverEntity entity = tile.entity(); - entity.link = position; - }*/ - @Override public void configured(Tile tile, Player player, int value){ tile.entity().link = value; @@ -213,11 +206,6 @@ public class MassDriver extends Block{ return tile.entity.items.total() < itemCapacity && linkValid(tile); } - @Override - public TileEntity newEntity(){ - return new MassDriverEntity(); - } - protected void fire(Tile tile, Tile target){ MassDriverEntity entity = tile.entity(); MassDriverEntity other = target.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java b/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java index e1bdc27bd8..b25635e005 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java @@ -19,6 +19,7 @@ public class OverflowGate extends Block{ update = true; group = BlockGroup.transportation; unloadable = false; + entityType = OverflowGateEntity::new; } @Override @@ -108,11 +109,6 @@ public class OverflowGate extends Block{ return to; } - @Override - public TileEntity newEntity(){ - return new OverflowGateEntity(); - } - public class OverflowGateEntity extends TileEntity{ Item lastItem; Tile lastInput; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java index bd92126717..fdff392743 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java @@ -19,6 +19,7 @@ public class Router extends Block{ itemCapacity = 1; group = BlockGroup.transportation; unloadable = false; + entityType = RouterEntity::new; } @Override @@ -82,11 +83,6 @@ public class Router extends Block{ return result; } - @Override - public TileEntity newEntity(){ - return new RouterEntity(); - } - public class RouterEntity extends TileEntity{ Item lastItem; Tile lastInput; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java index 46486bc074..13eb1224e8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java @@ -28,6 +28,7 @@ public class Sorter extends Block{ group = BlockGroup.transportation; configurable = true; unloadable = false; + entityType = SorterEntity::new; } @Override @@ -84,7 +85,7 @@ public class Sorter extends Block{ } boolean isSame(Tile tile, Tile other){ - return other != null && other.block() instanceof Sorter && other.entity().sortItem == tile.entity().sortItem; + return other != null && other.block() instanceof Sorter; } Tile getTileTarget(Item item, Tile dest, Tile source, boolean flip){ @@ -137,12 +138,6 @@ public class Sorter extends Block{ }); } - @Override - public TileEntity newEntity(){ - return new SorterEntity(); - } - - public class SorterEntity extends TileEntity{ @Nullable Item sortItem; diff --git a/core/src/io/anuke/mindustry/world/blocks/liquid/ArmoredConduit.java b/core/src/io/anuke/mindustry/world/blocks/liquid/ArmoredConduit.java new file mode 100644 index 0000000000..7a50ef5f0a --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/liquid/ArmoredConduit.java @@ -0,0 +1,45 @@ +package io.anuke.mindustry.world.blocks.liquid; + +import io.anuke.arc.Core; +import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.graphics.g2d.TextureRegion; +import io.anuke.mindustry.type.Liquid; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Edges; +import io.anuke.mindustry.world.Tile; + +public class ArmoredConduit extends Conduit{ + protected TextureRegion capRegion; + + public ArmoredConduit(String name){ + super(name); + leakResistance = 10f; + } + + @Override + public void load(){ + super.load(); + capRegion = Core.atlas.find(name + "-cap"); + } + + @Override + public void draw(Tile tile){ + super.draw(tile); + + // draw the cap when a conduit would normally leak + Tile next = tile.front(); + if(next != null && next.getTeam() == tile.getTeam() && next.block().hasLiquids) return; + + Draw.rect(capRegion, tile.drawx(), tile.drawy(), tile.rotation() * 90); + } + + @Override + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + return super.acceptLiquid(tile, source, liquid, amount) && (source.block() instanceof Conduit) || Edges.getFacingEdge(source, tile).relativeTo(tile) == tile.rotation(); + } + + @Override + public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ + return otherblock.outputsLiquid && blendsArmored(tile, rotation, otherx, othery, otherrot, otherblock); + } +} diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java b/core/src/io/anuke/mindustry/world/blocks/liquid/Conduit.java similarity index 96% rename from core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java rename to core/src/io/anuke/mindustry/world/blocks/liquid/Conduit.java index 6459c6be68..80c2ab5baf 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java +++ b/core/src/io/anuke/mindustry/world/blocks/liquid/Conduit.java @@ -1,4 +1,4 @@ -package io.anuke.mindustry.world.blocks.distribution; +package io.anuke.mindustry.world.blocks.liquid; import io.anuke.arc.*; import io.anuke.arc.collection.*; @@ -21,12 +21,15 @@ public class Conduit extends LiquidBlock implements Autotiler{ protected TextureRegion[] topRegions = new TextureRegion[7]; protected TextureRegion[] botRegions = new TextureRegion[7]; + protected float leakResistance = 1.5f; + public Conduit(String name){ super(name); rotate = true; solid = false; floating = true; conveyorPlacement = true; + entityType = ConduitEntity::new; } @Override @@ -109,7 +112,7 @@ public class Conduit extends LiquidBlock implements Autotiler{ entity.smoothLiquid = Mathf.lerpDelta(entity.smoothLiquid, entity.liquids.total() / liquidCapacity, 0.05f); if(tile.entity.liquids.total() > 0.001f && tile.entity.timer.get(timerFlow, 1)){ - tryMoveLiquid(tile, tile.getNearby(tile.rotation()), true, tile.entity.liquids.current()); + tryMoveLiquid(tile, tile.getNearby(tile.rotation()), leakResistance, tile.entity.liquids.current()); entity.noSleep(); }else{ entity.sleep(); @@ -128,11 +131,6 @@ public class Conduit extends LiquidBlock implements Autotiler{ && ((source.absoluteRelativeTo(tile.x, tile.y) + 2) % 4 != tile.rotation()); } - @Override - public TileEntity newEntity(){ - return new ConduitEntity(); - } - public static class ConduitEntity extends TileEntity{ public float smoothLiquid; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidBridge.java similarity index 89% rename from core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java rename to core/src/io/anuke/mindustry/world/blocks/liquid/LiquidBridge.java index b676950594..f64a16ba80 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidBridge.java @@ -1,9 +1,10 @@ -package io.anuke.mindustry.world.blocks.distribution; +package io.anuke.mindustry.world.blocks.liquid; import io.anuke.arc.math.*; import io.anuke.arc.util.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.blocks.distribution.*; import io.anuke.mindustry.world.meta.*; import static io.anuke.mindustry.Vars.world; @@ -29,6 +30,8 @@ public class LiquidBridge extends ItemBridge{ if(!linkValid(tile, other)){ tryDumpLiquid(tile, entity.liquids.current()); }else{ + ((ItemBridgeEntity)world.tile(entity.link).entity).incoming.add(tile.pos()); + if(entity.cons.valid()){ float alpha = 0.04f; if(hasPower){ diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidExtendingBridge.java similarity index 88% rename from core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java rename to core/src/io/anuke/mindustry/world/blocks/liquid/LiquidExtendingBridge.java index 53abc6d128..8c82053b7f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidExtendingBridge.java @@ -1,9 +1,10 @@ -package io.anuke.mindustry.world.blocks.distribution; +package io.anuke.mindustry.world.blocks.liquid; import io.anuke.arc.math.*; import io.anuke.arc.util.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.blocks.distribution.*; import io.anuke.mindustry.world.meta.*; import static io.anuke.mindustry.Vars.world; @@ -29,6 +30,8 @@ public class LiquidExtendingBridge extends ExtendingItemBridge{ if(!linkValid(tile, other)){ tryDumpLiquid(tile, entity.liquids.current()); }else{ + ((ItemBridgeEntity)world.tile(entity.link).entity).incoming.add(tile.pos()); + if(entity.cons.valid()){ entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, 0.04f); }else{ diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidJunction.java similarity index 70% rename from core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java rename to core/src/io/anuke/mindustry/world/blocks/liquid/LiquidJunction.java index db5623276f..34cf6c4916 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java +++ b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidJunction.java @@ -1,7 +1,8 @@ -package io.anuke.mindustry.world.blocks.distribution; +package io.anuke.mindustry.world.blocks.liquid; import io.anuke.arc.*; import io.anuke.arc.graphics.g2d.*; +import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.blocks.*; import io.anuke.mindustry.world.meta.*; @@ -35,10 +36,13 @@ public class LiquidJunction extends LiquidBlock{ } @Override - public Tile getLiquidDestination(Tile tile, Tile source){ + public Tile getLiquidDestination(Tile tile, Tile source, Liquid liquid){ int dir = source.relativeTo(tile.x, tile.y); dir = (dir + 4) % 4; Tile next = tile.getNearby(dir).link(); - return next.block().getLiquidDestination(next, tile); + if(!next.block().acceptLiquid(next, tile, liquid, 0f) && !(next.block() instanceof LiquidJunction)){ + return tile; + } + return next.block().getLiquidDestination(next, tile, liquid); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidOverflowGate.java b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidOverflowGate.java new file mode 100644 index 0000000000..dafcef1508 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidOverflowGate.java @@ -0,0 +1,53 @@ +package io.anuke.mindustry.world.blocks.liquid; + +import io.anuke.arc.*; +import io.anuke.arc.graphics.g2d.*; +import io.anuke.mindustry.type.*; +import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.blocks.*; +import io.anuke.mindustry.world.meta.*; + +//TODO implement later +public class LiquidOverflowGate extends LiquidBlock{ + int topRegion; + + public LiquidOverflowGate(String name){ + super(name); + rotate = true; + topRegion = reg("-top"); + } + + @Override + public void setStats(){ + super.setStats(); + stats.remove(BlockStat.liquidCapacity); + } + + @Override + public void setBars(){ + super.setBars(); + bars.remove("liquid"); + } + + @Override + public void draw(Tile tile){ + Draw.rect(name, tile.drawx(), tile.drawy()); + Draw.rect(reg(topRegion), tile.drawx(), tile.drawy(), tile.rotation() * 90); + } + + @Override + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")}; + } + + @Override + public Tile getLiquidDestination(Tile tile, Tile source, Liquid liquid){ + int dir = source.relativeTo(tile.x, tile.y); + dir = (dir + 4) % 4; + Tile next = tile.getNearby(dir).link(); + if(!next.block().acceptLiquid(next, tile, liquid, 0.0001f) && !(next.block() instanceof LiquidOverflowGate || next.block() instanceof LiquidJunction)){ + return tile; + } + return next.block().getLiquidDestination(next, tile, liquid); + } +} diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidRouter.java b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidRouter.java similarity index 92% rename from core/src/io/anuke/mindustry/world/blocks/distribution/LiquidRouter.java rename to core/src/io/anuke/mindustry/world/blocks/liquid/LiquidRouter.java index 52dbe920fd..e5c4103a3c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidRouter.java +++ b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidRouter.java @@ -1,4 +1,4 @@ -package io.anuke.mindustry.world.blocks.distribution; +package io.anuke.mindustry.world.blocks.liquid; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidTank.java b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidTank.java similarity index 67% rename from core/src/io/anuke/mindustry/world/blocks/distribution/LiquidTank.java rename to core/src/io/anuke/mindustry/world/blocks/liquid/LiquidTank.java index c73ab0d2d0..c8303771a6 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidTank.java +++ b/core/src/io/anuke/mindustry/world/blocks/liquid/LiquidTank.java @@ -1,4 +1,4 @@ -package io.anuke.mindustry.world.blocks.distribution; +package io.anuke.mindustry.world.blocks.liquid; public class LiquidTank extends LiquidRouter{ diff --git a/core/src/io/anuke/mindustry/world/blocks/logic/MessageBlock.java b/core/src/io/anuke/mindustry/world/blocks/logic/MessageBlock.java index 0c21c5db15..9b773c6356 100644 --- a/core/src/io/anuke/mindustry/world/blocks/logic/MessageBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/logic/MessageBlock.java @@ -7,14 +7,12 @@ import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.math.geom.*; import io.anuke.arc.scene.ui.*; -import io.anuke.arc.scene.ui.TextField.*; import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.util.*; import io.anuke.arc.util.pooling.*; import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.gen.*; -import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.*; import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.dialogs.*; @@ -33,6 +31,7 @@ public class MessageBlock extends Block{ configurable = true; solid = true; destructible = true; + entityType = MessageBlockEntity::new; } @Remote(targets = Loc.both, called = Loc.both, forward = true) @@ -99,7 +98,7 @@ public class MessageBlock extends Block{ public void buildTable(Tile tile, Table table){ MessageBlockEntity entity = tile.entity(); - table.addImageButton(io.anuke.mindustry.gen.Icon.pencilSmall, () -> { + table.addImageButton(Icon.pencilSmall, () -> { if(mobile){ Core.input.getTextInput(new TextInput(){{ text = entity.message; @@ -147,11 +146,6 @@ public class MessageBlock extends Block{ table.setPosition(pos.x, pos.y, Align.bottom); } - @Override - public TileEntity newEntity(){ - return new MessageBlockEntity(); - } - public class MessageBlockEntity extends TileEntity{ protected String message = ""; protected String[] lines = {""}; diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ImpactReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/ImpactReactor.java index 03ef45e1d0..e1945f1609 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ImpactReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ImpactReactor.java @@ -7,7 +7,6 @@ import io.anuke.arc.math.*; import io.anuke.arc.util.*; import io.anuke.mindustry.content.*; import io.anuke.mindustry.entities.*; -import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.gen.*; import io.anuke.mindustry.graphics.*; @@ -17,7 +16,7 @@ import io.anuke.mindustry.world.meta.*; import java.io.*; -import static io.anuke.mindustry.Vars.tilesize; +import static io.anuke.mindustry.Vars.*; public class ImpactReactor extends PowerGenerator{ protected int timerUse = timers++; @@ -39,6 +38,7 @@ public class ImpactReactor extends PowerGenerator{ liquidCapacity = 30f; hasItems = true; outputsPower = consumesPower = true; + entityType = FusionReactorEntity::new; bottomRegion = reg("-bottom"); plasmaRegions = new int[plasmas]; @@ -117,13 +117,14 @@ public class ImpactReactor extends PowerGenerator{ } @Override - public TextureRegion[] generateIcons(){ - return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name)}; + public void drawLight(Tile tile){ + float fract = tile.entity().warmup; + renderer.lights.add(tile.drawx(), tile.drawy(), (110f + Mathf.absin(5, 5f)) * fract, Tmp.c1.set(plasma2).lerp(plasma1, Mathf.absin(7f, 0.2f)), 0.8f * fract); } @Override - public TileEntity newEntity(){ - return new FusionReactorEntity(); + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name)}; } @Override @@ -132,7 +133,7 @@ public class ImpactReactor extends PowerGenerator{ FusionReactorEntity entity = tile.entity(); - if(entity.warmup < 0.4f) return; + if(entity.warmup < 0.4f || !state.rules.reactorExplosions) return; Sounds.explosionbig.at(tile); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java index d185a9f9cd..07effa5b30 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -8,7 +8,6 @@ import io.anuke.arc.util.*; import io.anuke.mindustry.content.*; import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.Effects.*; -import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.consumers.*; @@ -37,15 +36,15 @@ public class ItemLiquidGenerator extends PowerGenerator{ protected boolean defaults = false; public ItemLiquidGenerator(boolean hasItems, boolean hasLiquids, String name){ - super(name); + this(name); this.hasItems = hasItems; this.hasLiquids = hasLiquids; - setDefaults(); } public ItemLiquidGenerator(String name){ super(name); + this.entityType = ItemLiquidGeneratorEntity::new; } protected void setDefaults(){ @@ -140,7 +139,7 @@ public class ItemLiquidGenerator extends PowerGenerator{ if(entity.generateTime > 0f){ entity.generateTime -= Math.min(1f / itemDuration * entity.delta(), entity.generateTime); - if(randomlyExplode && Mathf.chance(entity.delta() * 0.06 * Mathf.clamp(entity.explosiveness - 0.5f))){ + if(randomlyExplode && state.rules.reactorExplosions && Mathf.chance(entity.delta() * 0.06 * Mathf.clamp(entity.explosiveness - 0.5f))){ //this block is run last so that in the event of a block destruction, no code relies on the block type Core.app.post(() -> { entity.damage(Mathf.random(11f)); @@ -174,6 +173,13 @@ public class ItemLiquidGenerator extends PowerGenerator{ } } + @Override + public void drawLight(Tile tile){ + ItemLiquidGeneratorEntity entity = tile.entity(); + + renderer.lights.add(tile.drawx(), tile.drawy(), (60f + Mathf.absin(10f, 5f)) * entity.productionEfficiency * size, Color.orange, 0.5f); + } + protected float getItemEfficiency(Item item){ return 0.0f; } @@ -182,11 +188,6 @@ public class ItemLiquidGenerator extends PowerGenerator{ return 0.0f; } - @Override - public TileEntity newEntity(){ - return new ItemLiquidGeneratorEntity(); - } - public static class ItemLiquidGeneratorEntity extends GeneratorEntity{ public float explosiveness; public float heat; diff --git a/core/src/io/anuke/mindustry/world/blocks/power/LightBlock.java b/core/src/io/anuke/mindustry/world/blocks/power/LightBlock.java new file mode 100644 index 0000000000..0fc61676f2 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/power/LightBlock.java @@ -0,0 +1,95 @@ +package io.anuke.mindustry.world.blocks.power; + +import io.anuke.arc.graphics.*; +import io.anuke.arc.graphics.g2d.*; +import io.anuke.arc.scene.ui.layout.*; +import io.anuke.arc.util.*; +import io.anuke.mindustry.entities.type.*; +import io.anuke.mindustry.gen.*; +import io.anuke.mindustry.graphics.*; +import io.anuke.mindustry.world.*; + +import java.io.*; + +import static io.anuke.mindustry.Vars.*; + +public class LightBlock extends Block{ + private static int lastColor = 0; + + protected float brightness = 0.9f; + protected float radius = 200f; + protected int topRegion; + + public LightBlock(String name){ + super(name); + hasPower = true; + update = true; + topRegion = reg("-top"); + configurable = true; + entityType = LightEntity::new; + } + + @Override + public void playerPlaced(Tile tile){ + if(lastColor != 0){ + tile.configure(lastColor); + } + } + + @Override + public void draw(Tile tile){ + super.draw(tile); + LightEntity entity = tile.entity(); + + Draw.blend(Blending.additive); + Draw.color(Tmp.c1.set(entity.color), entity.efficiency() * 0.3f); + Draw.rect(reg(topRegion), tile.drawx(), tile.drawy()); + Draw.color(); + Draw.blend(); + } + + @Override + public void buildTable(Tile tile, Table table){ + LightEntity entity = tile.entity(); + + table.addImageButton(Icon.pencilSmall, () -> { + ui.picker.show(Tmp.c1.set(entity.color).a(0.5f), false, res -> { + entity.color = res.rgba(); + lastColor = entity.color; + }); + control.input.frag.config.hideConfig(); + }).size(40f); + } + + @Override + public void configured(Tile tile, Player player, int value){ + tile.entity().color = value; + } + + @Override + public void drawLight(Tile tile){ + LightEntity entity = tile.entity(); + renderer.lights.add(tile.drawx(), tile.drawy(), radius, Tmp.c1.set(entity.color), brightness * tile.entity.efficiency()); + } + + public class LightEntity extends TileEntity{ + public int color = Pal.accent.rgba(); + + @Override + public int config(){ + return color; + } + + @Override + public void write(DataOutput stream) throws IOException{ + super.write(stream); + stream.writeInt(color); + } + + @Override + public void read(DataInput stream, byte revision) throws IOException{ + super.read(stream, revision); + color = stream.readInt(); + } + } +} diff --git a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java index 9a1d12ac39..2aa478a3bf 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java @@ -1,35 +1,32 @@ package io.anuke.mindustry.world.blocks.power; import io.anuke.arc.*; -import io.anuke.arc.graphics.Color; +import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.g2d.*; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.math.geom.Vector2; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Damage; -import io.anuke.mindustry.entities.Effects; -import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.arc.math.*; +import io.anuke.arc.math.geom.*; +import io.anuke.arc.util.*; +import io.anuke.mindustry.content.*; +import io.anuke.mindustry.entities.*; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.gen.*; -import io.anuke.mindustry.graphics.Pal; -import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Liquid; -import io.anuke.mindustry.ui.Bar; -import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.graphics.*; +import io.anuke.mindustry.type.*; +import io.anuke.mindustry.ui.*; +import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.consumers.*; -import io.anuke.mindustry.world.meta.BlockStat; -import io.anuke.mindustry.world.meta.StatUnit; +import io.anuke.mindustry.world.meta.*; import java.io.*; -import static io.anuke.mindustry.Vars.tilesize; +import static io.anuke.mindustry.Vars.*; public class NuclearReactor extends PowerGenerator{ protected final int timerFuel = timers++; protected final Vector2 tr = new Vector2(); + protected Color lightColor = Color.valueOf("7f19ea"); protected Color coolColor = new Color(1, 1, 1, 0f); protected Color hotColor = Color.valueOf("ff9575a3"); protected float itemDuration = 120; //time to consume 1 fuel @@ -48,6 +45,7 @@ public class NuclearReactor extends PowerGenerator{ liquidCapacity = 30; hasItems = true; hasLiquids = true; + entityType = NuclearReactorEntity::new; } @Override @@ -93,10 +91,9 @@ public class NuclearReactor extends PowerGenerator{ } Liquid liquid = cliquid.liquid; - float liquidAmount = cliquid.amount; if(entity.heat > 0){ - float maxUsed = Math.min(Math.min(entity.liquids.get(liquid), entity.heat / coolantPower), liquidAmount * entity.delta()); + float maxUsed = Math.min(entity.liquids.get(liquid), entity.heat / coolantPower); entity.heat -= maxUsed * coolantPower; entity.liquids.remove(liquid, maxUsed); } @@ -127,7 +124,7 @@ public class NuclearReactor extends PowerGenerator{ int fuel = entity.items.get(consumes.get(ConsumeType.item).items[0].item); - if(fuel < 5 && entity.heat < 0.5f) return; + if((fuel < 5 && entity.heat < 0.5f) || !state.rules.reactorExplosions) return; Effects.shake(6f, 16f, tile.worldx(), tile.worldy()); Effects.effect(Fx.nuclearShockwave, tile.worldx(), tile.worldy()); @@ -152,6 +149,13 @@ public class NuclearReactor extends PowerGenerator{ } } + @Override + public void drawLight(Tile tile){ + NuclearReactorEntity entity = tile.entity(); + float fract = entity.productionEfficiency; + renderer.lights.add(tile.drawx(), tile.drawy(), (90f + Mathf.absin(5, 5f)) * fract, Tmp.c1.set(lightColor).lerp(Color.scarlet, entity.heat), 0.6f * fract); + } + @Override public void draw(Tile tile){ super.draw(tile); @@ -176,11 +180,6 @@ public class NuclearReactor extends PowerGenerator{ Draw.reset(); } - @Override - public TileEntity newEntity(){ - return new NuclearReactorEntity(); - } - public static class NuclearReactorEntity extends GeneratorEntity{ public float heat; public float flash; diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerDiode.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerDiode.java index 3d2f76d08c..08d621a09c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerDiode.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerDiode.java @@ -27,7 +27,7 @@ public class PowerDiode extends Block{ public void update(Tile tile){ super.update(tile); - if(!tile.back().block().hasPower || !tile.front().block().hasPower) return; + if(tile.front() == null || tile.back() == null || !tile.back().block().hasPower || !tile.front().block().hasPower) return; PowerGraph backGraph = tile.back().entity.power.graph; PowerGraph frontGraph = tile.front().entity.power.graph; @@ -51,15 +51,15 @@ public class PowerDiode extends Block{ // battery % of the graph on either side, defaults to zero protected float bar(Tile tile){ - return tile.block().hasPower ? tile.entity.power.graph.getBatteryStored() / tile.entity.power.graph.getTotalBatteryCapacity() : 0f; + return (tile != null && tile.block().hasPower) ? tile.entity.power.graph.getBatteryStored() / tile.entity.power.graph.getTotalBatteryCapacity() : 0f; } @Override public void setBars(){ super.setBars(); - bars.add("back", entity -> new Bar("bar.input", Pal.lighterOrange, () -> bar(entity.tile.back())) ); - bars.add("front", entity -> new Bar("bar.output", Pal.lighterOrange, () -> bar(entity.tile.front())) ); + bars.add("back", entity -> new Bar("bar.input", Pal.powerBar, () -> bar(entity.tile.back()))); + bars.add("front", entity -> new Bar("bar.output", Pal.powerBar, () -> bar(entity.tile.front()))); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java index f4e1597445..9f0f21f008 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java @@ -20,6 +20,7 @@ public class PowerGenerator extends PowerDistributor{ super(name); baseExplosiveness = 5f; flags = EnumSet.of(BlockFlag.producer); + entityType = GeneratorEntity::new; } @Override @@ -51,11 +52,6 @@ public class PowerGenerator extends PowerDistributor{ return false; } - @Override - public TileEntity newEntity(){ - return new GeneratorEntity(); - } - public static class GeneratorEntity extends TileEntity{ public float generateTime; /** The efficiency of the producer. An efficiency of 1.0 means 100% */ diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java index 07ebe96040..b5d29266ac 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -1,11 +1,10 @@ package io.anuke.mindustry.world.blocks.power; -import io.anuke.arc.Core; +import io.anuke.arc.*; import io.anuke.arc.collection.*; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.math.WindowedMean; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.world.Tile; +import io.anuke.arc.math.*; +import io.anuke.arc.util.*; +import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.consumers.*; public class PowerGraph{ @@ -181,6 +180,7 @@ public class PowerGraph{ tile.entity.power.status = 1f; } + lastPowerNeeded = lastPowerProduced = 1f; return; } @@ -192,21 +192,22 @@ public class PowerGraph{ lastPowerNeeded = powerNeeded; lastPowerProduced = powerProduced; - powerBalance.addValue((powerProduced - powerNeeded) / Time.delta()); + if(!(consumers.size == 0 && producers.size == 0 && batteries.size == 0)){ - if(consumers.size == 0 && producers.size == 0 && batteries.size == 0){ - return; - } - - if(!Mathf.equal(powerNeeded, powerProduced)){ - if(powerNeeded > powerProduced){ - powerProduced += useBatteries(powerNeeded - powerProduced); - }else if(powerProduced > powerNeeded){ - powerProduced -= chargeBatteries(powerProduced - powerNeeded); + if(!Mathf.equal(powerNeeded, powerProduced)){ + if(powerNeeded > powerProduced){ + float powerBatteryUsed = useBatteries(powerNeeded - powerProduced); + powerProduced += powerBatteryUsed; + lastPowerProduced += powerBatteryUsed; + }else if(powerProduced > powerNeeded){ + powerProduced -= chargeBatteries(powerProduced - powerNeeded); + } } + + distributePower(powerNeeded, powerProduced); } - distributePower(powerNeeded, powerProduced); + powerBalance.addValue((lastPowerProduced - lastPowerNeeded) / Time.delta()); } public void add(PowerGraph graph){ diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java index 6a5d1e9c11..8c3002c417 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java @@ -91,7 +91,7 @@ public class PowerNode extends PowerBlock{ Core.bundle.format("bar.powerbalance", ((entity.power.graph.getPowerBalance() >= 0 ? "+" : "") + Strings.fixed(entity.power.graph.getPowerBalance() * 60, 1))), () -> Pal.powerBar, - () -> Mathf.clamp(entity.power.graph.getPowerProduced() / entity.power.graph.getPowerNeeded()))); + () -> Mathf.clamp(entity.power.graph.getLastPowerProduced() / entity.power.graph.getLastPowerNeeded()))); bars.add("batteries", entity -> new Bar(() -> Core.bundle.format("bar.powerstored", diff --git a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java index fd8f9cf642..4844fc2297 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java @@ -1,8 +1,10 @@ package io.anuke.mindustry.world.blocks.power; -import io.anuke.arc.collection.EnumSet; -import io.anuke.mindustry.entities.type.TileEntity; -import io.anuke.mindustry.world.meta.StatUnit; +import io.anuke.arc.collection.*; +import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.meta.*; + +import static io.anuke.mindustry.Vars.state; public class SolarGenerator extends PowerGenerator{ @@ -10,6 +12,12 @@ public class SolarGenerator extends PowerGenerator{ super(name); // Remove the BlockFlag.producer flag to make this a lower priority target than other generators. flags = EnumSet.of(); + entityType = GeneratorEntity::new; + } + + @Override + public void update(Tile tile){ + tile.entity().productionEfficiency = state.rules.lighting ? 1f - state.rules.ambientLight.a : 1f; } @Override @@ -19,12 +27,4 @@ public class SolarGenerator extends PowerGenerator{ stats.remove(generationType); stats.add(generationType, powerProduction * 60.0f, StatUnit.powerSecond); } - - @Override - public TileEntity newEntity(){ - return new PowerGenerator.GeneratorEntity(){{ - productionEfficiency = 1.0f; - }}; - } - } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ThermalGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ThermalGenerator.java index 2415a84578..b2d9576718 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ThermalGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ThermalGenerator.java @@ -1,12 +1,15 @@ package io.anuke.mindustry.world.blocks.power; -import io.anuke.arc.Core; -import io.anuke.arc.math.Mathf; -import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Effects; -import io.anuke.mindustry.entities.Effects.Effect; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.meta.Attribute; +import io.anuke.arc.*; +import io.anuke.arc.graphics.*; +import io.anuke.arc.math.*; +import io.anuke.mindustry.content.*; +import io.anuke.mindustry.entities.*; +import io.anuke.mindustry.entities.Effects.*; +import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.meta.*; + +import static io.anuke.mindustry.Vars.renderer; public class ThermalGenerator extends PowerGenerator{ protected Effect generateEffect = Fx.none; @@ -29,6 +32,12 @@ public class ThermalGenerator extends PowerGenerator{ drawPlaceText(Core.bundle.formatFloat("bar.efficiency", sumAttribute(Attribute.heat, x, y) * 100, 1), x, y, valid); } + @Override + public void drawLight(Tile tile){ + GeneratorEntity entity = tile.entity(); + renderer.lights.add(tile.drawx(), tile.drawy(), (40f + Mathf.absin(10f, 5f)) * entity.productionEfficiency * size, Color.scarlet, 0.4f); + } + @Override public void onProximityAdded(Tile tile){ super.onProximityAdded(tile); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java index 62bdef1e2d..c3901d435c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java @@ -28,6 +28,7 @@ public class Cultivator extends GenericCrafter{ public Cultivator(String name){ super(name); craftEffect = Fx.none; + entityType = CultivatorEntity::new; } @Override @@ -94,11 +95,6 @@ public class Cultivator extends GenericCrafter{ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top"),}; } - @Override - public TileEntity newEntity(){ - return new CultivatorEntity(); - } - @Override public void onProximityAdded(Tile tile){ super.onProximityAdded(tile); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java index d3756dbd35..309761830b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java @@ -66,6 +66,7 @@ public class Drill extends Block{ hasLiquids = true; liquidCapacity = 5f; hasItems = true; + entityType = DrillEntity::new; idleSound = Sounds.drill; idleSoundVolume = 0.003f; @@ -133,6 +134,11 @@ public class Drill extends Block{ return tile.entity.items.total() < itemCapacity; } + @Override + public boolean shouldIdleSound(Tile tile){ + return tile.entity.efficiency() > 0.01f; + } + @Override public void drawPlace(int x, int y, int rotation, boolean valid){ Tile tile = world.tile(x, y); @@ -300,11 +306,6 @@ public class Drill extends Block{ } } - @Override - public TileEntity newEntity(){ - return new DrillEntity(); - } - public int tier(){ return tier; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java index 3e77f8f666..deb606eedd 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java @@ -2,7 +2,6 @@ package io.anuke.mindustry.world.blocks.production; import io.anuke.arc.*; import io.anuke.arc.graphics.g2d.*; -import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.meta.*; @@ -16,6 +15,7 @@ public class Fracker extends SolidPump{ public Fracker(String name){ super(name); hasItems = true; + entityType = FrackerEntity::new; } @Override @@ -85,11 +85,6 @@ public class Fracker extends SolidPump{ } } - @Override - public TileEntity newEntity(){ - return new FrackerEntity(); - } - @Override public float typeLiquid(Tile tile){ return tile.entity.liquids.get(result); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java index 5ee91e3f01..1878ada116 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java @@ -36,6 +36,7 @@ public class GenericCrafter extends Block{ health = 60; idleSound = Sounds.machine; idleSoundVolume = 0.03f; + entityType = GenericCrafterEntity::new; } @Override @@ -142,11 +143,6 @@ public class GenericCrafter extends Block{ return outputLiquid == null || !(tile.entity.liquids.get(outputLiquid.liquid) >= liquidCapacity); } - @Override - public TileEntity newEntity(){ - return new GenericCrafterEntity(); - } - @Override public int getMaximumAccepted(Tile tile, Item item){ return itemCapacity; diff --git a/core/src/io/anuke/mindustry/world/blocks/production/GenericSmelter.java b/core/src/io/anuke/mindustry/world/blocks/production/GenericSmelter.java index 576236cd53..828decc1e0 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/GenericSmelter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/GenericSmelter.java @@ -1,11 +1,13 @@ package io.anuke.mindustry.world.blocks.production; -import io.anuke.arc.Core; -import io.anuke.arc.graphics.Color; +import io.anuke.arc.*; +import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.g2d.*; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.world.Tile; +import io.anuke.arc.math.*; +import io.anuke.arc.util.*; +import io.anuke.mindustry.world.*; + +import static io.anuke.mindustry.Vars.renderer; /** A GenericCrafter with a new glowing region drawn on top. */ public class GenericSmelter extends GenericCrafter{ @@ -45,4 +47,11 @@ public class GenericSmelter extends GenericCrafter{ Draw.color(); } } + + @Override + public void drawLight(Tile tile){ + GenericCrafterEntity entity = tile.entity(); + + renderer.lights.add(tile.drawx(), tile.drawy(), (60f + Mathf.absin(10f, 5f)) * entity.warmup * size, flameColor, 0.65f); + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java b/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java index 7e28b8bc67..fce368f246 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java @@ -24,6 +24,7 @@ public class Incinerator extends Block{ hasLiquids = true; update = true; solid = true; + entityType = IncineratorEntity::new; } @Override @@ -84,11 +85,6 @@ public class Incinerator extends Block{ return entity.heat > 0.5f; } - @Override - public TileEntity newEntity(){ - return new IncineratorEntity(); - } - public static class IncineratorEntity extends TileEntity{ public float heat; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/LiquidConverter.java b/core/src/io/anuke/mindustry/world/blocks/production/LiquidConverter.java index 6fa9477e69..6908ad4176 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/LiquidConverter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/LiquidConverter.java @@ -32,6 +32,13 @@ public class LiquidConverter extends GenericCrafter{ stats.add(BlockStat.output, outputLiquid.liquid, outputLiquid.amount * craftTime, false); } + @Override + public void drawLight(Tile tile){ + if(hasLiquids && drawLiquidLight && outputLiquid.liquid.lightColor.a > 0.001f){ + drawLiquidLight(tile, outputLiquid.liquid, tile.entity.liquids.get(outputLiquid.liquid)); + } + } + @Override public void update(Tile tile){ GenericCrafterEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Separator.java b/core/src/io/anuke/mindustry/world/blocks/production/Separator.java index b7813c5b4f..bd3f98966b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Separator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Separator.java @@ -1,21 +1,15 @@ package io.anuke.mindustry.world.blocks.production; -import io.anuke.arc.graphics.Color; -import io.anuke.arc.graphics.g2d.Draw; -import io.anuke.arc.graphics.g2d.Lines; -import io.anuke.arc.math.Mathf; +import io.anuke.arc.graphics.*; +import io.anuke.arc.graphics.g2d.*; +import io.anuke.arc.math.*; import io.anuke.arc.util.ArcAnnotate.*; -import io.anuke.mindustry.entities.type.TileEntity; -import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.production.GenericCrafter.GenericCrafterEntity; -import io.anuke.mindustry.world.consumers.ConsumeLiquidBase; -import io.anuke.mindustry.world.consumers.ConsumeType; -import io.anuke.mindustry.world.meta.BlockStat; -import io.anuke.mindustry.world.meta.StatUnit; -import io.anuke.mindustry.world.meta.values.ItemFilterValue; +import io.anuke.mindustry.type.*; +import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.blocks.production.GenericCrafter.*; +import io.anuke.mindustry.world.consumers.*; +import io.anuke.mindustry.world.meta.*; +import io.anuke.mindustry.world.meta.values.*; /** * Extracts a random list of items from an input item and an input liquid. @@ -39,6 +33,7 @@ public class Separator extends Block{ hasLiquids = true; liquidRegion = reg("-liquid"); + entityType = GenericCrafterEntity::new; } @Override @@ -123,9 +118,4 @@ public class Separator extends Block{ tryDump(tile); } } - - @Override - public TileEntity newEntity(){ - return new GenericCrafterEntity(); - } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java index efe34f5dfb..bb6cb397cf 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java @@ -30,6 +30,7 @@ public class SolidPump extends Pump{ public SolidPump(String name){ super(name); hasPower = true; + entityType = SolidPumpEntity::new; } @Override @@ -42,7 +43,7 @@ public class SolidPump extends Pump{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ if(attribute != null){ - drawPlaceText(Core.bundle.formatFloat("bar.efficiency", (sumAttribute(attribute, x, y) + 1f) * 100, 1), x, y, valid); + drawPlaceText(Core.bundle.formatFloat("bar.efficiency", (sumAttribute(attribute, x, y) + 1f) * 100 * percentSolid(x, y), 1), x, y, valid); } } @@ -51,7 +52,7 @@ public class SolidPump extends Pump{ super.setBars(); bars.add("efficiency", entity -> new Bar(() -> Core.bundle.formatFloat("bar.efficiency", - ((((SolidPumpEntity)entity).boost + 1f) * ((SolidPumpEntity)entity).warmup) * 100, 1), + ((((SolidPumpEntity)entity).boost + 1f) * ((SolidPumpEntity)entity).warmup) * 100 * percentSolid(entity.tile.x, entity.tile.y), 1), () -> Pal.ammo, () -> ((SolidPumpEntity)entity).warmup)); } @@ -134,11 +135,6 @@ public class SolidPump extends Pump{ return tile != null && !tile.floor().isLiquid; } - @Override - public TileEntity newEntity(){ - return new SolidPumpEntity(); - } - @Override public void onProximityAdded(Tile tile){ super.onProximityAdded(tile); diff --git a/core/src/io/anuke/mindustry/world/blocks/sandbox/ItemSource.java b/core/src/io/anuke/mindustry/world/blocks/sandbox/ItemSource.java index 332c8c6d67..d38c9dc432 100644 --- a/core/src/io/anuke/mindustry/world/blocks/sandbox/ItemSource.java +++ b/core/src/io/anuke/mindustry/world/blocks/sandbox/ItemSource.java @@ -25,6 +25,7 @@ public class ItemSource extends Block{ solid = true; group = BlockGroup.transportation; configurable = true; + entityType = ItemSourceEntity::new; } @Override @@ -91,11 +92,6 @@ public class ItemSource extends Block{ return false; } - @Override - public TileEntity newEntity(){ - return new ItemSourceEntity(); - } - public class ItemSourceEntity extends TileEntity{ Item outputItem; diff --git a/core/src/io/anuke/mindustry/world/blocks/sandbox/LiquidSource.java b/core/src/io/anuke/mindustry/world/blocks/sandbox/LiquidSource.java index df34b54342..5513f462ec 100644 --- a/core/src/io/anuke/mindustry/world/blocks/sandbox/LiquidSource.java +++ b/core/src/io/anuke/mindustry/world/blocks/sandbox/LiquidSource.java @@ -31,6 +31,7 @@ public class LiquidSource extends Block{ liquidCapacity = 100f; configurable = true; outputsLiquid = true; + entityType = LiquidSourceEntity::new; } @Override @@ -106,11 +107,6 @@ public class LiquidSource extends Block{ table.add(cont); } - @Override - public TileEntity newEntity(){ - return new LiquidSourceEntity(); - } - @Override public void configured(Tile tile, Player player, int value){ tile.entity().source = value == -1 ? null : content.liquid(value); diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java index b5d7188d02..c164e7011e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -36,6 +36,7 @@ public class CoreBlock extends StorageBlock{ activeSound = Sounds.respawning; activeSoundVolume = 1f; layer = Layer.overlay; + entityType = CoreEntity::new; } @Remote(called = Loc.server) @@ -63,6 +64,11 @@ public class CoreBlock extends StorageBlock{ )); } + @Override + public void drawLight(Tile tile){ + renderer.lights.add(tile.drawx(), tile.drawy(), 30f * size, Pal.accent, 0.5f + Mathf.absin(20f, 0.1f)); + } + @Override public boolean acceptItem(Item item, Tile tile, Tile source){ return tile.entity.items.get(item) < getMaximumAccepted(tile, item); @@ -224,11 +230,6 @@ public class CoreBlock extends StorageBlock{ return entity.spawnPlayer != null; } - @Override - public TileEntity newEntity(){ - return new CoreEntity(); - } - public class CoreEntity extends TileEntity implements SpawnerTrait{ protected Player spawnPlayer; protected float progress; diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java b/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java index 6473e1c18e..47973a9a8b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java @@ -80,6 +80,7 @@ public class LaunchPad extends StorageBlock{ int used = Math.min(entity.items.get(item), itemCapacity); data.addItem(item, used); entity.items.remove(item, used); + Events.fire(new LaunchItemEvent(item, used)); } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java index aa177b1caf..7746932916 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java @@ -11,6 +11,7 @@ public abstract class StorageBlock extends Block{ public StorageBlock(String name){ super(name); hasItems = true; + entityType = StorageBlockEntity::new; } @Override @@ -69,11 +70,6 @@ public abstract class StorageBlock extends Block{ } } - @Override - public TileEntity newEntity(){ - return new StorageBlockEntity(); - } - public class StorageBlockEntity extends TileEntity{ protected @Nullable Tile linkedCore; diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java b/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java index 5c7ce01bf6..f67701d4d5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java @@ -27,6 +27,7 @@ public class Unloader extends Block{ health = 70; hasItems = true; configurable = true; + entityType = UnloaderEntity::new; } @Override @@ -128,11 +129,6 @@ public class Unloader extends Block{ }); } - @Override - public TileEntity newEntity(){ - return new UnloaderEntity(); - } - public static class UnloaderEntity extends TileEntity{ public Item sortItem = null; diff --git a/core/src/io/anuke/mindustry/world/blocks/units/CommandCenter.java b/core/src/io/anuke/mindustry/world/blocks/units/CommandCenter.java index 01487f6b44..d44b966493 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/CommandCenter.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/CommandCenter.java @@ -36,6 +36,7 @@ public class CommandCenter extends Block{ destructible = true; solid = true; configurable = true; + entityType = CommandCenterEntity::new; } @Override @@ -122,11 +123,6 @@ public class CommandCenter extends Block{ Events.fire(new CommandIssueEvent(tile, command)); } - @Override - public TileEntity newEntity(){ - return new CommandCenterEntity(); - } - public class CommandCenterEntity extends TileEntity{ public UnitCommand command = UnitCommand.attack; diff --git a/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java b/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java index 1c82bed65c..ef7314e00b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java @@ -35,6 +35,7 @@ public class MechPad extends Block{ hasPower = true; layer = Layer.overlay; flags = EnumSet.of(BlockFlag.mechPad); + entityType = MechFactoryEntity::new; } @Override @@ -134,11 +135,6 @@ public class MechPad extends Block{ } } - @Override - public TileEntity newEntity(){ - return new MechFactoryEntity(); - } - public class MechFactoryEntity extends TileEntity implements SpawnerTrait{ Player player; boolean sameMech; diff --git a/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java b/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java index 917f2748d6..6c5e8698b2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java @@ -36,6 +36,7 @@ public class RepairPoint extends Block{ layer2 = Layer.power; hasPower = true; outlineIcon = true; + entityType = RepairPointEntity::new; } @Override @@ -126,11 +127,6 @@ public class RepairPoint extends Block{ return entity.target != null; } - @Override - public TileEntity newEntity(){ - return new RepairPointEntity(); - } - public class RepairPointEntity extends TileEntity{ public Unit target; public float strength, rotation = 90; diff --git a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java index 2747093746..678d43c10f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java @@ -41,6 +41,7 @@ public class UnitFactory extends Block{ hasItems = true; solid = false; flags = EnumSet.of(BlockFlag.producer); + entityType = UnitFactoryEntity::new; } @Remote(called = Loc.server) @@ -175,16 +176,12 @@ public class UnitFactory extends Block{ entity.cons.trigger(); } } + @Override public int getMaximumAccepted(Tile tile, Item item){ return capacities[item.id]; } - @Override - public TileEntity newEntity(){ - return new UnitFactoryEntity(); - } - @Override public boolean shouldConsume(Tile tile){ UnitFactoryEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/meta/BuildVisibility.java b/core/src/io/anuke/mindustry/world/meta/BuildVisibility.java index 9006d51b09..6197312ebc 100644 --- a/core/src/io/anuke/mindustry/world/meta/BuildVisibility.java +++ b/core/src/io/anuke/mindustry/world/meta/BuildVisibility.java @@ -8,7 +8,8 @@ public enum BuildVisibility{ shown(() -> true), debugOnly(() -> false), sandboxOnly(() -> Vars.state.rules.infiniteResources), - campaignOnly(() -> Vars.world.isZone()); + campaignOnly(() -> Vars.world.isZone()), + lightingOnly(() -> Vars.state.rules.lighting); private final Boolp visible; diff --git a/core/src/io/anuke/mindustry/world/modules/LiquidModule.java b/core/src/io/anuke/mindustry/world/modules/LiquidModule.java index 3eb50fc8e4..e597be1b66 100644 --- a/core/src/io/anuke/mindustry/world/modules/LiquidModule.java +++ b/core/src/io/anuke/mindustry/world/modules/LiquidModule.java @@ -1,5 +1,6 @@ package io.anuke.mindustry.world.modules; +import io.anuke.arc.math.*; import io.anuke.mindustry.type.Liquid; import java.io.*; @@ -11,6 +12,15 @@ public class LiquidModule extends BlockModule{ private float[] liquids = new float[content.liquids().size]; private float total; private Liquid current = content.liquid(0); + private float smoothLiquid; + + public void update(){ + smoothLiquid = Mathf.lerpDelta(smoothLiquid, currentAmount(), 0.1f); + } + + public float smoothAmount(){ + return smoothLiquid; + } /** Returns total amount of liquids. */ public float total(){ @@ -54,7 +64,7 @@ public class LiquidModule extends BlockModule{ add(liquid, -amount); } - public void forEach(LiquidConsumer cons){ + public void each(LiquidConsumer cons){ for(int i = 0; i < liquids.length; i++){ if(liquids[i] > 0){ cons.accept(content.liquid(i), liquids[i]); diff --git a/desktop/build.gradle b/desktop/build.gradle index f8af30311c..c9bc28a869 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -151,7 +151,7 @@ PackrConfig.Platform.values().each{ platform -> include "${lib}steamworks4j${platform == PackrConfig.Platform.Windows64 ? '64.dll' : platform == PackrConfig.Platform.Windows32 ? '.dll' : platform == PackrConfig.Platform.Linux64 ? '.so' : '.dylib'}" include "${lib}steam_api${platform == PackrConfig.Platform.Windows64 ? '64.dll' : platform == PackrConfig.Platform.Windows32 ? '.dll' : platform == PackrConfig.Platform.Linux64 ? '.so' : '.dylib'}" } - into "build/packr/output/" + into platform != PackrConfig.Platform.MacOS ? "build/packr/output/" : "build/packr/output/${appName}.app/Contents/Resources" } } diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SStats.java b/desktop/src/io/anuke/mindustry/desktop/steam/SStats.java index d7678d7a92..7c083d5546 100644 --- a/desktop/src/io/anuke/mindustry/desktop/steam/SStats.java +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SStats.java @@ -195,17 +195,15 @@ public class SStats implements SteamUserStatsCallback{ }); Events.on(LaunchEvent.class, e -> { - int total = 0; - for(Item item : Vars.content.items()){ - total += Vars.state.stats.itemsDelivered.get(item, 0); - } - if(state.rules.tutorial){ completeTutorial.complete(); } SStat.timesLaunched.add(); - SStat.itemsLaunched.add(total); + }); + + Events.on(LaunchItemEvent.class, e -> { + SStat.itemsLaunched.add(e.stack.amount); }); Events.on(WaveEvent.class, e -> { diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java b/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java index 170e014a18..8f12e22ca9 100644 --- a/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java @@ -39,7 +39,7 @@ public class SWorkshop implements SteamUGCCallback{ workshopFiles.put(Map.class, folders.select(f -> f.list().length == 1 && f.list()[0].extension().equals(mapExtension)).map(f -> f.list()[0])); workshopFiles.put(Schematic.class, folders.select(f -> f.list().length == 1 && f.list()[0].extension().equals(schematicExtension)).map(f -> f.list()[0])); - workshopFiles.put(LoadedMod.class, folders.select(f -> f.child("mod.json").exists())); + workshopFiles.put(LoadedMod.class, folders.select(f -> f.child("mod.json").exists() || f.child("mod.hjson").exists())); if(!workshopFiles.get(Map.class).isEmpty()){ SAchievement.downloadMapWorkshop.complete(); diff --git a/fastlane/metadata/android/en-US/changelogs/100.1.txt b/fastlane/metadata/android/en-US/changelogs/100.1.txt new file mode 100644 index 0000000000..53c981258b --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100.1.txt @@ -0,0 +1,5 @@ +- Added fallback mod loading for poorly formatted old mods +- Fixed infinite building range +- Fixed impact reactors being able to blow up core on servers +- Fixed liquid bridges passing backwards +- Updated various translations diff --git a/fastlane/metadata/android/en-US/changelogs/100.txt b/fastlane/metadata/android/en-US/changelogs/100.txt new file mode 100644 index 0000000000..362a138fae --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100.txt @@ -0,0 +1,9 @@ +- Added experimental lighting system - can be enabled in custom game rules +- Added power diode block (Contributed by Quezler) +- Added plated conduit block (Contributed by Quezler) +- Added light block for dark maps only +- Improved pulse conduit speed (Contributed by Quezler) +- Improved building priority +- New permissive mod parsing format (HJSON) +- Fixed a few incorrect consumption displays in blocks +- Fixed 'underwater' ores in editor diff --git a/fastlane/metadata/android/en-US/changelogs/29547.txt b/fastlane/metadata/android/en-US/changelogs/29547.txt new file mode 100644 index 0000000000..362a138fae --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29547.txt @@ -0,0 +1,9 @@ +- Added experimental lighting system - can be enabled in custom game rules +- Added power diode block (Contributed by Quezler) +- Added plated conduit block (Contributed by Quezler) +- Added light block for dark maps only +- Improved pulse conduit speed (Contributed by Quezler) +- Improved building priority +- New permissive mod parsing format (HJSON) +- Fixed a few incorrect consumption displays in blocks +- Fixed 'underwater' ores in editor diff --git a/fastlane/metadata/android/en-US/changelogs/29550.txt b/fastlane/metadata/android/en-US/changelogs/29550.txt new file mode 100644 index 0000000000..53c981258b --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29550.txt @@ -0,0 +1,5 @@ +- Added fallback mod loading for poorly formatted old mods +- Fixed infinite building range +- Fixed impact reactors being able to blow up core on servers +- Fixed liquid bridges passing backwards +- Updated various translations diff --git a/fastlane/metadata/android/pl/changelogs/100.1.txt b/fastlane/metadata/android/pl/changelogs/100.1.txt new file mode 100644 index 0000000000..aab1b41ea0 --- /dev/null +++ b/fastlane/metadata/android/pl/changelogs/100.1.txt @@ -0,0 +1,6 @@ +- Dodano awaryjne wczytywani modów dla źle przygotowanych modów na starsze wersje +- Naprawiono nieskończony zasięg budowy +- Naprawiono reaktor uderzeniowy mogący zniszczyć rdzeń na serwerze +- Naprawiono most płynów działąjący wstecz +- Updated various translations +- Zaktualizowano tłumaczenia diff --git a/fastlane/metadata/android/pl/changelogs/100.txt b/fastlane/metadata/android/pl/changelogs/100.txt new file mode 100644 index 0000000000..1a8f4fd6a5 --- /dev/null +++ b/fastlane/metadata/android/pl/changelogs/100.txt @@ -0,0 +1,10 @@ +- Dodano eksperymentalny system oświetlenia - może być aktywowany w menu własnych zasad gry +- Added power diode block (Contributed by Quezler) +- Dodano blok diody (Dodane dzięki Quezler) +- Dodano opancerzoną rurę (Dodane dzięki Quezler) +- Dodano bloki światła tylko dla ciemnych map +- Polepszono prędkość rury pulsacyjnej (Dodano dzięki Quezler) +- Polepszono piorytet budowy +- Nowy format parsowania modów (HJSON) +- Naprawiono wyświetlanie niepoprawnych wartości zużycia bloku +- Naprawiono 'underwater' w edytorze diff --git a/fastlane/metadata/android/pl/full_description.txt b/fastlane/metadata/android/pl/full_description.txt new file mode 100644 index 0000000000..1fe15307d9 --- /dev/null +++ b/fastlane/metadata/android/pl/full_description.txt @@ -0,0 +1,15 @@ +Twórz skomplikowane linie transportowe przy użyciu przenośników by zaopatrzyć wieżyczki w amunicję, produkować materiały używane do budowy, oraz broń swoje struktury przed falami wrogów. Graj ze swoimi przyjaciółmi w międzyplatformowych rozgrywkach wieloosobwych typu co-op, lub rzuć im wyzwanie w drużynowych rozgrywkach PvP. + +W grze znajdziesz: +- 24 podstawowe mapy +- Kampanię z drzewkiem rozwoju technologii i terenami do odblokowania +- 4 potężne fale bossów +- System zarządzania elektrycznoścą, transportem cieczy i przedmiotów +- 19 unikatowych typów dronów, mechów i statków +- 120+ bloków do użycia podczas gry +- 75+ różnorodnych bloków terenu +- Graj ze znajomymi przez sieć lokalną lub na serwerze dedykowanym +- Zmieniaj zasady gry: Modyfikuj kosz budowy bloków, statystyki przeciwników, przedmioty na start, czas trwania tury i więcej +- Stwórz własną mapę przy użyciu wbudowanego edytora i popisz się kreatywnością z innymi +- Sam zdecyduj skąd nadejdzie następny atak + diff --git a/fastlane/metadata/android/pl/short_description.txt b/fastlane/metadata/android/pl/short_description.txt new file mode 100644 index 0000000000..6628c453f0 --- /dev/null +++ b/fastlane/metadata/android/pl/short_description.txt @@ -0,0 +1 @@ +Bazująca na przetrwaniu i zarządzaniu fabryką sandboxowa gra typu obrony wieży. \ No newline at end of file diff --git a/fastlane/metadata/android/pl/summary.txt b/fastlane/metadata/android/pl/summary.txt new file mode 100644 index 0000000000..6628c453f0 --- /dev/null +++ b/fastlane/metadata/android/pl/summary.txt @@ -0,0 +1 @@ +Bazująca na przetrwaniu i zarządzaniu fabryką sandboxowa gra typu obrony wieży. \ No newline at end of file diff --git a/fastlane/metadata/android/pl/title.txt b/fastlane/metadata/android/pl/title.txt new file mode 100644 index 0000000000..2beb939017 --- /dev/null +++ b/fastlane/metadata/android/pl/title.txt @@ -0,0 +1 @@ +Mindustry \ No newline at end of file diff --git a/fastlane/metadata/android/uk/changelogs/100.txt b/fastlane/metadata/android/uk/changelogs/100.txt new file mode 100644 index 0000000000..3e7cafd4f6 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/100.txt @@ -0,0 +1,9 @@ +- Додана експериментальна система освітлення. Можна увімкнути у користувацьких правилах гри. +- Додано блок діоду (Сприяв Quezler). +- Додано зміцнений трубопровід (Сприяв Quezler). +- Додано блок освітлювача. Є тільки на темних мапах. +- Підвищена швидкість трубопровода (Сприяв Quezler). +- Поліпшено пріоритет спорудження. +- Новий дозвільний формат для модифікацій (HJSON). +- Виправлено кілька неправильних відображень споживання в блоках. +- Виправлені «підводні» руди в редакторі мап. diff --git a/fastlane/metadata/android/uk/changelogs/29547.txt b/fastlane/metadata/android/uk/changelogs/29547.txt new file mode 100644 index 0000000000..3e7cafd4f6 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/29547.txt @@ -0,0 +1,9 @@ +- Додана експериментальна система освітлення. Можна увімкнути у користувацьких правилах гри. +- Додано блок діоду (Сприяв Quezler). +- Додано зміцнений трубопровід (Сприяв Quezler). +- Додано блок освітлювача. Є тільки на темних мапах. +- Підвищена швидкість трубопровода (Сприяв Quezler). +- Поліпшено пріоритет спорудження. +- Новий дозвільний формат для модифікацій (HJSON). +- Виправлено кілька неправильних відображень споживання в блоках. +- Виправлені «підводні» руди в редакторі мап. diff --git a/gradle.properties b/gradle.properties index fd97332604..1863b5958b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=640a9a5546f742c272c6117ea4ad886c80cd84ef +archash=58bfbdbe4446ca80d133a87cdffee249070ab32d diff --git a/ios/Info.plist.xml b/ios/Info.plist.xml index 0ab706af32..b93d1da2a7 100644 --- a/ios/Info.plist.xml +++ b/ios/Info.plist.xml @@ -74,6 +74,23 @@ + + CFBundleTypeIconFiles + + icon-72.png + + CFBundleTypeName + Mindustry Schematic File + CFBundleTypeRole + Editor + LSHandlerRank + Owner + LSItemContentTypes + + io.anuke.mindustry.schematicfile + + + CFBundleTypeIconFiles @@ -111,6 +128,24 @@ mindustry/msav + + + UTTypeConformsTo + + public.data + + UTTypeDescription + Mindustry Schematic File + UTTypeIdentifier + io.anuke.mindustry.schematicfile + UTTypeTagSpecification + + public.filename-extension + msch + public.mime-type + mindustry/msch + + diff --git a/ios/build.gradle b/ios/build.gradle index 94e198be83..0f5e0ec6b3 100644 --- a/ios/build.gradle +++ b/ios/build.gradle @@ -41,9 +41,6 @@ task deploy{ dependsOn createIPA } - -build.dependsOn copyAssets - launchIPhoneSimulator.dependsOn build launchIPadSimulator.dependsOn build launchIOSDevice.dependsOn build diff --git a/ios/src/io/anuke/mindustry/IOSLauncher.java b/ios/src/io/anuke/mindustry/IOSLauncher.java index 7f2998a317..7f4783d1a8 100644 --- a/ios/src/io/anuke/mindustry/IOSLauncher.java +++ b/ios/src/io/anuke/mindustry/IOSLauncher.java @@ -12,6 +12,7 @@ import io.anuke.mindustry.game.Saves.*; import io.anuke.mindustry.io.*; import io.anuke.mindustry.mod.*; import io.anuke.mindustry.ui.*; +import org.robovm.apple.coregraphics.*; import org.robovm.apple.foundation.*; import org.robovm.apple.uikit.*; import org.robovm.objc.block.*; @@ -58,129 +59,31 @@ public class IOSLauncher extends IOSApplication.Delegate{ public void didPickDocumentsAtURLs(UIDocumentBrowserViewController controller, NSArray documentURLs){ if(documentURLs.size() < 1) return; - cont.dismissViewController(true, () -> {}); + NSURL url = documentURLs.first(); NSFileCoordinator coord = new NSFileCoordinator(null); - + url.startAccessingSecurityScopedResource(); try{ - coord.coordinateReadingItem(documentURLs.get(0), NSFileCoordinatorReadingOptions.None, url -> { - if(url.startAccessingSecurityScopedResource()){ + coord.coordinateReadingItem(url, NSFileCoordinatorReadingOptions.ForUploading, result -> { + + FileHandle src = Core.files.absolute(result.getAbsoluteURL().getPath()); + FileHandle dst = Core.files.absolute(getDocumentsDirectory()).child(src.name()); + src.copyTo(dst); + + Core.app.post(() -> { try{ - controller.importDocument(url, new NSURL(getDocumentsDirectory() + "/document"), UIDocumentBrowserImportMode.Copy, (result, error) -> { - if(error != null){ - ui.showErrorMessage("Import error.\n" + error.getLocalizedFailureReason() + "\n" + error.getLocalizedDescription()); - }else{ - try{ - cons.get(Core.files.absolute(url.getPath())); - }catch(Throwable t){ - ui.showException(t); - } - } - }); + cons.get(dst); }catch(Throwable t){ ui.showException(t); } - - /* - - try{ - int[] tread = {0}; - - cons.get(new FileHandle(url.getPath()){ - @Override - public InputStream read(){ - NSInputStream stream = new NSInputStream(url); - - return new InputStream(){ - byte[] tmp = {0}; - - @Override - public int read() throws IOException{ - read(tmp); - return tmp[0]; - } - - @Override - public int read(byte[] bytes, int offset, int length){ - int read = (int)stream.read(bytes, offset, length); - tread[0] += read; - return read; - } - }; - } - }); - Core.app.post(() -> Core.app.post(() -> Core.app.post(() -> ui.showInfo("Read " + tread[0])))); - //cons.get(new FileHandle(url.getAbsoluteString())); - }catch(Throwable t){ - ui.showException(t); - - try{ - cons.get(new FileHandle(url.getPath())); - }catch(Throwable t2){ - ui.showException(t2); - - try{ - cons.get(new FileHandle(url.getAbsoluteURL().getPath())); - }catch(Throwable t3){ - ui.showException(t3); - } - } - }*/ - }else{ - ui.showErrorMessage("Failed to access file."); - } - - /* - try{ - int[] tread = {0}; - - cons.get(new FileHandle(url.getPath()){ - @Override - public InputStream read(){ - NSInputStream stream = new NSInputStream(url); - - return new InputStream(){ - byte[] tmp = {0}; - - @Override - public int read() throws IOException{ - read(tmp); - return tmp[0]; - } - - @Override - public int read(byte[] bytes, int offset, int length){ - int read = (int)stream.read(bytes, offset, length); - tread[0] += read; - return read; - } - }; - } - }); - Core.app.post(() -> Core.app.post(() -> Core.app.post(() -> ui.showInfo("Read " + tread[0])))); - }catch(Throwable t){ - ui.showException(t); - }*/ + }); }); - }catch(Throwable t){ - ui.showException(t); + }catch(Throwable e){ + ui.showException(e); } - /* - try{ - controller.importDocument(documentURLs.get(0), new NSURL(getDocumentsDirectory() + "/document"), UIDocumentBrowserImportMode.Copy, (url, error) -> { - if(error != null){ - ui.showErrorMessage("Import error.\n" + error.getLocalizedFailureReason() + "\n" + error.getLocalizedDescription()); - }else{ - try{ - cons.get(Core.files.absolute(url.getPath())); - }catch(Throwable t){ - ui.showException(t); - } - } - }); - }catch(Throwable t){ - ui.showException(t); - }*/ + url.stopAccessingSecurityScopedResource(); + + cont.dismissViewController(true, () -> {}); } @Override @@ -190,7 +93,6 @@ public class IOSLauncher extends IOSApplication.Delegate{ @Override public void didImportDocument(UIDocumentBrowserViewController controller, NSURL sourceURL, NSURL destinationURL){ - //cons.get(Core.files.absolute(destinationURL.getAbsoluteString())); } @Override @@ -223,7 +125,17 @@ public class IOSLauncher extends IOSApplication.Delegate{ NSURL url = new NSURL(to.file()); UIActivityViewController p = new UIActivityViewController(Collections.singletonList(url), null); - UIApplication.getSharedApplication().getKeyWindow().getRootViewController().presentViewController(p, true, () -> Log.info("Success! Presented {0}", to)); + UIViewController rootVc = UIApplication.getSharedApplication().getKeyWindow().getRootViewController(); + if(UIDevice.getCurrentDevice().getUserInterfaceIdiom() == UIUserInterfaceIdiom.Pad){ + // Set up the pop-over for iPad + UIPopoverPresentationController pop = p.getPopoverPresentationController(); + UIView mainView = rootVc.getView(); + pop.setSourceView(mainView); + CGRect targetRect = new CGRect(mainView.getBounds().getMidX(), mainView.getBounds().getMidY(), 0, 0); + pop.setSourceRect(targetRect); + pop.setPermittedArrowDirections(UIPopoverArrowDirection.None); + } + rootVc.presentViewController(p, true, () -> Log.info("Success! Presented {0}", to)); }catch(Throwable t){ ui.showException(t); } diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index fc9014a987..acbe681ad9 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -5,9 +5,12 @@ import io.anuke.arc.collection.*; import io.anuke.arc.collection.Array.*; import io.anuke.arc.files.*; import io.anuke.arc.util.*; +import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.Timer; import io.anuke.arc.util.CommandHandler.*; import io.anuke.arc.util.Timer.*; +import io.anuke.arc.util.serialization.*; +import io.anuke.arc.util.serialization.JsonValue.*; import io.anuke.mindustry.*; import io.anuke.mindustry.core.GameState.*; import io.anuke.mindustry.core.*; @@ -19,6 +22,7 @@ import io.anuke.mindustry.gen.*; import io.anuke.mindustry.io.*; import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.*; +import io.anuke.mindustry.maps.Maps.*; import io.anuke.mindustry.mod.Mods.*; import io.anuke.mindustry.net.Administration.*; import io.anuke.mindustry.net.Packets.*; @@ -46,6 +50,7 @@ public class ServerControl implements ApplicationListener{ private boolean inExtraRound; private Task lastTask; private Gamemode lastMode = Gamemode.survival; + private @Nullable Map nextMapOverride; private Thread socketThread; private PrintWriter socketOutput; @@ -55,11 +60,12 @@ public class ServerControl implements ApplicationListener{ "shufflemode", "normal", "bans", "", "admins", "", - "shuffle", true, + "shufflemode", "custom", "crashreport", false, "port", port, "logging", true, - "socket", false + "socket", false, + "globalrules", "{reactorExplosions: false}" ); Log.setLogger(new LogHandler(){ @@ -139,34 +145,34 @@ public class ServerControl implements ApplicationListener{ warn("&lyIt is highly advised to specify which version you're using by building with gradle args &lc-Pbuildversion=&lm&ly."); } + //set up default shuffle mode + try{ + maps.setShuffleMode(ShuffleMode.valueOf(Core.settings.getString("shufflemode"))); + }catch(Exception e){ + maps.setShuffleMode(ShuffleMode.all); + } + Events.on(GameOverEvent.class, event -> { if(inExtraRound) return; - info("Game over!"); - displayStatus(); + if(state.rules.waves){ + info("&lcGame over! Reached wave &ly{0}&lc with &ly{1}&lc players online on map &ly{2}&lc.", state.wave, playerGroup.size(), Strings.capitalize(world.getMap().name())); + }else{ + info("&lcGame over! Team &ly{0}&lc is victorious with &ly{1}&lc players online on map &ly{2}&lc.", event.winner.name(), playerGroup.size(), Strings.capitalize(world.getMap().name())); + } - if(Core.settings.getBool("shuffle")){ - if(maps.all().size > 0){ - Array maps = Array.with(Vars.maps.customMaps().size == 0 ? Vars.maps.defaultMaps() : Vars.maps.customMaps()); - maps.shuffle(); + //set next map to be played + Map map = nextMapOverride != null ? nextMapOverride : maps.getNextMap(world.getMap()); + nextMapOverride = null; + if(map != null){ + Call.onInfoMessage((state.rules.pvp + ? "[YELLOW]The " + event.winner.name() + " team is victorious![]" : "[SCARLET]Game over![]") + + "\nNext selected map:[accent] " + map.name() + "[]" + + (map.tags.containsKey("author") && !map.tags.get("author").trim().isEmpty() ? " by[accent] " + map.author() + "[]" : "") + "." + + "\nNew game begins in " + roundExtraTime + "[] seconds."); - Map previous = world.getMap(); - Map map = maps.find(m -> m != previous || maps.size == 1); + info("Selected next map to be {0}.", map.name()); - if(map != null){ - - Call.onInfoMessage((state.rules.pvp - ? "[YELLOW]The " + event.winner.name() + " team is victorious![]" : "[SCARLET]Game over![]") - + "\nNext selected map:[accent] " + map.name() + "[]" - + (map.tags.containsKey("author") && !map.tags.get("author").trim().isEmpty() ? " by[accent] " + map.author() + "[]" : "") + "." + - "\nNew game begins in " + roundExtraTime + "[] seconds."); - - info("Selected next map to be {0}.", map.name()); - - play(true, () -> world.loadMap(map, map.applyRules(lastMode))); - }else{ - Log.err("No suitable map found."); - } - } + play(true, () -> world.loadMap(map, map.applyRules(lastMode))); }else{ netServer.kickAll(KickReason.gameover); state.set(State.menu); @@ -250,8 +256,9 @@ public class ServerControl implements ApplicationListener{ logic.reset(); lastMode = preset; try{ - world.loadMap(result, result.applyRules(lastMode)); + world.loadMap(result, result.applyRules(lastMode)); state.rules = result.applyRules(preset); + applyRules(); logic.play(); info("Map loaded."); @@ -300,7 +307,29 @@ public class ServerControl implements ApplicationListener{ }); handler.register("status", "Display server status.", arg -> { - displayStatus(); + if(state.is(State.menu)){ + info("Status: &rserver closed"); + }else{ + info("Status:"); + info(" &lyPlaying on map &fi{0}&fb &lb/&ly Wave {1}", Strings.capitalize(world.getMap().name()), state.wave); + + if(state.rules.waves){ + info("&ly {0} enemies.", unitGroups[Team.crux.ordinal()].size()); + }else{ + info("&ly {0} seconds until next wave.", (int)(state.wavetime / 60)); + } + + info(" &ly{0} FPS, {1} MB used.", (int)(60f / Time.delta()), Core.app.getJavaHeap() / 1024 / 1024); + + if(playerGroup.size() > 0){ + info(" &lyPlayers: {0}", playerGroup.size()); + for(Player p : playerGroup.all()){ + info(" &y{0} / {1}", p.name, p.uuid); + } + }else{ + info(" &lyNo players connected."); + } + } }); handler.register("mods", "Display all loaded mods.", arg -> { @@ -348,6 +377,58 @@ public class ServerControl implements ApplicationListener{ } }); + handler.register("rules", "[remove/add] [name] [value...]", "List, remove or add global rules. These will apply regardless of map.", arg -> { + String rules = Core.settings.getString("globalrules"); + JsonValue base = JsonIO.json().fromJson(null, rules); + + if(arg.length == 0){ + Log.info("&lyRules:\n{0}", JsonIO.print(rules)); + }else if(arg.length == 1){ + Log.err("Invalid usage. Specify which rule to remove or add."); + }else{ + if(!(arg[0].equals("remove") || arg[0].equals("add"))){ + Log.err("Invalid usage. Either add or remove rules."); + return; + } + + boolean remove = arg[0].equals("remove"); + if(remove){ + if(base.has(arg[1])){ + Log.info("Rule &lc'{0}'&lg removed.", arg[1]); + base.remove(arg[1]); + }else{ + Log.err("Rule not defined, so not removed."); + return; + } + }else{ + if(arg.length < 3){ + Log.err("Missing last argument. Specify which value to set the rule to."); + return; + } + + try{ + JsonValue value = new JsonReader().parse(arg[2]); + value.name = arg[1]; + + JsonValue parent = new JsonValue(ValueType.object); + parent.addChild(value); + + JsonIO.json().readField(state.rules, value.name, parent); + if(base.has(value.name)){ + base.remove(value.name); + } + base.addChild(arg[1], value); + Log.info("Changed rule: &ly{0}", value.toString().replace("\n", " ")); + }catch(Throwable e){ + Log.err("Error parsing rule JSON", e); + } + } + + Core.settings.putSave("globalrules", base.toString()); + Call.onSetRules(state.rules); + } + }); + handler.register("fillitems", "[team]", "Fill the core with items.", arg -> { if(!state.is(State.playing)){ err("Not playing. Host first."); @@ -497,14 +578,29 @@ public class ServerControl implements ApplicationListener{ } }); - handler.register("shuffle", "", "Set map shuffling.", arg -> { - if(!arg[0].equals("on") && !arg[0].equals("off")){ - err("Invalid shuffle mode."); - return; + handler.register("shuffle", "[none/all/custom/builtin]", "Set map shuffling mode.", arg -> { + if(arg.length == 0){ + info("Shuffle mode current set to &ly'{0}'&lg.", maps.getShuffleMode()); + }else{ + try{ + ShuffleMode mode = ShuffleMode.valueOf(arg[0]); + Core.settings.putSave("shufflemode", mode.name()); + maps.setShuffleMode(mode); + info("Shuffle mode set to &ly'{0}'&lg.", arg[0]); + }catch(Exception e){ + err("Invalid shuffle mode."); + } + } + }); + + handler.register("nextmap", "", "Set the next map to be played after a game-over. Overrides shuffling.", arg -> { + Map res = maps.all().find(map -> map.name().equalsIgnoreCase(arg[0].replace('_', ' ')) || map.name().equalsIgnoreCase(arg[0])); + if(res != null){ + nextMapOverride = res; + Log.info("Next map set to &ly'{0}'.", res.name()); + }else{ + Log.err("No map '{0}' found.", arg[0]); } - Core.settings.put("shuffle", arg[0].equals("on")); - Core.settings.save(); - info("Shuffle mode set to '{0}'.", arg[0]); }); handler.register("kick", "", "Kick a person by name.", arg -> { @@ -703,7 +799,7 @@ public class ServerControl implements ApplicationListener{ handler.register("gameover", "Force a game over.", arg -> { if(state.is(State.menu)){ - info("Not playing a map."); + err("Not playing a map."); return; } @@ -744,29 +840,12 @@ public class ServerControl implements ApplicationListener{ mods.each(p -> p.registerClientCommands(netServer.clientCommands)); } - private void displayStatus() { - if(state.is(State.menu)){ - info("Status: &rserver closed"); - }else{ - info("Status:"); - info(" &lyPlaying on map &fi{0}&fb &lb/&ly Wave {1}", Strings.capitalize(world.getMap().name()), state.wave); - - if(state.rules.waves){ - info("&ly {0} enemies.", unitGroups[Team.crux.ordinal()].size()); - }else{ - info("&ly {0} seconds until next wave.", (int)(state.wavetime / 60)); - } - - info(" &ly{0} FPS, {1} MB used.", (int)(60f / Time.delta()), Core.app.getJavaHeap() / 1024 / 1024); - - if(playerGroup.size() > 0){ - info(" &lyPlayers: {0}", playerGroup.size()); - for(Player p : playerGroup.all()){ - info(" &y{0} / {1}", p.name, p.uuid); - } - }else{ - info(" &lyNo players connected."); - } + private void applyRules(){ + try{ + JsonValue value = JsonIO.json().fromJson(null, Core.settings.getString("globalrules")); + JsonIO.json().readFields(state.rules, value); + }catch(Throwable t){ + Log.err("Error applying custom rules, proceeding without them.", t); } } @@ -824,6 +903,7 @@ public class ServerControl implements ApplicationListener{ run.run(); logic.play(); state.rules = world.getMap().applyRules(lastMode); + applyRules(); for(Player p : players){ if(p.con == null) continue; diff --git a/servers.json b/servers.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/servers.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/tests/src/test/java/ApplicationTests.java b/tests/src/test/java/ApplicationTests.java index 801de1b495..a6ebbe0e01 100644 --- a/tests/src/test/java/ApplicationTests.java +++ b/tests/src/test/java/ApplicationTests.java @@ -60,6 +60,7 @@ public class ApplicationTests{ super.init(); begins[0] = true; testMap = maps.loadInternalMap("groundZero"); + Thread.currentThread().interrupt(); } }; @@ -212,15 +213,24 @@ public class ApplicationTests{ } @Test - void loadOldSave(){ + void load77Save(){ resetWorld(); - SaveIO.load(Core.files.internal("build77.msav")); + SaveIO.load(Core.files.internal("77.msav")); //just tests if the map was loaded properly and didn't crash, no validity checks currently assertEquals(276, world.width()); assertEquals(10, world.height()); } + @Test + void load85Save(){ + resetWorld(); + SaveIO.load(Core.files.internal("85.msav")); + + assertEquals(250, world.width()); + assertEquals(300, world.height()); + } + @Test void arrayIterators(){ Array arr = Array.with("a", "b" , "c", "d", "e", "f"); diff --git a/tests/src/test/java/power/ItemLiquidGeneratorTests.java b/tests/src/test/java/power/ItemLiquidGeneratorTests.java index 77f5b67570..e6bc2a20de 100644 --- a/tests/src/test/java/power/ItemLiquidGeneratorTests.java +++ b/tests/src/test/java/power/ItemLiquidGeneratorTests.java @@ -1,18 +1,18 @@ package power; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.content.Liquids; -import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Liquid; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.power.ItemLiquidGenerator; +import io.anuke.arc.util.*; +import io.anuke.mindustry.*; +import io.anuke.mindustry.content.*; +import io.anuke.mindustry.core.*; +import io.anuke.mindustry.game.*; +import io.anuke.mindustry.type.*; +import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.blocks.power.*; import org.junit.jupiter.api.*; -import java.util.ArrayList; +import java.util.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.DynamicTest.dynamicTest; /** @@ -31,6 +31,8 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{ private final float maximumLiquidUsage = 0.5f; public void createGenerator(InputType inputType){ + Vars.state = new GameState(); + Vars.state.rules = new Rules(); generator = new ItemLiquidGenerator(inputType != InputType.liquids, inputType != InputType.items, "fakegen"){ { powerProduction = 0.1f; diff --git a/tests/src/test/resources/build77.msav b/tests/src/test/resources/77.msav similarity index 100% rename from tests/src/test/resources/build77.msav rename to tests/src/test/resources/77.msav diff --git a/tests/src/test/resources/85.msav b/tests/src/test/resources/85.msav new file mode 100644 index 0000000000..085f9ec247 Binary files /dev/null and b/tests/src/test/resources/85.msav differ