diff --git a/.gitignore b/.gitignore index 3ba42ebece..08f0090dfb 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ logs/ /core/assets/locales /ios/src/io/anuke/mindustry/gen/ /core/src/io/anuke/mindustry/gen/ +ios/robovm.properties *.gif version.properties diff --git a/.travis.yml b/.travis.yml index c8349974ea..c0f4f1a5e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,8 @@ jdk: - openjdk8 script: - "./gradlew test" -- "./gradlew desktop:dist" -- "./gradlew server:dist" +- "./gradlew desktop:dist -Pbuildversion=${TRAVIS_TAG:1}" +- "./gradlew server:dist -Pbuildversion=${TRAVIS_TAG:1}" deploy: provider: releases diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index b0e4475812..8fdb041fc7 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -20,7 +20,7 @@ diff --git a/android/build.gradle b/android/build.gradle index e7790fb299..eecd23ce01 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -93,7 +93,7 @@ android { applicationId "io.anuke.mindustry" minSdkVersion 14 - targetSdkVersion 27 + targetSdkVersion 28 versionCode code versionName versionNameResult } diff --git a/android/src/io/anuke/mindustry/DonationsActivity.java b/android/src/io/anuke/mindustry/DonationsActivity.java index 0a868f8ed3..09b6a6b12f 100644 --- a/android/src/io/anuke/mindustry/DonationsActivity.java +++ b/android/src/io/anuke/mindustry/DonationsActivity.java @@ -68,7 +68,6 @@ public class DonationsActivity extends FragmentActivity{ Fragment fragment = fragmentManager.findFragmentByTag("donationsFragment"); if(fragment != null){ fragment.onActivityResult(requestCode, resultCode, data); - //TODO donation event, set settings? } } } diff --git a/build.gradle b/build.gradle index 10d8492d99..6367e64024 100644 --- a/build.gradle +++ b/build.gradle @@ -19,13 +19,13 @@ allprojects { version = 'release' ext { - versionNumber = '4.0' + versionNumber = '4' versionModifier = 'alpha' versionType = 'official' appName = 'Mindustry' gdxVersion = '1.9.9' roboVMVersion = '2.3.0' - uCoreVersion = 'c9aadd4d0b5848dbc4dbbd0fcd701b11c30c02bb' + uCoreVersion = 'f73e538757ac66ff62d7f25d93011142b6abb8df' getVersionString = { String buildVersion = getBuildVersion() @@ -110,17 +110,35 @@ project(":ios") { include "**/*.java" } - into "ios/src/io/anuke/mindustry/gen" + into "core/src/io/anuke/mindustry/gen" } doFirst{ delete{ - delete "ios/src/io/anuke/mindustry/gen/" + delete "core/src/io/anuke/mindustry/gen/" } } } - //build.dependsOn(copyGen) + task incrementConfig{ + def vfile = file('robovm.properties') + + def props = new Properties() + if(vfile.exists()){ + props.load(new FileInputStream(vfile)) + } + + props['app.id'] = 'io.anuke.mindustry' + props['app.version'] = '4.0' + props['app.mainclass'] = 'io.anuke.mindustry.IOSLauncher' + props['app.executable'] = 'IOSLauncher' + props['app.name'] = 'Mindustry' + props['app.build'] = (!props.hasProperty("app.build") ? 40 : props['app.build'].toInteger() + 1)+"" + props.store(vfile.newWriter(), null) + } + + build.dependsOn(incrementConfig) + build.dependsOn(copyGen) dependencies { compile project(":core") diff --git a/core/assets-raw/sprites/ui/icons/icon-liquid-small.png b/core/assets-raw/sprites/ui/icons/icon-liquid-small.png new file mode 100644 index 0000000000..48c93ed9d2 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-liquid-small.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-power-small.png b/core/assets-raw/sprites/ui/icons/icon-power-small.png new file mode 100644 index 0000000000..666058d5c7 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-power-small.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 5c12a3f2d0..6cae7f175d 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1,6 +1,7 @@ -text.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\!) +text.credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[] text.credits = Credits -text.discord = Join the mindustry discord\! +text.contributors = Translators and Contributors +text.discord = Join the mindustry discord! text.link.discord.description = The official Mindustry discord chatroom text.link.github.description = Game source code text.link.dev-builds.description = Unstable development builds @@ -8,25 +9,26 @@ text.link.trello.description = Official trello board for planned features text.link.itch.io.description = itch.io page with PC downloads and web version text.link.google-play.description = Google Play store listing text.link.wiki.description = Official Mindustry wiki -text.linkfail = Failed to open link\!\nThe URL has been copied to your clipboard. +text.linkfail = Failed to open link!\nThe URL has been copied to your clipboard. +text.screenshot = Screenshot saved to {0} text.gameover = Game Over -text.gameover.pvp = The[accent] {0}[] team is victorious\! +text.gameover.pvp = The[accent] {0}[] team is victorious! text.sector.gameover = This sector has been lost. Re-deploy? text.sector.retry = Retry -text.highscore = [accent]New highscore\! +text.highscore = [accent]New highscore! text.wave.lasted = You lasted until wave [accent]{0}[]. -text.level.highscore = High Score\: [accent]{0} +text.level.highscore = High Score: [accent]{0} text.level.delete.title = Confirm Delete text.map.delete = Are you sure you want to delete the map "[accent]{0}[]"? text.level.select = Level Select -text.level.mode = Gamemode\: +text.level.mode = Gamemode: text.construction.desktop = To deselect a block or stop building, [accent]use space[]. text.construction.title = Block Construction Guide text.construction = You've just selected [accent]block construction mode[].\n\nTo begin placing, simply tap a valid location near your ship.\nOnce you have selected some blocks, press the checkbox to confirm, and your ship will begin constructing them.\n\n- [accent]Remove blocks[] from your selection by tapping them.\n- [accent]Shift the selection[] by holding and dragging any block in the selection.\n- [accent]Place blocks in a line[] by tapping and holding an empty spot, then dragging in a direction.\n- [accent]Cancel construction or selection[] by pressing the X at the bottom left. text.deconstruction.title = Block Deconstruction Guide text.deconstruction = You've just selected [accent]block deconstruction mode[].\n\nTo begin breaking, simply tap a block near your ship.\nOnce you have selected some blocks, press the checkbox to confirm, and your ship will begin de-constructing them.\n\n- [accent]Remove blocks[] from your selection by tapping them.\n- [accent]Remove blocks in an area[] by tapping and holding an empty spot, then dragging in a direction.\n- [accent]Cancel deconstruction or selection[] by pressing the X at the bottom left. text.showagain = Don't show again next session -text.coreattack = < Core is under attack\! > +text.coreattack = < Core is under attack! > text.unlocks = Unlocks text.savegame = Save Game text.loadgame = Load Game @@ -34,19 +36,19 @@ text.joingame = Join Game text.addplayers = Add/Remove Players text.customgame = Custom Game text.sectors = Sectors -text.sector = Sector\: [LIGHT_GRAY]{0} -text.sector.time = Time\: [LIGHT_GRAY]{0} +text.sector = Sector: [LIGHT_GRAY]{0} +text.sector.time = Time: [LIGHT_GRAY]{0} text.sector.deploy = Deploy text.sector.abandon = Abandon -text.sector.abandon.confirm = Are you sure you want to abandon all progress at this sector?\nThis cannot be undone\! +text.sector.abandon.confirm = Are you sure you want to abandon all progress at this sector?\nThis cannot be undone! text.sector.resume = Resume text.sector.locked = [scarlet][[Incomplete] text.sector.unexplored = [accent][[Unexplored] -text.missions = Missions\:[LIGHT_GRAY] {0} -text.mission = Mission\:[LIGHT_GRAY] {0} -text.mission.main = Main Mission\:[LIGHT_GRAY] {0} +text.missions = Missions:[LIGHT_GRAY] {0} +text.mission = Mission:[LIGHT_GRAY] {0} +text.mission.main = Main Mission:[LIGHT_GRAY] {0} text.mission.info = Mission Info -text.mission.complete = Mission complete\! +text.mission.complete = Mission complete! text.mission.complete.body = Sector {0},{1} has been conquered. text.mission.wave = Survive[accent] {0}/{1} []waves\nWave in {2} text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies @@ -54,12 +56,12 @@ text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy text.mission.wave.menu = Survive[accent] {0}[] waves text.mission.battle = Destroy enemy core text.mission.resource.menu = Obtain {0} x{1} -text.mission.resource = Obtain {0}\:\n[accent]{1}/{2}[] +text.mission.resource = Obtain {0}:\n[accent]{1}/{2}[] text.mission.block = Create {0} text.mission.unit = Create {0} Unit text.mission.command = Send Command {0} To Units text.mission.linknode = Link Power Node -text.mission.display = [accent]Mission\:\n[LIGHT_GRAY]{0} +text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0} text.mission.mech = Switch to mech[accent] {0}[] text.mission.create = Create[accent] {0}[] text.none = @@ -68,29 +70,30 @@ text.quit = Quit text.maps = Maps text.continue = Continue text.nextmission = Next Mission -text.maps.none = [LIGHT_GRAY]No maps found\! +text.maps.none = [LIGHT_GRAY]No maps found! text.about.button = About -text.name = Name\: -text.filename = File Name\: -text.unlocked = New Block Unlocked\! -text.unlocked.plural = New Blocks Unlocked\! +text.name = Name: +text.noname = Pick a[accent] player name[] first. +text.filename = File Name: +text.unlocked = New Block Unlocked! +text.unlocked.plural = New Blocks Unlocked! text.players = {0} players online text.players.single = {0} player online text.server.closing = [accent]Closing server... -text.server.kicked.kick = You have been kicked from the server\! +text.server.kicked.kick = You have been kicked from the server! text.server.kicked.serverClose = Server closed. text.server.kicked.sectorComplete = Sector completed. text.server.kicked.sectorComplete.text = Your mission is complete.\nThe server will now continue at the next sector. -text.server.kicked.clientOutdated = Outdated client\! Update your game\! -text.server.kicked.serverOutdated = Outdated server\! Ask the host to update\! +text.server.kicked.clientOutdated = Outdated client! Update your game! +text.server.kicked.serverOutdated = Outdated server! Ask the host to update! text.server.kicked.banned = You are banned on this server. text.server.kicked.recentKick = You have been kicked recently.\nWait before connecting again. text.server.kicked.nameInUse = There is someone with that name\nalready on this server. text.server.kicked.nameEmpty = Your chosen name is invalid. -text.server.kicked.idInUse = You are already on this server\! Connecting with two accounts is not permitted. +text.server.kicked.idInUse = You are already on this server! Connecting with two accounts is not permitted. text.server.kicked.customClient = This server does not support custom builds. Download an official version. -text.host.info = The [accent]host[] button hosts a server on port [scarlet]6567[]. \nAnybody on the same [LIGHT_GRAY]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[LIGHT_GRAY]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. -text.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[LIGHT_GRAY]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. +text.host.info = The [accent]host[] button hosts a server on port [scarlet]6567[]. \nAnybody on the same [LIGHT_GRAY]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[LIGHT_GRAY]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. +text.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[LIGHT_GRAY]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. text.hostserver = Host Game text.hostserver.mobile = Host\nGame text.host = Host @@ -98,31 +101,31 @@ text.hosting = [accent]Opening server... text.hosts.refresh = Refresh text.hosts.discovering = Discovering LAN games text.server.refreshing = Refreshing server -text.hosts.none = [lightgray]No local games found\! +text.hosts.none = [lightgray]No local games found! text.host.invalid = [scarlet]Can't connect to host. text.trace = Trace Player -text.trace.playername = Player name\: [accent]{0} -text.trace.ip = IP\: [accent]{0} -text.trace.id = Unique ID\: [accent]{0} -text.trace.android = Android Client\: [accent]{0} -text.trace.modclient = Custom Client\: [accent]{0} -text.trace.totalblocksbroken = Total blocks broken\: [accent]{0} -text.trace.structureblocksbroken = Structure blocks broken\: [accent]{0} -text.trace.lastblockbroken = Last block broken\: [accent]{0} -text.trace.totalblocksplaced = Total blocks placed\: [accent]{0} -text.trace.lastblockplaced = Last block placed\: [accent]{0} -text.invalidid = Invalid client ID\! Submit a bug report. +text.trace.playername = Player name: [accent]{0} +text.trace.ip = IP: [accent]{0} +text.trace.id = Unique ID: [accent]{0} +text.trace.android = Android Client: [accent]{0} +text.trace.modclient = Custom Client: [accent]{0} +text.trace.totalblocksbroken = Total blocks broken: [accent]{0} +text.trace.structureblocksbroken = Structure blocks broken: [accent]{0} +text.trace.lastblockbroken = Last block broken: [accent]{0} +text.trace.totalblocksplaced = Total blocks placed: [accent]{0} +text.trace.lastblockplaced = Last block placed: [accent]{0} +text.invalidid = Invalid client ID! Submit a bug report. text.server.bans = Bans -text.server.bans.none = No banned players found\! +text.server.bans.none = No banned players found! text.server.admins = Admins -text.server.admins.none = No admins found\! +text.server.admins.none = No admins found! text.server.add = Add Server text.server.delete = Are you sure you want to delete this server? -text.server.hostname = Host\: {0} +text.server.hostname = Host: {0} text.server.edit = Edit Server -text.server.outdated = [crimson]Outdated Server\![] -text.server.outdated.client = [crimson]Outdated Client\![] -text.server.version = [lightgray]Version\: {0} {1} +text.server.outdated = [crimson]Outdated Server![] +text.server.outdated.client = [crimson]Outdated Client![] +text.server.version = [lightgray]Version: {0} {1} text.server.custombuild = [yellow]Custom Build text.confirmban = Are you sure you want to ban this player? text.confirmkick = Are you sure you want to kick this player? @@ -130,45 +133,45 @@ text.confirmunban = Are you sure you want to unban this player? text.confirmadmin = Are you sure you want to make this player an admin? text.confirmunadmin = Are you sure you want to remove admin status from this player? text.joingame.title = Join Game -text.joingame.ip = IP\: +text.joingame.ip = IP: text.disconnect = Disconnected. -text.disconnect.data = Failed to load world data\! +text.disconnect.data = Failed to load world data! text.connecting = [accent]Connecting... text.connecting.data = [accent]Loading world data... -text.server.port = Port\: -text.server.addressinuse = Address already in use\! -text.server.invalidport = Invalid port number\! -text.server.error = [crimson]Error hosting server\: [accent]{0} +text.server.port = Port: +text.server.addressinuse = Address already in use! +text.server.invalidport = Invalid port number! +text.server.error = [crimson]Error hosting server: [accent]{0} text.save.old = This save is for an older version of the game, and can no longer be used.\n\n[LIGHT_GRAY]Save backwards compatibility will be implemented in the full 4.0 release. text.save.new = New Save text.save.overwrite = Are you sure you want to overwrite\nthis save slot? text.overwrite = Overwrite -text.save.none = No saves found\! +text.save.none = No saves found! text.saveload = [accent]Saving... -text.savefail = Failed to save game\! +text.savefail = Failed to save game! text.save.delete.confirm = Are you sure you want to delete this save? text.save.delete = Delete text.save.export = Export Save -text.save.import.invalid = [accent]This save is invalid\! -text.save.import.fail = [crimson]Failed to import save\: [accent]{0} -text.save.export.fail = [crimson]Failed to export save\: [accent]{0} +text.save.import.invalid = [accent]This save is invalid! +text.save.import.fail = [crimson]Failed to import save: [accent]{0} +text.save.export.fail = [crimson]Failed to export save: [accent]{0} text.save.import = Import Save -text.save.newslot = Save name\: +text.save.newslot = Save name: text.save.rename = Rename -text.save.rename.text = New name\: +text.save.rename.text = New name: text.selectslot = Select a save. text.slot = [accent]Slot {0} -text.save.corrupted = [accent]Save file corrupted or invalid\!\nIf you have just updated your game, this is probably a change in the save format and [scarlet]not[] a bug. +text.save.corrupted = [accent]Save file corrupted or invalid!\nIf you have just updated your game, this is probably a change in the save format and [scarlet]not[] a bug. text.sector.corrupted = [accent]A save file for this sector was found, but loading failed.\nA new one has been created. text.empty = text.on = On text.off = Off -text.save.autosave = Autosave\: {0} -text.save.map = Map\: {0} +text.save.autosave = Autosave: {0} +text.save.map = Map: {0} text.save.wave = Wave {0} -text.save.difficulty = Difficulty\: {0} -text.save.date = Last Saved\: {0} -text.save.playtime = Playtime\: {0} +text.save.difficulty = Difficulty: {0} +text.save.date = Last Saved: {0} +text.save.playtime = Playtime: {0} text.confirm = Confirm text.delete = Delete text.ok = OK @@ -180,9 +183,9 @@ text.back = Back text.quit.confirm = Are you sure you want to quit? text.changelog.title = Changelog text.changelog.loading = Getting changelog... -text.changelog.error.android = [accent]Note that the changelog sometimes does not work on Android 4.4 and below\!\nThis is due to an internal Android bug. +text.changelog.error.android = [accent]Note that the changelog sometimes does not work on Android 4.4 and below!\nThis is due to an internal Android bug. text.changelog.error.ios = [accent]The changelog is currently not supported in iOS. -text.changelog.error = [scarlet]Error getting changelog\!\nCheck your internet connection. +text.changelog.error = [scarlet]Error getting changelog!\nCheck your internet connection. text.changelog.current = [yellow][[Current version] text.changelog.latest = [accent][[Latest version] text.loading = [accent]Loading... @@ -198,32 +201,32 @@ text.saveimage = Save Image text.unknown = Unknown text.custom = Custom text.builtin = Built-In -text.map.delete.confirm = Are you sure you want to delete this map? This action cannot be undone\! +text.map.delete.confirm = Are you sure you want to delete this map? This action cannot be undone! text.map.random = [accent]Random Map -text.map.nospawn = This map does not have any cores for the player to spawn in\! Add a[ROYAL] blue[] core to this map in the editor. -text.map.nospawn.pvp = This map does not have any enemy cores for player to spawn into\! Add[SCARLET] red[] cores to this map in the editor. -text.map.invalid = Error loading map\: corrupted or invalid map file. +text.map.nospawn = This map does not have any cores for the player to spawn in! Add a[ROYAL] blue[] core to this map in the editor. +text.map.nospawn.pvp = This map does not have any enemy cores for player to spawn into! Add[SCARLET] red[] cores to this map in the editor. +text.map.invalid = Error loading map: corrupted or invalid map file. text.editor.brush = Brush text.editor.slope = \\ text.editor.openin = Open In Editor text.editor.oregen = Ore Generation -text.editor.oregen.info = Ore Generation\: +text.editor.oregen.info = Ore Generation: text.editor.mapinfo = Map Info -text.editor.author = Author\: -text.editor.description = Description\: -text.editor.name = Name\: +text.editor.author = Author: +text.editor.description = Description: +text.editor.name = Name: text.editor.teams = Teams text.editor.elevation = Elevation -text.editor.errorimageload = Error loading file\:\n[accent]{0} -text.editor.errorimagesave = Error saving file\:\n[accent]{0} +text.editor.errorimageload = Error loading file:\n[accent]{0} +text.editor.errorimagesave = Error saving file:\n[accent]{0} text.editor.generate = Generate text.editor.resize = Resize text.editor.loadmap = Load Map text.editor.savemap = Save Map -text.editor.saved = Saved\! -text.editor.save.noname = Your map does not have a name\! Set one in the 'map info' menu. -text.editor.save.overwrite = Your map overwrites a built-in map\! Pick a different name in the 'map info' menu. -text.editor.import.exists = [scarlet]Unable to import\:[] a built-in map named '{0}' already exists\! +text.editor.saved = Saved! +text.editor.save.noname = Your map does not have a name! Set one in the 'map info' menu. +text.editor.save.overwrite = Your map overwrites a built-in map! Pick a different name in the 'map info' menu. +text.editor.import.exists = [scarlet]Unable to import:[] a built-in map named '{0}' already exists! text.editor.import = Import... text.editor.importmap = Import Map text.editor.importmap.description = Import an already existing map @@ -238,21 +241,21 @@ text.editor.exportimage = Export Terrain Image text.editor.exportimage.description = Export a map image file text.editor.loadimage = Import Terrain text.editor.saveimage = Export Terrain -text.editor.unsaved = [scarlet]You have unsaved changes\![]\nAre you sure you want to exit? +text.editor.unsaved = [scarlet]You have unsaved changes![]\nAre you sure you want to exit? text.editor.resizemap = Resize Map -text.editor.mapname = Map Name\: -text.editor.overwrite = [accent]Warning\!\nThis overwrites an existing map. -text.editor.overwrite.confirm = [scarlet]Warning\![] A map with this name already exists. Are you sure you want to overwrite it? -text.editor.selectmap = Select a map to load\: -text.width = Width\: -text.height = Height\: +text.editor.mapname = Map Name: +text.editor.overwrite = [accent]Warning!\nThis overwrites an existing map. +text.editor.overwrite.confirm = [scarlet]Warning![] A map with this name already exists. Are you sure you want to overwrite it? +text.editor.selectmap = Select a map to load: +text.width = Width: +text.height = Height: text.menu = Menu text.play = Play text.load = Load text.save = Save -text.fps = FPS\: {0} -text.tps = TPS\: {0} -text.ping = Ping\: {0}ms +text.fps = FPS: {0} +text.tps = TPS: {0} +text.ping = Ping: {0}ms text.language.restart = Please restart your game for the language settings to take effect. text.settings = Settings text.tutorial = Tutorial @@ -260,7 +263,7 @@ text.editor = Editor text.mapeditor = Map Editor text.donate = Donate -text.connectfail = [crimson]Failed to connect to server\:\n\n[accent]{0} +text.connectfail = [crimson]Failed to connect to server:\n\n[accent]{0} text.error.unreachable = Server unreachable.\nIs the address spelled correctly? text.error.invalidaddress = Invalid address. text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! @@ -277,8 +280,8 @@ text.settings.game = Game text.settings.sound = Sound text.settings.graphics = Graphics text.settings.cleardata = Clear Game Data... -text.settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone\! -text.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. +text.settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone! +text.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. text.settings.clearsectors = Clear Sectors text.settings.clearunlocks = Clear Unlocks text.settings.clearall = Clear All @@ -321,7 +324,8 @@ text.blocks.coolant = Coolant text.blocks.coolantuse = Coolant Use text.blocks.inputliquidfuel = Fuel Liquid text.blocks.liquidfueluse = Liquid Fuel Use -text.blocks.explosive = Highly explosive\! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Health text.blocks.inaccuracy = Inaccuracy text.blocks.shots = Shots @@ -346,6 +350,7 @@ text.category.liquids = Liquids text.category.items = Items text.category.crafting = Crafting text.category.shooting = Shooting +text.category.optional = Optional Enhancements setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS setting.fpscap.none = None @@ -355,14 +360,13 @@ setting.difficulty.easy = easy setting.difficulty.normal = normal setting.difficulty.hard = hard setting.difficulty.insane = insane -setting.difficulty.name = Difficulty\: +setting.difficulty.name = Difficulty: setting.screenshake.name = Screen Shake setting.effects.name = Display Effects setting.sensitivity.name = Controller Sensitivity setting.saveinterval.name = Autosave Interval setting.seconds = {0} Seconds setting.fullscreen.name = Fullscreen -setting.multithread.name = Multithreading setting.fps.name = Show FPS setting.vsync.name = VSync setting.lasers.name = Show Power Lasers @@ -381,6 +385,7 @@ command.retreat = Retreat command.patrol = Patrol 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 @@ -461,7 +466,7 @@ mech.delta-mech.description = A fast, lightly-armored mech made for hit-and-run mech.tau-mech.name = Tau mech.tau-mech.weapon = Restruct Laser mech.tau-mech.ability = Repair Burst -mech.tau-mech.description = The support mech. Heals allied blocks by shooting at them. Can extinguish fires and heal allies in a radius with its repair ability. +mech.tau-mech.description = The support mech. Heals allied blocks by shooting at them. Can heal allies in a radius with its repair ability. mech.omega-mech.name = Omega mech.omega-mech.weapon = Swarm Missiles mech.omega-mech.ability = Armored Configuration @@ -479,21 +484,21 @@ mech.trident-ship.weapon = Bomb Bay mech.glaive-ship.name = Glaive mech.glaive-ship.description = A large, well-armored gunship. Equipped with an incendiary repeater. Good acceleration and maximum speed. mech.glaive-ship.weapon = Flame Repeater -text.item.explosiveness = [LIGHT_GRAY]Explosiveness\: {0}% -text.item.flammability = [LIGHT_GRAY]Flammability\: {0}% -text.item.radioactivity = [LIGHT_GRAY]Radioactivity\: {0}% -text.item.fluxiness = [LIGHT_GRAY]Flux Power\: {0}% -text.unit.health = [LIGHT_GRAY]Health\: {0} -text.unit.speed = [LIGHT_GRAY]Speed\: {0} -text.mech.weapon = [LIGHT_GRAY]Weapon\: {0} -text.mech.armor = [LIGHT_GRAY]Armor\: {0} -text.mech.itemcapacity = [LIGHT_GRAY]Item Capacity\: {0} -text.mech.minespeed = [LIGHT_GRAY]Mining Speed\: {0} -text.mech.minepower = [LIGHT_GRAY]Mining Power\: {0} -text.mech.ability = [LIGHT_GRAY]Ability\: {0} -text.liquid.heatcapacity = [LIGHT_GRAY]Heat Capacity\: {0} -text.liquid.viscosity = [LIGHT_GRAY]Viscosity\: {0} -text.liquid.temperature = [LIGHT_GRAY]Temperature\: {0} +text.item.explosiveness = [LIGHT_GRAY]Explosiveness: {0}% +text.item.flammability = [LIGHT_GRAY]Flammability: {0}% +text.item.radioactivity = [LIGHT_GRAY]Radioactivity: {0}% +text.item.fluxiness = [LIGHT_GRAY]Flux Power: {0}% +text.unit.health = [LIGHT_GRAY]Health: {0} +text.unit.speed = [LIGHT_GRAY]Speed: {0} +text.mech.weapon = [LIGHT_GRAY]Weapon: {0} +text.mech.armor = [LIGHT_GRAY]Armor: {0} +text.mech.itemcapacity = [LIGHT_GRAY]Item Capacity: {0} +text.mech.minespeed = [LIGHT_GRAY]Mining Speed: {0} +text.mech.minepower = [LIGHT_GRAY]Mining Power: {0} +text.mech.ability = [LIGHT_GRAY]Ability: {0} +text.liquid.heatcapacity = [LIGHT_GRAY]Heat Capacity: {0} +text.liquid.viscosity = [LIGHT_GRAY]Viscosity: {0} +text.liquid.temperature = [LIGHT_GRAY]Temperature: {0} block.constructing = {0} [LIGHT_GRAY](Constructing) block.spawn.name = Enemy Spawn block.core.name = Core diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties index 3678908918..d7840e685c 100644 --- a/core/assets/bundles/bundle_de.properties +++ b/core/assets/bundles/bundle_de.properties @@ -286,6 +286,7 @@ text.no = Nein text.info.title = [accent]Info text.error.title = [crimson] Ein Fehler ist aufgetreten text.error.crashtitle = Ein Fehler ist aufgetreten! +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Blockinfo: text.blocks.powercapacity = Kapazität text.blocks.powershot = Stromverbrauch/Schuss @@ -318,7 +319,8 @@ text.blocks.coolant = Kühlmittel text.blocks.coolantuse = Kühlmittelverbrauch text.blocks.inputliquidfuel = Kraftstoff text.blocks.liquidfueluse = Kraftstoffverbrauch -text.blocks.explosive = Hochexplosiv! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Lebenspunkte text.blocks.inaccuracy = Ungenauigkeit text.blocks.shots = Schüsse @@ -343,6 +345,7 @@ text.category.liquids = Flüssigkeiten text.category.items = Materialien text.category.crafting = Erzeugung text.category.shooting = Schießen +text.category.optional = Optional Enhancements setting.autotarget.name = Auto-Zielauswahl setting.fpscap.name = Max FPS setting.fpscap.none = kein @@ -359,7 +362,6 @@ setting.sensitivity.name = Controller-Empfindlichkeit setting.saveinterval.name = Autosave Häufigkeit setting.seconds = {0} Sekunden setting.fullscreen.name = Vollbild -setting.multithread.name = Multithreading setting.fps.name = Zeige FPS setting.vsync.name = VSync setting.lasers.name = Zeige Stromlaser @@ -404,8 +406,6 @@ mode.waves.name = Wellen mode.waves.description = Der normale Modus. Begrenzte Ressourcen und automatische Wellen. mode.sandbox.name = Sandkasten mode.sandbox.description = Unendliche Ressourcen und kein Timer für Wellen. -mode.custom.warning = [scarlet]FREISCHALTUNGEN IN BENUTZERDEFINIERTEN SPIELEN ODER SERVERN WERDEN NICHT GESPEICHERT.[]\n\nSpiele in Sektoren, um Dinge freizuschalten. -mode.custom.warning.read = Nur um sicherzugehen, dass du es gelesen hast:\n[scarlet]FREISCHALTUNGEN IN BENUTZERDEFINIERTEN SPIELEN ODER SERVERN WERDEN NICHT GESPEICHERT.[]\n\nSpiele in Sektoren, um Dinge freizuschalten.(Ich wünschte, der Hinweis wäre nicht notwendig, aber anscheinend ist er das)[] mode.freebuild.name = Freier Bau mode.freebuild.description = Begrenzte Ressourcen und kein Timer für Wellen. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties index d745f83d96..5d753f7732 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -286,6 +286,7 @@ text.no = No text.info.title = [accent]Información text.error.title = [crimson]Un error ha ocurrido. text.error.crashtitle = Un error ha ocurrido. +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Información del Bloque text.blocks.powercapacity = Capacidad de Energía text.blocks.powershot = Energía/Disparo @@ -318,7 +319,8 @@ text.blocks.coolant = Refrigerante text.blocks.coolantuse = Uso del Refrigerante text.blocks.inputliquidfuel = Combustible Líquido text.blocks.liquidfueluse = Uso del Combustible Líquido -text.blocks.explosive = ¡Altamente Explosivo! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Vida text.blocks.inaccuracy = Imprecisión text.blocks.shots = Disparos @@ -343,6 +345,7 @@ text.category.liquids = Líquidos text.category.items = Objetos text.category.crafting = Fabricación text.category.shooting = Disparo +text.category.optional = Optional Enhancements setting.autotarget.name = Auto apuntado setting.fpscap.name = Máx FPS setting.fpscap.none = Nada @@ -359,7 +362,6 @@ setting.sensitivity.name = Sensibilidad del Control setting.saveinterval.name = Intervalo del Auto-guardado setting.seconds = {0} Segundos setting.fullscreen.name = Pantalla Completa -setting.multithread.name = Multiproceso setting.fps.name = Mostrar FPS setting.vsync.name = VSync setting.lasers.name = Mostrar Energía de los Láseres @@ -404,8 +406,6 @@ mode.waves.name = hordas mode.waves.description = El modo normal. con recursos limitados y entrada de hordas automática. mode.sandbox.name = sandbox mode.sandbox.description = Recursos ilimitados y sin temporizador para las hordas. -mode.custom.warning = Ten en cuenta que los bloques no pueden usarse en partidas personalizadas hasta que se desbloqueen en sectores.\n\n[LIGHT_GRAY]Si no desbloqueaste ningún bloque, ningno aparecerá. -mode.custom.warning.read = Solo para asegurar que lo has leído:\n[scarlet]¡LOS DESBLOQUEOS EN PARTIDAS PERSONALIZADAS NO ESTÁN DISPONIBLES EN LOS SECTORES U OTROS MODOS DE JUEGO!\n\n[LIGHT_GRAY](Ojalá esto no fuera necesario, pero parece que lo es) mode.freebuild.name = construcción libre mode.freebuild.description = recursos limitados y no hay temporizador para las hordas. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index ae82c370fd..f8351c8f7b 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -286,6 +286,7 @@ text.no = Non text.info.title = Info text.error.title = [crimson]Une erreur s'est produite text.error.crashtitle = Une erreur s'est produite +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Info sur le bloc text.blocks.powercapacity = capacité d'énergie text.blocks.powershot = Énergie/Tir @@ -318,7 +319,8 @@ text.blocks.coolant = Liquide de refroidissement text.blocks.coolantuse = Quantité de liquide de refroidissement utilisée text.blocks.inputliquidfuel = Carburant liquide text.blocks.liquidfueluse = Quantité de carburant liquide utilisé -text.blocks.explosive = Hautement explosif! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Santé text.blocks.inaccuracy = Précision text.blocks.shots = Tir @@ -343,6 +345,7 @@ text.category.liquids = Liquides text.category.items = Objets text.category.crafting = Fabrication text.category.shooting = Défense +text.category.optional = Optional Enhancements setting.autotarget.name = Visée automatique setting.fpscap.name = Max FPS setting.fpscap.none = None @@ -359,7 +362,6 @@ setting.sensitivity.name = Sensibilité de la manette setting.saveinterval.name = Intervalle des sauvegardes auto setting.seconds = {0} secondes setting.fullscreen.name = Plein écran -setting.multithread.name = Multithreading [scarlet] (instable!) setting.fps.name = Afficher FPS setting.vsync.name = VSync setting.lasers.name = Afficher les rayons des lasers @@ -404,8 +406,6 @@ mode.waves.name = Vagues mode.waves.description = le mode de jeu normal. Ressource limitée et vagues d'ennemis. mode.sandbox.name = bac à sable mode.sandbox.description = Ressources infinies et pas de timer pour les vagues. -mode.custom.warning = Notez que les blocs débloqués en partie personnalisées ne sont pas conservés pour les secteurs.\n\n[LIGHT_GRAY]En mode bac à sable, seul les blocs débloqués en mode secteur peuvent être utilisés. -mode.custom.warning.read = Simplement pour vérifier que vous l'avez lu :\n[scarlet]CE QUI EST DEBLOQUE LORS DES PARITES PERSONNALISEES NE L'EST POUR LES SECTEURS OU LES AUTRES MODES DE JEU!\n\n[LIGHT_GRAY](J'aurais souhaité que ce ne soit pas nécessaire, mais ça a l'air de l'être ) mode.freebuild.name = construction libre mode.freebuild.description = Ressource limitée et pas de timer pour les vagues. mode.pvp.name = JcJ diff --git a/core/assets/bundles/bundle_fr_BE.properties b/core/assets/bundles/bundle_fr_BE.properties index 011bd405ec..1abdc7f293 100644 --- a/core/assets/bundles/bundle_fr_BE.properties +++ b/core/assets/bundles/bundle_fr_BE.properties @@ -1,5 +1,6 @@ -text.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!) +text.credits.text = Créé par [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[] text.credits = Crédits +text.contributors = Traducteurs et contributeurs text.discord = Rejoignez le discord de Mindustry ! text.link.discord.description = Le discord officiel de Mindustry text.link.github.description = Code source du jeu @@ -9,6 +10,7 @@ text.link.itch.io.description = Page web itch.io avec les versions ordinateurs t text.link.google-play.description = Page Google Play Store du jeu text.link.wiki.description = Wiki officiel de Mindustry text.linkfail = L'ouverture du lien a échoué!\nL'URL a été copiée dans votre presse-papier. +text.screenshot = Capture d'écran enregistrée sur {0} text.gameover = Le base a été détruit. text.gameover.pvp = L'équipe[accent] {0}[] a gagnée ! text.sector.gameover = Ce secteur a été perdu. Réessayer ? @@ -54,7 +56,7 @@ text.mission.wave.enemy = Survivez[accent] {0}/{1} []vagues\n{2} Ennemi text.mission.wave.menu = Survivez[accent] {0} []vagues text.mission.battle = Détruire la base ennemie. text.mission.resource.menu = Obtenez {0} x{1} -text.mission.resource = Obtain {0}:\n[accent]{1}/{2}[] +text.mission.resource = Obtenez {0}:\n[accent]{1}/{2}[] text.mission.block = Créez {0} text.mission.unit = Créez {0} unité text.mission.command = Envoyer une commande à {0} unités @@ -71,6 +73,7 @@ text.nextmission = Prochaine Mission text.maps.none = [LIGHT_GRAY]Aucune carte trouvée! text.about.button = À propos text.name = Nom: +text.noname = Choisissez d'abord [accent]un pseudo[]. text.filename = Nom du fichier: text.unlocked = Nouveau bloc debloqué! text.unlocked.plural = Nouveaux blocs débloqués! @@ -150,8 +153,8 @@ text.save.delete.confirm = Êtes-vous sûr de supprimer cette sauvegarde ? text.save.delete = Supprimer text.save.export = Exporter une\nSauvegarde text.save.import.invalid = [accent]Cette sauvegarde est invalide! -text.save.import.fail = [crimson]L'importation de la sauvegarde\na échoué: [accent]{0} -text.save.export.fail = [crimson]L'exportation de la sauvegarde\na échoué: [accent]{0} +text.save.import.fail = [crimson]L'importation de la sauvegarde\na échouée: [accent]{0} +text.save.export.fail = [crimson]L'exportation de la sauvegarde\na échouée: [accent]{0} text.save.import = Importer une sauvegarde text.save.newslot = Nom de la sauvegarde: text.save.rename = Renommer @@ -286,6 +289,7 @@ text.no = Non text.info.title = Info text.error.title = [crimson]Une erreur s'est produite text.error.crashtitle = Une erreur s'est produite +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Info sur le bloc text.blocks.powercapacity = Capacité d'énergie text.blocks.powershot = Énergie/Tir @@ -318,7 +322,8 @@ text.blocks.coolant = Liquide de refroidissement text.blocks.coolantuse = Quantité de liquide de refroidissement utilisé text.blocks.inputliquidfuel = Carburant liquide text.blocks.liquidfueluse = Quantité de carburant liquide utilisé -text.blocks.explosive = Hautement explosif ! +text.blocks.boostitem = Objet boostant la production +text.blocks.boostliquid = Liquide boostant la production text.blocks.health = Santé text.blocks.inaccuracy = Précision text.blocks.shots = Tirs @@ -343,6 +348,7 @@ text.category.liquids = Liquides text.category.items = Objets text.category.crafting = Fabrication text.category.shooting = Défense +text.category.optional = Améliorations facultatives setting.autotarget.name = Visée automatique setting.fpscap.name = Max FPS setting.fpscap.none = Vide @@ -359,7 +365,6 @@ setting.sensitivity.name = Contôle de la sensibilité setting.saveinterval.name = Intervalle des sauvegardes auto setting.seconds = {0} Secondes setting.fullscreen.name = Plein écran -setting.multithread.name = Multithreading setting.fps.name = Afficher FPS setting.vsync.name = VSync setting.lasers.name = Afficher les rayons des lasers @@ -368,7 +373,7 @@ setting.musicvol.name = Volume de la musique setting.mutemusic.name = Couper la musique setting.sfxvol.name = Volume des SFX setting.mutesound.name = Couper les SFX -setting.crashreport.name = Send Anonymous Crash Reports +setting.crashreport.name = Envoyer des rapports d'incident anonymement. text.keybind.title = Paramétrer les touches category.general.name = Général category.view.name = Voir @@ -404,8 +409,6 @@ mode.waves.name = Vagues mode.waves.description = Le mode normal. Ressources limitées et vagues déclenchées automatiquement. mode.sandbox.name = Bac à sable mode.sandbox.description = Ressources infinies et pas de compte à rebours pour les vagues. -mode.custom.warning = Notez que les blocs débloqués en partie personnalisées ne sont pas conservés pour les secteurs.\n\n[LIGHT_GRAY]En mode bac à sable, seul les blocs débloqués en mode secteur peuvent être utilisés. -mode.custom.warning.read = Juste pour vous assurer que vous l'avez lu:\n[scarlet]Les déverrouillages dans les jeux personnalisés ne sont pas transférés aux secteurs ou à d'autres modes!\n\n[LIGHT_GRAY](J'aimerais que ce ne soit pas nécessaire, mais apparemment c'est le cas) mode.freebuild.name = Construction libre mode.freebuild.description = Ressources limitées et pas de compte à rebours pour les vagues. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_in_ID.properties b/core/assets/bundles/bundle_in_ID.properties index fe9cf095c1..387e2f6bf3 100644 --- a/core/assets/bundles/bundle_in_ID.properties +++ b/core/assets/bundles/bundle_in_ID.properties @@ -286,6 +286,7 @@ text.no = No text.info.title = [accent]Info text.error.title = [crimson]Telah terjadi kesalahan text.error.crashtitle = Telah terjadi kesalahan +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Info Blok text.blocks.powercapacity = Kapasitas Tenaga text.blocks.powershot = Tenaga/tembakan @@ -318,7 +319,8 @@ text.blocks.coolant = Coolant text.blocks.coolantuse = Coolant Use text.blocks.inputliquidfuel = Fuel Liquid text.blocks.liquidfueluse = Liquid Fuel Use -text.blocks.explosive = Mudah meledak! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Darah text.blocks.inaccuracy = Ketidaktelitian text.blocks.shots = Tembakan @@ -343,6 +345,7 @@ text.category.liquids = Liquids text.category.items = Items text.category.crafting = Crafting text.category.shooting = Shooting +text.category.optional = Optional Enhancements setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS setting.fpscap.none = None @@ -359,7 +362,6 @@ setting.sensitivity.name = Sensitivitas Pengendali setting.saveinterval.name = Waktu Simpan Otomatis setting.seconds = {0} Detik setting.fullscreen.name = Layar Penuh -setting.multithread.name = Multithreading setting.fps.name = Tunjukkan FPS setting.vsync.name = VSync setting.lasers.name = Tampilkan Laser Tenaga @@ -404,8 +406,6 @@ mode.waves.name = gelombang mode.waves.description = the normal mode. limited resources and automatic incoming waves. mode.sandbox.name = sandbox mode.sandbox.description = infinite resources and no timer for waves. -mode.custom.warning = Note that blocks cannot be used in custom games until they are unlocked in sectors.\n\n[LIGHT_GRAY]If you have not unlocked any blocks, none will appear. -mode.custom.warning.read = Just to make sure you've read it:\n[scarlet]UNLOCKS IN CUSTOM GAMES DO NOT CARRY OVER TO SECTORS OR OTHER MODES!\n\n[LIGHT_GRAY](I wish this wasn't necessary, but apparently it is) mode.freebuild.name = freebuild mode.freebuild.description = limited resources and no timer for waves. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_it.properties b/core/assets/bundles/bundle_it.properties index 1001b8369c..514ff0569f 100644 --- a/core/assets/bundles/bundle_it.properties +++ b/core/assets/bundles/bundle_it.properties @@ -286,6 +286,7 @@ text.no = No text.info.title = [accent] Info text.error.title = [crimson]Si è verificato un errore text.error.crashtitle = Si è verificato un errore +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = info sul blocco text.blocks.powercapacity = Capacità Energetica text.blocks.powershot = Danno/Colpo @@ -318,7 +319,8 @@ text.blocks.coolant = Refrigerante text.blocks.coolantuse = uso refrigerante text.blocks.inputliquidfuel = carburante liquido text.blocks.liquidfueluse = Utilizzo carburante liquido -text.blocks.explosive = Altamente esplosivo! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Salute text.blocks.inaccuracy = Inaccuratezza text.blocks.shots = Colpi @@ -343,6 +345,7 @@ text.category.liquids = Liquidi text.category.items = Oggetti text.category.crafting = Produzione text.category.shooting = Potenza di fuoco +text.category.optional = Optional Enhancements setting.autotarget.name = Auto-Target setting.fpscap.name = Limite FPS setting.fpscap.none = Niente @@ -359,7 +362,6 @@ setting.sensitivity.name = Sensibilità del controller setting.saveinterval.name = Intervallo di salvataggio automatico setting.seconds = {0} Secondi setting.fullscreen.name = Schermo Intero -setting.multithread.name = multithreading setting.fps.name = Mostra FPS setting.vsync.name = VSync setting.lasers.name = Mostra Laser Energetici @@ -404,8 +406,6 @@ mode.waves.name = ondate mode.waves.description = modalità normale. risorse limitate e ondate automatiche. mode.sandbox.name = Sandbox mode.sandbox.description = risorse infinite e nessun timer per le ondate. -mode.custom.warning = Note that blocks cannot be used in custom games until they are unlocked in sectors.\n\n[LIGHT_GRAY]If you have not unlocked any blocks, none will appear. -mode.custom.warning.read = Just to make sure you've read it:\n[scarlet]UNLOCKS IN CUSTOM GAMES DO NOT CARRY OVER TO SECTORS OR OTHER MODES!\n\n[LIGHT_GRAY](I wish this wasn't necessary, but apparently it is) mode.freebuild.name = freebuild mode.freebuild.description = risorse limitate e nessun timer per le ondate. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_ja.properties b/core/assets/bundles/bundle_ja.properties index 109bd62369..b9c8600522 100644 --- a/core/assets/bundles/bundle_ja.properties +++ b/core/assets/bundles/bundle_ja.properties @@ -1,5 +1,6 @@ text.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!) text.credits = クレジット +text.contributors = 翻訳や協力してくださった方々 text.discord = DiscordのMindustryに参加! text.link.discord.description = Mindustryの公式Discordグループ text.link.github.description = ゲームのソースコード @@ -22,7 +23,7 @@ text.level.select = レベル選択 text.level.mode = ゲームモード: text.construction.desktop = ブロックの選択や建設を止めるには、[accent]スペースを使用してください[]。 text.construction.title = ブロック建設ガイド -text.construction = [accent]ブロック建設モード[]になりました。\n設置するには、機体の近くの設置可能な場所をタップしてください。\nブロックを選択した状態で、チェックボタンを押して確認すると、機体が建設を始めます。\n\n- [accent]ブロックの削除[]は、タップで範囲を選択してください。\n- [accent]範囲の選択[]は、長押しして、範囲のブロックをドラッグしてください。\n- [accent]一列にブロックを設置[]するには、 タップで空いている場所を長押しして、伸ばしたい方向にドラッグしてください\n- [accent]建設や範囲の選択をキャンセル[]するには、左下の X ボタンを押してください。 +text.construction = [accent]ブロック建設モード[]になりました。\n設置するには、機体の近くの設置可能な場所をタップしてください。\nブロックを選択した状態で、チェックボタンを押して確認すると、機体が建設を始めます。\n\n- [accent]ブロックの撤去[]は、タップして範囲を選択してください。\n- [accent]範囲の選択[]は、長押しして、範囲のブロックをドラッグしてください。\n- [accent]一列にブロックを設置[]するには、 タップで空いている場所を長押しして、伸ばしたい方向にドラッグしてください\n- [accent]建設や範囲の選択をキャンセル[]するには、左下の X ボタンを押してください。 text.deconstruction.title = ブロック撤去ガイド text.deconstruction = [accent]ブロック撤去モード[]になりました。\n\nブロックを撤去するには、機体の近くのブロックをタップしてください。\nブロックを選択した状態で、チェックボタンを押して確認すると、機体がブロックの撤去を始めます。\n\n- [accent]ブロックの破壊[]は、タップで範囲を選択してください。\n- [accent]範囲を選択してブロックを撤去[]するには、 タップで空いている場所を長押しして、伸ばしたい方向にドラッグしてください\n- [accent]撤去や範囲選択をキャンセル[]するには、左下の X ボタンを押してください。 text.showagain = 次回以降表示しない @@ -71,6 +72,7 @@ text.nextmission = 次のミッションへ text.maps.none = [LIGHT_GRAY]マップが存在しません! text.about.button = About text.name = 名前: +text.noname = 先に[accent]プレイヤー名[]を決めてください。 text.filename = ファイル名: text.unlocked = 新しいブロックをアンロック! text.unlocked.plural = 新しいブロックをアンロック! @@ -286,6 +288,7 @@ text.no = いいえ text.info.title = 情報 text.error.title = [crimson]エラーが発生しました text.error.crashtitle = エラーが発生しました +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = ブロック情報 text.blocks.powercapacity = 電力容量 text.blocks.powershot = 電力/ショット @@ -301,7 +304,7 @@ text.blocks.powerdamage = 電力/ダメージ text.blocks.inputitemcapacity = 搬入アイテム容量 text.blocks.outputitemcapacity = 搬出アイテム容量 text.blocks.itemcapacity = アイテム容量 -text.blocks.basepowergeneration = 電力発電量 +text.blocks.basepowergeneration = 基本発電量 text.blocks.powertransferspeed = 電力伝送量 text.blocks.craftspeed = 生産速度 text.blocks.inputliquid = 必要な液体 @@ -310,7 +313,7 @@ text.blocks.inputitem = 必要なアイテム text.blocks.inputitems = 必要なアイテム text.blocks.outputitem = 搬出アイテム text.blocks.drilltier = ドリル -text.blocks.drillspeed = 採掘速度 +text.blocks.drillspeed = 基本採掘速度 text.blocks.liquidoutput = 搬出液体 text.blocks.liquidoutputspeed = 液体搬出速度 text.blocks.liquiduse = 液体使用量 @@ -318,7 +321,8 @@ text.blocks.coolant = 冷却 text.blocks.coolantuse = 冷却使用量 text.blocks.inputliquidfuel = 液体燃料 text.blocks.liquidfueluse = 液体燃料使用量 -text.blocks.explosive = 高い爆発性! +text.blocks.boostitem = 加速アイテム +text.blocks.boostliquid = 加速液体 text.blocks.health = 耐久値 text.blocks.inaccuracy = 不正確 text.blocks.shots = ショット @@ -343,6 +347,7 @@ text.category.liquids = 液体 text.category.items = アイテム text.category.crafting = 製作速度 text.category.shooting = 攻撃速度 +text.category.optional = 機能強化オプション setting.autotarget.name = 自動ターゲット setting.fpscap.name = 最大FPS setting.fpscap.none = なし @@ -359,7 +364,6 @@ setting.sensitivity.name = 操作感度 setting.saveinterval.name = 自動保存間隔 setting.seconds = {0} 秒 setting.fullscreen.name = フルスクリーン -setting.multithread.name = マルチスレッド setting.fps.name = FPSを表示 setting.vsync.name = VSync setting.lasers.name = 電力レーザーを表示 @@ -399,13 +403,11 @@ keybind.chat_history_next.name = 次のチャット履歴 keybind.chat_scroll.name = チャットスクロール keybind.drop_unit.name = ドロップユニット keybind.zoom_minimap.name = ミニマップのズーム -mode.text.help.title = モードの説明 +mode.text.help.title = モード説明 mode.waves.name = ウェーブ mode.waves.description = ノーマルモードです。限られた資源でウェーブが自動的に始まります。 mode.sandbox.name = サンドボックス mode.sandbox.description = 無限の資源でウェーブを自由に始められます。 -mode.custom.warning = [scarlet]カスタムゲームまたは、サーバ内でのアンロックは保存されません。[]\n\nアンロックするには区域でプレイしてください。 -mode.custom.warning.read = 必ずお読みください:\n[scarlet]カスタムゲーム内でのアンロックは区域やほかのモードには影響しません!\n\n[LIGHT_GRAY](多分必要ないと思いますが) mode.freebuild.name = フリービルド mode.freebuild.description = 限られた資源でウェーブを自由に始められます。 mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 402732502c..e72a97601e 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -1,779 +1,780 @@ -text.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!) -text.credits=제작자 -text.discord=Mindustry Discord 에 참여하세요! -text.link.discord.description=공식 Mindustry Discord 채팅방 -text.link.github.description=게임 소스코드 -text.link.dev-builds.description=개발중인 빌드 -text.link.trello.description=다음 출시될 기능들을 게시한 공식 Trello 보드 -text.link.itch.io.description=PC 버전 다운로드와 HTML5 버전이 있는 itch.io 사이트 -text.link.google-play.description=Google Play 스토어 정보 -text.link.wiki.description=공식 Mindustry 위키 (영어) -text.linkfail=링크를 여는데 실패했습니다! URL이 기기의 클립보드에 복사되었습니다. -text.gameover=코어가 터졌습니다. 게임 오버! -text.gameover.pvp=[accent]{0}[] 팀이 승리했습니다! -text.sector.gameover=이 지역을 공략하는데 실패했습니다. 포기 하시겠습니까? -text.sector.retry=아니오 -text.highscore=[YELLOW]최고점수 달성! -text.wave.lasted=[accent]{0}[] 까지 버티셨습니다. -text.level.highscore=최고 점수 : [accent]{0} -text.level.delete.title=삭제 확인 -text.map.delete=정말로 "[accent]{0}[]" 맵을 삭제하시겠습니까? -text.level.select=맵 선택 -text.level.mode=게임모드 : -text.construction.desktop=PC 에서의 조작 방법이 변경되었습니다.\n블록 선택을 해제하거나 건설을 중지하려면 [accent]스페이스 바[]를 누르세요. -text.construction.title=블록 배치 안내서 -text.construction=[accent]블록 배치 모드[]를 선택하셨습니다.\n\n블록을 설치하고 싶으면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 배치 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요. \n- [accent]블록을 넓게 배치[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록을 한줄로 배치[]하고 싶다면 배치하고 싶은 시작 영역을 한번 탭 하고 길게 누르면서 드래그 하면 됩니다. \n- [accent]블록 배치 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다. -text.deconstruction.title=블록 삭제 안내서 -text.deconstruction=[accent]블록 삭제 모드[]를 선택하셨습니다\n\n블록을 삭제하고 싶다면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 파괴 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요\n- [accent]블록을 넓은 범위로 삭제[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록 삭제 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다. -text.showagain=다음 세션에서 이 메세지를 표시하지 않습니다 -text.coreattack=< 코어가 공격받고 있습니다! > -text.unlocks=아이템들 -text.savegame=게임 저장 -text.loadgame=게임 불러오기 -text.joingame=멀티플레이 -text.addplayers=플레이어 추가/제거 -text.customgame=커스텀 게임 -text.sectors=지역 플레이 -text.sector=지역 : [LIGHT_GRAY]{0} -text.sector.time=시간 : [LIGHT_GRAY]{0} -text.sector.deploy=시작 -text.sector.abandon=초기화 -text.sector.abandon.confirm=정말로 이 지역의 모든 진행상황을 초기화 하겠습니까?\n이 작업은 되돌릴 수 없습니다! -text.sector.resume=계속하기 -text.sector.locked=[scarlet][[완료안됨] -text.sector.unexplored=[accent][[탐색안됨] -text.missions=목표 : [LIGHT_GRAY] {0} -text.mission=목표 : [LIGHT_GRAY] {0} -text.mission.main=주요 목표 : [LIGHT_GRAY]{0} -text.mission.info=미션 정보 -text.mission.complete=미션 성공! -text.mission.complete.body=지역 {0},{1} 클리어. -text.mission.wave=[accent]{0}/{1}[] 단계 생존\n{2}초 남음 -text.mission.wave.enemies=[accent]{0}/{1} []단계 생존\n{2}마리 남음 -text.mission.wave.enemy=[accent]{0}/{1} []단계 생존\n{2}마리 남음 -text.mission.wave.menu=[accent]{0}[] 단계 -text.mission.battle=적 코어를 파괴하세요 -text.mission.resource.menu={0} {1}개 수집 -text.mission.resource={0} 을(를) 수집하세요\n[accent]{1}/{2} -text.mission.block={0} 를 만드세요 -text.mission.unit={0} 유닛을 만드세요 -text.mission.command=유닛에게 {0} 명령을 보내세요 -text.mission.linknode=전력 노드를 연결하세요 -text.mission.display=[accent]목표 : [LIGHT_GRAY]{0} -text.mission.mech=[accent]{0}[] 기체로 바꾸세요 -text.mission.create=[accent]{0}[] 을(를)설치하세요. -text.none=<없음> -text.close=닫기 -text.quit=나가기 -text.maps=맵 -text.continue=계속하기 -text.nextmission=다음 임무 -text.maps.none=[LIGHT_GRAY]맵을 찾을 수 없습니다! -text.about.button=정보 -text.name=이름 : -text.filename=파일 이름 : -text.unlocked=새 블록 잠금 해제됨 -text.unlocked.plural=잠금 해제 -text.players=현재 {0}명 접속중 -text.players.single=현재 {0}명만 있음. -text.server.closing=[accent]서버 닫는중... -text.server.kicked.kick=서버에서 추방되었습니다! -text.server.kicked.serverClose=서버 종료됨. -text.server.kicked.sectorComplete=지역 클리어. -text.server.kicked.sectorComplete.text=임무 성공.\n서버가 다음지역 맵으로 이동되었습니다. -text.server.kicked.clientOutdated=오래된 버전의 클라이언트 입니다! 게임을 업데이트 하세요! -text.server.kicked.serverOutdated=오래된 버전의 서버입니다! 서버 호스트 관리자에게 문의하세요! -text.server.kicked.banned=뭘 하셨는지는 모르겠지만, 이제 영원히 서버에 접속할 수 없습니다. -text.server.kicked.recentKick=방금 추방처리 되었습니다. 잠시 기다린 후에 접속 해 주세요. -text.server.kicked.nameInUse=이 닉네임이 이미 서버에서 사용중입니다. -text.server.kicked.nameEmpty=닉네임에는 반드시 영어 또는 숫자가 있어야 합니다. -text.server.kicked.idInUse=이미 서버에 접속중입니다! 다중 계정은 허용되지 않습니다. -text.server.kicked.customClient=이 서버는 직접 빌드한 버전을 지원하지 않습니다. 공식 버전을 사용하세요. -text.host.info=[accent]호스트[] 버튼은 현재 네트워크의 [scarlet]6567[] 포트를 사용합니다.\n[LIGHY_GRAY]같은 Wi-Fi 또는 로컬 네트워크[] 에서 서버 목록을 볼 수 있습니다.\n\n만약 플레이어들이 이 IP를 통해 어디에서나 연결할 수 있게 하고 싶다면, 공유기 설정에서 [accent]포트 포워딩[]을 해야 합니다.\n\n[LIGHT_GRAY]참고 : LAN 게임 연결에 문제가 있는 사람이 있다면, 방화벽 설정에서 Mindustry 가 로컬 네트워크에 액세스하도록 허용했는지 확인 해 주세요. -text.join.info=여기서 [accent]서버 IP[]를 입력하여 다른 서버에 접속할 수 있습니다.\n또는 [accent]로컬 네트워크(LAN)[] 서버를 검색하여 접속할 수 있습니다.\nLAN 및 WAN 멀티 플레이어 모두 지원됩니다.\n\n[LIGHT_GRAY]참고:여기에서는 자동으로 글로벌 서버를 추가하지 않습니다. IP로 다른 사람의 서버에 접속할려면 서버장에게 IP를 요청해야 합니다. -text.hostserver=서버 열기 -text.hostserver.mobile=서버\n열기 -text.host=서버 열기 -text.hosting=[accent]서버 여는중... -text.hosts.refresh=새로고침 -text.hosts.discovering=LAN 게임 찾기 -text.server.refreshing=서버 목록 새로고치는중... -text.hosts.none=[lightgray]LAN 게임을 찾을 수 없습니다! -text.host.invalid=[scarlet]서버에 연결할 수 없습니다! -text.trace=플레이어 정보 보기 -text.trace.playername=이름 : [accent]{0} -text.trace.ip=IP : [accent]{0} -text.trace.id=고유 ID : [accent]{0} -text.trace.android=Android 클라이언트 : [accent]{0} -text.trace.modclient=수정된 클라이언트 : [accent]{0} -text.trace.totalblocksbroken=총 블록 파괴 개수 : [accent]{0} -text.trace.structureblocksbroken=구조 블록 파괴 수 : [accent]{0} -text.trace.lastblockbroken=마지막으로 파괴한 블록 : [accent]{0} -text.trace.totalblocksplaced=총 설치한 블록 개수 : [accent]{0} -text.trace.lastblockplaced=마지막으로 설치한 블록 : [accent]{0} -text.invalidid=잘못된 클라이언트 ID 입니다! 공식 Mindustry Discord 으로 버그 보고서를 제출 해 주세요. -text.server.bans=차단된 유저 -text.server.bans.none=차단된 플레이어가 없습니다. -text.server.admins=관리자 -text.server.admins.none=관리자가 없습니다! -text.server.add=서버 추가 -text.server.delete=이 서버를 삭제 하시겠습니까? -text.server.hostname=호스트 : {0} -text.server.edit=서버 수정 -text.server.outdated=[crimson]서버 버전이 낮습니다![] -text.server.outdated.client=[Crimson]클라이언트 버전이 낮습니다![] -text.server.version=[lightgray]서버 버전 : {0} -text.server.custombuild=[yellow]커스텀 서버 -text.confirmban=이 플레이어를 차단하시겠습니까? -text.confirmkick=정말로 이 플레이어를 추방시키겠습니까? -text.confirmunban=이 플레이어를 차단해제 하시겠습니까? -text.confirmadmin=이 플레이어를 관리자로 만들겠습니까? -text.confirmunadmin=이 플레이어를 일반 유저로 만들겠습니까? -text.joingame.title=게임 참가 -text.joingame.ip=IP : -text.disconnect=서버와 연결이 해제되었습니다. -text.disconnect.data=맵 데이터를 받아오는데 실패했습니다. -text.connecting=[accent]연결중... -text.connecting.data=[accent]맵 데이터 다운로드중... -text.server.port=포트 : -text.server.addressinuse=이 주소는 이미 사용중입니다! -text.server.invalidport=포트 번호가 잘못되었습니다. -text.server.error=[crimson]{0}[accent]서버를 여는데 오류가 발생했습니다.[] -text.save.old=이 저장파일은 이전 버전의 게임용이며, 지금은 사용할 수 없습니다. \n\n[LIGHT_GRAY]4.0 정식때 이전 게임버전에서 만든 저장파일과 호환됩니다. -text.save.new=새로 저장 -text.save.overwrite=이 저장 슬롯을 덮어씌우겠습니까? -text.overwrite=덮어쓰기 -text.save.none=저장 파일을 찾지 못했습니다! -text.saveload=[accent]저장중... -text.savefail=게임을 저장하지 못했습니다! -text.save.delete.confirm=이 저장파일을 삭제 하시겠습니까? -text.save.delete=삭제 -text.save.export=저장파일 내보내기 -text.save.import.invalid=[accent]파일이 잘못되었습니다! -text.save.import.fail=[crimson]저장파일을 불러오지 못함 : [accent]{0} -text.save.export.fail=[crimson]저장파일을 내보내지 못함 : [accent]{0} -text.save.import=저장파일 불러오기 -text.save.newslot=저장 파일이름 : -text.save.rename=이름 변경 -text.save.rename.text=새 이름 : -text.selectslot=저장슬롯을 선택하십시오. -text.slot=[accent]{0}번째 슬롯 -text.save.corrupted=[accent]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[]. -text.sector.corrupted=[accent]저장 파일에서 지역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다. -text.empty=<비어있음> -text.on=켜기 -text.off=끄기 -text.save.autosave=자동저장 : {0} -text.save.map=맵 : {0} -text.save.wave={0}단계[] -text.save.difficulty=난이도 : {0} -text.save.date=마지막 저장날짜 : {0} -text.save.playtime=플레이시간 : {0} -text.confirm=확인 -text.delete=삭제 -text.ok=확인 -text.open=열기 -text.cancel=취소 -text.openlink=링크 열기 -text.copylink=링크 복사 -text.back=뒤로가기 -text.quit.confirm=정말로 종료하시겠습니까? -text.changelog.title=변경사항 -text.changelog.loading=변경사항 가져오는중... -text.changelog.error.android=[accent]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다. 이것은 내부 Android 버그 때문입니다. -text.changelog.error.ios=[accent]현재 iOS에서는 변경 사항을 지원하지 않습니다. -text.changelog.error=[scarlet]게임 변경사항을 가져오는 중 오류가 발생했습니다![]\n인터넷 연결을 확인하십시오. -text.changelog.current=[accent][[현재 버전] -text.changelog.latest=[accent][[최신 버전] -text.loading=[accent]불러오는중... -text.saving=[accent]저장중... -text.wave=[accent]{0}단계 -text.wave.waiting=남은 시간 : [green]{0}초[] -text.waiting=[LIGHT_GRAY]대기중... -text.waiting.players=다른 플레이어를 기다리는 중.. -text.wave.enemies=[LIGHT_GRAY]{0} 마리 남았음 -text.wave.enemy=[LIGHT_GRAY]{0} 마리 남음 -text.loadimage=사진 불러오기 -text.saveimage=사진 저장 -text.unknown=알 수 없음 -text.custom=커스텀 -text.builtin=기본맵 -text.map.delete.confirm=이 맵을 삭제하시겠습니까? 이 명령은 취소할 수 없습니다! -text.map.random=[accent]랜덤 맵 -text.map.nospawn=이 맵에 플레이어가 스폰 할 코어가 없습니다! 맵 편집기에서 [ROYAL]파란색[]코어를 맵에 추가하세요. -text.map.nospawn.pvp=이 맵에는 적팀 코어가 없습니다! 에디터에서 [scarlet]빨간팀[] 코어를 추가하세요. -text.map.invalid=파일이 잘못되었거나 손상되어 맵을 열 수 없습니다. -text.editor.brush=브러쉬 -text.editor.slope=\\ -text.editor.openin=편집기 열기 -text.editor.oregen=광물 무작위 생성 -text.editor.oregen.info=광물 무작위 생성 : -text.editor.mapinfo=맵 정보 -text.editor.author=만든이 : -text.editor.description=설명 : -text.editor.name=이름 : -text.editor.teams=팀 -text.editor.elevation=지형 높이 -text.editor.errorimageload=[accent]{0}[] 파일을 불러오는데 오류가 발생했습니다. -text.editor.errorimagesave=[accent]{0}[] 파일 저장중 오류가 발생했습니다. -text.editor.generate=생성 -text.editor.resize=맵 크기조정 -text.editor.loadmap=맵 불러오기 -text.editor.savemap=맵 저장 -text.editor.saved=저장됨! -text.editor.save.noname=지도에 이름이 없습니다! 메뉴 -> '맵 정보' 에서 설정하세요. -text.editor.save.overwrite=이 맵의 이름은 기존에 있던 맵을 덮어씁니다! '맵 정보' 메뉴에서 다른 이름을 선택하세요. -text.editor.import.exists=[scarlet]맵을 불러올 수 없음 : [] 기존에 있던 '{0}' 맵이 이미 존재합니다! -text.editor.import=가져오기 -text.editor.importmap=맵 가져오기 -text.editor.importmap.description=이미 존재하는 맵 가져오기 -text.editor.importfile=파일 가져오기 -text.editor.importfile.description=외부 맵 파일 가져오기 -text.editor.importimage=지형 사진 가져오기 -text.editor.importimage.description=외부 맵 이미지 파일 가져오기 -text.editor.export=내보내기 -text.editor.exportfile=파일 내보내기 -text.editor.exportfile.description=맵 파일 내보내기 -text.editor.exportimage=지형 이미지 내보내기 -text.editor.exportimage.description=맵 이미지 파일 내보내기 -text.editor.loadimage=지형 가져오기 -text.editor.saveimage=지형 내보내기 -text.editor.unsaved=[scarlet]변경사항을 저장하지 않았습니다![]\n정말로 나가시겠습니까? -text.editor.resizemap=맵 크기 조정 -text.editor.mapname=맵 이름 : -text.editor.overwrite=[accept]경고!이 명령은 기존 맵을 덮어씌우게 됩니다. -text.editor.overwrite.confirm=[scarlet]경고![] 이 이름을 가진 맵이 이미 있습니다. 덮어 쓰시겠습니까? -text.editor.selectmap=불러올 맵 선택 : -text.width=넓이 : -text.height=높이 : -text.menu=메뉴 -text.play=플레이 -text.load=불러오기 -text.save=저장 -text.fps={0}FPS -text.tps={0}TPS -text.ping=ping : {0}ms -text.language.restart=언어를 변경하려면 게임을 다시시작 해 주세요. -text.settings=설정 -text.tutorial=게임 방법 -text.editor=편집기 -text.mapeditor=맵 편집기 -text.donate=기부 -text.connectfail=[crimson]{0}[accent] 서버에 연결하지 못했습니다.[] -text.error.unreachable=서버에 연결하지 못했습니다. -text.error.invalidaddress=잘못된 주소입니다. -text.error.timedout=시간 초과!\n서버에 포트 포워딩이 설정되어 있고 주소가 올바른지 확인하십시오. -text.error.mismatch=패킷 오류:\n클라이언트/서버 버전이 일치하지 않습니다.\n접속할려는 서버가 최신 버전의 Mindustry 인지 확인하세요! -text.error.alreadyconnected=이미 접속중입니다. -text.error.mapnotfound=맵 파일을 찾을 수 없습니다! -text.error.any=알 수 없는 네트워크 오류. -text.settings.language=언어 -text.settings.reset=설정 초기화 -text.settings.rebind=키 재설정 -text.settings.controls=컨트롤 -text.settings.game=게임 -text.settings.sound=소리 -text.settings.graphics=그래픽 -text.settings.cleardata=게임 데이터 초기화... -text.settings.clear.confirm=정말로 초기화 하겠습니까?\n이 작업을 되돌릴 수 없습니다! -text.settings.clearall.confirm=[scarlet]경고![]\n이 작업은 저장된 맵, 맵파일, 잠금 해제된 목록과 키 매핑, 그리고 모든 데이터를 삭제합니다.\n확인 버튼을 다시 눌러 모든 데이터를 삭제하고 게임에서 나갑니다. -text.settings.clearsectors=지역 초기화 -text.settings.clearunlocks=잠금 해제 초기화 -text.settings.clearall=모두 초기화 -text.paused=일시 정지 -text.yes=예 -text.no=아니오 -text.info.title=[accent]정보 -text.error.title=[crimson]오류가 발생했습니다. -text.error.crashtitle=오류가 발생했습니다. -text.blocks.unknown=[LIGHT_GRAY]??? -text.blocks.blockinfo=블록 정보 -text.blocks.powercapacity=최대 전력 용량 -text.blocks.powershot=1발당 전력 소모량 -text.blocks.targetsair=공중공격 가능 -text.blocks.itemspeed=유닛 이동 속도 -text.blocks.shootrange=사거리 -text.blocks.size=블록 크기 -text.blocks.liquidcapacity=최대 액체 용량 -text.blocks.maxitemssecond=최대 아이템 보관량 -text.blocks.powerrange=전력 범위 -text.blocks.poweruse=전력 사용 -text.blocks.powerdamage=전력/데미지 -text.blocks.inputitemcapacity=입력 아이템 용량 -text.blocks.outputitemcapacity=출력 아이템 용량 -text.blocks.itemcapacity=저장 용량 -text.blocks.basepowergeneration=기지 전력 생성기 -text.blocks.powertransferspeed=전력 전송량 -text.blocks.craftspeed=생산 속도 -text.blocks.inputliquid=사용되는 액체 -text.blocks.inputliquidaux=보조 액체 -text.blocks.inputitem=사용되는 아이템 -text.blocks.inputitems=사용되는 아이템들 -text.blocks.outputitem=출력 아이템 -text.blocks.drilltier=드릴 -text.blocks.drillspeed=기본 드릴 속도 -text.blocks.liquidoutput=액체 출력 -text.blocks.liquidoutputspeed=액체 출력속도 -text.blocks.liquiduse=액체 사용량 -text.blocks.coolant=냉각제 -text.blocks.coolantuse=냉각수 사용 -text.blocks.inputliquidfuel=연료 액 -text.blocks.liquidfueluse=액체 연료 사용 -text.blocks.explosive=이 블록이 터지면 주변 블록과 같이 자폭을 합니다!! -text.blocks.health=체력 -text.blocks.inaccuracy=오차각 -text.blocks.shots=발포 횟수 -text.blocks.reload=재장전 -text.blocks.inputfuel=연료 -text.blocks.fuelburntime=연료 연소 시간 -text.blocks.inputcapacity=입력 용량 -text.blocks.outputcapacity=출력 용량 -text.unit.blocks=블록 -text.unit.powersecond=전력/초 -text.unit.liquidsecond=액체/초 -text.unit.itemssecond=개/초 -text.unit.pixelssecond=초당 픽셀 -text.unit.liquidunits=액체 -text.unit.powerunits=전력 -text.unit.degrees=도 -text.unit.seconds=초 -text.unit.items=아이템 -text.category.general=일반 -text.category.power=전력 -text.category.liquids=액체 -text.category.items=아이템 -text.category.crafting=제작 -text.category.shooting=사격 -setting.autotarget.name=자동 조준 -setting.fpscap.name=최대 FPS -setting.fpscap.none=없음 -setting.fpscap.text={0} FPS -setting.difficulty.training=훈련 -setting.difficulty.easy=쉬움 -setting.difficulty.normal=보통 -setting.difficulty.hard=어려움 -setting.difficulty.insane=[#00ff00]멀[#2efe2e]티[#58fa58]플[#81f781]레[#a9f5a9]이 [#81f781]전[#58fa58]용[] -setting.difficulty.name=난이도 : -setting.screenshake.name=화면 흔들기 강도 -setting.effects.name=화면 효과 -setting.sensitivity.name=컨트롤러 감도 -setting.saveinterval.name=자동저장 간격 -setting.seconds={0}초 -setting.fullscreen.name=전체 화면 -setting.multithread.name=멀티 스레드 -setting.fps.name=FPS 표시 -setting.vsync.name=VSync 활성화 -setting.lasers.name=전력 노드 레이저 표시 -setting.minimap.name=미니맵 보기 -setting.musicvol.name=음악 크기 -setting.mutemusic.name=음소거 -setting.sfxvol.name=효과음 크기 -setting.mutesound.name=소리 끄기 -setting.crashreport.name=오류 보고서 보내기 -text.keybind.title=조작키 설정 -category.general.name=일반 -category.view.name=보기 -category.multiplayer.name=멀티플레이 -command.attack=공격 -command.retreat=후퇴 -command.patrol=순찰 -keybind.press=키를 누르세요... -keybind.press.axis=축 또는 키를 누르세요... -keybind.move_x.name=오른쪽/왼쪽 이동 -keybind.move_y.name=위쪽/아래쪽 이동 -keybind.select.name=선택 -keybind.break.name=파괴 -keybind.deselect.name=선택해제 -keybind.shoot.name=사격 -keybind.zoom_hold.name=길게눌러 확대 -keybind.zoom.name=확대 -keybind.menu.name=메뉴 -keybind.pause.name=일시중지 -keybind.dash.name=달리기 -keybind.chat.name=채팅 -keybind.player_list.name=플레이어 목록 -keybind.console.name=콘솔 -keybind.rotate.name=회전 -keybind.toggle_menus.name=메뉴 보이기/숨기기 -keybind.chat_history_prev.name=이전 채팅기록 -keybind.chat_history_next.name=다음 채팅기록 -keybind.chat_scroll.name=채팅 스크롤 -keybind.drop_unit.name=유닛 드롭 -keybind.zoom_minimap.name=미니맵 확대 -mode.text.help.title=도움말 -mode.waves.name=단계 -mode.waves.description=이것은 일반 모드입니다. 제한된 자원과 자동으로 다음 단계가 시작됩니다. -mode.sandbox.name=샌드박스 -mode.sandbox.description=무한한 자원과 다음단계 시작을 위한 타이머가 없습니다. -mode.freebuild.name=자유 건축 -mode.freebuild.description=제한된 자원과 다음단계 시작을 위한 타이머가 없습니다. -mode.pvp.name=PvP -mode.pvp.description=몹이 아닌 실제 플레이어와 PvP를 합니다. -content.item.name=아이템 -content.liquid.name=액체 -content.unit.name=유닛 -content.recipe.name=블록 -content.mech.name=기체 -item.stone.name=돌 -item.stone.description=주로 용암을 사용하여 얻을 수 있는 자원입니다. -item.copper.name=구리 -item.copper.description=모든 유형의 블록에서 광범위하게 사용되는 자원입니다. -item.lead.name=납 -item.lead.description=쉽게 구할 수 있으며, 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다. -item.coal.name=석탄 -item.coal.description=쉽게 구할 수 있으며, 주로 제련소 등에서 연료로 사용됩니다. -item.dense-alloy.name=고밀도 합금 -item.dense-alloy.description=납과 구리로 만든 튼튼한 고밀도 합금.\n고급 수송 블록이나 상위 티어 블록을 건설하는데 사용됩니다. -item.titanium.name=티타늄 -item.titanium.description=파이프 재료나 고급 드릴, 비행기/기체 등에서 재료로 사용되는 자원입니다. -item.thorium.name=토륨 -item.thorium.description=건물의 재료, 포탑의 탄약 또는 핵연료로 사용되는 방사성 금속입니다. -item.silicon.name=실리콘 -item.silicon.description=매우 유용한 반도체로, 태양 전지판과 복잡한 전자 제품에 사용할 수 있습니다. -item.plastanium.name=플라스터늄 -item.plastanium.description=고급 항공기 및 분열 탄약에 사용되는 가벼운 연성 재료. -item.phase-fabric.name=메타 -item.phase-fabric.description=최첨단 전자 제품과 자기수리 기술에 사용되는 거의 무중력에 가까운 물질입니다. -item.surge-alloy.name=설금 -item.surge-alloy.description=주로 건물의 재료로 사용되는 자원입니다 -item.biomatter.name=바이오메터 -item.biomatter.description=이것은 유기농 덤불입니다!\n압축기에 넣어 석유로 바꿀 수 있습니다. -item.sand.name=모래 -item.sand.description=고밀도 합금이나 플럭스 등에서 제련시 광범위하게 사용되는 일반적인 재료입니다. -item.blast-compound.name=폭발물 -item.blast-compound.description=포탑 및 건설의 재료로 사용되는 휘발성 폭발물.\n연료로도 사용할 수 있지만, 별로 추천하지는 않습니다. -item.pyratite.name=피라테 -item.pyratite.description=폭발성을 가진 재료로, 주로 포탑의 탄약으로 사용됩니다. -liquid.water.name=물 -liquid.lava.name=용암 -liquid.oil.name=석유 -liquid.cryofluid.name=냉각수 -mech.alpha-mech.name=알파 -mech.alpha-mech.weapon=중무장 소총 -mech.alpha-mech.ability=드론 소환 -mech.alpha-mech.description=표준 기체.\n적절한 속도와 공격력을 갖추고 있으며, 공격 능력을 높이기 위해 최대 3대의 드론을 만들 수 있습니다. -mech.delta-mech.name=델타 -mech.delta-mech.weapon=전격 생산기 -mech.delta-mech.ability=충전 -mech.delta-mech.description=빠르게 이동하는 적을 처치하기 위한 가벼운 기체.\n구조물에는 거의 피해를 주지 않지만, 전격 무기를 사용하여 많은 적군을 매우 빠르게 죽일 수 있습니다. -mech.tau-mech.name=타우 -mech.tau-mech.weapon=건물 수리총 -mech.tau-mech.ability=유닛 치료 -mech.tau-mech.description=지원형 기체.\n총을 발사하여 건물을 치료하고 회복 능력 사용으로 화재를 진압하거나, 반경 내 아군을 치유시킵니다. -mech.omega-mech.name=오메가 -mech.omega-mech.weapon=전방 유도미사일 -mech.omega-mech.ability=방어모드 -mech.omega-mech.description=지상 기체 최종판이자 건물 파괴용으로 적합한 부피가 크고 튼튼한 기체. 방어 모드는 최대 90% 의 피해를 줄일 수 있습니다. -mech.dart-ship.name=다트 -mech.dart-ship.weapon=소총 -mech.dart-ship.description=표준 비행선. 빠르고 가볍지만 공격력이 거의 없고 채광 속도가 느립니다. -mech.javelin-ship.name=자비린 -mech.javelin-ship.description=치고 빠지는 공격을 위한 비행선. 처음에는 느리지만, 가속도가 붙어 엄청난 속도로 미사일 피해를 입힐 수 있으며, 전격 능력을 사용할 수 있습니다. -mech.javelin-ship.weapon=유도 미사일 -mech.javelin-ship.ability=가속 전격 생성기 -mech.trident-ship.name=삼지창 -mech.trident-ship.description=대형 공중 폭격기. 당연하게도 엄청 단단합니다. -mech.trident-ship.weapon=폭탄 저장고 -mech.glaive-ship.name=글레브 -mech.glaive-ship.description=크고 잘 무장된 총을 가진 비행선. 방화용 리피터가 장착되어 있으며, 가속도와 최대속도가 높습니다. -mech.glaive-ship.weapon=방화총 -text.item.explosiveness=[LIGHT_GRAY]폭발력 : {0} -text.item.flammability=[LIGHT_GRAY]인화성 : {0} -text.item.radioactivity=[LIGHT_GRAY]방사능 : {0} -text.item.fluxiness=[LIGHT_GRAY]플럭스 파워 : {0} -text.unit.health=[LIGHT_GRAY]체력 : {0} -text.unit.speed=[LIGHT_GRAY]속도 : {0} -text.mech.weapon=[LIGHT_GRAY]무기 : {0} -text.mech.armor=[LIGHT_GRAY]방어력 : {0} -text.mech.itemcapacity=[LIGHT_GRAY]아이템 수용 용량 : {0} -text.mech.minespeed=[LIGHT_GRAY]채광 속도 : {0} -text.mech.minepower=[LIGHT_GRAY]채광 레벨 : {0} -text.mech.ability=[LIGHT_GRAY]능력 : {0} -text.liquid.heatcapacity=[LIGHT_GRAY]발열량 : {0} -text.liquid.viscosity=[LIGHT_GRAY]점도 : {0} -text.liquid.temperature=[LIGHT_GRAY]온도 : {0} -block.constructing={0}[LIGHT_GRAY](만드는중) -block.spawn.name=적 스폰지점 -block.core.name=코어 -block.metalfloor.name=철판 -block.deepwater.name=깊은물 -block.water.name=물 -block.lava.name=용암 -block.tar.name=타르 -block.blackstone.name=검은돌 -block.stone.name=돌 -block.dirt.name=흙 -block.sand.name=모래 -block.ice.name=얼음 -block.snow.name=눈 -block.grass.name=잔디 -block.shrub.name=관목 -block.rock.name=바위 -block.blackrock.name=검은바위 -block.icerock.name=얼음바위 -block.copper-wall.name=구리벽 -block.copper-wall-large.name=큰 구리벽 -block.dense-alloy-wall.name=합금 벽 -block.dense-alloy-wall-large.name=큰 합금 벽 -block.phase-wall.name=메타벽 -block.phase-wall-large.name=큰 메타벽 -block.thorium-wall.name=토륨벽 -block.thorium-wall-large.name=대형 토륨벽 -block.door.name=문 -block.door-large.name=대형문 -block.duo.name=듀오 -block.scorch.name=스코치 -block.hail.name=헤일 -block.lancer.name=랜서 -block.conveyor.name=컨베이어 -block.titanium-conveyor.name=티타늄 컨베이어 -block.junction.name=교차기 -block.router.name=분배기 -block.distributor.name=대형 분배기 -block.sorter.name=필터 -block.sorter.description=아이템을 넣어서 필터에 설정된 아이템일 경우 바로 앞으로 통과하며, 그렇지 않을 경우 옆으로 통과합니다. -block.overflow-gate.name=오버플로 게이트 -block.overflow-gate.description=정면으로 가는 자원이 막히면 옆으로 출력하고, 그렇지 않으면 계속 정면으로 출력합니다. -block.smelter.name=제련소 -block.arc-smelter.name=대형 제련소 -block.silicon-smelter.name=실리콘 제련소 -block.phase-weaver.name=메타 합성기 -block.pulverizer.name=분쇄기 -block.cryofluidmixer.name=냉각수 제조기 -block.melter.name=융해기 -block.incinerator.name=소각로 -block.biomattercompressor.name=바이오메터 압축기 -block.separator.name=셉터 -block.centrifuge.name=원심 분리기 -block.power-node.name=전력 송신기 -block.power-node-large.name=대형 전력 송신기 -block.battery.name=배터리 -block.battery-large.name=대형 배터리 -block.combustion-generator.name=석탄 발전기 -block.turbine-generator.name=터빈 발전기 -block.mechanical-drill.name=기계식 드릴 -block.pneumatic-drill.name=강철 드릴 -block.laser-drill.name=레이저 드릴 -block.water-extractor.name=물 추출기 -block.cultivator.name=온실 -block.alpha-mech-pad.name=알파 기체 패드 -block.dart-ship-pad.name=다트 비행선 패드 -block.delta-mech-pad.name=델타 기체 패드 -block.javelin-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=파이프 -block.mechanical-pump.name=기계식 펌프 -block.itemsource.name=아이템 소스 -block.itemvoid.name=아이템 삭제 장치 -block.liquidsource.name=무한 액체공급 장치 -block.powervoid.name=방전장치 -block.powerinfinite.name=무한 전력공급 장치 -block.unloader.name=언로더 -block.vault.name=창고 -block.wave.name=파도 -block.swarmer.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.solidifer.name=고체 -block.solar-panel.name=태양 전지판 -block.solar-panel-large.name=대형 태양 전지판 -block.oil-extractor.name=석유 추출기 -block.spirit-factory.name=스피릿 드론 공장 -block.phantom-factory.name=팬텀 드론 공장 -block.wraith-factory.name=유령 전투기 공장 -block.ghoul-factory.name=구울 폭격기 공장 -block.dagger-factory.name=디거 기체 공장 -block.titan-factory.name=타이탄 기체 공장 -block.fortress-factory.name=포트리스 기체 공장 -block.revenant-factory.name=레비던트 전투기 공장 -block.repair-point.name=정비소 -block.pulse-conduit.name=퓨즈 파이프 -block.phase-conduit.name=메타 파이프 -block.liquid-router.name=액체 분배기 -block.liquid-tank.name=물탱크 -block.liquid-junction.name=액체 교차기 -block.bridge-conduit.name=다리 파이프 -block.rotary-pump.name=동력 펌프 -block.thorium-reactor.name=토륨 원자로 -block.command-center.name=명령 본부 -block.mass-driver.name=물질 이동기 -block.blast-drill.name=고속 발열 드릴 -block.thermal-pump.name=화력 펌프 -block.thermal-generator.name=열발전기 -block.alloy-smelter.name=설금 제련소 -block.mend-projector.name=수리 프로젝터 -block.surge-wall.name=설금벽 -block.surge-wall-large.name=큰 설금벽 -block.cyclone.name=사이클론 -block.fuse.name=퓨즈 -block.shock-mine.name=전격 지뢰 -block.overdrive-projector.name=오버드라이브 프로젝터 -block.force-projector.name=보호막 프로젝터 -block.arc.name=Arc -block.rtg-generator.name=토륨 발전소 -block.spectre.name=스펙터 -block.meltdown.name=멜트다운 -block.container.name=컨테이너 -team.blue.name=블루팀 -team.red.name=레드팀 -team.orange.name=오렌지팀 -team.none.name=공기팀 -team.green.name=그린팀 -team.purple.name=보라색팀 -unit.alpha-drone.name=알파 드론 -unit.spirit.name=스피릿 드론 -unit.spirit.description=기본 드론 유닛. 기본적으로 코어에서 1개가 스폰됩니다. 자동으로 채광하며 아이템을 수집하고, 블록을 수리합니다. -unit.phantom.name=팬텀 드론 -unit.phantom.description=첨단 드론 유닛. 광석을 자동으로 채광하며, 아이템을 수집하고 블록을 수리합니다. 일반 드론보다 훨씬 효과적입니다. -unit.dagger.name=디거 -unit.dagger.description=기본 지상 유닛입니다. 스웜과 같이 쓰면 유용합니다. -unit.titan.name=타이탄 -unit.titan.description=고급 지상 유닛입니다. 고밀도 합금을 탄약으로 사용하며 지상과 공중 둘다 공격할 수 있습니다. -unit.ghoul.name=구울 폭격기 -unit.ghoul.description=무거운 지상 폭격기 입니다. 폭발물 또는 피라테를 탄약으로 사용합니다. -unit.wraith.name=유령 전투기 -unit.wraith.description=코어를 집중적으로 공격하는 방식을 사용하는 전투기 입니다. -unit.fortress.name=포트리스 -unit.fortress.description=중포 지상 유닛. 높은 공격력과 체력을 가지고 있습니다. -unit.revenant.name=레비던트 -unit.revenant.description=대형 레이저를 발사하는 공중 유닛입니다. -tutorial.begin=플레이어의 주요 목표는 [LIGHT_GRAY]적군[]을 제거하는 것입니다.\n\n이 게임은 [accent]구리를 채광[]하는 것으로 시작합니다.\n이것을 하기 위해 플레이어의 중심부 근처에 있는 구리 광맥을 누르세요. -tutorial.drill=수동으로 채광하는 것은 효율이 낮습니다.\n[accent]드릴[]은 자동으로 채광 작업을 합니다.\n구리 광맥에 표시된 영역에 드릴을 하나를 놓으세요. -tutorial.conveyor=[accent]컨베이어[]를 사용하여 아이템을 코어로 운반합니다.\n드릴에서 코어까지 컨베이어 라인을 만드세요. -tutorial.morecopper=더 많은 구리가 필요합니다.\n\n수동으로 채광하거나, 드릴을 더 설치하세요. -tutorial.turret=방어 구조물은 [LIGHT_GRAY]적[]을 물리치기 위해 반드시 필요합니다.\n기지 근처에 듀오 터렛을 설치하세요. -tutorial.drillturret=듀오 터렛이 작동하기 위해서는[accent] 구리 탄약 []을 필요로 합니다.\n터렛 옆에 드릴을 설치하여 구리를 공급하세요. -tutorial.waves=[LIGHT_GRAY]적[]이 접근합니다.\n\n2단계 동안 코어를 보호하고 더 많은 터렛을 만드세요. -tutorial.lead=더 많은 광석을 이용할 수 있습니다. [accent]납[]을 찾아 탐색하세요.\n\n아이템을 코어로 전송할려면 플레이어 기체 또는 비행기에서 코어로 드래그 하세요. -tutorial.smelter=구리와 납은 약한 금속입니다.\n[accent]고밀도 합금[]은 제련소에서 만들 수 있습니다.\n\n하나 만드세요. -tutorial.densealloy=이 제련소는 이제 고밀도 합금을 생산할 것입니다.\n몇개 더 생산하세요.\n필요한 경우 더 만드세요. -tutorial.siliconsmelter=이제 이코어는 채굴과 수리하기 위한[accent] 스피릿 드론[]을 생성 할 것 입니다.\n\n[accent]실리콘[]을 사용해 다른 유닛을 생성하기 위한 공장을 만들 수 있습니다.\n실리콘 제련기를 제작하세요! -tutorial.silicondrill=실리콘을 제작하려면[accent] 석탄[] 과[accent] 모래[]가 필요합니다.\n드릴을 먼저 건설해보는건 어떤가요? -tutorial.generator=이 건물은 [LIGHT_YELLOW]전력[]이 필요합니다.\n[accent] 석탄 발전기[]를 건설하세요. -tutorial.generatordrill=[accent] 석탄 발전기[]는 연료가 필요합니다.\n[accent] 석탄[]을 드릴로 채굴해서 연료를 체워주세요. -tutorial.node=전력은 송신해줄 송신기가 필요합니다.\n[accent] 전력 송신기[]를 석탄 등등 발전기 옆에 설치해서 생산된 전기를 다른곳으로 송신합시다. -tutorial.nodelink=전력은 전력 블록과 발전기에 연결하거나, 연결된 전력 송신기를 통해 전송이 가능합니다. \n\n전력 송신기를 누르고 발전기와 실리콘 제련기를 선택하여 전원을 연결합시다. -tutorial.silicon=실리콘이 생산되고 있습니다.\n\n생산 시스템의 개선을 권고 드립니다. -tutorial.daggerfactory=이[accent] 디거 기체 공장[]은\n\n공격하는 기체를 생산하기 위해 사용됩니다. -tutorial.router=공장을 작동시키기 위해 자원이 필요합니다.\n컨베이어에 운반되고 있는 자원을 분할할 분배기를 만드세요. -tutorial.dagger=전력 노드를 공장에 연결하세요.\n일단 요구 사항이 충족되면 기체 생산을 시작합니다.\n\n필요에 따라 드릴 및 발전기, 컨베이어를 더 많이 만들 수 있습니다. -tutorial.battle=[LIGHT_GRAY]적[]의 코어가 드러났습니다.\n당신의 부대와 디거를 사용하여 파괴하세요. -block.core.description=게임에서 가장 중요한 건물.\n파괴되면 게임이 끝납니다. -block.copper-wall.description=구리로 만든 벽. -block.copper-wall-large.description=구리로 만든 큰 벽. -block.dense-alloy-wall.description=고밀도 합금으로 만든 벽. 구리벽보다 체력이 높습니다. -block.dense-alloy-wall-large.description=고밀도 합금으로 만든 큰 벽. -block.thorium-wall.description=토륨으로 만든 벽. -block.thorium-wall-large.description=토륨으로 만든 큰 벽. -block.phase-wall.description=날라오는 모든 총알을 튕겨내고 데미지를 입는 특수한 벽입니다. -block.phase-wall-large.description=메타로 제작한 큰 벽. 날라오는 총알을 모두 튕겨냅니다. -block.surge-wall.description=데미지를 입으면 번개를 일으켜 대상에게 피해를 입히는 특수한 벽입니다. -block.surge-wall-large.description=설금을 재료로 한 큰 벽.\n데미지를 입으면 번개를 일으켜 대상에게 피해를 입힙니다. -block.door.description=유닛이 지나갈 수 있도록 만든 문. 클릭하면 열고 닫습니다. -block.door-large.description=유닛이 자나갈 수 있도록 만든 큰 문. 클릭하면 열고 닫습니다. -block.mend-projector.description=주위 건물을 치료하는 건물입니다. -block.overdrive-projector.description=범위 내 모든 행동의 속도를 높여주는 보조형 건물입니다. -block.force-projector.description=보호막을 생성하는 건물.\n기본적으로 전력만 있으면 작동하지만, 메타를 넣어 보호막의 범위를 크게 확장시킬 수 있습니다. -block.shock-mine.description=적이 이 블록을 지나가면 전격 공격을 하는 함정형 방어 건물입니다. -block.duo.description=범용성을 가진 터렛.\n지상 및 공중공격을 하며, 초중반에 유용합니다. -block.arc.description=목표 방향으로 전격 공격을 하는 포탑입니다. -block.hail.description=장거리 지상 공격을 하는 터렛입니다.\n적이 오기 전에 쓸어버릴 수 있습니다. -block.lancer.description=중거리 레이져 포탑입니다.\n적을 관통하기 때문에 뭉쳐있는 적들에게 매우 효과적입니다. -block.wave.description=적이 있는 자리에 액체를 뿌립니다.\n이 포탑을 활용하여 액체를 뿌린 곳에 불을 붙이거나 적을 느리게 할 수 있습니다. -block.salvo.description=명중률이 높고, 3발씩 끊어 발사하는 포탑입니다. -block.swarmer.description=4발씩 끊어서 유도체를 발사하는 포탑입니다 -block.ripple.description=4개의 탄약으로 나눠 발사하여 명중률이 낮지만, 사거리가 매우 긴 포탑입니다. -block.cyclone.description=낮은 명중률과 높은 RPM 을 가진 포탑입니다.\n탄약이 남아있는 한 멈추지 않고 계속 연사합니다. -block.fuse.description=단거리에서 범위형 레이저를 발사하는 포탑입니다. -block.spectre.description=높은 명중률과 RPM 을 가진 포탑입니다.\n탄약이 남아있는 한 멈추지 않고 계속 연사합니다. -block.meltdown.description=목표를 따라 초대형 레이져를 발사하는 포탑입니다.\n뭉쳐있는 몹에게 매우 효과가 좋습니다. -block.conveyor.description=느린 속도로 자원을 수송할 수 있는 컨베이어. -block.titanium-conveyor.description=빠른 속도로 자원을 수송할 수 있는 컨베이어. -block.phase-conveyor.description=자원을 순간이동 시켜 주는 컨베이어 입니다. -block.junction.description=컨베이어를 교차시켜 자원을 수송할 때 사용할 수 있는 블록입니다. -block.mass-driver.description=자원을 받아서 다른 물질 이동기로 전달할 수 있는 블록입니다.\n엄청난 사거리를 가지고 있으며, 주로 컨베이어가 접근할 수 없는 곳에 유용하게 사용됩니다. -block.smelter.description=고밀도 합금을 제작할 수 있는 건물입니다. -block.arc-smelter.description=고밀도 합금을 제작할 수 있는 건물이지만, 이 건물은 석탄이 필요 없고 좀더 빠른 속도로 합금을 생산해낼 수 있습니다. -block.silicon-smelter.description=실리콘을 제작할 수 있는 건물입니다. -block.plastanium-compressor.description=플라스터늄을 제조할 수 있는 건물입니다. -block.phase-weaver.description=메타를 제작할 수 있는 건물입니다. -block.alloy-smelter.description=설금을 제작할 수 있는 건물입니다. -block.pulverizer.description=돌을 갈아서 모래로 만들 수 있는 건물입니다. -block.pyratite-mixer.description=피라테를 제조할 수 있는 건물입니다. -block.blast-mixer.description=폭발물을 제조할 수 있는 건물입니다. -block.cryofluidmixer.description=냉각수를 제작할 수 있는 건물입니다. -block.solidifer.description=용암을 돌로 만들 수 있는 건물입니다. -block.melter.description=돌로 용암을 만들 수 있는 건물입니다. -block.incinerator.description=불필요한 아이템을 소각시켜 줄 수 있는 건물입니다. -block.biomattercompressor.description=잔디밭에서 바이오메터를 추출할 수 있는 건물입니다. -block.separator.description=돌을 분해하여 각종 자원으로 재활용 할 수 있게 해 주는 건물입니다. -block.centrifuge.description=돌을 분해하여 각종 자원으로 재활용 할 수 있게 해 주는 건물이지만, 이 건물은 좀 더 다양한 자원을 얻을 수 있게 해 줍니다. -block.power-node.description=생성된 전력를 다른 건물로 전달하기 위한 전력 노드입니다. -block.power-node-large.description=생성된 전력를 다른 건물로 전달하기 위한 건물이며, 일반 노드보다 더 많은 전력을 이동시킬 수 있습니다. -block.battery.description=흔히 아는 충전식 배터리입니다.\n전력을 사용하는 건물에 전력이 떨어질경우, 이 배터리를 전력 노드에 연결하면 이 배터리에 저장된 전력을 소모하여 지속적으로 공급할 수 있습니다. -block.battery-large.description=일반 배터리보다 용량이 매우 커진 커진 배터리. -block.combustion-generator.description=석탄을 연료로 전력를 생산해내는 발전소 입니다. -block.turbine-generator.description=석탄 발전기보다 더 많은량의 전력를 생산하는 발전기입니다. -block.thermal-generator.description=용암을 원료로 전력을 생산할 수 있는 발전소입니다. -block.solar-panel.description=태양열을 받아 자기 스스로 전력을 생산하는 건물입니다. -block.solar-panel-large.description=태양열을 받아 자기 스스로 전력을 생산하지만, 이 블록은 더 빨리 전력을 생산할 수 있습니다. -block.thorium-reactor.description=토륨을 원료로 하는 토륨 원자로 입니다.\n많은 전력을 생산하지만 엄청난 열을 발생시키기 때문에, 많은 량의 물 또는 냉각수가 있어야 터지지 않고 작동합니다. -block.rtg-generator.description=냉각은 필요 없지만 토륨 원자로보다 적은량의 전력을 생산하는 방사선 동위원소 열전자 발전기. -block.unloader.description=해당 창고 및 코어에서 자원을 빼내는데 사용됩니다. -block.container.description=아이템을 임시로 저장할 수 있는 소형 창고입니다. -block.vault.description=아이템을 임시로 저장할 수 있는 대형 창고입니다. -block.mechanical-drill.description=구리로 제작할 수 있는 기본 드릴입니다. -block.pneumatic-drill.description=돌, 티타늄을 채광할 수 있는 고급 드릴입니다. -block.laser-drill.description=토륨을 채광할 수 있는 최고급 드릴입니다.\n전력과 물을 공급하여 빠른 속도로 채광할 수 있습니다. -block.blast-drill.description=최상위 드릴입니다. 엄청난 양의 전력과 물을 소모하는 대신, 매우 빠른 속도로 채광합니다. -block.water-extractor.description=바닥에서 물을 추출하여 건물에 공급할 수 있는 건물입니다. -block.cultivator.description=잔디에서 바이오메터를 추출할 수 있는 건물입니다. -block.oil-extractor.description=석유를 추출 해 주는 건물입니다. -block.dart-ship-pad.description=다트 비행선으로 바꿀 수 있는 패드입니다. -block.trident-ship-pad.description=삼지창 비행선으로 바꿀 수 있는 패드입니다. -block.javelin-ship-pad.description=자비린 비행선으로 바꿀 수 있는 패드입니다. -block.glaive-ship-pad.description=글레브 비행선으로 바꿀 수 있는 패드입니다. -block.tau-mech-pad.description=타우 기체로 바꿀 수 있는 패드 -block.delta-mech-pad.description=델타 기체로 바꿀 수 있는 패드입니다. -block.omega-mech-pad.description=오메가 기체로 바꿀 수 있는 패드 -block.spirit-factory.description=스피릿 유닛을 생산하는 공장입니다. -block.phantom-factory.description=유닛 팬텀을 생산하는 공장입니다. -block.wraith-factory.description=유닛 유령 전투기를 소환하는 공장입니다. -block.ghoul-factory.description=구울 유닛을 생산하는 공장입니다. -block.dagger-factory.description=디거를 생산하는 공장입니다. -block.titan-factory.description=타이탄 유닛을 생산할 수 있는 공장입니다. -block.fortress-factory.description=포트리스를 생산하는 공장입니다. -block.revenant-factory.description=레비던트 유닛을 생산할 수 있는 공장입니다. -block.repair-point.description=근처 유닛들을 수리하는 건물입니다. -block.command-center.description=생산된 유닛들을 제어할 수 있는 건물.\n첫번째 버튼은 적 기지로 공격하며, 두번째는 대기 상태, 세번째는 기지 근처를 돌며 정찰합니다. -block.conduit.description=일반 파이프. 액체가 지나갈 수 있도록 해 줍니다. -block.pulse-conduit.description=티타늄으로 만들어 졌으며, 일반 파이프보다 액체 수용량이 높습니다. -block.phase-conduit.description=물을 먼거리로 순간이동 시켜 주는 장치입니다. -block.liquid-router.description=물펌프를 다른 방향으로 분배할 수 있게 하는 블럭입니다. -block.liquid-tank.description=액체 종류를 저장할 수 있는 물탱크 입니다. -block.liquid-junction.description=물펌프와 다른 물펌프를 서로 교차시키게 할 수 있는 블럭입니다. -block.bridge-conduit.description=다리와 다리 사이를 연결하여 액체가 지나갈 수 있게 해 줍니다.\n주로 다리 사이에 지나갈 수 없는 장애물이 있을 때 사용합니다. -block.mechanical-pump.description=구리로 제작할 수 있는 기계식 물펌프입니다. -block.rotary-pump.description=일반 물 펌프보다 더 빠른 속도로 물을 끌어올릴 수 있는 펌프입니다. -block.thermal-pump.description=기계식 펌프보다 3배 빠른 속도로 액체를 퍼올릴 수 있는 펌프이며, 용암도 퍼올릴 수 있는 유일한 펌프입니다. -block.router.description=한 방향에서 아이템을 받은 후 최대 3개의 다른 방향으로 동일하게 출력합니다.\n재료를 한곳에서 여러 대상으로 분할하여 운반하는데 유용합니다. -block.distributor.description=아이템을 최대 7개의 다른 방향으로 똑같이 분할하는 고급 분배기. -block.bridge-conveyor.description=고급 자원 수송 블록.\n지형이나 건물을 넘어 최대 3개 타일을 건너뛰고 자원을 운송할 수 있습니다. -block.alpha-mech-pad.description=알파 기체로 바꿀 수 있는 패드입니다. -block.itemsource.description=자원을 선택하면 그 자원이 무한하게 생성되는 블록입니다. -block.liquidsource.description=무한한 액체를 출력해냅니다. -block.itemvoid.description=아이템을 사라지게 만듭니다. -block.powerinfinite.description=무한한 전력을 공급해주는 블록입니다. -block.powervoid.description=설정된 아이템을 계속해서 출력하는 블록입니다. -liquid.water.description=지상 유닛이 이 위를 지나가면 이동속도가 느려지고, 깊은 물에 빠지면 죽습니다. -liquid.lava.description=지상 유닛이 이 위를 지나가면 이동속도가 매우 느려지고, 지속적으로 데미지를 입습니다. -liquid.oil.description=일부 조합 블록에서 사용되는 자원입니다. -liquid.cryofluid.description=포탑 및 토륨 원자로에서 사용되는 자원입니다. +text.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!) +text.credits = 제작자 +text.discord = Mindustry Discord 에 참여하세요! +text.link.discord.description = 공식 Mindustry Discord 채팅방 +text.link.github.description = 게임 소스코드 +text.link.dev-builds.description = 개발중인 빌드 +text.link.trello.description = 다음 출시될 기능들을 게시한 공식 Trello 보드 +text.link.itch.io.description = PC 버전 다운로드와 HTML5 버전이 있는 itch.io 사이트 +text.link.google-play.description = Google Play 스토어 정보 +text.link.wiki.description = 공식 Mindustry 위키 (영어) +text.linkfail = 링크를 여는데 실패했습니다! URL이 기기의 클립보드에 복사되었습니다. +text.gameover = 코어가 터졌습니다. 게임 오버! +text.gameover.pvp = [accent]{0}[] 팀이 승리했습니다! +text.sector.gameover = 이 지역을 공략하는데 실패했습니다. 포기 하시겠습니까? +text.sector.retry = 아니오 +text.highscore = [YELLOW]최고점수 달성! +text.wave.lasted = [accent]{0}[] 까지 버티셨습니다. +text.level.highscore = 최고 점수 : [accent]{0} +text.level.delete.title = 삭제 확인 +text.map.delete = 정말로 "[accent]{0}[]" 맵을 삭제하시겠습니까? +text.level.select = 맵 선택 +text.level.mode = 게임모드 : +text.construction.desktop = PC 에서의 조작 방법이 변경되었습니다.\n블록 선택을 해제하거나 건설을 중지하려면 [accent]스페이스 바[]를 누르세요. +text.construction.title = 블록 배치 안내서 +text.construction = [accent]블록 배치 모드[]를 선택하셨습니다.\n\n블록을 설치하고 싶으면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 배치 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요. \n- [accent]블록을 넓게 배치[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록을 한줄로 배치[]하고 싶다면 배치하고 싶은 시작 영역을 한번 탭 하고 길게 누르면서 드래그 하면 됩니다. \n- [accent]블록 배치 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다. +text.deconstruction.title = 블록 삭제 안내서 +text.deconstruction = [accent]블록 삭제 모드[]를 선택하셨습니다\n\n블록을 삭제하고 싶다면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 파괴 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요\n- [accent]블록을 넓은 범위로 삭제[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록 삭제 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다. +text.showagain = 다음 세션에서 이 메세지를 표시하지 않습니다 +text.coreattack = < 코어가 공격받고 있습니다! > +text.unlocks = 아이템들 +text.savegame = 게임 저장 +text.loadgame = 게임 불러오기 +text.joingame = 멀티플레이 +text.addplayers = 플레이어 추가/제거 +text.customgame = 커스텀 게임 +text.sectors = 지역 플레이 +text.sector = 지역 : [LIGHT_GRAY]{0} +text.sector.time = 시간 : [LIGHT_GRAY]{0} +text.sector.deploy = 시작 +text.sector.abandon = 초기화 +text.sector.abandon.confirm = 정말로 이 지역의 모든 진행상황을 초기화 하겠습니까?\n이 작업은 되돌릴 수 없습니다! +text.sector.resume = 계속하기 +text.sector.locked = [scarlet][[완료안됨] +text.sector.unexplored = [accent][[탐색안됨] +text.missions = 목표 : [LIGHT_GRAY] {0} +text.mission = 목표 : [LIGHT_GRAY] {0} +text.mission.main = 주요 목표 : [LIGHT_GRAY]{0} +text.mission.info = 미션 정보 +text.mission.complete = 미션 성공! +text.mission.complete.body = 지역 {0},{1} 클리어. +text.mission.wave = [accent]{0}/{1}[] 단계 생존\n{2}초 남음 +text.mission.wave.enemies = [accent]{0}/{1} []단계 생존\n{2}마리 남음 +text.mission.wave.enemy = [accent]{0}/{1} []단계 생존\n{2}마리 남음 +text.mission.wave.menu = [accent]{0}[] 단계 +text.mission.battle = 적 코어를 파괴하세요 +text.mission.resource.menu = {0} {1}개 수집 +text.mission.resource = {0} 을(를) 수집하세요\n[accent]{1}/{2} +text.mission.block = {0} 를 만드세요 +text.mission.unit = {0} 유닛을 만드세요 +text.mission.command = 유닛에게 {0} 명령을 보내세요 +text.mission.linknode = 전력 노드를 연결하세요 +text.mission.display = [accent]목표 : [LIGHT_GRAY]{0} +text.mission.mech = [accent]{0}[] 기체로 바꾸세요 +text.mission.create = [accent]{0}[] 을(를)설치하세요. +text.none = <없음> +text.close = 닫기 +text.quit = 나가기 +text.maps = 맵 +text.continue = 계속하기 +text.nextmission = 다음 임무 +text.maps.none = [LIGHT_GRAY]맵을 찾을 수 없습니다! +text.about.button = 정보 +text.name = 이름 : +text.filename = 파일 이름 : +text.unlocked = 새 블록 잠금 해제됨 +text.unlocked.plural = 잠금 해제 +text.players = 현재 {0}명 접속중 +text.players.single = 현재 {0}명만 있음. +text.server.closing = [accent]서버 닫는중... +text.server.kicked.kick = 서버에서 추방되었습니다! +text.server.kicked.serverClose = 서버 종료됨. +text.server.kicked.sectorComplete = 지역 클리어. +text.server.kicked.sectorComplete.text = 임무 성공.\n서버가 다음지역 맵으로 이동되었습니다. +text.server.kicked.clientOutdated = 오래된 버전의 클라이언트 입니다! 게임을 업데이트 하세요! +text.server.kicked.serverOutdated = 오래된 버전의 서버입니다! 서버 호스트 관리자에게 문의하세요! +text.server.kicked.banned = 뭘 하셨는지는 모르겠지만, 이제 영원히 서버에 접속할 수 없습니다. +text.server.kicked.recentKick = 방금 추방처리 되었습니다. 잠시 기다린 후에 접속 해 주세요. +text.server.kicked.nameInUse = 이 닉네임이 이미 서버에서 사용중입니다. +text.server.kicked.nameEmpty = 닉네임에는 반드시 영어 또는 숫자가 있어야 합니다. +text.server.kicked.idInUse = 이미 서버에 접속중입니다! 다중 계정은 허용되지 않습니다. +text.server.kicked.customClient = 이 서버는 직접 빌드한 버전을 지원하지 않습니다. 공식 버전을 사용하세요. +text.host.info = [accent]호스트[] 버튼은 현재 네트워크의 [scarlet]6567[] 포트를 사용합니다.\n[LIGHY_GRAY]같은 Wi-Fi 또는 로컬 네트워크[] 에서 서버 목록을 볼 수 있습니다.\n\n만약 플레이어들이 이 IP를 통해 어디에서나 연결할 수 있게 하고 싶다면, 공유기 설정에서 [accent]포트 포워딩[]을 해야 합니다.\n\n[LIGHT_GRAY]참고 : LAN 게임 연결에 문제가 있는 사람이 있다면, 방화벽 설정에서 Mindustry 가 로컬 네트워크에 액세스하도록 허용했는지 확인 해 주세요. +text.join.info = 여기서 [accent]서버 IP[]를 입력하여 다른 서버에 접속할 수 있습니다.\n또는 [accent]로컬 네트워크(LAN)[] 서버를 검색하여 접속할 수 있습니다.\nLAN 및 WAN 멀티 플레이어 모두 지원됩니다.\n\n[LIGHT_GRAY]참고:여기에서는 자동으로 글로벌 서버를 추가하지 않습니다. IP로 다른 사람의 서버에 접속할려면 서버장에게 IP를 요청해야 합니다. +text.hostserver = 서버 열기 +text.hostserver.mobile = 서버\n열기 +text.host = 서버 열기 +text.hosting = [accent]서버 여는중... +text.hosts.refresh = 새로고침 +text.hosts.discovering = LAN 게임 찾기 +text.server.refreshing = 서버 목록 새로고치는중... +text.hosts.none = [lightgray]LAN 게임을 찾을 수 없습니다! +text.host.invalid = [scarlet]서버에 연결할 수 없습니다! +text.trace = 플레이어 정보 보기 +text.trace.playername = 이름 : [accent]{0} +text.trace.ip = IP : [accent]{0} +text.trace.id = 고유 ID : [accent]{0} +text.trace.android = Android 클라이언트 : [accent]{0} +text.trace.modclient = 수정된 클라이언트 : [accent]{0} +text.trace.totalblocksbroken = 총 블록 파괴 개수 : [accent]{0} +text.trace.structureblocksbroken = 구조 블록 파괴 수 : [accent]{0} +text.trace.lastblockbroken = 마지막으로 파괴한 블록 : [accent]{0} +text.trace.totalblocksplaced = 총 설치한 블록 개수 : [accent]{0} +text.trace.lastblockplaced = 마지막으로 설치한 블록 : [accent]{0} +text.invalidid = 잘못된 클라이언트 ID 입니다! 공식 Mindustry Discord 으로 버그 보고서를 제출 해 주세요. +text.server.bans = 차단된 유저 +text.server.bans.none = 차단된 플레이어가 없습니다. +text.server.admins = 관리자 +text.server.admins.none = 관리자가 없습니다! +text.server.add = 서버 추가 +text.server.delete = 이 서버를 삭제 하시겠습니까? +text.server.hostname = 호스트 : {0} +text.server.edit = 서버 수정 +text.server.outdated = [crimson]서버 버전이 낮습니다![] +text.server.outdated.client = [Crimson]클라이언트 버전이 낮습니다![] +text.server.version = [lightgray]서버 버전 : {0} +text.server.custombuild = [yellow]커스텀 서버 +text.confirmban = 이 플레이어를 차단하시겠습니까? +text.confirmkick = 정말로 이 플레이어를 추방시키겠습니까? +text.confirmunban = 이 플레이어를 차단해제 하시겠습니까? +text.confirmadmin = 이 플레이어를 관리자로 만들겠습니까? +text.confirmunadmin = 이 플레이어를 일반 유저로 만들겠습니까? +text.joingame.title = 게임 참가 +text.joingame.ip = IP : +text.disconnect = 서버와 연결이 해제되었습니다. +text.disconnect.data = 맵 데이터를 받아오는데 실패했습니다. +text.connecting = [accent]연결중... +text.connecting.data = [accent]맵 데이터 다운로드중... +text.server.port = 포트 : +text.server.addressinuse = 이 주소는 이미 사용중입니다! +text.server.invalidport = 포트 번호가 잘못되었습니다. +text.server.error = [crimson]{0}[accent]서버를 여는데 오류가 발생했습니다.[] +text.save.old = 이 저장파일은 이전 버전의 게임용이며, 지금은 사용할 수 없습니다. \n\n[LIGHT_GRAY]4.0 정식때 이전 게임버전에서 만든 저장파일과 호환됩니다. +text.save.new = 새로 저장 +text.save.overwrite = 이 저장 슬롯을 덮어씌우겠습니까? +text.overwrite = 덮어쓰기 +text.save.none = 저장 파일을 찾지 못했습니다! +text.saveload = [accent]저장중... +text.savefail = 게임을 저장하지 못했습니다! +text.save.delete.confirm = 이 저장파일을 삭제 하시겠습니까? +text.save.delete = 삭제 +text.save.export = 저장파일 내보내기 +text.save.import.invalid = [accent]파일이 잘못되었습니다! +text.save.import.fail = [crimson]저장파일을 불러오지 못함 : [accent]{0} +text.save.export.fail = [crimson]저장파일을 내보내지 못함 : [accent]{0} +text.save.import = 저장파일 불러오기 +text.save.newslot = 저장 파일이름 : +text.save.rename = 이름 변경 +text.save.rename.text = 새 이름 : +text.selectslot = 저장슬롯을 선택하십시오. +text.slot = [accent]{0}번째 슬롯 +text.save.corrupted = [accent]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[]. +text.sector.corrupted = [accent]저장 파일에서 지역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다. +text.empty = <비어있음> +text.on = 켜기 +text.off = 끄기 +text.save.autosave = 자동저장 : {0} +text.save.map = 맵 : {0} +text.save.wave = {0}단계[] +text.save.difficulty = 난이도 : {0} +text.save.date = 마지막 저장날짜 : {0} +text.save.playtime = 플레이시간 : {0} +text.confirm = 확인 +text.delete = 삭제 +text.ok = 확인 +text.open = 열기 +text.cancel = 취소 +text.openlink = 링크 열기 +text.copylink = 링크 복사 +text.back = 뒤로가기 +text.quit.confirm = 정말로 종료하시겠습니까? +text.changelog.title = 변경사항 +text.changelog.loading = 변경사항 가져오는중... +text.changelog.error.android = [accent]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다. 이것은 내부 Android 버그 때문입니다. +text.changelog.error.ios = [accent]현재 iOS에서는 변경 사항을 지원하지 않습니다. +text.changelog.error = [scarlet]게임 변경사항을 가져오는 중 오류가 발생했습니다![]\n인터넷 연결을 확인하십시오. +text.changelog.current = [accent][[현재 버전] +text.changelog.latest = [accent][[최신 버전] +text.loading = [accent]불러오는중... +text.saving = [accent]저장중... +text.wave = [accent]{0}단계 +text.wave.waiting = 남은 시간 : [green]{0}초[] +text.waiting = [LIGHT_GRAY]대기중... +text.waiting.players = 다른 플레이어를 기다리는 중.. +text.wave.enemies = [LIGHT_GRAY]{0} 마리 남았음 +text.wave.enemy = [LIGHT_GRAY]{0} 마리 남음 +text.loadimage = 사진 불러오기 +text.saveimage = 사진 저장 +text.unknown = 알 수 없음 +text.custom = 커스텀 +text.builtin = 기본맵 +text.map.delete.confirm = 이 맵을 삭제하시겠습니까? 이 명령은 취소할 수 없습니다! +text.map.random = [accent]랜덤 맵 +text.map.nospawn = 이 맵에 플레이어가 스폰 할 코어가 없습니다! 맵 편집기에서 [ROYAL]파란색[]코어를 맵에 추가하세요. +text.map.nospawn.pvp = 이 맵에는 적팀 코어가 없습니다! 에디터에서 [scarlet]빨간팀[] 코어를 추가하세요. +text.map.invalid = 파일이 잘못되었거나 손상되어 맵을 열 수 없습니다. +text.editor.brush = 브러쉬 +text.editor.slope = \\ +text.editor.openin = 편집기 열기 +text.editor.oregen = 광물 무작위 생성 +text.editor.oregen.info = 광물 무작위 생성 : +text.editor.mapinfo = 맵 정보 +text.editor.author = 만든이 : +text.editor.description = 설명 : +text.editor.name = 이름 : +text.editor.teams = 팀 +text.editor.elevation = 지형 높이 +text.editor.errorimageload = [accent]{0}[] 파일을 불러오는데 오류가 발생했습니다. +text.editor.errorimagesave = [accent]{0}[] 파일 저장중 오류가 발생했습니다. +text.editor.generate = 생성 +text.editor.resize = 맵 크기조정 +text.editor.loadmap = 맵 불러오기 +text.editor.savemap = 맵 저장 +text.editor.saved = 저장됨! +text.editor.save.noname = 지도에 이름이 없습니다! 메뉴 -> '맵 정보' 에서 설정하세요. +text.editor.save.overwrite = 이 맵의 이름은 기존에 있던 맵을 덮어씁니다! '맵 정보' 메뉴에서 다른 이름을 선택하세요. +text.editor.import.exists = [scarlet]맵을 불러올 수 없음 : [] 기존에 있던 '{0}' 맵이 이미 존재합니다! +text.editor.import = 가져오기 +text.editor.importmap = 맵 가져오기 +text.editor.importmap.description = 이미 존재하는 맵 가져오기 +text.editor.importfile = 파일 가져오기 +text.editor.importfile.description = 외부 맵 파일 가져오기 +text.editor.importimage = 지형 사진 가져오기 +text.editor.importimage.description = 외부 맵 이미지 파일 가져오기 +text.editor.export = 내보내기 +text.editor.exportfile = 파일 내보내기 +text.editor.exportfile.description = 맵 파일 내보내기 +text.editor.exportimage = 지형 이미지 내보내기 +text.editor.exportimage.description = 맵 이미지 파일 내보내기 +text.editor.loadimage = 지형 가져오기 +text.editor.saveimage = 지형 내보내기 +text.editor.unsaved = [scarlet]변경사항을 저장하지 않았습니다![]\n정말로 나가시겠습니까? +text.editor.resizemap = 맵 크기 조정 +text.editor.mapname = 맵 이름 : +text.editor.overwrite = [accept]경고!이 명령은 기존 맵을 덮어씌우게 됩니다. +text.editor.overwrite.confirm = [scarlet]경고![] 이 이름을 가진 맵이 이미 있습니다. 덮어 쓰시겠습니까? +text.editor.selectmap = 불러올 맵 선택 : +text.width = 넓이 : +text.height = 높이 : +text.menu = 메뉴 +text.play = 플레이 +text.load = 불러오기 +text.save = 저장 +text.fps = {0}FPS +text.tps = {0}TPS +text.ping = ping : {0}ms +text.language.restart = 언어를 변경하려면 게임을 다시시작 해 주세요. +text.settings = 설정 +text.tutorial = 게임 방법 +text.editor = 편집기 +text.mapeditor = 맵 편집기 +text.donate = 기부 +text.connectfail = [crimson]{0}[accent] 서버에 연결하지 못했습니다.[] +text.error.unreachable = 서버에 연결하지 못했습니다. +text.error.invalidaddress = 잘못된 주소입니다. +text.error.timedout = 시간 초과!\n서버에 포트 포워딩이 설정되어 있고 주소가 올바른지 확인하십시오. +text.error.mismatch = 패킷 오류:\n클라이언트/서버 버전이 일치하지 않습니다.\n접속할려는 서버가 최신 버전의 Mindustry 인지 확인하세요! +text.error.alreadyconnected = 이미 접속중입니다. +text.error.mapnotfound = 맵 파일을 찾을 수 없습니다! +text.error.any = 알 수 없는 네트워크 오류. +text.settings.language = 언어 +text.settings.reset = 설정 초기화 +text.settings.rebind = 키 재설정 +text.settings.controls = 컨트롤 +text.settings.game = 게임 +text.settings.sound = 소리 +text.settings.graphics = 그래픽 +text.settings.cleardata = 게임 데이터 초기화... +text.settings.clear.confirm = 정말로 초기화 하겠습니까?\n이 작업을 되돌릴 수 없습니다! +text.settings.clearall.confirm = [scarlet]경고![]\n이 작업은 저장된 맵, 맵파일, 잠금 해제된 목록과 키 매핑, 그리고 모든 데이터를 삭제합니다.\n확인 버튼을 다시 눌러 모든 데이터를 삭제하고 게임에서 나갑니다. +text.settings.clearsectors = 지역 초기화 +text.settings.clearunlocks = 잠금 해제 초기화 +text.settings.clearall = 모두 초기화 +text.paused = 일시 정지 +text.yes = 예 +text.no = 아니오 +text.info.title = [accent]정보 +text.error.title = [crimson]오류가 발생했습니다. +text.error.crashtitle = 오류가 발생했습니다. +text.blocks.unknown = [LIGHT_GRAY]??? +text.blocks.blockinfo = 블록 정보 +text.blocks.powercapacity = 최대 전력 용량 +text.blocks.powershot = 1발당 전력 소모량 +text.blocks.targetsair = 공중공격 가능 +text.blocks.itemspeed = 유닛 이동 속도 +text.blocks.shootrange = 사거리 +text.blocks.size = 블록 크기 +text.blocks.liquidcapacity = 최대 액체 용량 +text.blocks.maxitemssecond = 최대 아이템 보관량 +text.blocks.powerrange = 전력 범위 +text.blocks.poweruse = 전력 사용 +text.blocks.powerdamage = 전력/데미지 +text.blocks.inputitemcapacity = 입력 아이템 용량 +text.blocks.outputitemcapacity = 출력 아이템 용량 +text.blocks.itemcapacity = 저장 용량 +text.blocks.basepowergeneration = 기지 전력 생성기 +text.blocks.powertransferspeed = 전력 전송량 +text.blocks.craftspeed = 생산 속도 +text.blocks.inputliquid = 사용되는 액체 +text.blocks.inputliquidaux = 보조 액체 +text.blocks.inputitem = 사용되는 아이템 +text.blocks.inputitems = 사용되는 아이템들 +text.blocks.outputitem = 출력 아이템 +text.blocks.drilltier = 드릴 +text.blocks.drillspeed = 기본 드릴 속도 +text.blocks.liquidoutput = 액체 출력 +text.blocks.liquidoutputspeed = 액체 출력속도 +text.blocks.liquiduse = 액체 사용량 +text.blocks.coolant = 냉각제 +text.blocks.coolantuse = 냉각수 사용 +text.blocks.inputliquidfuel = 연료 액 +text.blocks.liquidfueluse = 액체 연료 사용 +text.blocks.boostitem = 가속 아이템 +text.blocks.boostliquid = 가속 액체 +text.blocks.health = 체력 +text.blocks.inaccuracy = 오차각 +text.blocks.shots = 발포 횟수 +text.blocks.reload = 재장전 +text.blocks.inputfuel = 연료 +text.blocks.fuelburntime = 연료 연소 시간 +text.blocks.inputcapacity = 입력 용량 +text.blocks.outputcapacity = 출력 용량 +text.unit.blocks = 블록 +text.unit.powersecond = 전력/초 +text.unit.liquidsecond = 액체/초 +text.unit.itemssecond = 개/초 +text.unit.pixelssecond = 초당 픽셀 +text.unit.liquidunits = 액체 +text.unit.powerunits = 전력 +text.unit.degrees = 도 +text.unit.seconds = 초 +text.unit.items = 아이템 +text.category.general = 일반 +text.category.power = 전력 +text.category.liquids = 액체 +text.category.items = 아이템 +text.category.crafting = 제작 +text.category.shooting = 사격 +text.category.optional = 선택적 향상 +setting.autotarget.name = 자동 조준 +setting.fpscap.name = 최대 FPS +setting.fpscap.none = 없음 +setting.fpscap.text = {0} FPS +setting.difficulty.training = 훈련 +setting.difficulty.easy = 쉬움 +setting.difficulty.normal = 보통 +setting.difficulty.hard = 어려움 +setting.difficulty.insane = [#00ff00]멀[#2efe2e]티[#58fa58]플[#81f781]레[#a9f5a9]이 [#81f781]전[#58fa58]용[] +setting.difficulty.name = 난이도 : +setting.screenshake.name = 화면 흔들기 강도 +setting.effects.name = 화면 효과 +setting.sensitivity.name = 컨트롤러 감도 +setting.saveinterval.name = 자동저장 간격 +setting.seconds = {0}초 +setting.fullscreen.name = 전체 화면 +setting.fps.name = FPS 표시 +setting.vsync.name = VSync 활성화 +setting.lasers.name = 전력 노드 레이저 표시 +setting.minimap.name = 미니맵 보기 +setting.musicvol.name = 음악 크기 +setting.mutemusic.name = 음소거 +setting.sfxvol.name = 효과음 크기 +setting.mutesound.name = 소리 끄기 +setting.crashreport.name = 오류 보고서 보내기 +text.keybind.title = 조작키 설정 +category.general.name = 일반 +category.view.name = 보기 +category.multiplayer.name = 멀티플레이 +command.attack = 공격 +command.retreat = 후퇴 +command.patrol = 순찰 +keybind.press = 키를 누르세요... +keybind.press.axis = 축 또는 키를 누르세요... +keybind.move_x.name = 오른쪽/왼쪽 이동 +keybind.move_y.name = 위쪽/아래쪽 이동 +keybind.select.name = 선택 +keybind.break.name = 파괴 +keybind.deselect.name = 선택해제 +keybind.shoot.name = 사격 +keybind.zoom_hold.name = 길게눌러 확대 +keybind.zoom.name = 확대 +keybind.menu.name = 메뉴 +keybind.pause.name = 일시중지 +keybind.dash.name = 달리기 +keybind.chat.name = 채팅 +keybind.player_list.name = 플레이어 목록 +keybind.console.name = 콘솔 +keybind.rotate.name = 회전 +keybind.toggle_menus.name = 메뉴 보이기/숨기기 +keybind.chat_history_prev.name = 이전 채팅기록 +keybind.chat_history_next.name = 다음 채팅기록 +keybind.chat_scroll.name = 채팅 스크롤 +keybind.drop_unit.name = 유닛 드롭 +keybind.zoom_minimap.name = 미니맵 확대 +mode.text.help.title = 도움말 +mode.waves.name = 단계 +mode.waves.description = 이것은 일반 모드입니다. 제한된 자원과 자동으로 다음 단계가 시작됩니다. +mode.sandbox.name = 샌드박스 +mode.sandbox.description = 무한한 자원과 다음단계 시작을 위한 타이머가 없습니다. +mode.freebuild.name = 자유 건축 +mode.freebuild.description = 제한된 자원과 다음단계 시작을 위한 타이머가 없습니다. +mode.pvp.name = PvP +mode.pvp.description = 몹이 아닌 실제 플레이어와 PvP를 합니다. +content.item.name = 아이템 +content.liquid.name = 액체 +content.unit.name = 유닛 +content.recipe.name = 블록 +content.mech.name = 기체 +item.stone.name = 돌 +item.stone.description = 주로 용암을 사용하여 얻을 수 있는 자원입니다. +item.copper.name = 구리 +item.copper.description = 모든 유형의 블록에서 광범위하게 사용되는 자원입니다. +item.lead.name = 납 +item.lead.description = 쉽게 구할 수 있으며, 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다. +item.coal.name = 석탄 +item.coal.description = 쉽게 구할 수 있으며, 주로 제련소 등에서 연료로 사용됩니다. +item.dense-alloy.name = 고밀도 합금 +item.dense-alloy.description = 납과 구리로 만든 튼튼한 고밀도 합금.\n고급 수송 블록이나 상위 티어 블록을 건설하는데 사용됩니다. +item.titanium.name = 티타늄 +item.titanium.description = 파이프 재료나 고급 드릴, 비행기/기체 등에서 재료로 사용되는 자원입니다. +item.thorium.name = 토륨 +item.thorium.description = 건물의 재료, 포탑의 탄약 또는 핵연료로 사용되는 방사성 금속입니다. +item.silicon.name = 실리콘 +item.silicon.description = 매우 유용한 반도체로, 태양 전지판과 복잡한 전자 제품에 사용할 수 있습니다. +item.plastanium.name = 플라스터늄 +item.plastanium.description = 고급 항공기 및 분열 탄약에 사용되는 가벼운 연성 재료. +item.phase-fabric.name = 메타 +item.phase-fabric.description = 최첨단 전자 제품과 자기수리 기술에 사용되는 거의 무중력에 가까운 물질입니다. +item.surge-alloy.name = 설금 +item.surge-alloy.description = 주로 건물의 재료로 사용되는 자원입니다 +item.biomatter.name = 바이오메터 +item.biomatter.description = 이것은 유기농 덤불입니다!\n압축기에 넣어 석유로 바꿀 수 있습니다. +item.sand.name = 모래 +item.sand.description = 고밀도 합금이나 플럭스 등에서 제련시 광범위하게 사용되는 일반적인 재료입니다. +item.blast-compound.name = 폭발물 +item.blast-compound.description = 포탑 및 건설의 재료로 사용되는 휘발성 폭발물.\n연료로도 사용할 수 있지만, 별로 추천하지는 않습니다. +item.pyratite.name = 피라테 +item.pyratite.description = 폭발성을 가진 재료로, 주로 포탑의 탄약으로 사용됩니다. +liquid.water.name = 물 +liquid.lava.name = 용암 +liquid.oil.name = 석유 +liquid.cryofluid.name = 냉각수 +mech.alpha-mech.name = 알파 +mech.alpha-mech.weapon = 중무장 소총 +mech.alpha-mech.ability = 드론 소환 +mech.alpha-mech.description = 표준 기체.\n적절한 속도와 공격력을 갖추고 있으며, 공격 능력을 높이기 위해 최대 3대의 드론을 만들 수 있습니다. +mech.delta-mech.name = 델타 +mech.delta-mech.weapon = 전격 생산기 +mech.delta-mech.ability = 충전 +mech.delta-mech.description = 빠르게 이동하는 적을 처치하기 위한 가벼운 기체.\n구조물에는 거의 피해를 주지 않지만, 전격 무기를 사용하여 많은 적군을 매우 빠르게 죽일 수 있습니다. +mech.tau-mech.name = 타우 +mech.tau-mech.weapon = 건물 수리총 +mech.tau-mech.ability = 유닛 치료 +mech.tau-mech.description = 지원형 기체.\n총을 발사하여 건물을 치료하고 회복 능력 사용으로 화재를 진압하거나, 반경 내 아군을 치유시킵니다. +mech.omega-mech.name = 오메가 +mech.omega-mech.weapon = 전방 유도미사일 +mech.omega-mech.ability = 방어모드 +mech.omega-mech.description = 지상 기체 최종판이자 건물 파괴용으로 적합한 부피가 크고 튼튼한 기체. 방어 모드는 최대 90% 의 피해를 줄일 수 있습니다. +mech.dart-ship.name = 다트 +mech.dart-ship.weapon = 소총 +mech.dart-ship.description = 표준 비행선. 빠르고 가볍지만 공격력이 거의 없고 채광 속도가 느립니다. +mech.javelin-ship.name = 자비린 +mech.javelin-ship.description = 치고 빠지는 공격을 위한 비행선. 처음에는 느리지만, 가속도가 붙어 엄청난 속도로 미사일 피해를 입힐 수 있으며, 전격 능력을 사용할 수 있습니다. +mech.javelin-ship.weapon = 유도 미사일 +mech.javelin-ship.ability = 가속 전격 생성기 +mech.trident-ship.name = 삼지창 +mech.trident-ship.description = 대형 공중 폭격기. 당연하게도 엄청 단단합니다. +mech.trident-ship.weapon = 폭탄 저장고 +mech.glaive-ship.name = 글레브 +mech.glaive-ship.description = 크고 잘 무장된 총을 가진 비행선. 방화용 리피터가 장착되어 있으며, 가속도와 최대속도가 높습니다. +mech.glaive-ship.weapon = 방화총 +text.item.explosiveness = [LIGHT_GRAY]폭발력 : {0} +text.item.flammability = [LIGHT_GRAY]인화성 : {0} +text.item.radioactivity = [LIGHT_GRAY]방사능 : {0} +text.item.fluxiness = [LIGHT_GRAY]플럭스 파워 : {0} +text.unit.health = [LIGHT_GRAY]체력 : {0} +text.unit.speed = [LIGHT_GRAY]속도 : {0} +text.mech.weapon = [LIGHT_GRAY]무기 : {0} +text.mech.armor = [LIGHT_GRAY]방어력 : {0} +text.mech.itemcapacity = [LIGHT_GRAY]아이템 수용 용량 : {0} +text.mech.minespeed = [LIGHT_GRAY]채광 속도 : {0} +text.mech.minepower = [LIGHT_GRAY]채광 레벨 : {0} +text.mech.ability = [LIGHT_GRAY]능력 : {0} +text.liquid.heatcapacity = [LIGHT_GRAY]발열량 : {0} +text.liquid.viscosity = [LIGHT_GRAY]점도 : {0} +text.liquid.temperature = [LIGHT_GRAY]온도 : {0} +block.constructing = {0}[LIGHT_GRAY](만드는중) +block.spawn.name = 적 스폰지점 +block.core.name = 코어 +block.metalfloor.name = 철판 +block.deepwater.name = 깊은물 +block.water.name = 물 +block.lava.name = 용암 +block.tar.name = 타르 +block.blackstone.name = 검은돌 +block.stone.name = 돌 +block.dirt.name = 흙 +block.sand.name = 모래 +block.ice.name = 얼음 +block.snow.name = 눈 +block.grass.name = 잔디 +block.shrub.name = 관목 +block.rock.name = 바위 +block.blackrock.name = 검은바위 +block.icerock.name = 얼음바위 +block.copper-wall.name = 구리벽 +block.copper-wall-large.name = 큰 구리벽 +block.dense-alloy-wall.name = 합금 벽 +block.dense-alloy-wall-large.name = 큰 합금 벽 +block.phase-wall.name = 메타벽 +block.phase-wall-large.name = 큰 메타벽 +block.thorium-wall.name = 토륨벽 +block.thorium-wall-large.name = 대형 토륨벽 +block.door.name = 문 +block.door-large.name = 대형문 +block.duo.name = 듀오 +block.scorch.name = 스코치 +block.hail.name = 헤일 +block.lancer.name = 랜서 +block.conveyor.name = 컨베이어 +block.titanium-conveyor.name = 티타늄 컨베이어 +block.junction.name = 교차기 +block.router.name = 분배기 +block.distributor.name = 대형 분배기 +block.sorter.name = 필터 +block.sorter.description = 아이템을 넣어서 필터에 설정된 아이템일 경우 바로 앞으로 통과하며, 그렇지 않을 경우 옆으로 통과합니다. +block.overflow-gate.name = 오버플로 게이트 +block.overflow-gate.description = 정면으로 가는 자원이 막히면 옆으로 출력하고, 그렇지 않으면 계속 정면으로 출력합니다. +block.smelter.name = 제련소 +block.arc-smelter.name = 대형 제련소 +block.silicon-smelter.name = 실리콘 제련소 +block.phase-weaver.name = 메타 합성기 +block.pulverizer.name = 분쇄기 +block.cryofluidmixer.name = 냉각수 제조기 +block.melter.name = 융해기 +block.incinerator.name = 소각로 +block.biomattercompressor.name = 바이오메터 압축기 +block.separator.name = 셉터 +block.centrifuge.name = 원심 분리기 +block.power-node.name = 전력 송신기 +block.power-node-large.name = 대형 전력 송신기 +block.battery.name = 배터리 +block.battery-large.name = 대형 배터리 +block.combustion-generator.name = 석탄 발전기 +block.turbine-generator.name = 터빈 발전기 +block.mechanical-drill.name = 기계식 드릴 +block.pneumatic-drill.name = 강철 드릴 +block.laser-drill.name = 레이저 드릴 +block.water-extractor.name = 물 추출기 +block.cultivator.name = 온실 +block.alpha-mech-pad.name = 알파 기체 패드 +block.dart-ship-pad.name = 다트 비행선 패드 +block.delta-mech-pad.name = 델타 기체 패드 +block.javelin-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 = 파이프 +block.mechanical-pump.name = 기계식 펌프 +block.itemsource.name = 아이템 소스 +block.itemvoid.name = 아이템 삭제 장치 +block.liquidsource.name = 무한 액체공급 장치 +block.powervoid.name = 방전장치 +block.powerinfinite.name = 무한 전력공급 장치 +block.unloader.name = 언로더 +block.vault.name = 창고 +block.wave.name = 파도 +block.swarmer.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.solidifer.name = 고체 +block.solar-panel.name = 태양 전지판 +block.solar-panel-large.name = 대형 태양 전지판 +block.oil-extractor.name = 석유 추출기 +block.spirit-factory.name = 스피릿 드론 공장 +block.phantom-factory.name = 팬텀 드론 공장 +block.wraith-factory.name = 유령 전투기 공장 +block.ghoul-factory.name = 구울 폭격기 공장 +block.dagger-factory.name = 디거 기체 공장 +block.titan-factory.name = 타이탄 기체 공장 +block.fortress-factory.name = 포트리스 기체 공장 +block.revenant-factory.name = 레비던트 전투기 공장 +block.repair-point.name = 정비소 +block.pulse-conduit.name = 퓨즈 파이프 +block.phase-conduit.name = 메타 파이프 +block.liquid-router.name = 액체 분배기 +block.liquid-tank.name = 물탱크 +block.liquid-junction.name = 액체 교차기 +block.bridge-conduit.name = 다리 파이프 +block.rotary-pump.name = 동력 펌프 +block.thorium-reactor.name = 토륨 원자로 +block.command-center.name = 명령 본부 +block.mass-driver.name = 물질 이동기 +block.blast-drill.name = 고속 발열 드릴 +block.thermal-pump.name = 화력 펌프 +block.thermal-generator.name = 열발전기 +block.alloy-smelter.name = 설금 제련소 +block.mend-projector.name = 수리 프로젝터 +block.surge-wall.name = 설금벽 +block.surge-wall-large.name = 큰 설금벽 +block.cyclone.name = 사이클론 +block.fuse.name = 퓨즈 +block.shock-mine.name = 전격 지뢰 +block.overdrive-projector.name = 오버드라이브 프로젝터 +block.force-projector.name = 보호막 프로젝터 +block.arc.name = Arc +block.rtg-generator.name = 토륨 발전소 +block.spectre.name = 스펙터 +block.meltdown.name = 멜트다운 +block.container.name = 컨테이너 +team.blue.name = 블루팀 +team.red.name = 레드팀 +team.orange.name = 오렌지팀 +team.none.name = 공기팀 +team.green.name = 그린팀 +team.purple.name = 보라색팀 +unit.alpha-drone.name = 알파 드론 +unit.spirit.name = 스피릿 드론 +unit.spirit.description = 기본 드론 유닛. 기본적으로 코어에서 1개가 스폰됩니다. 자동으로 채광하며 아이템을 수집하고, 블록을 수리합니다. +unit.phantom.name = 팬텀 드론 +unit.phantom.description = 첨단 드론 유닛. 광석을 자동으로 채광하며, 아이템을 수집하고 블록을 수리합니다. 일반 드론보다 훨씬 효과적입니다. +unit.dagger.name = 디거 +unit.dagger.description = 기본 지상 유닛입니다. 스웜과 같이 쓰면 유용합니다. +unit.titan.name = 타이탄 +unit.titan.description = 고급 지상 유닛입니다. 고밀도 합금을 탄약으로 사용하며 지상과 공중 둘다 공격할 수 있습니다. +unit.ghoul.name = 구울 폭격기 +unit.ghoul.description = 무거운 지상 폭격기 입니다. 폭발물 또는 피라테를 탄약으로 사용합니다. +unit.wraith.name = 유령 전투기 +unit.wraith.description = 코어를 집중적으로 공격하는 방식을 사용하는 전투기 입니다. +unit.fortress.name = 포트리스 +unit.fortress.description = 중포 지상 유닛. 높은 공격력과 체력을 가지고 있습니다. +unit.revenant.name = 레비던트 +unit.revenant.description = 대형 레이저를 발사하는 공중 유닛입니다. +tutorial.begin = 플레이어의 주요 목표는 [LIGHT_GRAY]적군[]을 제거하는 것입니다.\n\n이 게임은 [accent]구리를 채광[]하는 것으로 시작합니다.\n이것을 하기 위해 플레이어의 중심부 근처에 있는 구리 광맥을 누르세요. +tutorial.drill = 수동으로 채광하는 것은 효율이 낮습니다.\n[accent]드릴[]은 자동으로 채광 작업을 합니다.\n구리 광맥에 표시된 영역에 드릴을 하나를 놓으세요. +tutorial.conveyor = [accent]컨베이어[]를 사용하여 아이템을 코어로 운반합니다.\n드릴에서 코어까지 컨베이어 라인을 만드세요. +tutorial.morecopper = 더 많은 구리가 필요합니다.\n\n수동으로 채광하거나, 드릴을 더 설치하세요. +tutorial.turret = 방어 구조물은 [LIGHT_GRAY]적[]을 물리치기 위해 반드시 필요합니다.\n기지 근처에 듀오 터렛을 설치하세요. +tutorial.drillturret = 듀오 터렛이 작동하기 위해서는[accent] 구리 탄약 []을 필요로 합니다.\n터렛 옆에 드릴을 설치하여 구리를 공급하세요. +tutorial.waves = [LIGHT_GRAY]적[]이 접근합니다.\n\n2단계 동안 코어를 보호하고 더 많은 터렛을 만드세요. +tutorial.lead = 더 많은 광석을 이용할 수 있습니다. [accent]납[]을 찾아 탐색하세요.\n\n아이템을 코어로 전송할려면 플레이어 기체 또는 비행기에서 코어로 드래그 하세요. +tutorial.smelter = 구리와 납은 약한 금속입니다.\n[accent]고밀도 합금[]은 제련소에서 만들 수 있습니다.\n\n하나 만드세요. +tutorial.densealloy = 이 제련소는 이제 고밀도 합금을 생산할 것입니다.\n몇개 더 생산하세요.\n필요한 경우 더 만드세요. +tutorial.siliconsmelter = 이제 이코어는 채굴과 수리하기 위한[accent] 스피릿 드론[]을 생성 할 것 입니다.\n\n[accent]실리콘[]을 사용해 다른 유닛을 생성하기 위한 공장을 만들 수 있습니다.\n실리콘 제련기를 제작하세요! +tutorial.silicondrill = 실리콘을 제작하려면[accent] 석탄[] 과[accent] 모래[]가 필요합니다.\n드릴을 먼저 건설해보는건 어떤가요? +tutorial.generator = 이 건물은 [LIGHT_YELLOW]전력[]이 필요합니다.\n[accent] 석탄 발전기[]를 건설하세요. +tutorial.generatordrill = [accent] 석탄 발전기[]는 연료가 필요합니다.\n[accent] 석탄[]을 드릴로 채굴해서 연료를 체워주세요. +tutorial.node = 전력은 송신해줄 송신기가 필요합니다.\n[accent] 전력 송신기[]를 석탄 등등 발전기 옆에 설치해서 생산된 전기를 다른곳으로 송신합시다. +tutorial.nodelink = 전력은 전력 블록과 발전기에 연결하거나, 연결된 전력 송신기를 통해 전송이 가능합니다. \n\n전력 송신기를 누르고 발전기와 실리콘 제련기를 선택하여 전원을 연결합시다. +tutorial.silicon = 실리콘이 생산되고 있습니다.\n\n생산 시스템의 개선을 권고 드립니다. +tutorial.daggerfactory = 이[accent] 디거 기체 공장[]은\n\n공격하는 기체를 생산하기 위해 사용됩니다. +tutorial.router = 공장을 작동시키기 위해 자원이 필요합니다.\n컨베이어에 운반되고 있는 자원을 분할할 분배기를 만드세요. +tutorial.dagger = 전력 노드를 공장에 연결하세요.\n일단 요구 사항이 충족되면 기체 생산을 시작합니다.\n\n필요에 따라 드릴 및 발전기, 컨베이어를 더 많이 만들 수 있습니다. +tutorial.battle = [LIGHT_GRAY]적[]의 코어가 드러났습니다.\n당신의 부대와 디거를 사용하여 파괴하세요. +block.core.description = 게임에서 가장 중요한 건물.\n파괴되면 게임이 끝납니다. +block.copper-wall.description = 구리로 만든 벽. +block.copper-wall-large.description = 구리로 만든 큰 벽. +block.dense-alloy-wall.description = 고밀도 합금으로 만든 벽. 구리벽보다 체력이 높습니다. +block.dense-alloy-wall-large.description = 고밀도 합금으로 만든 큰 벽. +block.thorium-wall.description = 토륨으로 만든 벽. +block.thorium-wall-large.description = 토륨으로 만든 큰 벽. +block.phase-wall.description = 날라오는 모든 총알을 튕겨내고 데미지를 입는 특수한 벽입니다. +block.phase-wall-large.description = 메타로 제작한 큰 벽. 날라오는 총알을 모두 튕겨냅니다. +block.surge-wall.description = 데미지를 입으면 번개를 일으켜 대상에게 피해를 입히는 특수한 벽입니다. +block.surge-wall-large.description = 설금을 재료로 한 큰 벽.\n데미지를 입으면 번개를 일으켜 대상에게 피해를 입힙니다. +block.door.description = 유닛이 지나갈 수 있도록 만든 문. 클릭하면 열고 닫습니다. +block.door-large.description = 유닛이 자나갈 수 있도록 만든 큰 문. 클릭하면 열고 닫습니다. +block.mend-projector.description = 주위 건물을 치료하는 건물입니다. +block.overdrive-projector.description = 범위 내 모든 행동의 속도를 높여주는 보조형 건물입니다. +block.force-projector.description = 보호막을 생성하는 건물.\n기본적으로 전력만 있으면 작동하지만, 메타를 넣어 보호막의 범위를 크게 확장시킬 수 있습니다. +block.shock-mine.description = 적이 이 블록을 지나가면 전격 공격을 하는 함정형 방어 건물입니다. +block.duo.description = 범용성을 가진 터렛.\n지상 및 공중공격을 하며, 초중반에 유용합니다. +block.arc.description = 목표 방향으로 전격 공격을 하는 포탑입니다. +block.hail.description = 장거리 지상 공격을 하는 터렛입니다.\n적이 오기 전에 쓸어버릴 수 있습니다. +block.lancer.description = 중거리 레이져 포탑입니다.\n적을 관통하기 때문에 뭉쳐있는 적들에게 매우 효과적입니다. +block.wave.description = 적이 있는 자리에 액체를 뿌립니다.\n이 포탑을 활용하여 액체를 뿌린 곳에 불을 붙이거나 적을 느리게 할 수 있습니다. +block.salvo.description = 명중률이 높고, 3발씩 끊어 발사하는 포탑입니다. +block.swarmer.description = 4발씩 끊어서 유도체를 발사하는 포탑입니다 +block.ripple.description = 4개의 탄약으로 나눠 발사하여 명중률이 낮지만, 사거리가 매우 긴 포탑입니다. +block.cyclone.description = 낮은 명중률과 높은 RPM 을 가진 포탑입니다.\n탄약이 남아있는 한 멈추지 않고 계속 연사합니다. +block.fuse.description = 단거리에서 범위형 레이저를 발사하는 포탑입니다. +block.spectre.description = 높은 명중률과 RPM 을 가진 포탑입니다.\n탄약이 남아있는 한 멈추지 않고 계속 연사합니다. +block.meltdown.description = 목표를 따라 초대형 레이져를 발사하는 포탑입니다.\n뭉쳐있는 몹에게 매우 효과가 좋습니다. +block.conveyor.description = 느린 속도로 자원을 수송할 수 있는 컨베이어. +block.titanium-conveyor.description = 빠른 속도로 자원을 수송할 수 있는 컨베이어. +block.phase-conveyor.description = 자원을 순간이동 시켜 주는 컨베이어 입니다. +block.junction.description = 컨베이어를 교차시켜 자원을 수송할 때 사용할 수 있는 블록입니다. +block.mass-driver.description = 자원을 받아서 다른 물질 이동기로 전달할 수 있는 블록입니다.\n엄청난 사거리를 가지고 있으며, 주로 컨베이어가 접근할 수 없는 곳에 유용하게 사용됩니다. +block.smelter.description = 고밀도 합금을 제작할 수 있는 건물입니다. +block.arc-smelter.description = 고밀도 합금을 제작할 수 있는 건물이지만, 이 건물은 석탄이 필요 없고 좀더 빠른 속도로 합금을 생산해낼 수 있습니다. +block.silicon-smelter.description = 실리콘을 제작할 수 있는 건물입니다. +block.plastanium-compressor.description = 플라스터늄을 제조할 수 있는 건물입니다. +block.phase-weaver.description = 메타를 제작할 수 있는 건물입니다. +block.alloy-smelter.description = 설금을 제작할 수 있는 건물입니다. +block.pulverizer.description = 돌을 갈아서 모래로 만들 수 있는 건물입니다. +block.pyratite-mixer.description = 피라테를 제조할 수 있는 건물입니다. +block.blast-mixer.description = 폭발물을 제조할 수 있는 건물입니다. +block.cryofluidmixer.description = 냉각수를 제작할 수 있는 건물입니다. +block.solidifer.description = 용암을 돌로 만들 수 있는 건물입니다. +block.melter.description = 돌로 용암을 만들 수 있는 건물입니다. +block.incinerator.description = 불필요한 아이템을 소각시켜 줄 수 있는 건물입니다. +block.biomattercompressor.description = 잔디밭에서 바이오메터를 추출할 수 있는 건물입니다. +block.separator.description = 돌을 분해하여 각종 자원으로 재활용 할 수 있게 해 주는 건물입니다. +block.centrifuge.description = 돌을 분해하여 각종 자원으로 재활용 할 수 있게 해 주는 건물이지만, 이 건물은 좀 더 다양한 자원을 얻을 수 있게 해 줍니다. +block.power-node.description = 생성된 전력를 다른 건물로 전달하기 위한 전력 노드입니다. +block.power-node-large.description = 생성된 전력를 다른 건물로 전달하기 위한 건물이며, 일반 노드보다 더 많은 전력을 이동시킬 수 있습니다. +block.battery.description = 흔히 아는 충전식 배터리입니다.\n전력을 사용하는 건물에 전력이 떨어질경우, 이 배터리를 전력 노드에 연결하면 이 배터리에 저장된 전력을 소모하여 지속적으로 공급할 수 있습니다. +block.battery-large.description = 일반 배터리보다 용량이 매우 커진 커진 배터리. +block.combustion-generator.description = 석탄을 연료로 전력를 생산해내는 발전소 입니다. +block.turbine-generator.description = 석탄 발전기보다 더 많은량의 전력를 생산하는 발전기입니다. +block.thermal-generator.description = 용암을 원료로 전력을 생산할 수 있는 발전소입니다. +block.solar-panel.description = 태양열을 받아 자기 스스로 전력을 생산하는 건물입니다. +block.solar-panel-large.description = 태양열을 받아 자기 스스로 전력을 생산하지만, 이 블록은 더 빨리 전력을 생산할 수 있습니다. +block.thorium-reactor.description = 토륨을 원료로 하는 토륨 원자로 입니다.\n많은 전력을 생산하지만 엄청난 열을 발생시키기 때문에, 많은 량의 물 또는 냉각수가 있어야 터지지 않고 작동합니다. +block.rtg-generator.description = 냉각은 필요 없지만 토륨 원자로보다 적은량의 전력을 생산하는 방사선 동위원소 열전자 발전기. +block.unloader.description = 해당 창고 및 코어에서 자원을 빼내는데 사용됩니다. +block.container.description = 아이템을 임시로 저장할 수 있는 소형 창고입니다. +block.vault.description = 아이템을 임시로 저장할 수 있는 대형 창고입니다. +block.mechanical-drill.description = 구리로 제작할 수 있는 기본 드릴입니다. +block.pneumatic-drill.description = 돌, 티타늄을 채광할 수 있는 고급 드릴입니다. +block.laser-drill.description = 토륨을 채광할 수 있는 최고급 드릴입니다.\n전력과 물을 공급하여 빠른 속도로 채광할 수 있습니다. +block.blast-drill.description = 최상위 드릴입니다. 엄청난 양의 전력과 물을 소모하는 대신, 매우 빠른 속도로 채광합니다. +block.water-extractor.description = 바닥에서 물을 추출하여 건물에 공급할 수 있는 건물입니다. +block.cultivator.description = 잔디에서 바이오메터를 추출할 수 있는 건물입니다. +block.oil-extractor.description = 석유를 추출 해 주는 건물입니다. +block.dart-ship-pad.description = 다트 비행선으로 바꿀 수 있는 패드입니다. +block.trident-ship-pad.description = 삼지창 비행선으로 바꿀 수 있는 패드입니다. +block.javelin-ship-pad.description = 자비린 비행선으로 바꿀 수 있는 패드입니다. +block.glaive-ship-pad.description = 글레브 비행선으로 바꿀 수 있는 패드입니다. +block.tau-mech-pad.description = 타우 기체로 바꿀 수 있는 패드 +block.delta-mech-pad.description = 델타 기체로 바꿀 수 있는 패드입니다. +block.omega-mech-pad.description = 오메가 기체로 바꿀 수 있는 패드 +block.spirit-factory.description = 스피릿 유닛을 생산하는 공장입니다. +block.phantom-factory.description = 유닛 팬텀을 생산하는 공장입니다. +block.wraith-factory.description = 유닛 유령 전투기를 소환하는 공장입니다. +block.ghoul-factory.description = 구울 유닛을 생산하는 공장입니다. +block.dagger-factory.description = 디거를 생산하는 공장입니다. +block.titan-factory.description = 타이탄 유닛을 생산할 수 있는 공장입니다. +block.fortress-factory.description = 포트리스를 생산하는 공장입니다. +block.revenant-factory.description = 레비던트 유닛을 생산할 수 있는 공장입니다. +block.repair-point.description = 근처 유닛들을 수리하는 건물입니다. +block.command-center.description = 생산된 유닛들을 제어할 수 있는 건물.\n첫번째 버튼은 적 기지로 공격하며, 두번째는 대기 상태, 세번째는 기지 근처를 돌며 정찰합니다. +block.conduit.description = 일반 파이프. 액체가 지나갈 수 있도록 해 줍니다. +block.pulse-conduit.description = 티타늄으로 만들어 졌으며, 일반 파이프보다 액체 수용량이 높습니다. +block.phase-conduit.description = 물을 먼거리로 순간이동 시켜 주는 장치입니다. +block.liquid-router.description = 물펌프를 다른 방향으로 분배할 수 있게 하는 블럭입니다. +block.liquid-tank.description = 액체 종류를 저장할 수 있는 물탱크 입니다. +block.liquid-junction.description = 물펌프와 다른 물펌프를 서로 교차시키게 할 수 있는 블럭입니다. +block.bridge-conduit.description = 다리와 다리 사이를 연결하여 액체가 지나갈 수 있게 해 줍니다.\n주로 다리 사이에 지나갈 수 없는 장애물이 있을 때 사용합니다. +block.mechanical-pump.description = 구리로 제작할 수 있는 기계식 물펌프입니다. +block.rotary-pump.description = 일반 물 펌프보다 더 빠른 속도로 물을 끌어올릴 수 있는 펌프입니다. +block.thermal-pump.description = 기계식 펌프보다 3배 빠른 속도로 액체를 퍼올릴 수 있는 펌프이며, 용암도 퍼올릴 수 있는 유일한 펌프입니다. +block.router.description = 한 방향에서 아이템을 받은 후 최대 3개의 다른 방향으로 동일하게 출력합니다.\n재료를 한곳에서 여러 대상으로 분할하여 운반하는데 유용합니다. +block.distributor.description = 아이템을 최대 7개의 다른 방향으로 똑같이 분할하는 고급 분배기. +block.bridge-conveyor.description = 고급 자원 수송 블록.\n지형이나 건물을 넘어 최대 3개 타일을 건너뛰고 자원을 운송할 수 있습니다. +block.alpha-mech-pad.description = 알파 기체로 바꿀 수 있는 패드입니다. +block.itemsource.description = 자원을 선택하면 그 자원이 무한하게 생성되는 블록입니다. +block.liquidsource.description = 무한한 액체를 출력해냅니다. +block.itemvoid.description = 아이템을 사라지게 만듭니다. +block.powerinfinite.description = 무한한 전력을 공급해주는 블록입니다. +block.powervoid.description = 설정된 아이템을 계속해서 출력하는 블록입니다. +liquid.water.description = 지상 유닛이 이 위를 지나가면 이동속도가 느려지고, 깊은 물에 빠지면 죽습니다. +liquid.lava.description = 지상 유닛이 이 위를 지나가면 이동속도가 매우 느려지고, 지속적으로 데미지를 입습니다. +liquid.oil.description = 일부 조합 블록에서 사용되는 자원입니다. +liquid.cryofluid.description = 포탑 및 토륨 원자로에서 사용되는 자원입니다. diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index fe40ac1fe6..93a78942b5 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -286,6 +286,7 @@ text.no = Nie ma mowy! text.info.title = [accent]Informacje text.error.title = [crimson]Wystąpił błąd text.error.crashtitle = Wystąpił błąd +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Informacje o bloku text.blocks.powercapacity = Pojemność mocy text.blocks.powershot = moc / strzał @@ -318,7 +319,8 @@ text.blocks.coolant = Płyn chłodzący text.blocks.coolantuse = Zużycie płynu chłodzącego text.blocks.inputliquidfuel = Paliwo text.blocks.liquidfueluse = Zużycie paliwa -text.blocks.explosive = Wysoce wybuchowy! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Zdrowie text.blocks.inaccuracy = Niedokładność text.blocks.shots = Strzały @@ -343,6 +345,7 @@ text.category.liquids = Płyny text.category.items = Przedmioty text.category.crafting = Przetwórstwo text.category.shooting = Strzelanie +text.category.optional = Optional Enhancements setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS setting.fpscap.none = None @@ -359,7 +362,6 @@ setting.sensitivity.name = Czułość kontrolera setting.saveinterval.name = Interwał automatycznego zapisywania setting.seconds = Sekundy setting.fullscreen.name = Pełny ekran -setting.multithread.name = Wielowątkowość setting.fps.name = Widoczny licznik FPS setting.vsync.name = Synchronizacja pionowa setting.lasers.name = Pokaż lasery zasilające @@ -404,8 +406,6 @@ mode.waves.name = Fale mode.waves.description = Normalny tryb. Normalne surowce i fale. mode.sandbox.name = sandbox mode.sandbox.description = Nieskończone surowce i fale bez odliczania. Dla przedszkolaków! -mode.custom.warning = Note that blocks cannot be used in custom games until they are unlocked in sectors.\n\n[LIGHT_GRAY]If you have not unlocked any blocks, none will appear. -mode.custom.warning.read = Just to make sure you've read it:\n[scarlet]UNLOCKS IN CUSTOM GAMES DO NOT CARRY OVER TO SECTORS OR OTHER MODES!\n\n[LIGHT_GRAY](I wish this wasn't necessary, but apparently it is) mode.freebuild.name = budowanie mode.freebuild.description = Normalne surowce i fale bez odliczania. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index 0550933b49..d663e8f5ac 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -286,6 +286,7 @@ text.no = Não text.info.title = [accent]Informação text.error.title = [crimson]Ocorreu um Erro. text.error.crashtitle = Ocorreu um Erro +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Informação do Bloco text.blocks.powercapacity = Capacidade de Energia text.blocks.powershot = Energia/tiro @@ -318,7 +319,8 @@ text.blocks.coolant = Esfriador text.blocks.coolantuse = Uso do esfriador text.blocks.inputliquidfuel = Liquido de combustivel text.blocks.liquidfueluse = Uso do liquido de combustivel -text.blocks.explosive = Altamente Explosivo! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Saúde text.blocks.inaccuracy = Imprecisão text.blocks.shots = Tiros @@ -343,6 +345,7 @@ text.category.liquids = Liquidos text.category.items = Itens text.category.crafting = Construindo text.category.shooting = Atirando +text.category.optional = Optional Enhancements setting.autotarget.name = Auto-Target setting.fpscap.name = FPS Maximo setting.fpscap.none = Nenhum @@ -359,7 +362,6 @@ setting.sensitivity.name = Sensibilidade do Controle setting.saveinterval.name = Intervalo de autosalvamento setting.seconds = {0} Segundos setting.fullscreen.name = Tela Cheia -setting.multithread.name = Multithreading setting.fps.name = Mostrar FPS setting.vsync.name = VSync setting.lasers.name = Mostrar lasers @@ -404,8 +406,6 @@ mode.waves.name = hordas mode.waves.description = O modo normal. Recursos limitados E os ataques vem automaticamente. mode.sandbox.name = sandbox mode.sandbox.description = Recursos infinitos E sem tempo para Ataques. -mode.custom.warning = Note that blocks cannot be used in custom games until they are unlocked in sectors.\n\n[LIGHT_GRAY]If you have not unlocked any blocks, none will appear. -mode.custom.warning.read = Just to make sure you've read it:\n[scarlet]UNLOCKS IN CUSTOM GAMES DO NOT CARRY OVER TO SECTORS OR OTHER MODES!\n\n[LIGHT_GRAY](I wish this wasn't necessary, but apparently it is) mode.freebuild.name = construção \nlivre mode.freebuild.description = recursos limitados e Sem tempo para Ataques. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index 478dc8dbbf..7218e4051e 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -286,6 +286,7 @@ text.no = Нет text.info.title = Информация text.error.title = [crimson]Произошла ошибка text.error.crashtitle = Произошла ошибка +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Информация о блоке text.blocks.powercapacity = Вместимость энергии text.blocks.powershot = Энергия/выстрел @@ -318,7 +319,8 @@ text.blocks.coolant = Охлаждающая жидкость text.blocks.coolantuse = Охлажд. жидкости используется text.blocks.inputliquidfuel = Жидкое топливо text.blocks.liquidfueluse = Жидкого топлива используется -text.blocks.explosive = Взрывоопасно! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Здоровье text.blocks.inaccuracy = Разброс text.blocks.shots = Выстрелы @@ -343,6 +345,7 @@ text.category.liquids = Жидкости text.category.items = Предметы text.category.crafting = Создание text.category.shooting = Cтрельба +text.category.optional = Optional Enhancements setting.autotarget.name = Авто-цель setting.fpscap.name = Макс. FPS setting.fpscap.none = Неограниченный @@ -359,7 +362,6 @@ setting.sensitivity.name = Чувствительность контроллер setting.saveinterval.name = Интервал автосохранения setting.seconds = {0} Секунд setting.fullscreen.name = Полноэкранный режим -setting.multithread.name = Многопоточность (TPS) setting.fps.name = Показывать FPS setting.vsync.name = Верт. синхронизация setting.lasers.name = Показывать энергетические лазеры @@ -404,8 +406,6 @@ mode.waves.name = Волны mode.waves.description = В режиме "волны" ограниченные ресурсы и автоматические наступающие волны. mode.sandbox.name = Песочница mode.sandbox.description = Бесконечные ресурсы и нет таймера для волн, но можно самим вызвать волну. -mode.custom.warning = [scarlet]РАЗБЛОКИРОВАННОЕ В ПОЛЬЗОВАТЕЛЬСКИХ ИГРАХ ИЛИ НА СЕРВЕРАХ НЕ СОХРАНЯЕТСЯ[]\n\nИграйте в секторах для разблокировки чего-либо -mode.custom.warning.read = Внимательно прочитайте это!:\n[scarlet]РАЗБЛОКИРОВАННОЕ В ПОЛЬЗОВАТЕЛЬСКИХ ИГРАХ ИЛИ ДРУГИХ РЕЖИМАХ ИГРЫ НЕ РАСПРОСТРАНЯЕТСЯ НА СЕКТОРА ИЛИ ДРУГИЕ РЕЖИМЫ ИГРЫ!\n\n[LIGHT_GRAY](Я бы хотел, чтобы это не было необходимо, но, по-видимому, это так) mode.freebuild.name = Свободная\nстройка mode.freebuild.description = ограниченные ресурсы и нет таймера для волн. mode.pvp.name = Противо-\nстояние diff --git a/core/assets/bundles/bundle_tk.properties b/core/assets/bundles/bundle_tk.properties index a93ca6ec6e..e0476393f0 100644 --- a/core/assets/bundles/bundle_tk.properties +++ b/core/assets/bundles/bundle_tk.properties @@ -286,6 +286,7 @@ text.no = Hayir text.info.title = [accent]Bilgi text.error.title = [crimson]Bir hata olustu text.error.crashtitle = Bir hata olustu +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Yapi bilgisi text.blocks.powercapacity = Guc kapasitesi text.blocks.powershot = Guc/Saldiri hizi @@ -318,7 +319,8 @@ text.blocks.coolant = Sogutma sivisi text.blocks.coolantuse = Sogutma sivi kullanimi text.blocks.inputliquidfuel = Yakit sivisi text.blocks.liquidfueluse = Sivi yakit kullanimi -text.blocks.explosive = Patlayici! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Can text.blocks.inaccuracy = sekme text.blocks.shots = vuruslar @@ -343,6 +345,7 @@ text.category.liquids = sivilar text.category.items = esyalar text.category.crafting = uretim text.category.shooting = sikma +text.category.optional = Optional Enhancements setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS setting.fpscap.none = Yok @@ -359,7 +362,6 @@ setting.sensitivity.name = Kumanda hassasligi setting.saveinterval.name = Otomatik kaydetme suresi setting.seconds = {0} Saniye setting.fullscreen.name = Tam ekran -setting.multithread.name = Parcaciklar setting.fps.name = FPS'i goster setting.vsync.name = VSync setting.lasers.name = Guc lazerlerini goster @@ -404,8 +406,6 @@ mode.waves.name = Dalgali mode.waves.description = Klasik mod. Dalgalara karsi cekirdegi koru. mode.sandbox.name = Serbest mode.sandbox.description = Sonsuz esyalar ve Dalga suresi yok -mode.custom.warning = Note that blocks cannot be used in custom games until they are unlocked in sectors.\n\n[LIGHT_GRAY]If you have not unlocked any blocks, none will appear. -mode.custom.warning.read = Just to make sure you've read it:\n[scarlet]UNLOCKS IN CUSTOM GAMES DO NOT CARRY OVER TO SECTORS OR OTHER MODES!\n\n[LIGHT_GRAY](I wish this wasn't necessary, but apparently it is) mode.freebuild.name = Yapi Yapma mode.freebuild.description = Sinirli esyalar ama dalga suresi yok. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_tr.properties b/core/assets/bundles/bundle_tr.properties index f48c389c47..d4e7a788b7 100644 --- a/core/assets/bundles/bundle_tr.properties +++ b/core/assets/bundles/bundle_tr.properties @@ -286,6 +286,7 @@ text.no = No text.info.title = [Vurgu] Bilgi text.error.title = [crimson] Bir hata oluştu text.error.crashtitle = Bir hata oluştu +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Blok Bilgisi text.blocks.powercapacity = Güç kapasitesi text.blocks.powershot = Güç / atış @@ -318,7 +319,8 @@ text.blocks.coolant = Coolant text.blocks.coolantuse = Coolant Use text.blocks.inputliquidfuel = Fuel Liquid text.blocks.liquidfueluse = Liquid Fuel Use -text.blocks.explosive = Çok patlayıcı! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Can text.blocks.inaccuracy = yanlışlık text.blocks.shots = atışlar @@ -343,6 +345,7 @@ text.category.liquids = Liquids text.category.items = Items text.category.crafting = Crafting text.category.shooting = Shooting +text.category.optional = Optional Enhancements setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS setting.fpscap.none = None @@ -359,7 +362,6 @@ setting.sensitivity.name = Denetleyici hassasiyeti setting.saveinterval.name = Otomatik Kaydetme Aralığı setting.seconds = saniye setting.fullscreen.name = Tam ekran -setting.multithread.name = Çok iş parçacığı setting.fps.name = Saniyede ... Kare göstermek setting.vsync.name = VSync setting.lasers.name = Güç Lazerleri Göster @@ -404,8 +406,6 @@ mode.waves.name = dalgalar mode.waves.description = normal mod. sınırlı kaynaklar ve otomatik gelen dalgalar. mode.sandbox.name = Limitsiz Oynama mode.sandbox.description = sonsuz kaynaklar ve dalgalar için zamanlayıcı yok. -mode.custom.warning = Note that blocks cannot be used in custom games until they are unlocked in sectors.\n\n[LIGHT_GRAY]If you have not unlocked any blocks, none will appear. -mode.custom.warning.read = Just to make sure you've read it:\n[scarlet]UNLOCKS IN CUSTOM GAMES DO NOT CARRY OVER TO SECTORS OR OTHER MODES!\n\n[LIGHT_GRAY](I wish this wasn't necessary, but apparently it is) mode.freebuild.name = Özgür Oynama mode.freebuild.description = sınırlı kaynaklar ve dalgalar için zamanlayıcı yok. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_uk_UA.properties b/core/assets/bundles/bundle_uk_UA.properties index 71b077368b..f5d883551b 100644 --- a/core/assets/bundles/bundle_uk_UA.properties +++ b/core/assets/bundles/bundle_uk_UA.properties @@ -286,6 +286,7 @@ text.no = Ні text.info.title = [accent]Інформація text.error.title = [crimson]Виникла помилка text.error.crashtitle = Виникла помилка +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = Інформація про блок text.blocks.powercapacity = Місткість енергії text.blocks.powershot = Енергія/постріл @@ -318,7 +319,8 @@ text.blocks.coolant = Охолоджуюча рідина text.blocks.coolantuse = Охолодж. рідини використовуеться text.blocks.inputliquidfuel = Рідке паливо text.blocks.liquidfueluse = Рідкого палива використовуеться -text.blocks.explosive = Вибухонебезпечний! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = Здоров'я text.blocks.inaccuracy = Розкид text.blocks.shots = Постріли @@ -343,6 +345,7 @@ text.category.liquids = Рідинне text.category.items = Елементи text.category.crafting = Створення text.category.shooting = Стрільба +text.category.optional = Optional Enhancements setting.autotarget.name = Авто-ціль setting.fpscap.name = Макс. FPS setting.fpscap.none = Необмежений @@ -359,7 +362,6 @@ setting.sensitivity.name = Чутливість контролера setting.saveinterval.name = Інтервал автозбереження setting.seconds = {0} сек. setting.fullscreen.name = Повноекранний режим -setting.multithread.name = Багатопотоковість (TPS) setting.fps.name = Показати FPS setting.vsync.name = Вертикальна синхронізація setting.lasers.name = Показати енергетичні лазери @@ -404,8 +406,6 @@ mode.waves.name = Хвилі mode.waves.description = Нормальний режим. Обмежені ресурси та автоматичні хвилі. mode.sandbox.name = Пісочниця mode.sandbox.description = Нескінченні ресурси і нема таймера для хвиль. -mode.custom.warning = [scarlet]РОЗБЛОКОВАНЕ В КОРИСТУВАЛЬНИЦЬКИХ ІГРАХ АБО НА СЕРВЕРАХ НЕ ЗБЕРІГАЄТЬСЯ.\n\nГрайте у секторах для розблокування. -mode.custom.warning.read = Уважно прочитайте це!:\n[scarlet]РОЗБЛОКОВАНЕ В КОРИСТУВАЛЬНИЦЬКИХ ІГРАХ АБО В ІНШИХ РЕЖИМАХ ГРИ НЕ ПОШИРЮЄТЬСЯ НА СЕКТОРИ ТА ІНШІ РЕЖИМИ ГРИ!\n\n[LIGHT_GRAY](Я б хотів, щоб це не було необхідно, але, мабуть, це так) mode.freebuild.name = Вільний режим mode.freebuild.description = обмежені ресурси і немає таймера для хвиль. mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_zh_CN.properties b/core/assets/bundles/bundle_zh_CN.properties index a024f004fc..cc6dbb00bb 100644 --- a/core/assets/bundles/bundle_zh_CN.properties +++ b/core/assets/bundles/bundle_zh_CN.properties @@ -286,6 +286,7 @@ text.no = 不 text.info.title = [accent]详情 text.error.title = [crimson]发生了一个错误 text.error.crashtitle = 发生了一个错误 +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = 方块详情 text.blocks.powercapacity = 能量容量 text.blocks.powershot = 能量/发射 @@ -318,7 +319,8 @@ text.blocks.coolant = 冷却剂 text.blocks.coolantuse = 冷却剂使用速度 text.blocks.inputliquidfuel = 液体燃料输入 text.blocks.liquidfueluse = 液体燃料使用速度 -text.blocks.explosive = 易爆炸! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = 生命值 text.blocks.inaccuracy = 误差 text.blocks.shots = 发射数 @@ -343,6 +345,7 @@ text.category.liquids = 液体 text.category.items = 物品 text.category.crafting = 制造 text.category.shooting = 发射 +text.category.optional = Optional Enhancements setting.autotarget.name = 自动发射 setting.fpscap.name = 最高 FPS setting.fpscap.none = 无 @@ -359,7 +362,6 @@ setting.sensitivity.name = 控制器灵敏度 setting.saveinterval.name = 自动保存间隔 setting.seconds = {0} 秒 setting.fullscreen.name = 全屏 -setting.multithread.name = 多线程 setting.fps.name = 显示 FPS setting.vsync.name = 帧同步 setting.lasers.name = 显示能量射线 @@ -404,8 +406,6 @@ mode.waves.name = 普通 mode.waves.description = 普通模式,有限的资源和自动生成敌人。 mode.sandbox.name = 沙盒 mode.sandbox.description = 无限的资源,不会自动生成敌人。 -mode.custom.warning = 请注意,方块在区域内解锁之前,不能用于自定义游戏。\n\n[LIGHT_GRAY]如果您没有解锁任何方块,则不会出现任何方块。 -mode.custom.warning.read = 确保你已经阅读过它:\n[scarlet]自定义游戏的解锁不带至区域或其他模式!\n\n[LIGHT_GRAY](我希望这不是必要的,但显然是必要的) mode.freebuild.name = 自由建造 mode.freebuild.description = 有限的资源,不会自动生成敌人。 mode.pvp.name = PvP diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 16a87728f9..f9ccc2ea8c 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -286,6 +286,7 @@ text.no = 否 text.info.title = [accent]資訊 text.error.title = [crimson]發生錯誤 text.error.crashtitle = 發生錯誤 +text.blocks.unknown = [LIGHT_GRAY]??? text.blocks.blockinfo = 方塊資訊 text.blocks.powercapacity = 蓄電量 text.blocks.powershot = 能源/射擊 @@ -318,7 +319,8 @@ text.blocks.coolant = 冷卻劑 text.blocks.coolantuse = 使用冷卻劑 text.blocks.inputliquidfuel = 輸入液體燃料 text.blocks.liquidfueluse = 使用液體燃料速度 -text.blocks.explosive = 容易爆炸! +text.blocks.boostitem = Boost Item +text.blocks.boostliquid = Boost Liquid text.blocks.health = 耐久度 text.blocks.inaccuracy = 誤差 text.blocks.shots = 射擊數 @@ -343,6 +345,7 @@ text.category.liquids = 液體 text.category.items = 物品 text.category.crafting = 合成 text.category.shooting = 射擊 +text.category.optional = Optional Enhancements setting.autotarget.name = 自動射擊 setting.fpscap.name = 最大螢幕刷新率 setting.fpscap.none = 没有 @@ -359,7 +362,6 @@ setting.sensitivity.name = 控制器靈敏度 setting.saveinterval.name = 自動存檔間隔 setting.seconds = {0}秒 setting.fullscreen.name = 全螢幕 -setting.multithread.name = 多執行緒 setting.fps.name = 顯示螢幕刷新率 setting.vsync.name = 垂直同步 setting.lasers.name = 顯示雷射光束 @@ -404,8 +406,6 @@ mode.waves.name = 一般 mode.waves.description = 一般模式,有限的資源與自動來襲的波次。 mode.sandbox.name = 沙盒 mode.sandbox.description = 無限的資源,與不倒數計時的波次。 -mode.custom.warning = 請注意,方塊在區域內解鎖之前,不能用於自訂遊戲。\n\n[LIGHT_GRAY]如果您沒有解鎖任何方塊,則不會出現任何方塊。 -mode.custom.warning.read = 確保你已閱讀過它:\n[scarlet]自訂遊戲的解鎖不帶至區域或其他模式!\n\n[LIGHT_GRAY](我希望這不是必要的,但顯然是必要的) mode.freebuild.name = 自由建造 mode.freebuild.description = 有限的資源,與不倒數計時的波次。 mode.pvp.name = 對戰 diff --git a/core/assets/shaders/shield.fragment b/core/assets/shaders/shield.fragment index e71cb95f37..f771e59dd3 100644 --- a/core/assets/shaders/shield.fragment +++ b/core/assets/shaders/shield.fragment @@ -12,7 +12,6 @@ precision highp int; uniform sampler2D u_texture; uniform vec2 u_texsize; uniform float u_time; -uniform float u_scaling; uniform float u_dp; uniform vec2 u_offset; @@ -28,7 +27,7 @@ void main() { vec2 T = v_texCoord.xy; vec2 coords = (T * u_texsize) + u_offset; - T += vec2(sin(coords.y / 3.0 + u_time / 20.0) / 240.0, sin(coords.x / 3.0 + u_time / 20.0) / 240.0) * u_scaling; + T += vec2(sin(coords.y / 3.0 + u_time / 20.0), sin(coords.x / 3.0 + u_time / 20.0)) / u_texsize; float si = sin(u_time / 20.0) / 8.0; vec4 color = texture2D(u_texture, T); diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 50116dc3d2..aee86eacf6 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -33,6 +33,7 @@ public class Vars{ public static final String appName = "Mindustry"; public static final String discordURL = "https://discord.gg/mindustry"; public static final String releasesURL = "https://api.github.com/repos/Anuken/Mindustry/releases"; + public static final String contributorsURL = "https://api.github.com/repos/Anuken/Mindustry/contributors"; public static final String crashReportURL = "http://mindustry.us.to/report"; //time between waves in frames (on normal mode) public static final float wavespace = 60 * 60 * 1.5f; @@ -73,6 +74,7 @@ public class Vars{ }; //server port public static final int port = 6567; + public static boolean disableUI; public static boolean testMobile; //shorthand for whether or not this is running on android or ios public static boolean mobile; @@ -80,6 +82,8 @@ public class Vars{ public static boolean android; //main data directory public static FileHandle dataDirectory; + //subdirectory for screenshots + public static FileHandle screenshotDirectory; //directory for user-created map data public static FileHandle customMapDirectory; //save file directory @@ -170,6 +174,7 @@ public class Vars{ android = Gdx.app.getType() == ApplicationType.Android; dataDirectory = Settings.getDataDirectory(appName); + screenshotDirectory = dataDirectory.child("screenshots/"); customMapDirectory = dataDirectory.child("maps/"); saveDirectory = dataDirectory.child("saves/"); baseCameraScale = Math.round(Unit.dp.scl(4)); diff --git a/core/src/io/anuke/mindustry/ai/BlockIndexer.java b/core/src/io/anuke/mindustry/ai/BlockIndexer.java index 04c5c04cb8..9b0c5f7bac 100644 --- a/core/src/io/anuke/mindustry/ai/BlockIndexer.java +++ b/core/src/io/anuke/mindustry/ai/BlockIndexer.java @@ -21,7 +21,6 @@ import io.anuke.ucore.util.ThreadArray; import static io.anuke.mindustry.Vars.*; //TODO consider using quadtrees for finding specific types of blocks within an area -//TODO maybe use Arrays instead of ObjectSets? /**Class used for indexing special target blocks for AI.*/ @SuppressWarnings("unchecked") diff --git a/core/src/io/anuke/mindustry/ai/Pathfinder.java b/core/src/io/anuke/mindustry/ai/Pathfinder.java index 7f9c77970c..ccb9fc6fc4 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfinder.java +++ b/core/src/io/anuke/mindustry/ai/Pathfinder.java @@ -182,7 +182,7 @@ public class Pathfinder{ } } - state.spawner.checkAllQuadrants(); + world.spawner.checkAllQuadrants(); } class PathData{ diff --git a/core/src/io/anuke/mindustry/content/UnitTypes.java b/core/src/io/anuke/mindustry/content/UnitTypes.java index 33b4a7cacf..16f630433c 100644 --- a/core/src/io/anuke/mindustry/content/UnitTypes.java +++ b/core/src/io/anuke/mindustry/content/UnitTypes.java @@ -37,6 +37,7 @@ public class UnitTypes implements ContentList{ }; spirit = new UnitType("spirit", Spirit.class, Spirit::new){{ + weapon = Weapons.healBlasterDrone; isFlying = true; drag = 0.01f; speed = 0.2f; diff --git a/core/src/io/anuke/mindustry/content/Weapons.java b/core/src/io/anuke/mindustry/content/Weapons.java index f37796ba13..6875f4d392 100644 --- a/core/src/io/anuke/mindustry/content/Weapons.java +++ b/core/src/io/anuke/mindustry/content/Weapons.java @@ -7,7 +7,7 @@ import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Weapon; public class Weapons implements ContentList{ - public static Weapon blaster, blasterSmall, glaiveBlaster, droneBlaster, healBlaster, chainBlaster, shockgun, + public static Weapon blaster, blasterSmall, glaiveBlaster, droneBlaster, healBlaster, healBlasterDrone, chainBlaster, shockgun, sapper, swarmer, bomber, bomberTrident, flakgun, flamethrower, missiles, artillery, laserBurster; @Override @@ -169,6 +169,16 @@ public class Weapons implements ContentList{ ejectEffect = Fx.none; ammo = AmmoTypes.lancerLaser; }}; + + healBlasterDrone = new Weapon("heal-blaster"){{ + length = 1.5f; + reload = 40f; + width = 0.5f; + roundrobin = true; + ejectEffect = Fx.none; + recoil = 2f; + ammo = AmmoTypes.healBlaster; + }}; } @Override diff --git a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java index 8e8e87e3e1..0b12920c72 100644 --- a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java @@ -64,9 +64,9 @@ public class LiquidBlocks extends BlockList implements ContentList{ }}; phaseConduit = new LiquidBridge("phase-conduit"){{ - range = 11; + range = 12; hasPower = true; - consumes.power(0.05f); + consumes.power(0.03f); }}; } } diff --git a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java index bce9e3bb5a..a3a805a557 100644 --- a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java @@ -32,24 +32,13 @@ public class TurretBlocks extends BlockList implements ContentList{ hail = new ArtilleryTurret("hail"){{ ammoTypes = new AmmoType[]{AmmoTypes.artilleryDense, AmmoTypes.artilleryHoming, AmmoTypes.artilleryIncindiary}; - reload = 70f; + reload = 60f; recoil = 2f; range = 230f; inaccuracy = 1f; shootCone = 10f; health = 120; }}; -/* - scatter = new BurstTurret("scatter"){{ - ammoTypes = new AmmoType[]{AmmoTypes.flakCopper}; - reload = 70f; - recoil = 2f; - shots = 3; - range = 220f; - inaccuracy = 2f; - shootCone = 40f; - health = 120; - }};*/ scorch = new LiquidTurret("scorch"){ protected TextureRegion shootRegion; @@ -117,11 +106,11 @@ public class TurretBlocks extends BlockList implements ContentList{ arc = new PowerTurret("arc"){{ shootType = AmmoTypes.arc; - reload = 55f; + reload = 85f; shootShake = 1f; shootCone = 40f; rotatespeed = 8f; - powerUsed = 7f; + powerUsed = 10f; powerCapacity = 30f; range = 150f; shootEffect = ShootFx.lightningShoot; @@ -132,7 +121,7 @@ public class TurretBlocks extends BlockList implements ContentList{ swarmer = new BurstTurret("swarmer"){{ ammoTypes = new AmmoType[]{AmmoTypes.missileExplosive, AmmoTypes.missileIncindiary, AmmoTypes.missileSurge}; - reload = 60f; + reload = 50f; shots = 4; burstSpacing = 5; inaccuracy = 10f; @@ -156,7 +145,7 @@ public class TurretBlocks extends BlockList implements ContentList{ size = 2; range = 120f; ammoTypes = new AmmoType[]{AmmoTypes.bulletCopper, AmmoTypes.bulletDense, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon}; - reload = 40f; + reload = 35f; restitution = 0.03f; ammoEjectBack = 3f; cooldown = 0.03f; @@ -216,7 +205,6 @@ public class TurretBlocks extends BlockList implements ContentList{ }}; fuse = new ItemTurret("fuse"){{ - //TODO make it use power ammoTypes = new AmmoType[]{AmmoTypes.fuseShotgun}; reload = 50f; shootShake = 4f; diff --git a/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java b/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java index ba7cac85b8..2b28ec0016 100644 --- a/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java +++ b/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java @@ -43,7 +43,7 @@ public class TurretBullets extends BulletList implements ContentList{ }; healBullet = new BulletType(5.2f, 13){ - float healAmount = 21f; + float healPercent = 3f; { hiteffect = BulletFx.hitLaser; @@ -51,6 +51,11 @@ public class TurretBullets extends BulletList implements ContentList{ collidesTeam = true; } + @Override + public boolean collides(Bullet b, Tile tile){ + return tile.getTeam() != b.getTeam() || tile.entity.healthf() < 1f; + } + @Override public void draw(Bullet b){ Draw.color(Palette.heal); @@ -67,8 +72,8 @@ public class TurretBullets extends BulletList implements ContentList{ tile = tile.target(); if(tile.getTeam() == b.getTeam() && !(tile.block() instanceof BuildBlock)){ - Effects.effect(BlockFx.healBlock, tile.drawx(), tile.drawy(), tile.block().size); - tile.entity.healBy(healAmount); + Effects.effect(BlockFx.healBlockFull, Palette.heal, tile.drawx(), tile.drawy(), tile.block().size); + tile.entity.healBy(healPercent / 100f * tile.entity.maxHealth()); } } }; @@ -304,7 +309,7 @@ public class TurretBullets extends BulletList implements ContentList{ } }; - arc = new BulletType(0.001f, 30){ + arc = new BulletType(0.001f, 26){ { lifetime = 1; despawneffect = Fx.none; diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 8dbcc2d1e6..84e2f45e2d 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -98,7 +98,7 @@ public class Control extends Module{ "color-1", Color.rgba8888(playerColors[11]), "color-2", Color.rgba8888(playerColors[13]), "color-3", Color.rgba8888(playerColors[9]), - "name", "player", + "name", "", "lastBuild", 0 ); @@ -382,6 +382,10 @@ public class Control extends Module{ } } + if(Inputs.keyTap("screenshot")){ + renderer.takeMapScreenshot(); + } + }else{ if(!state.isPaused()){ Timers.update(); diff --git a/core/src/io/anuke/mindustry/core/GameState.java b/core/src/io/anuke/mindustry/core/GameState.java index bde128eb91..96a36fad8a 100644 --- a/core/src/io/anuke/mindustry/core/GameState.java +++ b/core/src/io/anuke/mindustry/core/GameState.java @@ -1,6 +1,5 @@ package io.anuke.mindustry.core; -import io.anuke.mindustry.ai.WaveSpawner; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.EventType.StateChangeEvent; import io.anuke.mindustry.game.GameMode; @@ -12,14 +11,21 @@ import static io.anuke.mindustry.Vars.unitGroups; import static io.anuke.mindustry.Vars.waveTeam; public class GameState{ + /**Current wave number, can be anything in non-wave modes.*/ public int wave = 1; + /**Wave countdown in ticks.*/ public float wavetime; + /**Whether the game is in game over state.*/ public boolean gameOver = false; + /**The current game mode.*/ public GameMode mode = GameMode.waves; + /**The current difficulty for wave modes.*/ public Difficulty difficulty = Difficulty.normal; - public WaveSpawner spawner = new WaveSpawner(); + /**Team data. Gets reset every new game.*/ public Teams teams = new Teams(); + /**Number of enemies in the game; only used clientside in servers.*/ public int enemies; + /**Current game state.*/ private State state = State.menu; public int enemies(){ diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index 5063a29b0b..5f7035cb7e 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -93,7 +93,7 @@ public class Logic extends Module{ } public void runWave(){ - state.spawner.spawnEnemies(); + world.spawner.spawnEnemies(); state.wave++; state.wavetime = wavespace * state.difficulty.timeScaling; diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 99a224da9b..bf124f9be2 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -15,6 +15,7 @@ import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.SyncTrait; import io.anuke.mindustry.entities.traits.TypeTrait; +import io.anuke.mindustry.game.Version; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.RemoteReadClient; import io.anuke.mindustry.net.Net; @@ -95,6 +96,7 @@ public class NetClient extends Module{ ConnectPacket c = new ConnectPacket(); c.name = player.name; c.mobile = mobile; + c.versionType = Version.type; c.color = Color.rgba8888(player.color); c.usid = getUsid(packet.addressTCP); c.uuid = Platform.instance.getUUID(); diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 25ee6de9a4..052e31bc8f 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -16,6 +16,7 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.SyncTrait; +import io.anuke.mindustry.game.EventType.WorldLoadEvent; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Version; import io.anuke.mindustry.gen.Call; @@ -24,6 +25,7 @@ import io.anuke.mindustry.net.*; import io.anuke.mindustry.net.Administration.PlayerInfo; import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.world.Tile; +import io.anuke.ucore.core.Events; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.EntityGroup; @@ -76,6 +78,9 @@ public class NetServer extends Module{ private DataOutputStream dataStream = new DataOutputStream(syncStream); public NetServer(){ + Events.on(WorldLoadEvent.class, event -> { + connections.clear(); + }); Net.handleServer(Connect.class, (id, connect) -> { if(admins.isIPBanned(connect.addressTCP)){ @@ -120,7 +125,7 @@ public class NetServer extends Module{ return; } - if(packet.version == -1 && Version.build != -1 && !admins.allowsCustomClients()){ + if(packet.versionType == null || ((packet.version == -1 || !packet.versionType.equals("official")) && Version.build != -1 && !admins.allowsCustomClients())){ kick(id, KickReason.customClient); return; } diff --git a/core/src/io/anuke/mindustry/core/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java index 63695bac48..6c184cca81 100644 --- a/core/src/io/anuke/mindustry/core/Platform.java +++ b/core/src/io/anuke/mindustry/core/Platform.java @@ -10,7 +10,6 @@ import io.anuke.ucore.core.Timers; import io.anuke.ucore.function.Consumer; import io.anuke.ucore.scene.ui.Dialog; import io.anuke.ucore.scene.ui.TextField; -import io.anuke.ucore.util.Log; import java.util.Random; @@ -29,7 +28,6 @@ public abstract class Platform { if(!mobile) return; //this is mobile only, desktop doesn't need dialogs field.tapped(() -> { - Log.info("yappd"); Dialog dialog = new Dialog("", "dialog"); dialog.setFillParent(true); dialog.content().top(); diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 0841ef78bd..7b090ca143 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -1,9 +1,16 @@ package io.anuke.mindustry.core; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.PixmapIO; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.BufferUtils; +import com.badlogic.gdx.utils.ScreenUtils; +import com.badlogic.gdx.utils.TimeUtils; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; @@ -32,6 +39,7 @@ import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.graphics.Surface; import io.anuke.ucore.modules.RendererModule; import io.anuke.ucore.scene.utils.Cursors; +import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Pooling; import io.anuke.ucore.util.Translator; @@ -353,4 +361,44 @@ public class Renderer extends RendererModule{ targetscale = Mathf.clamp(targetscale, Math.round(s * 2), Math.round(s * 5)); } + public void takeMapScreenshot(){ + float vpW = Core.camera.viewportWidth, vpH = Core.camera.viewportHeight; + int w = world.width()*tilesize, h = world.height()*tilesize; + int pw = pixelSurface.width(), ph = pixelSurface.height(); + showFog = false; + disableUI = true; + pixelSurface.setSize(w, h, true); + Graphics.getEffectSurface().setSize(w, h, true); + Core.camera.viewportWidth = w; + Core.camera.viewportHeight = h; + Core.camera.position.x = w/2f; + Core.camera.position.y = h/2f; + + draw(); + + showFog = true; + disableUI = false; + Core.camera.viewportWidth = vpW; + Core.camera.viewportHeight = vpH; + + pixelSurface.getBuffer().begin(); + byte[] lines = ScreenUtils.getFrameBufferPixels(0, 0, w, h, true); + for(int i = 0; i < lines.length; i+= 4){ + lines[i + 3] = (byte)255; + } + pixelSurface.getBuffer().end(); + + Pixmap fullPixmap = new Pixmap(w, h, Pixmap.Format.RGBA8888); + + BufferUtils.copy(lines, 0, fullPixmap.getPixels(), lines.length); + FileHandle file = screenshotDirectory.child("screenshot-" + TimeUtils.millis() + ".png"); + PixmapIO.writePNG(file, fullPixmap); + fullPixmap.dispose(); + + pixelSurface.setSize(pw, ph, false); + Graphics.getEffectSurface().setSize(pw, ph, false); + + ui.showInfoFade(Bundles.format("text.screenshot", file.toString())); + } + } diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 0d7ca96820..27e8fd3569 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -123,6 +123,8 @@ public class UI extends SceneModule{ @Override public void update(){ + if(disableUI) return; + if(Graphics.drawing()) Graphics.end(); act(); diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 50469edacf..cf72719411 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; import io.anuke.mindustry.ai.BlockIndexer; import io.anuke.mindustry.ai.Pathfinder; +import io.anuke.mindustry.ai.WaveSpawner; import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.TileChangeEvent; @@ -30,6 +31,7 @@ public class World extends Module{ public final WorldGenerator generator = new WorldGenerator(); public final BlockIndexer indexer = new BlockIndexer(); public final Pathfinder pathfinder = new Pathfinder(); + public final WaveSpawner spawner = new WaveSpawner(); private Map currentMap; private Sector currentSector; diff --git a/core/src/io/anuke/mindustry/editor/EditorTool.java b/core/src/io/anuke/mindustry/editor/EditorTool.java index c988beb46b..6eca7e8fd4 100644 --- a/core/src/io/anuke/mindustry/editor/EditorTool.java +++ b/core/src/io/anuke/mindustry/editor/EditorTool.java @@ -17,6 +17,8 @@ import static io.anuke.mindustry.Vars.ui; public enum EditorTool{ pick{ public void touched(MapEditor editor, int x, int y){ + if(!Structs.inBounds(x, y, editor.getMap().width(), editor.getMap().height())) return; + byte bf = editor.getMap().read(x, y, DataPosition.floor); byte bw = editor.getMap().read(x, y, DataPosition.wall); byte link = editor.getMap().read(x, y, DataPosition.link); diff --git a/core/src/io/anuke/mindustry/editor/MapView.java b/core/src/io/anuke/mindustry/editor/MapView.java index 59894bd016..fca223c3fe 100644 --- a/core/src/io/anuke/mindustry/editor/MapView.java +++ b/core/src/io/anuke/mindustry/editor/MapView.java @@ -175,7 +175,6 @@ public class MapView extends Element implements GestureListener{ public void clearStack(){ stack.clear(); - //TODO clear und obuffer } public OperationStack getStack(){ @@ -292,7 +291,6 @@ public class MapView extends Element implements GestureListener{ } } - //todo is it really math.max? float scaling = zoom * Math.min(width, height) / editor.getMap().width(); Draw.color(Palette.accent); diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 168c5838be..67ffce265a 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -19,10 +19,7 @@ import io.anuke.mindustry.graphics.Trail; import io.anuke.mindustry.io.TypeIO; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetConnection; -import io.anuke.mindustry.type.ContentType; -import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.type.Mech; -import io.anuke.mindustry.type.Weapon; +import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Floor; @@ -192,6 +189,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra this.mining = tile; } + @Override + public boolean canMine(Item item){ + return item.hardness <= mech.drillPower; + } + @Override public float getArmor(){ return mech.armor + mech.getExtraArmor(this); diff --git a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java index f3d60b86f6..f918d6ce8b 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java +++ b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java @@ -209,7 +209,7 @@ public class Bullet extends BulletEntity implements TeamTrait, SyncT if(tile == null) return false; tile = tile.target(); - if(tile.entity != null && tile.entity.collide(this) && !tile.entity.isDead() && (type.collidesTeam || tile.getTeam() != team)){ + if(tile.entity != null && tile.entity.collide(this) && type.collides(this, tile) && !tile.entity.isDead() && (type.collidesTeam || tile.getTeam() != team)){ if(tile.getTeam() != team){ tile.entity.collision(this); } diff --git a/core/src/io/anuke/mindustry/entities/bullet/BulletType.java b/core/src/io/anuke/mindustry/entities/bullet/BulletType.java index 916ebbb52c..b6220dd9dd 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/BulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/BulletType.java @@ -55,6 +55,10 @@ public abstract class BulletType extends Content implements BaseBulletType mineDistance || tile.floor().drops == null || !unit.inventory.canAcceptItem(tile.floor().drops.item)){ + if(core == null || tile.block() != Blocks.air || unit.distanceTo(tile.worldx(), tile.worldy()) > mineDistance + || tile.floor().drops == null || !unit.inventory.canAcceptItem(tile.floor().drops.item) || !canMine(tile.floor().drops.item)){ setMineTile(null); }else{ Item item = tile.floor().drops.item; diff --git a/core/src/io/anuke/mindustry/entities/traits/RepairTrait.java b/core/src/io/anuke/mindustry/entities/traits/RepairTrait.java deleted file mode 100644 index 4712730e4c..0000000000 --- a/core/src/io/anuke/mindustry/entities/traits/RepairTrait.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.anuke.mindustry.entities.traits; - -import io.anuke.ucore.entities.trait.HealthTrait; - -//TODO implement -public interface RepairTrait extends TeamTrait{ - - HealthTrait getRepairing(); - - void setRepairing(HealthTrait trait); - - default void drawRepair(){ - if(getRepairing() == null) return; - } - - default void updateRepair(){ - if(getRepairing() == null) return; - } -} diff --git a/core/src/io/anuke/mindustry/entities/units/UnitType.java b/core/src/io/anuke/mindustry/entities/units/UnitType.java index 5087df0b81..6cae81a48f 100644 --- a/core/src/io/anuke/mindustry/entities/units/UnitType.java +++ b/core/src/io/anuke/mindustry/entities/units/UnitType.java @@ -19,7 +19,6 @@ import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Log; import io.anuke.ucore.util.Strings; -//TODO merge unit type with mech public class UnitType extends UnlockableContent{ protected final Supplier constructor; diff --git a/core/src/io/anuke/mindustry/entities/units/types/Drone.java b/core/src/io/anuke/mindustry/entities/units/types/Drone.java index afc926d2b0..477f640965 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Drone.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Drone.java @@ -1,14 +1,11 @@ package io.anuke.mindustry.entities.units.types; -import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.utils.Queue; import io.anuke.mindustry.content.blocks.Blocks; -import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.traits.BuilderTrait; -import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.entities.units.FlyingUnit; import io.anuke.mindustry.entities.units.UnitCommand; @@ -16,7 +13,6 @@ import io.anuke.mindustry.entities.units.UnitState; import io.anuke.mindustry.game.EventType.BuildSelectEvent; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Palette; -import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.ItemType; @@ -24,13 +20,11 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.BuildBlock; import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity; import io.anuke.mindustry.world.meta.BlockFlag; -import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Events; -import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.EntityGroup; -import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.graphics.Shapes; -import io.anuke.ucore.util.*; +import io.anuke.ucore.util.Geometry; +import io.anuke.ucore.util.Mathf; +import io.anuke.ucore.util.Structs; import java.io.DataInput; import java.io.DataOutput; @@ -117,12 +111,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{ if(target.distanceTo(Drone.this) > type.range){ circle(type.range*0.9f); }else{ - TileEntity entity = (TileEntity) target; - entity.healBy(type.healSpeed * entity.tile.block().health / 100f * Timers.delta()); - - if(timer.get(timerRepairEffect, 30)){ - Effects.effect(BlockFx.healBlockFull, Palette.heal, entity.x, entity.y, entity.tile.block().size); - } + getWeapon().update(Drone.this, target.getX(), target.getY()); } } }, @@ -279,6 +268,11 @@ public class Drone extends FlyingUnit implements BuilderTrait{ //no } + @Override + public boolean canMine(Item item){ + return type.toMine.contains(item); + } + @Override public float getBuildPower(Tile tile){ return type.buildPower; @@ -312,16 +306,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{ target = null; } - if(Net.client() && state.is(repair) && target instanceof TileEntity && target.distanceTo(this) < type.range){ - TileEntity entity = (TileEntity) target; - entity.health += type.healSpeed * Timers.delta(); - entity.health = Mathf.clamp(entity.health, 0, entity.tile.block().health); - - if(timer.get(timerRepairEffect, 30)){ - Effects.effect(BlockFx.healBlockFull, Palette.heal, entity.x, entity.y, entity.tile.block().size); - } - } - updateBuilding(this); } @@ -349,20 +333,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{ @Override public void drawOver(){ - trail.draw(Palette.lightTrail, 3f * Mathf.clamp(velocity.len(), 0, 1f) / 1f); - - TargetTrait entity = target; - - if(entity instanceof TileEntity && state.is(repair) && target.distanceTo(this) < type.range){ - float len = 5f; - Draw.color(Color.BLACK, Color.WHITE, 0.95f + Mathf.absin(Timers.time(), 0.8f, 0.05f)); - Shapes.laser("beam", "beam-end", - x + Angles.trnsx(rotation, len), - y + Angles.trnsy(rotation, len), - entity.getX(), entity.getY()); - Draw.color(); - } - + trail.draw(Palette.lightTrail, 3f); drawBuilding(this); } diff --git a/core/src/io/anuke/mindustry/game/Version.java b/core/src/io/anuke/mindustry/game/Version.java index e0d6ff304e..acc63bcc20 100644 --- a/core/src/io/anuke/mindustry/game/Version.java +++ b/core/src/io/anuke/mindustry/game/Version.java @@ -11,10 +11,10 @@ import java.io.IOException; public class Version{ /**Build type. 'official' for official releases; 'custom' or 'bleeding edge' are also used.*/ public static String type; - /**Number specifying the major version, e.g. '4.0'*/ - public static String number; /**Build modifier, e.g. 'alpha' or 'release'*/ public static String modifier; + /**Number specifying the major version, e.g. '4'*/ + public static int number; /**Build number, e.g. '43'. set to '-1' for custom builds.*/ public static int build = 0; @@ -26,7 +26,7 @@ public class Version{ PropertiesUtils.load(map, file.reader()); type = map.get("type"); - number = map.get("number"); + number = Integer.parseInt(map.get("number")); modifier = map.get("modifier"); build = Strings.canParseInt(map.get("build")) ? Integer.parseInt(map.get("build")) : -1; }catch(IOException e){ diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 705db80466..466c27a345 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -23,7 +23,7 @@ import static io.anuke.ucore.core.Core.camera; public class BlockRenderer{ private final static int initialRequests = 32 * 32; - private final static int expandr = 4; + private final static int expandr = 6; public final FloorRenderer floor = new FloorRenderer(); diff --git a/core/src/io/anuke/mindustry/graphics/Shaders.java b/core/src/io/anuke/mindustry/graphics/Shaders.java index e3c3a5a656..254234f419 100644 --- a/core/src/io/anuke/mindustry/graphics/Shaders.java +++ b/core/src/io/anuke/mindustry/graphics/Shaders.java @@ -157,17 +157,14 @@ public class Shaders{ @Override public void apply(){ - // shader.setUniformf("u_progress", progress); shader.setUniformf("u_color", color); shader.setUniformf("u_uv", region.getU(), region.getV()); shader.setUniformf("u_uv2", region.getU2(), region.getV2()); - //shader.setUniformf("u_time", Timers.time()); shader.setUniformf("u_texsize", region.getTexture().getWidth(), region.getTexture().getHeight()); } } public static class Shield extends Shader{ - //public Color color = new Color(); public Shield(){ super("shield", "default"); @@ -175,17 +172,13 @@ public class Shaders{ @Override public void apply(){ - float scaling = Core.cameraScale / 4f / Core.camera.zoom; - shader.setUniformf("u_dp", Unit.dp.scl(1f)); - //shader.setUniformf("u_color", color); shader.setUniformf("u_time", Timers.time() / Unit.dp.scl(1f)); - shader.setUniformf("u_scaling", scaling); shader.setUniformf("u_offset", Core.camera.position.x - Core.camera.viewportWidth / 2 * Core.camera.zoom, Core.camera.position.y - Core.camera.viewportHeight / 2 * Core.camera.zoom); - shader.setUniformf("u_texsize", Gdx.graphics.getWidth() / Core.cameraScale * Core.camera.zoom, - Gdx.graphics.getHeight() / Core.cameraScale * Core.camera.zoom); + shader.setUniformf("u_texsize", Core.camera.viewportWidth * Core.camera.zoom, + Core.camera.viewportHeight * Core.camera.zoom); } } @@ -200,8 +193,8 @@ public class Shaders{ shader.setUniformf("camerapos", Core.camera.position.x - Core.camera.viewportWidth / 2 * Core.camera.zoom, Core.camera.position.y - Core.camera.viewportHeight / 2 * Core.camera.zoom); - shader.setUniformf("screensize", Gdx.graphics.getWidth() / Core.cameraScale * Core.camera.zoom, - Gdx.graphics.getHeight() / Core.cameraScale * Core.camera.zoom); + shader.setUniformf("screensize", Core.camera.viewportWidth* Core.camera.zoom, + Core.camera.viewportHeight * Core.camera.zoom); shader.setUniformf("time", Timers.time()); } } diff --git a/core/src/io/anuke/mindustry/input/DefaultKeybinds.java b/core/src/io/anuke/mindustry/input/DefaultKeybinds.java index 9db284dc16..8f0117abf9 100644 --- a/core/src/io/anuke/mindustry/input/DefaultKeybinds.java +++ b/core/src/io/anuke/mindustry/input/DefaultKeybinds.java @@ -32,6 +32,7 @@ public class DefaultKeybinds{ "menu", Gdx.app.getType() == ApplicationType.Android ? Input.BACK : Input.ESCAPE, "pause", Input.SPACE, "toggle_menus", Input.C, + "screenshot", Input.P, new Category("multiplayer"), "player_list", Input.TAB, "chat", Input.ENTER, diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 36722ffe21..111b2f9718 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -193,7 +193,7 @@ public abstract class InputHandler extends InputAdapter{ } //call tapped event - if(tile.getTeam() == player.getTeam()){ + if(!consumed && tile.getTeam() == player.getTeam()){ Call.onTileTapped(player, tile); } diff --git a/core/src/io/anuke/mindustry/input/MobileInput.java b/core/src/io/anuke/mindustry/input/MobileInput.java index d21d832bf4..98fb139c97 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -230,7 +230,7 @@ public class MobileInput extends InputHandler implements GestureListener{ player.clearBuilding(); mode = none; recipe = null; - }).visible(() -> player.isBuilding() || recipe != null); + }).visible(() -> player.isBuilding() || recipe != null || mode == breaking); //confirm button table.addImageButton("icon-check", "clear-partial", 16 * 2f, () -> { @@ -528,7 +528,7 @@ public class MobileInput extends InputHandler implements GestureListener{ //ignore off-screen taps if(cursor == null || ui.hasMouse(x, y)) return false; - threads.run(() -> checkTargets(worldx, worldy)); + checkTargets(worldx, worldy); //remove if request present if(hasRequest(cursor)){ @@ -548,14 +548,13 @@ public class MobileInput extends InputHandler implements GestureListener{ consumed = true; player.dropCarry(); //drop off unit }else{ - threads.run(() -> { - Unit unit = Units.getClosest(player.getTeam(), Graphics.world(x, y).x, Graphics.world(x, y).y, 4f, u -> !u.isFlying() && u.getMass() <= player.mech.carryWeight); + Unit unit = Units.getClosest(player.getTeam(), Graphics.world(x, y).x, Graphics.world(x, y).y, 4f, u -> !u.isFlying() && u.getMass() <= player.mech.carryWeight); - if(unit != null){ - player.moveTarget = unit; - Effects.effect(Fx.select, unit.getX(), unit.getY()); - } - }); + if(unit != null){ + consumed = true; + player.moveTarget = unit; + Effects.effect(Fx.select, unit.getX(), unit.getY()); + } } } diff --git a/core/src/io/anuke/mindustry/io/Contributors.java b/core/src/io/anuke/mindustry/io/Contributors.java new file mode 100644 index 0000000000..f7c6e0f4b1 --- /dev/null +++ b/core/src/io/anuke/mindustry/io/Contributors.java @@ -0,0 +1,43 @@ +package io.anuke.mindustry.io; + +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.JsonReader; +import com.badlogic.gdx.utils.JsonValue; +import io.anuke.mindustry.net.Net; +import io.anuke.ucore.function.Consumer; + +import static io.anuke.mindustry.Vars.contributorsURL; + +public class Contributors{ + + public static void getContributors(Consumer> success, Consumer fail){ + Net.http(contributorsURL, "GET", result -> { + JsonReader reader = new JsonReader(); + JsonValue value = reader.parse(result).child; + Array out = new Array<>(); + + while(value != null){ + String login = value.getString("login"); + out.add(new Contributor(login)); + value = value.next; + } + + success.accept(out); + }, fail); + } + + public static class Contributor{ + public final String login; + + public Contributor(String login){ + this.login = login; + } + + @Override + public String toString(){ + return "Contributor{" + + "login='" + login + '\'' + + '}'; + } + } +} diff --git a/core/src/io/anuke/mindustry/io/TypeIO.java b/core/src/io/anuke/mindustry/io/TypeIO.java index 6061472054..94b3f0825f 100644 --- a/core/src/io/anuke/mindustry/io/TypeIO.java +++ b/core/src/io/anuke/mindustry/io/TypeIO.java @@ -27,7 +27,6 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import static io.anuke.mindustry.Vars.*; @@ -332,31 +331,21 @@ public class TypeIO{ @WriteClass(String.class) public static void writeString(ByteBuffer buffer, String string){ if(string != null){ - Charset charset = Charset.defaultCharset(); - byte[] nameBytes = charset.name().getBytes(StandardCharsets.UTF_8); - buffer.put((byte)nameBytes.length); - buffer.put(nameBytes); - - byte[] bytes = string.getBytes(charset); + byte[] bytes = string.getBytes(StandardCharsets.UTF_8); buffer.putShort((short) bytes.length); buffer.put(bytes); }else{ - buffer.put((byte) -1); + buffer.putShort((short) -1); } } @ReadClass(String.class) public static String readString(ByteBuffer buffer){ - byte length = buffer.get(); - if(length != -1){ - byte[] cbytes = new byte[length]; - buffer.get(cbytes); - Charset charset = Charset.forName(new String(cbytes, StandardCharsets.UTF_8)); - - short slength = buffer.getShort(); + short slength = buffer.getShort(); + if(slength != -1){ byte[] bytes = new byte[slength]; buffer.get(bytes); - return new String(bytes, charset); + return new String(bytes, StandardCharsets.UTF_8); }else{ return null; } @@ -378,30 +367,20 @@ public class TypeIO{ public static void writeStringData(DataOutput buffer, String string) throws IOException{ if(string != null){ - Charset charset = Charset.defaultCharset(); - byte[] nameBytes = charset.name().getBytes(StandardCharsets.UTF_8); - buffer.writeByte((byte)nameBytes.length); - buffer.write(nameBytes); - - byte[] bytes = string.getBytes(charset); + byte[] bytes = string.getBytes(StandardCharsets.UTF_8); buffer.writeShort((short) bytes.length); buffer.write(bytes); }else{ - buffer.writeByte((byte) -1); + buffer.writeShort((short) -1); } } public static String readStringData(DataInput buffer) throws IOException{ - byte length = buffer.readByte(); - if(length != -1){ - byte[] cbytes = new byte[length]; - buffer.readFully(cbytes); - Charset charset = Charset.forName(new String(cbytes, StandardCharsets.UTF_8)); - - short slength = buffer.readShort(); + short slength = buffer.readShort(); + if(slength != -1){ byte[] bytes = new byte[slength]; buffer.readFully(bytes); - return new String(bytes, charset); + return new String(bytes, StandardCharsets.UTF_8); }else{ return null; } diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index 3431873465..3dd485c41f 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -45,7 +45,7 @@ public class Save16 extends SaveFileVersion{ content.setTemporaryMapper(readContentHeader(stream)); - state.spawner.read(stream); + world.spawner.read(stream); readEntities(stream); @@ -71,7 +71,7 @@ public class Save16 extends SaveFileVersion{ writeContentHeader(stream); - state.spawner.write(stream); //spawnes + world.spawner.write(stream); //spawnes //--ENTITIES-- diff --git a/core/src/io/anuke/mindustry/maps/Map.java b/core/src/io/anuke/mindustry/maps/Map.java index 05e1a03e37..1ad60c0e1d 100644 --- a/core/src/io/anuke/mindustry/maps/Map.java +++ b/core/src/io/anuke/mindustry/maps/Map.java @@ -32,4 +32,13 @@ public class Map{ public String getDisplayName(){ return meta.tags.get("name", name); } + + @Override + public String toString(){ + return "Map{" + + "name='" + name + '\'' + + ", custom=" + custom + + ", meta=" + meta + + '}'; + } } diff --git a/core/src/io/anuke/mindustry/maps/MapMeta.java b/core/src/io/anuke/mindustry/maps/MapMeta.java index 148ad5a099..2f13ee59b9 100644 --- a/core/src/io/anuke/mindustry/maps/MapMeta.java +++ b/core/src/io/anuke/mindustry/maps/MapMeta.java @@ -37,4 +37,13 @@ public class MapMeta{ public boolean hasOreGen(){ return !tags.get("oregen", "0").equals("0"); } + + @Override + public String toString(){ + return "MapMeta{" + + "tags=" + tags + + ", width=" + width + + ", height=" + height + + '}'; + } } diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index f88dbbabc9..b597cc9ec0 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -30,7 +30,7 @@ public class TutorialSector{ new ItemMission(Items.copper, 100).setMessage("$tutorial.morecopper"), new BlockMission(TurretBlocks.duo).setMessage("$tutorial.turret"), - //TODO fill turret with items mission + / //new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drillturret"), // Create a wave mission which spawns the core at 60, 60 rather than in the center of the map diff --git a/core/src/io/anuke/mindustry/maps/generation/Generation.java b/core/src/io/anuke/mindustry/maps/generation/Generation.java index 076815e0f9..3929a160ad 100644 --- a/core/src/io/anuke/mindustry/maps/generation/Generation.java +++ b/core/src/io/anuke/mindustry/maps/generation/Generation.java @@ -30,7 +30,6 @@ public class Generation{ return tiles[x][y]; } - //TODO implement Item drillItem(int x, int y, Drill block){ if(block.isMultiblock()){ Item result = null; diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index 45e0c64bcf..db95af39f7 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -172,6 +172,25 @@ public class WorldGenerator{ prepareTiles(tiles); + for(int x = 0; x < width; x++){ + for(int y = 0; y < height; y++){ + Tile tile = tiles[x][y]; + + byte elevation = tile.getElevation(); + + for(GridPoint2 point : Geometry.d4){ + if(!Structs.inBounds(x + point.x, y + point.y, width, height)) continue; + if(tiles[x + point.x][y + point.y].getElevation() < elevation){ + + if(sim2.octaveNoise2D(1, 1, 1.0 / 8, x, y) > 0.8){ + tile.setElevation(-1); + } + break; + } + } + } + } + world.setBlock(tiles[spawns.get(0).x][spawns.get(0).y], StorageBlocks.core, Team.blue); if(state.mode.isPvp){ diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index 0e152cb18e..bdf55a0888 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -356,12 +356,13 @@ public class Net{ Gdx.net.sendHttpRequest(req, new HttpResponseListener(){ @Override public void handleHttpResponse(HttpResponse httpResponse){ - listener.accept(httpResponse.getResultAsString()); + String result = httpResponse.getResultAsString(); + Gdx.app.postRunnable(() -> listener.accept(result)); } @Override public void failed(Throwable t){ - failure.accept(t); + Gdx.app.postRunnable(() -> failure.accept(t)); } @Override diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index 037d343a62..1d3ef834e7 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.net; import com.badlogic.gdx.utils.Base64Coder; import io.anuke.mindustry.game.Version; -import io.anuke.ucore.io.IOUtils; +import io.anuke.mindustry.io.TypeIO; import io.anuke.ucore.util.Bundles; import java.nio.ByteBuffer; @@ -65,6 +65,7 @@ public class Packets{ public static class ConnectPacket implements Packet{ public int version; + public String versionType; public String name, uuid, usid; public boolean mobile; public int color; @@ -72,8 +73,9 @@ public class Packets{ @Override public void write(ByteBuffer buffer){ buffer.putInt(Version.build); - IOUtils.writeString(buffer, name); - IOUtils.writeString(buffer, usid); + TypeIO.writeString(buffer, versionType); + TypeIO.writeString(buffer, name); + TypeIO.writeString(buffer, usid); buffer.put(mobile ? (byte) 1 : 0); buffer.putInt(color); buffer.put(Base64Coder.decode(uuid)); @@ -82,8 +84,9 @@ public class Packets{ @Override public void read(ByteBuffer buffer){ version = buffer.getInt(); - name = IOUtils.readString(buffer); - usid = IOUtils.readString(buffer); + versionType = TypeIO.readString(buffer); + name = TypeIO.readString(buffer); + usid = TypeIO.readString(buffer); mobile = buffer.get() == 1; color = buffer.getInt(); byte[] idbytes = new byte[8]; diff --git a/core/src/io/anuke/mindustry/type/AmmoEntry.java b/core/src/io/anuke/mindustry/type/AmmoEntry.java index a4e0559df1..d92c7963e5 100644 --- a/core/src/io/anuke/mindustry/type/AmmoEntry.java +++ b/core/src/io/anuke/mindustry/type/AmmoEntry.java @@ -1,8 +1,6 @@ package io.anuke.mindustry.type; -/** - * Used to store ammo amounts in units and turrets. - */ +/**Used to store ammo amounts in turrets.*/ public class AmmoEntry{ public AmmoType type; public int amount; diff --git a/core/src/io/anuke/mindustry/type/Mech.java b/core/src/io/anuke/mindustry/type/Mech.java index 007435cde1..f075f1c2e1 100644 --- a/core/src/io/anuke/mindustry/type/Mech.java +++ b/core/src/io/anuke/mindustry/type/Mech.java @@ -11,7 +11,6 @@ import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Bundles; -//TODO merge unit type with mech public class Mech extends UnlockableContent{ public final String name; public final String description; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java index e4d2324560..3b27bcc252 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java @@ -2,7 +2,11 @@ package io.anuke.mindustry.ui.dialogs; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectSet; +import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.io.Contributors; +import io.anuke.mindustry.io.Contributors.Contributor; import io.anuke.mindustry.ui.Links; import io.anuke.mindustry.ui.Links.LinkEntry; import io.anuke.ucore.core.Core; @@ -18,11 +22,14 @@ import static io.anuke.mindustry.Vars.ios; import static io.anuke.mindustry.Vars.ui; public class AboutDialog extends FloatingDialog{ + private Array contributors = new Array<>(); private static ObjectSet bannedItems = ObjectSet.with("google-play", "itch.io", "dev-builds", "trello"); public AboutDialog(){ super("$text.about.button"); + Contributors.getContributors(out -> contributors = out, Throwable::printStackTrace); + shown(this::setup); onResize(this::setup); } @@ -94,7 +101,24 @@ public class AboutDialog extends FloatingDialog{ public void showCredits(){ FloatingDialog dialog = new FloatingDialog("$text.credits"); dialog.addCloseButton(); - dialog.content().labelWrap("$text.credits.text").width(400f); + dialog.content().add("$text.credits.text"); + dialog.content().row(); + if(!contributors.isEmpty()){ + dialog.content().addImage("blank").color(Palette.accent).fillX().height(3f).pad(3f); + dialog.content().row(); + dialog.content().add("$text.contributors"); + dialog.content().row(); + dialog.content().pane("clear", new Table(){{ + int i = 0; + left(); + for(Contributor c : contributors){ + add("[lightgray]" + c.login).left().pad(3).padLeft(6).padRight(6); + if(++i % 3 == 0){ + row(); + } + } + }}); + } dialog.show(); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java index 077cd57de9..2c9bf76d3b 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java @@ -28,7 +28,6 @@ public class HostDialog extends FloatingDialog{ content().table(t -> { t.add("$text.name").padRight(10); t.addField(Settings.getString("name"), text -> { - if(text.isEmpty()) return; player.name = text; Settings.put("name", text); Settings.save(); @@ -50,6 +49,11 @@ public class HostDialog extends FloatingDialog{ content().add().width(65f); content().addButton("$text.host", () -> { + if(Settings.getString("name").trim().isEmpty()){ + ui.showInfo("$text.noname"); + return; + } + ui.loadfrag.show("$text.hosting"); Timers.runTask(5f, () -> { try{ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java index d0ce1a574b..d844d18c5d 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java @@ -205,7 +205,6 @@ public class JoinDialog extends FloatingDialog{ content().table(t -> { t.add("$text.name").padRight(10); t.addField(Settings.getString("name"), text -> { - if(text.isEmpty()) return; player.name = text; Settings.put("name", text); Settings.save(); @@ -285,6 +284,11 @@ public class JoinDialog extends FloatingDialog{ } void connect(String ip, int port){ + if(Settings.getString("name").trim().isEmpty()){ + ui.showInfo("$text.noname"); + return; + } + ui.loadfrag.show("$text.connecting"); ui.loadfrag.setButton(() -> { diff --git a/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java b/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java index 4788f98527..3d96883b34 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java @@ -1,5 +1,7 @@ package io.anuke.mindustry.ui.fragments; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.BitmapFont; @@ -8,13 +10,13 @@ import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.core.Platform; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.net.Net; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.Group; +import io.anuke.ucore.scene.ui.Dialog; import io.anuke.ucore.scene.ui.Label; import io.anuke.ucore.scene.ui.Label.LabelStyle; import io.anuke.ucore.scene.ui.TextField; @@ -22,8 +24,7 @@ import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.util.Mathf; -import static io.anuke.mindustry.Vars.players; -import static io.anuke.mindustry.Vars.state; +import static io.anuke.mindustry.Vars.*; import static io.anuke.ucore.core.Core.scene; import static io.anuke.ucore.core.Core.skin; @@ -113,9 +114,35 @@ public class ChatFragment extends Table{ chatfield.getStyle().font = skin.getFont("default-font-chat"); chatfield.getStyle().fontColor = Color.WHITE; chatfield.setStyle(chatfield.getStyle()); - Platform.instance.addDialog(chatfield, Vars.maxTextLength); - bottom().left().marginBottom(offsety).marginLeft(offsetx * 2).add(fieldlabel).padBottom(4f); + if(mobile){ + chatfield.tapped(() -> { + Dialog dialog = new Dialog("", "dialog"); + dialog.setFillParent(true); + dialog.content().top(); + dialog.content().defaults().height(65f); + TextField to = dialog.content().addField("", t-> {}).pad(15).width(250f).get(); + to.setMaxLength(maxTextLength); + to.keyDown(Keys.ENTER, () -> dialog.content().find("okb").fireClick()); + dialog.content().addButton("$text.ok", () -> { + chatfield.clearText(); + chatfield.appendText(to.getText()); + chatfield.change(); + dialog.hide(); + Gdx.input.setOnscreenKeyboardVisible(false); + toggle(); + }).width(90f).name("okb"); + + dialog.show(); + Timers.runTask(1f, () -> { + to.setCursorPosition(to.getText().length()); + Core.scene.setKeyboardFocus(to); + Gdx.input.setOnscreenKeyboardVisible(true); + }); + }); + } + + bottom().left().marginBottom(offsety).marginLeft(offsetx * 2).add(fieldlabel).padBottom(6f); add(chatfield).padBottom(offsety).padLeft(offsetx).growX().padRight(offsetx).height(28); @@ -123,10 +150,6 @@ public class ChatFragment extends Table{ marginBottom(105f); marginRight(240f); } - - if(Vars.mobile){ - addImageButton("icon-arrow-right", 14 * 2, this::toggle).size(46f, 51f).visible(() -> chatOpen).pad(2f); - } } @Override diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index b26b728ae0..b50ff4d6db 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -11,6 +11,7 @@ import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.ucore.core.Events; import io.anuke.ucore.scene.Group; import io.anuke.ucore.scene.ui.layout.Table; +import io.anuke.ucore.util.Strings; import static io.anuke.mindustry.Vars.*; @@ -42,7 +43,7 @@ public class MenuFragment extends Fragment{ } //version info - parent.fill(c -> c.bottom().left().add("Mindustry " + Version.number + "-" + Version.modifier + " " + Version.type + " / " + (Version.build == -1 ? "custom build" : "build " + Version.build)) + parent.fill(c -> c.bottom().left().add(Strings.formatArgs("Mindustry v{0} {1}-{2} {3}", Version.number, Version.modifier, Version.type, (Version.build == -1 ? "custom build" : "build " + Version.build))) .visible(() -> state.is(State.menu))); } @@ -55,14 +56,14 @@ public class MenuFragment extends Fragment{ container.defaults().size(size).pad(5).padTop(4f); MobileButton - play = new MobileButton("icon-play-2", isize, "$text.play", this::showPlaySelect), - maps = new MobileButton("icon-map", isize, "$text.maps", ui.maps::show), - load = new MobileButton("icon-load", isize, "$text.load", ui.load::show), - join = new MobileButton("icon-add", isize, "$text.joingame", ui.join::show), - editor = new MobileButton("icon-editor", isize, "$text.editor", () -> ui.loadGraphics(ui.editor::show)), - tools = new MobileButton("icon-tools", isize, "$text.settings", ui.settings::show), - unlocks = new MobileButton("icon-unlocks", isize, "$text.unlocks", ui.unlocks::show), - donate = new MobileButton("icon-donate", isize, "$text.donate", Platform.instance::openDonations); + play = new MobileButton("icon-play-2", isize, "$text.play", this::showPlaySelect), + maps = new MobileButton("icon-map", isize, "$text.maps", ui.maps::show), + load = new MobileButton("icon-load", isize, "$text.load", ui.load::show), + join = new MobileButton("icon-add", isize, "$text.joingame", ui.join::show), + editor = new MobileButton("icon-editor", isize, "$text.editor", () -> ui.loadGraphics(ui.editor::show)), + tools = new MobileButton("icon-tools", isize, "$text.settings", ui.settings::show), + unlocks = new MobileButton("icon-unlocks", isize, "$text.unlocks", ui.unlocks::show), + donate = new MobileButton("icon-donate", isize, "$text.donate", Platform.instance::openDonations); if(Gdx.graphics.getWidth() > Gdx.graphics.getHeight()){ container.add(play); diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java index f3923079d8..6388b3ee28 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.ui.fragments; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.Interpolation; +import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.game.EventType.WorldLoadGraphicsEvent; @@ -33,7 +34,7 @@ public class PlacementFragment extends Fragment{ Category currentCategory = Category.turret; Block hovered, lastDisplay; Tile hoverTile; - Table blockTable, toggler; + Table blockTable, toggler, topTable; boolean shown = true; public PlacementFragment(){ @@ -106,6 +107,7 @@ public class PlacementFragment extends Fragment{ //top table with hover info frame.table("clear", top -> { + topTable = top; top.add(new Table()).growX().update(topTable -> { if((tileDisplayBlock() == null && lastDisplay == getSelected()) || (tileDisplayBlock() != null && lastDisplay == tileDisplayBlock())) return; @@ -194,8 +196,10 @@ public class PlacementFragment extends Fragment{ Block getSelected(){ Block toDisplay = null; + Vector2 v = topTable.stageToLocalCoordinates(Graphics.mouse()); + //setup hovering tile - if(!ui.hasMouse()){ + if(!ui.hasMouse() && topTable.hit(v.x, v.y, false) == null){ Tile tile = world.tileWorld(Graphics.mouseWorld().x, Graphics.mouseWorld().y); if(tile != null){ hoverTile = tile.target(); diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index 6b3ef027e7..804f12703c 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -43,7 +43,7 @@ public abstract class BaseBlock extends MappableContent{ /**Returns the amount of items this block can accept.*/ public int acceptStack(Item item, int amount, Tile tile, Unit source){ if(acceptItem(item, tile, tile) && hasItems && (source == null || source.getTeam() == tile.getTeam())){ - return Math.min(getMaximumAccepted(tile, item), amount); + return Math.min(getMaximumAccepted(tile, item) - tile.entity.items.get(item), amount); }else{ return 0; } diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 0c9e92f301..898f1ec187 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -150,7 +150,7 @@ public class Block extends BaseBlock { TileEntity entity = tile.entity(); for(Tile other : getPowerConnections(tile, tempTiles)){ - if(other.entity.power != null){ + if(other.entity.power != null && other.entity.power.graph != null){ other.entity.power.graph.add(entity.power.graph); } } @@ -331,7 +331,6 @@ public class Block extends BaseBlock { if(hasItems) stats.add(BlockStat.itemCapacity, itemCapacity, StatUnit.items); } - //TODO make this easier to config. public void setBars(){ if(hasPower) bars.add(new BlockBar(BarType.power, true, tile -> tile.entity.power.amount / powerCapacity)); if(hasLiquids) diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index b75b89e433..b6b87da8d7 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -241,7 +241,7 @@ public class Tile implements PosTrait, TargetTrait{ if(link == 0){ return (block.destructible || block.breakable || block.update); }else{ - return getLinked() != this && getLinked().breakable(); + return getLinked() != this && getLinked().getLinked() == null && getLinked().breakable(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/Floor.java b/core/src/io/anuke/mindustry/world/blocks/Floor.java index 4fc1771189..95796acf62 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/Floor.java @@ -191,7 +191,7 @@ public class Floor extends Block{ if(floor instanceof OreBlock) floor = ((OreBlock) floor).base; if(cur instanceof OreBlock) cur = ((OreBlock) cur).base; - if((floor.id <= cur.id && !(tile.getElevation() != -1 && other.getElevation() > tile.getElevation())) || (!cur.blends.test(floor) && !cur.tileBlends.test(tile, other)) || (floor.cacheLayer.ordinal() > cur.cacheLayer.ordinal() && !sameLayer) || + if(floor.edgeRegions == null || (floor.id <= cur.id && !(tile.getElevation() != -1 && other.getElevation() > tile.getElevation())) || (!cur.blends.test(floor) && !cur.tileBlends.test(tile, other)) || (floor.cacheLayer.ordinal() > cur.cacheLayer.ordinal() && !sameLayer) || (sameLayer && floor.cacheLayer == cur.cacheLayer)) continue; TextureRegion region = floor.edgeRegions[i]; 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 1119cf311f..997c821de9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java @@ -95,8 +95,11 @@ public class MendProjector extends Block{ @Override public void drawSelect(Tile tile){ + MendEntity entity = tile.entity(); + float realRange = range + entity.phaseHeat * phaseRangeBoost; + Draw.color(color); - Lines.dashCircle(tile.drawx(), tile.drawy() - 1f, range); + Lines.dashCircle(tile.drawx(), tile.drawy(), realRange); Draw.color(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/MendingWall.java b/core/src/io/anuke/mindustry/world/blocks/defense/MendingWall.java deleted file mode 100644 index aabcbcd8ef..0000000000 --- a/core/src/io/anuke/mindustry/world/blocks/defense/MendingWall.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.anuke.mindustry.world.blocks.defense; - -import com.badlogic.gdx.graphics.Color; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.bullet.Bullet; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.defense.DeflectorWall.DeflectorEntity; -import io.anuke.ucore.core.Graphics; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.util.Mathf; - -import static io.anuke.mindustry.Vars.tilesize; - -public class MendingWall extends Wall{ - protected float regenSpeed = 0.25f; - - public MendingWall(String name){ - super(name); - update = true; - } - - @Override - public void handleBulletHit(TileEntity entity, Bullet bullet){ - super.handleBulletHit(entity, bullet); - ((DeflectorEntity) entity).hit = 1f; - } - - @Override - public void draw(Tile tile){ - super.draw(tile); - - DeflectorEntity entity = tile.entity(); - - if(entity.hit < 0.0001f) return; - - Graphics.setAdditiveBlending(); - - Draw.color(Color.WHITE); - Draw.alpha(entity.hit * 0.5f); - Draw.rect("blank", tile.drawx(), tile.drawy(), tilesize * size, tilesize * size); - Draw.reset(); - - entity.hit = Mathf.clamp(entity.hit - Timers.delta() / DeflectorWall.hitTime); - - Graphics.setNormalBlending(); - } - - @Override - public void update(Tile tile){ - tile.entity.health = Mathf.clamp(tile.entity.health + regenSpeed * Timers.delta(), 0f, health); - } - - @Override - public TileEntity newEntity(){ - return new DeflectorEntity(); - } -} 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 cb340d1e40..615a6fa5a8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java @@ -36,6 +36,7 @@ public class OverdriveProjector extends Block{ protected float speedBoost = 1.5f; protected float speedBoostPhase = 0.75f; protected float useTime = 400f; + protected float phaseRangeBoost = 20f; public OverdriveProjector(String name){ super(name); @@ -66,7 +67,7 @@ public class OverdriveProjector extends Block{ } if(entity.charge >= reload){ - float realRange = range + entity.phaseHeat * 20f; + float realRange = range + entity.phaseHeat * phaseRangeBoost; float realBoost = speedBoost + entity.phaseHeat*speedBoostPhase; Effects.effect(BlockFx.overdriveWave, Hue.mix(color, phase, entity.phaseHeat), tile.drawx(), tile.drawy(), realRange); @@ -97,8 +98,11 @@ public class OverdriveProjector extends Block{ @Override public void drawSelect(Tile tile){ + OverdriveEntity entity = tile.entity(); + float realRange = range + entity.phaseHeat * phaseRangeBoost; + Draw.color(color); - Lines.dashCircle(tile.drawx(), tile.drawy() - 1f, range); + Lines.dashCircle(tile.drawx(), tile.drawy(), realRange); Draw.color(); } 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 9027fb632c..88359454cc 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java @@ -1,6 +1,5 @@ package io.anuke.mindustry.world.blocks.distribution; -import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.NumberUtils; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Item; @@ -8,10 +7,9 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.ucore.core.Timers; -import io.anuke.ucore.function.Consumer; import io.anuke.ucore.util.Bits; -import static io.anuke.mindustry.Vars.*; +import static io.anuke.mindustry.Vars.content; public class Junction extends Block{ protected float speed = 26; //frames taken to go through this junction @@ -34,8 +32,8 @@ public class Junction extends Block{ public void update(Tile tile){ JunctionEntity entity = tile.entity(); - for(int i = 0; i < 2; i++){ - Buffer buffer = (i == 0 ? entity.bx : entity.by); + for(int i = 0; i < 4; i++){ + Buffer buffer = entity.buffers[i]; if(buffer.index > 0){ if(buffer.index > buffer.items.length) buffer.index = buffer.items.length; @@ -44,17 +42,11 @@ public class Junction extends Block{ if(Timers.time() >= time + speed || Timers.time() < time){ - int val = Bits.getRightInt(l); - - Item item = content.item(Bits.getLeftShort(val)); - int direction = Bits.getRightShort(val); - Tile dest = tile.getNearby(direction); + Item item = content.item(Bits.getRightInt(l)); + Tile dest = tile.getNearby(i); + //skip blocks that don't want the item, keep waiting until they do if(dest == null || !dest.block().acceptItem(item, dest, tile)){ - if(buffer.index > 1 && Bits.getRightShort(Bits.getRightInt(buffer.items[1])) != direction){ - System.arraycopy(buffer.items, 1, buffer.items, 0, buffer.index - 1); - buffer.index--; - } continue; } @@ -69,25 +61,19 @@ public class Junction extends Block{ @Override public void handleItem(Item item, Tile tile, Tile source){ JunctionEntity entity = tile.entity(); - boolean x = tile.x == source.x; - long value = Bits.packLong(NumberUtils.floatToIntBits(Timers.time()), Bits.packInt((short) item.id, source.relativeTo(tile.x, tile.y))); - if(x){ - entity.bx.add(value); - }else{ - entity.by.add(value); - } + long value = Bits.packLong(NumberUtils.floatToIntBits(Timers.time()), item.id); + int relative = source.relativeTo(tile.x, tile.y); + entity.buffers[relative].add(value); } @Override public boolean acceptItem(Item item, Tile tile, Tile source){ JunctionEntity entity = tile.entity(); - boolean x = tile.x == source.x; + int relative = source.relativeTo(tile.x, tile.y); - if(entity == null || entity.bx == null || entity.by == null || (x && entity.bx.full()) || (!x && entity.by.full())) + if(entity == null || relative == -1 || entity.buffers[relative].full()) return false; - int dir = source.relativeTo(tile.x, tile.y); - if(dir == -1) return false; - Tile to = tile.getNearby(dir); + Tile to = tile.getNearby(relative); return to != null && to.block().acceptItem(item, to, tile); } @@ -96,41 +82,8 @@ public class Junction extends Block{ return new JunctionEntity(); } - @Override - public Array getDebugInfo(Tile tile){ - JunctionEntity entity = tile.entity(); - Array arr = super.getDebugInfo(tile); - for(int i = 0; i < 4; i++){ - arr.add("nearby." + i); - arr.add(tile.getNearby(i)); - } - - Consumer write = b -> { - for(int i = 0; i < b.index; i++){ - long l = b.items[i]; - float time = NumberUtils.intBitsToFloat(Bits.getLeftInt(l)); - int val = Bits.getRightInt(l); - Item item = content.item(Bits.getLeftShort(val)); - int direction = Bits.getRightShort(val); - Tile dest = tile.getNearby(direction); - arr.add(" bufferx.item"); - arr.add(time + " | " + item.name + " | " + dest.block() + ":" + dest.floor()); - } - }; - - arr.add("buffer.bx"); - arr.add(entity.bx.index); - write.accept(entity.bx); - arr.add("buffer.by"); - arr.add(entity.bx.index); - write.accept(entity.by); - - return arr; - } - class JunctionEntity extends TileEntity{ - Buffer bx = new Buffer(); - Buffer by = new Buffer(); + Buffer[] buffers = {new Buffer(), new Buffer(), new Buffer(), new Buffer()}; } class Buffer{ 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 f9da9999b8..c7a5737e54 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java @@ -4,7 +4,6 @@ import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -13,13 +12,17 @@ import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Mathf; +import io.anuke.mindustry.gen.Call; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import static io.anuke.mindustry.Vars.*; + +import static io.anuke.mindustry.Vars.content; +import static io.anuke.mindustry.Vars.threads; public class Sorter extends Block implements SelectionTrait{ + private static Item lastItem; public Sorter(String name){ super(name); @@ -35,6 +38,13 @@ public class Sorter extends Block implements SelectionTrait{ return true; } + @Override + public void playerPlaced(Tile tile){ + if(lastItem != null){ + threads.runDelay(() -> Call.setSorterItem(null, tile, lastItem)); + } + } + @Remote(targets = Loc.both, called = Loc.both, forward = true) public static void setSorterItem(Player player, Tile tile, Item item){ SorterEntity entity = tile.entity(); @@ -45,8 +55,6 @@ public class Sorter extends Block implements SelectionTrait{ public void draw(Tile tile){ super.draw(tile); - //TODO call event for change - SorterEntity entity = tile.entity(); Draw.color(entity.sortItem.color); @@ -110,7 +118,10 @@ public class Sorter extends Block implements SelectionTrait{ @Override public void buildTable(Tile tile, Table table){ SorterEntity entity = tile.entity(); - buildItemTable(table, () -> entity.sortItem, item -> Call.setSorterItem(null, tile, item)); + buildItemTable(table, () -> entity.sortItem, item -> { + lastItem = item; + Call.setSorterItem(null, tile, item); + }); } @Override 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 fa1a44c5cf..9aac369832 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -5,7 +5,6 @@ import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter; -import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.ucore.core.Effects; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; @@ -30,7 +29,6 @@ public abstract class ItemLiquidGenerator extends ItemGenerator{ @Override public void init(){ super.init(); - stats.remove(BlockStat.liquidFuelUse); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java index 7416986d6e..05f8daad7d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java @@ -4,7 +4,6 @@ import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.consumers.ConsumeLiquid; -//TODO public class TurbineGenerator extends BurnerGenerator{ public TurbineGenerator(String name){ 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 e2854906dd..69abb7d4c2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java @@ -42,7 +42,7 @@ public class Cultivator extends Drill{ stats.remove(BlockStat.drillTier); stats.add(BlockStat.drillTier, table -> { table.addImage("grass1").size(8 * 3).padBottom(3).padTop(3); - // TODO: find out localized name and add tool tip + table.add(Blocks.grass.formalName).padLeft(3); }); } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java b/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java index 2f7562b82c..01e96fb5c3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java @@ -21,6 +21,7 @@ public class LiquidMixer extends LiquidBlock{ hasItems = true; rotate = false; solid = true; + singleLiquid = false; outputsLiquid = true; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java b/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java index 49042d4180..e0481663f8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java @@ -152,11 +152,6 @@ public class Smelter extends Block{ Effects.effect(craftEffect, flameColor, tile.drawx(), tile.drawy()); } - @Override - public int getMaximumAccepted(Tile tile, Item item){ - return itemCapacity; - } - @Override public boolean acceptItem(Item item, Tile tile, Tile source){ boolean isInput = false; diff --git a/core/src/io/anuke/mindustry/world/consumers/Consume.java b/core/src/io/anuke/mindustry/world/consumers/Consume.java index 8408389933..f4ec4cb01f 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consume.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consume.java @@ -11,8 +11,8 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.mobile; public abstract class Consume{ - private boolean optional; - private boolean update = true; + protected boolean optional; + protected boolean update = true; public Consume optional(boolean optional){ this.optional = optional; diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java index 863cbc8dc7..9476e43eff 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java @@ -53,6 +53,6 @@ public class ConsumeItem extends Consume{ @Override public void display(BlockStats stats){ - stats.add(BlockStat.inputItem, item); + stats.add(optional ? BlockStat.boostItem : BlockStat.inputItem, item); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java index 69e1077db1..c7c24114a4 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java @@ -58,6 +58,6 @@ public class ConsumeItemFilter extends Consume{ @Override public void display(BlockStats stats){ - stats.add(BlockStat.inputItems, new ItemFilterValue(filter)); + stats.add(optional ? BlockStat.boostItem : BlockStat.inputItem, new ItemFilterValue(filter)); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java index f5a2a8e4b0..b46c984c2d 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java @@ -44,6 +44,6 @@ public class ConsumeItems extends Consume{ @Override public void display(BlockStats stats){ - stats.add(BlockStat.inputItems, new ItemListValue(items)); + stats.add(optional ? BlockStat.boostItem : BlockStat.inputItems, new ItemListValue(items)); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java index 0934cf73e5..be204b4dc0 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java @@ -32,7 +32,7 @@ public class ConsumeLiquid extends Consume{ @Override public String getIcon(){ - return "icon-liquid"; + return "icon-liquid-small"; } @Override @@ -47,8 +47,12 @@ public class ConsumeLiquid extends Consume{ @Override public void display(BlockStats stats){ - stats.add(BlockStat.liquidUse, use * 60f, StatUnit.liquidSecond); - stats.add(BlockStat.inputLiquid, liquid); + if(!optional){ + stats.add(BlockStat.liquidUse, use * 60f, StatUnit.liquidSecond); + stats.add(BlockStat.inputLiquid, liquid); + }else{ + stats.add(BlockStat.boostLiquid, liquid); + } } float use(Block block, TileEntity entity){ diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java index 19a5395522..03750ffa3b 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java @@ -47,7 +47,7 @@ public class ConsumeLiquidFilter extends Consume{ @Override public String getIcon(){ - return "icon-liquid"; + return "icon-liquid-small"; } @Override @@ -62,10 +62,12 @@ public class ConsumeLiquidFilter extends Consume{ @Override public void display(BlockStats stats){ - if(isFuel){ + if(optional){ + stats.add(BlockStat.boostLiquid, new LiquidFilterValue(filter)); + }else if(isFuel){ stats.add(BlockStat.inputLiquidFuel, new LiquidFilterValue(filter)); stats.add(BlockStat.liquidFuelUse, 60f * use, StatUnit.liquidSecond); - }else{ + }else { stats.add(BlockStat.inputLiquid, new LiquidFilterValue(filter)); stats.add(BlockStat.liquidUse, 60f * use, StatUnit.liquidSecond); } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java index fcbb35995e..d05ba2c4fa 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java @@ -21,7 +21,7 @@ public class ConsumePower extends Consume{ @Override public String getIcon(){ - return "icon-power"; + return "icon-power-small"; } @Override diff --git a/core/src/io/anuke/mindustry/world/meta/BlockStat.java b/core/src/io/anuke/mindustry/world/meta/BlockStat.java index 5bfd481570..834e8f3ce2 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockStat.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockStat.java @@ -45,8 +45,10 @@ public enum BlockStat{ shots(StatCategory.shooting), reload(StatCategory.shooting), powerShot(StatCategory.shooting), - targetsAir(StatCategory.shooting),; + targetsAir(StatCategory.shooting), + boostItem(StatCategory.optional), + boostLiquid(StatCategory.optional),; public final StatCategory category; diff --git a/core/src/io/anuke/mindustry/world/meta/BlockStats.java b/core/src/io/anuke/mindustry/world/meta/BlockStats.java index 2e6b3507aa..105222cf7a 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockStats.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockStats.java @@ -12,9 +12,7 @@ import io.anuke.ucore.util.Log; import java.util.Locale; -/** - * Hold and organizes a list of block stats. - */ +/**Hold and organizes a list of block stats.*/ public class BlockStats{ private static final boolean errorWhenMissing = false; @@ -26,52 +24,37 @@ public class BlockStats{ this.block = block; } - /** - * Adds a single float value with this stat, formatted to 2 decimal places. - */ + /**Adds a single float value with this stat, formatted to 2 decimal places.*/ public void add(BlockStat stat, float value, StatUnit unit){ add(stat, new NumberValue(value, unit)); } - /** - * Adds a single y/n boolean value. - */ + /**Adds a single y/n boolean value.*/ public void add(BlockStat stat, boolean value){ add(stat, new BooleanValue(value)); } - /** - * Adds an item value. - */ + /**Adds an item value.*/ public void add(BlockStat stat, Item item){ add(stat, new ItemValue(new ItemStack(item, 1))); } - /** - * Adds a liquid value. - */ + /**Adds a liquid value.*/ public void add(BlockStat stat, Liquid liquid){ add(stat, new LiquidValue(liquid)); } - - /** - * Adds an item value. - */ + /**Adds an item value.*/ public void add(BlockStat stat, ItemStack item){ add(stat, new ItemValue(item)); } - /** - * Adds a single string value with this stat. - */ + /**Adds a single string value with this stat.*/ public void add(BlockStat stat, String format, Object... args){ add(stat, new StringValue(format, args)); } - /** - * Adds a stat value. - */ + /**Adds a stat value.*/ public void add(BlockStat stat, StatValue value){ if(!Bundles.has("text.blocks." + stat.name().toLowerCase(Locale.ROOT))){ if(!errorWhenMissing){ @@ -102,6 +85,7 @@ public class BlockStats{ dirty = true; } + /**Removes a stat, if it exists.*/ public void remove(BlockStat stat){ if(!map.containsKey(stat.category) || !map.get(stat.category).containsKey(stat)){ throw new RuntimeException("No stat entry found: \"" + stat + "\" in block '" + block.name + "'!"); diff --git a/core/src/io/anuke/mindustry/world/meta/StatCategory.java b/core/src/io/anuke/mindustry/world/meta/StatCategory.java index ce1ef5b6f2..0080d5daf5 100644 --- a/core/src/io/anuke/mindustry/world/meta/StatCategory.java +++ b/core/src/io/anuke/mindustry/world/meta/StatCategory.java @@ -1,13 +1,12 @@ package io.anuke.mindustry.world.meta; -/** - * A specific category for a stat. - */ +/**A specific category for a stat.*/ public enum StatCategory{ general, power, liquids, items, crafting, - shooting + shooting, + optional, } diff --git a/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java b/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java index 4d434e32ee..d3bb8e1976 100644 --- a/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java +++ b/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java @@ -80,7 +80,6 @@ public class CrashHandler{ ex(() -> value.addChild("gamemode", new JsonValue(Vars.state.mode.name()))); ex(() -> value.addChild("state", new JsonValue(Vars.state.getState().name()))); ex(() -> value.addChild("os", new JsonValue(System.getProperty("os.name")))); - ex(() -> value.addChild("multithreading", new JsonValue(Settings.getBool("multithread")))); ex(() -> value.addChild("trace", new JsonValue(parseException(e)))); try{ diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java index 1a353b0656..d4cd5ad4e7 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java @@ -17,8 +17,6 @@ import io.anuke.ucore.util.OS; import io.anuke.ucore.util.Strings; import java.net.NetworkInterface; -import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.Enumeration; import static io.anuke.mindustry.Vars.*; @@ -26,7 +24,6 @@ import static io.anuke.mindustry.Vars.*; public class DesktopPlatform extends Platform{ final static boolean useDiscord = OS.is64Bit; final static String applicationId = "398246104468291591"; - final static DateFormat format = SimpleDateFormat.getDateTimeInstance(); String[] args; public DesktopPlatform(String[] args){ diff --git a/ios/build.gradle b/ios/build.gradle index b14d976190..d0bfc1752f 100644 --- a/ios/build.gradle +++ b/ios/build.gradle @@ -14,9 +14,4 @@ createIPA.dependsOn build robovm { archs = "thumbv7:arm64" -} - -eclipse.project { - name = appName + "-ios" - natures 'org.robovm.eclipse.RoboVMNature' } \ No newline at end of file diff --git a/ios/robovm.properties b/ios/robovm.properties deleted file mode 100644 index 694b9dfa68..0000000000 --- a/ios/robovm.properties +++ /dev/null @@ -1,6 +0,0 @@ -app.version=4.0 -app.id=io.anuke.mindustry -app.mainclass=io.anuke.mindustry.IOSLauncher -app.executable=IOSLauncher -app.build=27 -app.name=Mindustry diff --git a/ios/src/io/anuke/mindustry/IOSLauncher.java b/ios/src/io/anuke/mindustry/IOSLauncher.java index 5b7c7fbf3e..4938e4457f 100644 --- a/ios/src/io/anuke/mindustry/IOSLauncher.java +++ b/ios/src/io/anuke/mindustry/IOSLauncher.java @@ -31,8 +31,6 @@ public class IOSLauncher extends IOSApplication.Delegate { Net.setClientProvider(new KryoClient()); Net.setServerProvider(new KryoServer()); - Unit.dp.addition -= 0.2f; - if(UIDevice.getCurrentDevice().getUserInterfaceIdiom() == UIUserInterfaceIdiom.Pad){ Unit.dp.addition = 0.5f; } diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index e4be13ed40..22c1ab47f1 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -350,14 +350,19 @@ public class ServerControl extends Module{ } }); - handler.register("fillitems", "Fill the core with 2000 items.", arg -> { + handler.register("fillitems", "[team]", "Fill the core with 2000 items.", arg -> { if(!state.is(State.playing)){ err("Not playing. Host first."); return; } try{ - Team team = Team.valueOf(arg[0]); + Team team = arg.length == 0 ? Team.blue : Team.valueOf(arg[0]); + + if(state.teams.get(team).cores.isEmpty()){ + err("That team has no cores."); + return; + } for(Item item : content.items()){ if(item.type == ItemType.material){ diff --git a/tests/src/test/java/ApplicationTests.java b/tests/src/test/java/ApplicationTests.java index 8c47aabbb4..9845480b31 100644 --- a/tests/src/test/java/ApplicationTests.java +++ b/tests/src/test/java/ApplicationTests.java @@ -4,17 +4,23 @@ import com.badlogic.gdx.backends.headless.HeadlessApplicationConfiguration; import com.badlogic.gdx.math.GridPoint2; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Items; +import io.anuke.mindustry.content.UnitTypes; import io.anuke.mindustry.content.blocks.Blocks; +import io.anuke.mindustry.content.blocks.CraftingBlocks; +import io.anuke.mindustry.content.blocks.PowerBlocks; import io.anuke.mindustry.content.blocks.StorageBlocks; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.Logic; import io.anuke.mindustry.core.NetServer; import io.anuke.mindustry.core.World; +import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.BundleLoader; import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.maps.Map; +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Edges; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Timers; @@ -205,7 +211,14 @@ public class ApplicationTests{ } @Test - void edgeTest(){ + void inventoryDeposit(){ + depositTest(CraftingBlocks.smelter, Items.copper); + depositTest(StorageBlocks.vault, Items.copper); + depositTest(PowerBlocks.thoriumReactor, Items.thorium); + } + + @Test + void edges(){ GridPoint2[] edges = Edges.getEdges(1); assertEquals(edges[0], new GridPoint2(1, 0)); assertEquals(edges[1], new GridPoint2(0, 1)); @@ -215,4 +228,22 @@ public class ApplicationTests{ GridPoint2[] edges2 = Edges.getEdges(2); assertEquals(8, edges2.length); } + + void depositTest(Block block, Item item){ + BaseUnit unit = UnitTypes.alphaDrone.create(Team.none); + Tile tile = new Tile(0, 0, Blocks.air.id, block.id); + int capacity = tile.block().itemCapacity; + + int deposited = tile.block().acceptStack(item, capacity - 1, tile, unit); + assertEquals(capacity - 1, deposited); + + tile.block().handleStack(item, capacity - 1, tile, unit); + assertEquals(tile.entity.items.get(item), capacity - 1); + + int overflow = tile.block().acceptStack(item, 10, tile, unit); + assertEquals(1, overflow); + + tile.block().handleStack(item, 1, tile, unit); + assertEquals(capacity, tile.entity.items.get(item)); + } } \ No newline at end of file diff --git a/tests/src/test/java/IOTests.java b/tests/src/test/java/IOTests.java new file mode 100644 index 0000000000..5357bb515e --- /dev/null +++ b/tests/src/test/java/IOTests.java @@ -0,0 +1,34 @@ +import io.anuke.mindustry.io.TypeIO; +import org.junit.jupiter.api.Test; + +import java.nio.ByteBuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class IOTests{ + + @Test + void writeEnglish(){ + ByteBuffer buffer = ByteBuffer.allocate(500); + TypeIO.writeString(buffer, "asd asd asd asd asdagagasasjakbgeah;jwrej 23424234"); + buffer.position(0); + assertEquals(TypeIO.readString(buffer), "asd asd asd asd asdagagasasjakbgeah;jwrej 23424234"); + } + + @Test + void writeChinese(){ + ByteBuffer buffer = ByteBuffer.allocate(500); + TypeIO.writeString(buffer, "这个服务器可以用自己的语言说话"); + buffer.position(0); + assertEquals(TypeIO.readString(buffer), "这个服务器可以用自己的语言说话"); + } + + @Test + void writeNull(){ + ByteBuffer buffer = ByteBuffer.allocate(500); + TypeIO.writeString(buffer, null); + buffer.position(0); + assertEquals(TypeIO.readString(buffer), null); + } + +} diff --git a/tests/src/test/java/SectorTests.java b/tests/src/test/java/SectorTests.java index 3aae6cb305..bb07bc2743 100644 --- a/tests/src/test/java/SectorTests.java +++ b/tests/src/test/java/SectorTests.java @@ -46,7 +46,7 @@ public class SectorTests{ * This is achieved by adding at least one mission which defines a spawn point. */ @Test - void test_sectorHasACore(){ + void sectorHasACore(){ for(SectorPresets.SectorPreset preset : this.presets.getPresets().values()){ assertTrue(spawnPointIsDefined(preset.missions), "Sector at (" + preset.x + "|" + preset.y + ") contains no missions which define a spawn point. Add a battle or wave mission."); }