diff --git a/.gitignore b/.gitignore index cfa73a21a5..20247e61be 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,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 3ee56f9ad0..fcd3f64369 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 = 'c93c55179ec05b44926d59c5878534a3177d804f' + 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-category/icon-crafting.png b/core/assets-raw/sprites/ui/icons-category/icon-crafting.png new file mode 100644 index 0000000000..80447efca8 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-crafting.png differ diff --git a/core/assets-raw/sprites/ui/icons-category/icon-defense.png b/core/assets-raw/sprites/ui/icons-category/icon-defense.png new file mode 100644 index 0000000000..f0b4cabdad Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-defense.png differ diff --git a/core/assets-raw/sprites/ui/icons-category/icon-distribution.png b/core/assets-raw/sprites/ui/icons-category/icon-distribution.png new file mode 100644 index 0000000000..18233d41c0 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-distribution.png differ diff --git a/core/assets-raw/sprites/ui/icons-category/icon-effect.png b/core/assets-raw/sprites/ui/icons-category/icon-effect.png new file mode 100644 index 0000000000..5da7498a1f Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-effect.png differ diff --git a/core/assets-raw/sprites/ui/icons-category/icon-liquid.png b/core/assets-raw/sprites/ui/icons-category/icon-liquid.png new file mode 100644 index 0000000000..4d4142213b Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-liquid.png differ diff --git a/core/assets-raw/sprites/ui/icons-category/icon-power.png b/core/assets-raw/sprites/ui/icons-category/icon-power.png new file mode 100644 index 0000000000..5df68ce22b Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-power.png differ diff --git a/core/assets-raw/sprites/ui/icons-category/icon-production.png b/core/assets-raw/sprites/ui/icons-category/icon-production.png new file mode 100644 index 0000000000..0735582732 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-production.png differ diff --git a/core/assets-raw/sprites/ui/icons-category/icon-turret.png b/core/assets-raw/sprites/ui/icons-category/icon-turret.png new file mode 100644 index 0000000000..3ed23cf8b8 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-turret.png differ diff --git a/core/assets-raw/sprites/ui/icons-category/icon-units.png b/core/assets-raw/sprites/ui/icons-category/icon-units.png new file mode 100644 index 0000000000..b907051a23 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-units.png differ diff --git a/core/assets-raw/sprites/ui/icons-category/icon-upgrade.png b/core/assets-raw/sprites/ui/icons-category/icon-upgrade.png new file mode 100644 index 0000000000..6f054ad8d0 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons-category/icon-upgrade.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-crafting.png b/core/assets-raw/sprites/ui/icons/icon-crafting.png deleted file mode 100644 index 2a20c39b0b..0000000000 Binary files a/core/assets-raw/sprites/ui/icons/icon-crafting.png and /dev/null differ diff --git a/core/assets-raw/sprites/ui/icons/icon-defense.png b/core/assets-raw/sprites/ui/icons/icon-defense.png deleted file mode 100644 index 6e440a647a..0000000000 Binary files a/core/assets-raw/sprites/ui/icons/icon-defense.png and /dev/null differ diff --git a/core/assets-raw/sprites/ui/icons/icon-distribution.png b/core/assets-raw/sprites/ui/icons/icon-distribution.png deleted file mode 100644 index 858ba9bd3f..0000000000 Binary files a/core/assets-raw/sprites/ui/icons/icon-distribution.png and /dev/null differ diff --git a/core/assets-raw/sprites/ui/icons/icon-liquid.png b/core/assets-raw/sprites/ui/icons/icon-liquid-small.png similarity index 100% rename from core/assets-raw/sprites/ui/icons/icon-liquid.png rename to core/assets-raw/sprites/ui/icons/icon-liquid-small.png diff --git a/core/assets-raw/sprites/ui/icons/icon-power.png b/core/assets-raw/sprites/ui/icons/icon-power-small.png similarity index 100% rename from core/assets-raw/sprites/ui/icons/icon-power.png rename to core/assets-raw/sprites/ui/icons/icon-power-small.png diff --git a/core/assets-raw/sprites/ui/icons/icon-production.png b/core/assets-raw/sprites/ui/icons/icon-production.png deleted file mode 100644 index 8e1d914691..0000000000 Binary files a/core/assets-raw/sprites/ui/icons/icon-production.png and /dev/null differ diff --git a/core/assets-raw/sprites/ui/icons/icon-units.png b/core/assets-raw/sprites/ui/icons/icon-units.png deleted file mode 100644 index 5a7846974d..0000000000 Binary files a/core/assets-raw/sprites/ui/icons/icon-units.png and /dev/null differ diff --git a/core/assets-raw/sprites/ui/icons/icon-weapon.png b/core/assets-raw/sprites/ui/icons/icon-weapon.png deleted file mode 100644 index e59ec4582d..0000000000 Binary files a/core/assets-raw/sprites/ui/icons/icon-weapon.png and /dev/null differ diff --git a/core/assets-raw/sprites/ui/text-sides-down.png b/core/assets-raw/sprites/ui/text-sides-down.png deleted file mode 100644 index e3eb6b1708..0000000000 Binary files a/core/assets-raw/sprites/ui/text-sides-down.png and /dev/null differ diff --git a/core/assets-raw/sprites/ui/text-sides-over.png b/core/assets-raw/sprites/ui/text-sides-over.png deleted file mode 100644 index 110491b4d4..0000000000 Binary files a/core/assets-raw/sprites/ui/text-sides-over.png and /dev/null differ diff --git a/core/assets-raw/sprites/ui/text-sides.png b/core/assets-raw/sprites/ui/text-sides.png deleted file mode 100644 index 30e3c43031..0000000000 Binary files a/core/assets-raw/sprites/ui/text-sides.png and /dev/null differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 0dc46e60d8..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,27 +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.editor.web = The web version does not support the editor\!\nDownload the game to use it. -text.web.unsupported = The web version does not support this feature\! Download the game to use it. +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 @@ -36,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 @@ -56,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 = @@ -70,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 @@ -100,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? @@ -132,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 @@ -182,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... @@ -200,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 @@ -240,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 @@ -262,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! @@ -279,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 @@ -290,6 +291,7 @@ text.no = No text.info.title = Info text.error.title = [crimson]An error has occured text.error.crashtitle = An error has occured +text.blocks.unknown=[LIGHT_GRAY]??? text.blocks.blockinfo = Block Info text.blocks.powercapacity = Power Capacity text.blocks.powershot = Power/Shot @@ -322,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 @@ -347,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 @@ -356,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 @@ -382,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 @@ -408,8 +412,6 @@ mode.waves.name = waves 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 = [scarlet]UNLOCKS IN CUSTOM GAMES OR SERVERS ARE NOT SAVED.[]\n\nPlay in sectors to unlock things. -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 @@ -464,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 @@ -482,22 +484,22 @@ 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} -block.constructing = {0}\n[LIGHT_GRAY](Constructing) +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 block.metalfloor.name = Metal Floor diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties index 9c853977a2..d7840e685c 100644 --- a/core/assets/bundles/bundle_de.properties +++ b/core/assets/bundles/bundle_de.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = itch.io Seite mit Downloads und der Web-Version text.link.google-play.description = Google Play Store Seite text.link.wiki.description = Offizelles Mindustry Wiki text.linkfail = Fehler beim Öffnen des Links!\nDie URL wurde in die Zwischenablage kopiert. -text.editor.web = Die Web-Version unterstützt den Editor nicht!\nLade das Spiel herunter um ihn zu benutzen. -text.web.unsupported = Die Web-Version unterstützt dieses Feature nicht! Lade das Spiel herunter um es zu benutzen. text.gameover = Der Kern wurde zerstört. text.gameover.pvp = Das[accent] {0}[] Team ist siegreich! text.sector.gameover = Du hast diesen Sektor verloren. Erneuter Einsatz? @@ -288,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 @@ -320,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 @@ -345,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 @@ -361,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 @@ -406,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 d668090bdf..5d753f7732 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = itch.io es la página donde podes descargar las text.link.google-play.description = Ficha en la Google Play Store text.link.wiki.description = Wiki oficial de Mindustry text.linkfail = ¡Error al abrir el enlace!\nLa URL ha sido copiada a su portapapeles. -text.editor.web = ¡La versión web no es compatible con el editor!\nDescarga el juego para usarlo. -text.web.unsupported = ¡La versión web no soporta esta característica! Descarga el juego para poder usarla. text.gameover = Tu núcleo ha sido destruido. text.gameover.pvp = ¡El equipo[accent] {0}[] ha ganado! text.sector.gameover = Este sector ha sido perdido. ¿Re-desplegar? @@ -288,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 @@ -320,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 @@ -345,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 @@ -361,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 @@ -406,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 855775dccb..f8351c8f7b 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = page itch.io avec le lien du téléchargement po text.link.google-play.description = listing par le store google play text.link.wiki.description = wiki officiel de mindustry . text.linkfail = Erreur lors de l'ouverture du lien !\nL'URL a été copié avec succès. -text.editor.web = La version web ne possède pas l'éditeur !\nTéléchargez le jeu pour l'avoir. -text.web.unsupported = La version web ne supporte pas cette fonction ! Téléchargez le jeu pour l'utiliser. text.gameover = Partie terminée. text.gameover.pvp = L'équipe [accent] {0}[] a gagnée ! text.sector.gameover = Ce secteur a été perdu. Réessayer? @@ -288,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 @@ -320,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 @@ -345,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 @@ -361,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 @@ -406,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 538b3aefe4..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,8 +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.editor.web = La version web ne prend pas en charge l'éditeur !\nTéléchargez le jeu pour l'utiliser. -text.web.unsupported = La version web ne prend pas en charge cette fonctionnalité ! Téléchargez le jeu pour l'utiliser. +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 ? @@ -56,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 @@ -64,7 +64,7 @@ text.mission.linknode = Reliez le transmetteur énergétique text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0} text.mission.mech = Changer de mécha[accent] {0}[] text.mission.create = Créez[accent] {0}[] -text.none = +text.none = text.close = Fermer text.quit = Quitter text.maps = Cartes @@ -73,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! @@ -152,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 @@ -288,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 @@ -320,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 @@ -345,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 @@ -361,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 @@ -370,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 @@ -406,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 @@ -495,7 +496,7 @@ text.mech.ability = [LIGHT_GRAY]Compétence: {0} text.liquid.heatcapacity = [LIGHT_GRAY]Capacité Thermique {0} text.liquid.viscosity = [LIGHT_GRAY]Viscosité: {0} text.liquid.temperature = [LIGHT_GRAY]Température: {0} -block.constructing = {0}\n[LIGHT_GRAY](Constructing) +block.constructing = {0}\n[LIGHT_GRAY](En construction) block.spawn.name = Générateur d'ennemi block.core.name = Base block.metalfloor.name = Sol en métal diff --git a/core/assets/bundles/bundle_in_ID.properties b/core/assets/bundles/bundle_in_ID.properties index f62937a494..387e2f6bf3 100644 --- a/core/assets/bundles/bundle_in_ID.properties +++ b/core/assets/bundles/bundle_in_ID.properties @@ -9,8 +9,6 @@ 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 cliboard. -text.editor.web = The web version does not support the editor!\nDownload the game to use it. -text.web.unsupported = The web version does not support this feature! Download the game to use it. text.gameover = Intinya hancur. text.gameover.pvp = The[accent] {0}[] team is victorious! text.sector.gameover = This sector has been lost. Re-deploy? @@ -288,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 @@ -320,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 @@ -345,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 @@ -361,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 @@ -406,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 b91fe81ef4..514ff0569f 100644 --- a/core/assets/bundles/bundle_it.properties +++ b/core/assets/bundles/bundle_it.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = pagina di itch.io con download per PC e versione text.link.google-play.description = Elenco di Google Play Store text.link.wiki.description = wiki ufficiale di Mindustry text.linkfail = Impossibile aprire il link! L'URL è stato copiato nella tua bacheca. -text.editor.web = La versione web non supporta l'editor! Scarica il gioco per usarlo. -text.web.unsupported = La vcersione web non supporta questa funzione! Sacrica il gioco per utilizzarla. text.gameover = Il nucleo è stato distrutto. text.gameover.pvp = The[accent] {0}[] team is victorious! text.sector.gameover = Hai perso questo settore. Attaccare di nuovo? @@ -288,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 @@ -320,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 @@ -345,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 @@ -361,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 @@ -406,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 0af4f3b0f6..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 = ゲームのソースコード @@ -9,8 +10,6 @@ text.link.itch.io.description = itch.ioでPC版のダウンロードやweb版を text.link.google-play.description = Google Playのストアページ text.link.wiki.description = 公式 Mindustry Wiki text.linkfail = リンクを開くのに失敗しました!\nURLをクリップボードにコピーしました。 -text.editor.web = Web版はエディターをサポートしていません!\nゲームをダウンロードして、使用してください。 -text.web.unsupported = Web版はこの機能をサポートしてません! ゲームをダウンロードして、使用してください。 text.gameover = ゲームオーバー text.gameover.pvp = [accent] {0}[] チームの勝利! text.sector.gameover = この区域は敗北しました。 再配備しますか? @@ -24,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 = 次回以降表示しない @@ -73,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 = 新しいブロックをアンロック! @@ -288,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 = 電力/ショット @@ -303,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 = 必要な液体 @@ -312,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 = 液体使用量 @@ -320,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 = ショット @@ -345,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 = なし @@ -361,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 = 電力レーザーを表示 @@ -401,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 54e56c5368..e72a97601e 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -9,17 +9,15 @@ text.link.itch.io.description = PC 버전 다운로드와 HTML5 버전이 있는 text.link.google-play.description = Google Play 스토어 정보 text.link.wiki.description = 공식 Mindustry 위키 (영어) text.linkfail = 링크를 여는데 실패했습니다! URL이 기기의 클립보드에 복사되었습니다. -text.editor.web = HTML5 버전은 에디터 기능을 지원하지 않습니다! 게임을 다운로드 한 뒤에 사용 해 주세요. -text.web.unsupported = HTML5 버전은 이 기능을 지원하지 않습니다! 게임을 다운로드 한 뒤에 사용 해 주세요. text.gameover = 코어가 터졌습니다. 게임 오버! text.gameover.pvp = [accent]{0}[] 팀이 승리했습니다! -text.sector.gameover = 이 구역을 공략하는데 실패했습니다. 포기 하시겠습니까? +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 = 정말로 "[orange]{0}[]" 맵을 삭제하시겠습니까? +text.map.delete = 정말로 "[accent]{0}[]" 맵을 삭제하시겠습니까? text.level.select = 맵 선택 text.level.mode = 게임모드 : text.construction.desktop = PC 에서의 조작 방법이 변경되었습니다.\n블록 선택을 해제하거나 건설을 중지하려면 [accent]스페이스 바[]를 누르세요. @@ -35,12 +33,12 @@ text.loadgame = 게임 불러오기 text.joingame = 멀티플레이 text.addplayers = 플레이어 추가/제거 text.customgame = 커스텀 게임 -text.sectors = 싱글 플레이 -text.sector = 구역 : [LIGHT_GRAY]{0} +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.abandon.confirm = 정말로 이 지역의 모든 진행상황을 초기화 하겠습니까?\n이 작업은 되돌릴 수 없습니다! text.sector.resume = 계속하기 text.sector.locked = [scarlet][[완료안됨] text.sector.unexplored = [accent][[탐색안됨] @@ -49,21 +47,21 @@ 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}[] 단계동안 생존하세요.남은 시간 {2}\n -text.mission.wave.enemies = [accent] {0}/{1} []단계를 생존하세요.\n{2}마리 남음 -text.mission.wave.enemy = [accent] {0}/{1} []단계를 생존하세요.\n{2}마리 남음 +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.battle = 적 코어를 파괴하세요 text.mission.resource.menu = {0} {1}개 수집 -text.mission.resource = {0} 자원을 수집하세요 :\n[accent]{1}/{2}[] +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]미션 :\n[LIGHT_GRAY]{0} +text.mission.linknode = 전력 노드를 연결하세요 +text.mission.display = [accent]목표 : [LIGHT_GRAY]{0} text.mission.mech = [accent]{0}[] 기체로 바꾸세요 -text.mission.create = [accent]{0}[] 자원을 만드세요 +text.mission.create = [accent]{0}[] 을(를)설치하세요. text.none = <없음> text.close = 닫기 text.quit = 나가기 @@ -81,8 +79,8 @@ 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.sectorComplete = 지역 클리어. +text.server.kicked.sectorComplete.text = 임무 성공.\n서버가 다음지역 맵으로 이동되었습니다. text.server.kicked.clientOutdated = 오래된 버전의 클라이언트 입니다! 게임을 업데이트 하세요! text.server.kicked.serverOutdated = 오래된 버전의 서버입니다! 서버 호스트 관리자에게 문의하세요! text.server.kicked.banned = 뭘 하셨는지는 모르겠지만, 이제 영원히 서버에 접속할 수 없습니다. @@ -140,7 +138,7 @@ text.connecting.data = [accent]맵 데이터 다운로드중... text.server.port = 포트 : text.server.addressinuse = 이 주소는 이미 사용중입니다! text.server.invalidport = 포트 번호가 잘못되었습니다. -text.server.error = [crimson]{0}[orange]서버를 여는데 오류가 발생했습니다.[] +text.server.error = [crimson]{0}[accent]서버를 여는데 오류가 발생했습니다.[] text.save.old = 이 저장파일은 이전 버전의 게임용이며, 지금은 사용할 수 없습니다. \n\n[LIGHT_GRAY]4.0 정식때 이전 게임버전에서 만든 저장파일과 호환됩니다. text.save.new = 새로 저장 text.save.overwrite = 이 저장 슬롯을 덮어씌우겠습니까? @@ -151,17 +149,17 @@ text.savefail = 게임을 저장하지 못했습니다! text.save.delete.confirm = 이 저장파일을 삭제 하시겠습니까? text.save.delete = 삭제 text.save.export = 저장파일 내보내기 -text.save.import.invalid = [orange]파일이 잘못되었습니다! -text.save.import.fail = [crimson]저장파일을 불러오지 못함 : [orange]{0} -text.save.export.fail = [crimson]저장파일을 내보내지 못함 : [orange]{0} +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 = [orange]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[]. -text.sector.corrupted = [orange]저장 파일에서 구역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다. +text.save.corrupted = [accent]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[]. +text.sector.corrupted = [accent]저장 파일에서 지역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다. text.empty = <비어있음> text.on = 켜기 text.off = 끄기 @@ -182,15 +180,15 @@ text.back = 뒤로가기 text.quit.confirm = 정말로 종료하시겠습니까? text.changelog.title = 변경사항 text.changelog.loading = 변경사항 가져오는중... -text.changelog.error.android = [orange]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다. 이것은 내부 Android 버그 때문입니다. -text.changelog.error.ios = [orange]현재 iOS에서는 변경 사항을 지원하지 않습니다. +text.changelog.error.android = [accent]게임 변경사항은 가끔 Android 4.4 이하에서 작동하지 않습니다. 이것은 내부 Android 버그 때문입니다. +text.changelog.error.ios = [accent]현재 iOS에서는 변경 사항을 지원하지 않습니다. text.changelog.error = [scarlet]게임 변경사항을 가져오는 중 오류가 발생했습니다![]\n인터넷 연결을 확인하십시오. -text.changelog.current = [orange][[현재 버전] -text.changelog.latest = [orange][[최신 버전] +text.changelog.current = [accent][[현재 버전] +text.changelog.latest = [accent][[최신 버전] text.loading = [accent]불러오는중... text.saving = [accent]저장중... -text.wave = [orange]{0}단계 -text.wave.waiting = 다음 단계 시작까지 {0}초 +text.wave = [accent]{0}단계 +text.wave.waiting = 남은 시간 : [green]{0}초[] text.waiting = [LIGHT_GRAY]대기중... text.waiting.players = 다른 플레이어를 기다리는 중.. text.wave.enemies = [LIGHT_GRAY]{0} 마리 남았음 @@ -216,8 +214,8 @@ text.editor.description = 설명 : text.editor.name = 이름 : text.editor.teams = 팀 text.editor.elevation = 지형 높이 -text.editor.errorimageload = [orange]{0}[] 파일을 불러오는데 오류가 발생했습니다. -text.editor.errorimagesave = [orange]{0}[] 파일 저장중 오류가 발생했습니다. +text.editor.errorimageload = [accent]{0}[] 파일을 불러오는데 오류가 발생했습니다. +text.editor.errorimagesave = [accent]{0}[] 파일 저장중 오류가 발생했습니다. text.editor.generate = 생성 text.editor.resize = 맵 크기조정 text.editor.loadmap = 맵 불러오기 @@ -261,7 +259,7 @@ text.tutorial = 게임 방법 text.editor = 편집기 text.mapeditor = 맵 편집기 text.donate = 기부 -text.connectfail = [crimson]{0}[orange] 서버에 연결하지 못했습니다.[] +text.connectfail = [crimson]{0}[accent] 서버에 연결하지 못했습니다.[] text.error.unreachable = 서버에 연결하지 못했습니다. text.error.invalidaddress = 잘못된 주소입니다. text.error.timedout = 시간 초과!\n서버에 포트 포워딩이 설정되어 있고 주소가 올바른지 확인하십시오. @@ -275,11 +273,11 @@ text.settings.rebind = 키 재설정 text.settings.controls = 컨트롤 text.settings.game = 게임 text.settings.sound = 소리 -text.settings.graphics = 화면 +text.settings.graphics = 그래픽 text.settings.cleardata = 게임 데이터 초기화... text.settings.clear.confirm = 정말로 초기화 하겠습니까?\n이 작업을 되돌릴 수 없습니다! text.settings.clearall.confirm = [scarlet]경고![]\n이 작업은 저장된 맵, 맵파일, 잠금 해제된 목록과 키 매핑, 그리고 모든 데이터를 삭제합니다.\n확인 버튼을 다시 눌러 모든 데이터를 삭제하고 게임에서 나갑니다. -text.settings.clearsectors = 구역 초기화 +text.settings.clearsectors = 지역 초기화 text.settings.clearunlocks = 잠금 해제 초기화 text.settings.clearall = 모두 초기화 text.paused = 일시 정지 @@ -288,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 = 1발당 전력 소모량 @@ -320,7 +319,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 = 발포 횟수 @@ -345,6 +345,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 = 없음 @@ -353,25 +354,24 @@ setting.difficulty.training = 훈련 setting.difficulty.easy = 쉬움 setting.difficulty.normal = 보통 setting.difficulty.hard = 어려움 -setting.difficulty.insane = 매우 어려움 +setting.difficulty.insane = [#00ff00]멀[#2efe2e]티[#58fa58]플[#81f781]레[#a9f5a9]이 [#81f781]전[#58fa58]용[] setting.difficulty.name = 난이도 : -setting.screenshake.name = 화면 흔들기 +setting.screenshake.name = 화면 흔들기 강도 setting.effects.name = 화면 효과 setting.sensitivity.name = 컨트롤러 감도 -setting.saveinterval.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.lasers.name = 전력 노드 레이저 표시 setting.minimap.name = 미니맵 보기 setting.musicvol.name = 음악 크기 setting.mutemusic.name = 음소거 setting.sfxvol.name = 효과음 크기 setting.mutesound.name = 소리 끄기 setting.crashreport.name = 오류 보고서 보내기 -text.keybind.title = 키 바인딩 +text.keybind.title = 조작키 설정 category.general.name = 일반 category.view.name = 보기 category.multiplayer.name = 멀티플레이 @@ -406,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 @@ -425,8 +423,8 @@ item.lead.name = 납 item.lead.description = 쉽게 구할 수 있으며, 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다. item.coal.name = 석탄 item.coal.description = 쉽게 구할 수 있으며, 주로 제련소 등에서 연료로 사용됩니다. -item.dense-alloy.name = 합금 -item.dense-alloy.description = 납과 구리로 만든 튼튼한 합금.\n고급 수송 블록이나 상위 티어 블록을 건설하는데 사용됩니다. +item.dense-alloy.name = 고밀도 합금 +item.dense-alloy.description = 납과 구리로 만든 튼튼한 고밀도 합금.\n고급 수송 블록이나 상위 티어 블록을 건설하는데 사용됩니다. item.titanium.name = 티타늄 item.titanium.description = 파이프 재료나 고급 드릴, 비행기/기체 등에서 재료로 사용되는 자원입니다. item.thorium.name = 토륨 @@ -442,9 +440,9 @@ 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.sand.description = 고밀도 합금이나 플럭스 등에서 제련시 광범위하게 사용되는 일반적인 재료입니다. +item.blast-compound.name = 폭발물 +item.blast-compound.description = 포탑 및 건설의 재료로 사용되는 휘발성 폭발물.\n연료로도 사용할 수 있지만, 별로 추천하지는 않습니다. item.pyratite.name = 피라테 item.pyratite.description = 폭발성을 가진 재료로, 주로 포탑의 탄약으로 사용됩니다. liquid.water.name = 물 @@ -495,7 +493,7 @@ 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}\n[LIGHT_GRAY](Constructing) +block.constructing = {0}[LIGHT_GRAY](만드는중) block.spawn.name = 적 스폰지점 block.core.name = 코어 block.metalfloor.name = 철판 @@ -570,7 +568,7 @@ block.tau-mech-pad.name = 타우 기체 패드 block.conduit.name = 파이프 block.mechanical-pump.name = 기계식 펌프 block.itemsource.name = 아이템 소스 -block.itemvoid.name = 히오스 +block.itemvoid.name = 아이템 삭제 장치 block.liquidsource.name = 무한 액체공급 장치 block.powervoid.name = 방전장치 block.powerinfinite.name = 무한 전력공급 장치 @@ -584,7 +582,7 @@ block.phase-conveyor.name = 메타 컨베이어 block.bridge-conveyor.name = 터널 block.plastanium-compressor.name = 플라스터늄 압축기 block.pyratite-mixer.name = 피라테 제조기 -block.blast-mixer.name = 화합물 제조기 +block.blast-mixer.name = 폭발물 제조기 block.solidifer.name = 고체 block.solar-panel.name = 태양 전지판 block.solar-panel-large.name = 대형 태양 전지판 @@ -593,7 +591,7 @@ block.spirit-factory.name = 스피릿 드론 공장 block.phantom-factory.name = 팬텀 드론 공장 block.wraith-factory.name = 유령 전투기 공장 block.ghoul-factory.name = 구울 폭격기 공장 -block.dagger-factory.name = 귀여운 디거 기체 공장 +block.dagger-factory.name = 디거 기체 공장 block.titan-factory.name = 타이탄 기체 공장 block.fortress-factory.name = 포트리스 기체 공장 block.revenant-factory.name = 레비던트 전투기 공장 @@ -609,23 +607,22 @@ 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.thermal-pump.name = 화력 펌프 +block.thermal-generator.name = 열발전기 block.alloy-smelter.name = 설금 제련소 -block.mend-projector.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 = 아크 +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 = 컨테이너 -block.core.description = 게임에서 가장 중요한 건물.\n파괴되면 게임이 끝납니다. team.blue.name = 블루팀 team.red.name = 레드팀 team.orange.name = 오렌지팀 @@ -637,43 +634,44 @@ unit.spirit.name = 스피릿 드론 unit.spirit.description = 기본 드론 유닛. 기본적으로 코어에서 1개가 스폰됩니다. 자동으로 채광하며 아이템을 수집하고, 블록을 수리합니다. unit.phantom.name = 팬텀 드론 unit.phantom.description = 첨단 드론 유닛. 광석을 자동으로 채광하며, 아이템을 수집하고 블록을 수리합니다. 일반 드론보다 훨씬 효과적입니다. -unit.dagger.name = 귀여운 디거 -unit.dagger.description = 밈의 대상으로 지정되어 이름이 바뀐 기본 지상 유닛입니다. +unit.dagger.name = 디거 +unit.dagger.description = 기본 지상 유닛입니다. 스웜과 같이 쓰면 유용합니다. unit.titan.name = 타이탄 -unit.titan.description = 고급 지상 유닛입니다. 합금을 탄약으로 사용하며 지상과 공중 둘다 공격할 수 있습니다. +unit.titan.description = 고급 지상 유닛입니다. 고밀도 합금을 탄약으로 사용하며 지상과 공중 둘다 공격할 수 있습니다. unit.ghoul.name = 구울 폭격기 -unit.ghoul.description = 무거운 지상 폭격기 입니다. 화합물 또는 피라테를 탄약으로 사용합니다. +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]구리를 채광[]하는 것으로 시작합니다. 이것을 하기 위해 플레이어의 중심부 근처에 있는 구리 광맥을 누르세요. -tutorial.drill = 수동으로 채광하는 것은 비효율 적입니다.\n[accent]드릴[]은 자동으로 채광 작업을 합니다.\n구리 광맥에 표시된 영역에 드릴을 하나를 놓으세요. +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.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.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.daggerfactory = 이[accent] 디거 기체 공장[]은\n\n공격하는 기체를 생산하기 위해 사용됩니다. tutorial.router = 공장을 작동시키기 위해 자원이 필요합니다.\n컨베이어에 운반되고 있는 자원을 분할할 분배기를 만드세요. tutorial.dagger = 전력 노드를 공장에 연결하세요.\n일단 요구 사항이 충족되면 기체 생산을 시작합니다.\n\n필요에 따라 드릴 및 발전기, 컨베이어를 더 많이 만들 수 있습니다. -tutorial.battle = [LIGHT_GRAY]적[]의 코어가 드러났습니다.\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.dense-alloy-wall.description = 고밀도 합금으로 만든 벽. 구리벽보다 체력이 높습니다. +block.dense-alloy-wall-large.description = 고밀도 합금으로 만든 큰 벽. block.thorium-wall.description = 토륨으로 만든 벽. block.thorium-wall-large.description = 토륨으로 만든 큰 벽. block.phase-wall.description = 날라오는 모든 총알을 튕겨내고 데미지를 입는 특수한 벽입니다. @@ -683,8 +681,8 @@ 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.overdrive-projector.description = 범위 내 모든 행동의 속도를 높여주는 보조형 건물입니다. +block.force-projector.description = 보호막을 생성하는 건물.\n기본적으로 전력만 있으면 작동하지만, 메타를 넣어 보호막의 범위를 크게 확장시킬 수 있습니다. block.shock-mine.description = 적이 이 블록을 지나가면 전격 공격을 하는 함정형 방어 건물입니다. block.duo.description = 범용성을 가진 터렛.\n지상 및 공중공격을 하며, 초중반에 유용합니다. block.arc.description = 목표 방향으로 전격 공격을 하는 포탑입니다. @@ -703,15 +701,15 @@ block.titanium-conveyor.description = 빠른 속도로 자원을 수송할 수 block.phase-conveyor.description = 자원을 순간이동 시켜 주는 컨베이어 입니다. block.junction.description = 컨베이어를 교차시켜 자원을 수송할 때 사용할 수 있는 블록입니다. block.mass-driver.description = 자원을 받아서 다른 물질 이동기로 전달할 수 있는 블록입니다.\n엄청난 사거리를 가지고 있으며, 주로 컨베이어가 접근할 수 없는 곳에 유용하게 사용됩니다. -block.smelter.description = 합금을 제작할 수 있는 건물입니다. -block.arc-smelter.description = 합금을 제작할 수 있는 건물이지만, 이 건물은 석탄이 필요 없고 좀더 빠른 속도로 합금을 생산해낼 수 있습니다. +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.blast-mixer.description = 폭발물을 제조할 수 있는 건물입니다. block.cryofluidmixer.description = 냉각수를 제작할 수 있는 건물입니다. block.solidifer.description = 용암을 돌로 만들 수 있는 건물입니다. block.melter.description = 돌로 용암을 만들 수 있는 건물입니다. @@ -719,14 +717,14 @@ 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.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.combustion-generator.description = 석탄을 연료로 전력를 생산해내는 발전소 입니다. +block.turbine-generator.description = 석탄 발전기보다 더 많은량의 전력를 생산하는 발전기입니다. block.thermal-generator.description = 용암을 원료로 전력을 생산할 수 있는 발전소입니다. -block.solar-panel.description = 태양열을 받아 자기 스스로 전력을 생산하는 블록입니다. +block.solar-panel.description = 태양열을 받아 자기 스스로 전력을 생산하는 건물입니다. block.solar-panel-large.description = 태양열을 받아 자기 스스로 전력을 생산하지만, 이 블록은 더 빨리 전력을 생산할 수 있습니다. block.thorium-reactor.description = 토륨을 원료로 하는 토륨 원자로 입니다.\n많은 전력을 생산하지만 엄청난 열을 발생시키기 때문에, 많은 량의 물 또는 냉각수가 있어야 터지지 않고 작동합니다. block.rtg-generator.description = 냉각은 필요 없지만 토륨 원자로보다 적은량의 전력을 생산하는 방사선 동위원소 열전자 발전기. @@ -739,7 +737,7 @@ block.laser-drill.description = 토륨을 채광할 수 있는 최고급 드릴 block.blast-drill.description = 최상위 드릴입니다. 엄청난 양의 전력과 물을 소모하는 대신, 매우 빠른 속도로 채광합니다. block.water-extractor.description = 바닥에서 물을 추출하여 건물에 공급할 수 있는 건물입니다. block.cultivator.description = 잔디에서 바이오메터를 추출할 수 있는 건물입니다. -block.oil-extractor.description = 기름(타르)을 추출 해 주는 건물입니다. +block.oil-extractor.description = 석유를 추출 해 주는 건물입니다. block.dart-ship-pad.description = 다트 비행선으로 바꿀 수 있는 패드입니다. block.trident-ship-pad.description = 삼지창 비행선으로 바꿀 수 있는 패드입니다. block.javelin-ship-pad.description = 자비린 비행선으로 바꿀 수 있는 패드입니다. @@ -751,7 +749,7 @@ block.spirit-factory.description = 스피릿 유닛을 생산하는 공장입니 block.phantom-factory.description = 유닛 팬텀을 생산하는 공장입니다. block.wraith-factory.description = 유닛 유령 전투기를 소환하는 공장입니다. block.ghoul-factory.description = 구울 유닛을 생산하는 공장입니다. -block.dagger-factory.description = 귀여운 디거를 생산하는 공장입니다. +block.dagger-factory.description = 디거를 생산하는 공장입니다. block.titan-factory.description = 타이탄 유닛을 생산할 수 있는 공장입니다. block.fortress-factory.description = 포트리스를 생산하는 공장입니다. block.revenant-factory.description = 레비던트 유닛을 생산할 수 있는 공장입니다. @@ -766,17 +764,17 @@ block.liquid-junction.description = 물펌프와 다른 물펌프를 서로 교 block.bridge-conduit.description = 다리와 다리 사이를 연결하여 액체가 지나갈 수 있게 해 줍니다.\n주로 다리 사이에 지나갈 수 없는 장애물이 있을 때 사용합니다. block.mechanical-pump.description = 구리로 제작할 수 있는 기계식 물펌프입니다. block.rotary-pump.description = 일반 물 펌프보다 더 빠른 속도로 물을 끌어올릴 수 있는 펌프입니다. -block.thermal-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.itemvoid.description = 아이템을 사라지게 만듭니다. block.powerinfinite.description = 무한한 전력을 공급해주는 블록입니다. block.powervoid.description = 설정된 아이템을 계속해서 출력하는 블록입니다. liquid.water.description = 지상 유닛이 이 위를 지나가면 이동속도가 느려지고, 깊은 물에 빠지면 죽습니다. liquid.lava.description = 지상 유닛이 이 위를 지나가면 이동속도가 매우 느려지고, 지속적으로 데미지를 입습니다. liquid.oil.description = 일부 조합 블록에서 사용되는 자원입니다. -liquid.cryofluid.description = 포탑 및 토륨 원자로에서 사용되는 자원입니다. 누출시 폭발 및 방화의 위험성이 있습니다. +liquid.cryofluid.description = 포탑 및 토륨 원자로에서 사용되는 자원입니다. diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index 251d4b4f07..93a78942b5 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = Strona itch.io z oficjanymi wersjami do pobrania text.link.google-play.description = Google Play store listing text.link.wiki.description = Oficjana Wiki Mindustry text.linkfail = Nie udało się otworzyć linku!\nURL został skopiowany. -text.editor.web = Wersja przeglądarkowa nie wspomaga edytora map!\nPobierz grę aby użyć edytora. -text.web.unsupported = Wersja przeglądarkowa nie wspomaga tej fukcji!\nPobierz grę aby użyć tej funkcji. text.gameover = Rdzeń został zniszczony. text.gameover.pvp = The[accent] {0}[] team is victorious! text.sector.gameover = This sector has been lost. Re-deploy? @@ -288,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ł @@ -320,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 @@ -345,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 @@ -361,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 @@ -406,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 b1be2af279..d663e8f5ac 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = Pagina da Itch.io com os Downloads text.link.google-play.description = Google Play store listing text.link.wiki.description = Wiki oficial do Mindustry text.linkfail = Falha ao abrir o link\nO Url foi copiado -text.editor.web = A versão web não suporta o editor!\nBaixe o jogo para usar. -text.web.unsupported = A versão web não suporta este recurso! Baixe o jogo para usar. text.gameover = O núcleo foi destruído. text.gameover.pvp = The[accent] {0}[] team is victorious! text.sector.gameover = Esse setor foi perdido! Soltar Novamente? @@ -288,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 @@ -320,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 @@ -345,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 @@ -361,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 @@ -406,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 ebe7bf00c3..7218e4051e 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = itch.io страница с загрузкой text.link.google-play.description = Скачать для Android c Google play text.link.wiki.description = Официальная вики Mindustry(англ.) text.linkfail = Не удалось открыть ссылку!\nURL-адрес был скопирован в буфер обмена. -text.editor.web = Веб-версия не поддерживает редактор!\nЗагрузите игру, чтобы использовать его. -text.web.unsupported = Веб-версия не поддерживает эту функцию! Загрузите игру, чтобы использовать её. text.gameover = Игра окончена text.gameover.pvp = [accent] {0}[] команда победила! text.sector.gameover = Этот сектор потерян. Высадится повторно? @@ -267,6 +265,7 @@ text.error.invalidaddress = Некорректный адрес. text.error.timedout = Время ожидания истекло!\nУбедитесь, что хост настроен для перенаправления портов и адрес корректный! text.error.mismatch = Ошибка пакета:\nвозможное несоответствие версии клиента/сервера. \nУбедитесь, что у вас и у создателя сервера установлена последняя версия Mindustry\\! text.error.alreadyconnected = Вы уже подключены. +text.error.mapnotfound = Map file not found! text.error.any = Неизвестная сетевая ошибка. text.settings.language = Язык text.settings.reset = Сбросить по умолчанию @@ -287,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 = Энергия/выстрел @@ -319,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 = Выстрелы @@ -344,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 = Неограниченный @@ -360,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 = Показывать энергетические лазеры @@ -405,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стояние @@ -624,6 +623,7 @@ block.rtg-generator.name = Радиоизотопный термоэлектри block.spectre.name = Призрак block.meltdown.name = Катастрофа block.container.name = Склад +block.core.description = Самое главное здание в игре. team.blue.name = Синяя team.red.name = Красная team.orange.name = Оранжевая @@ -668,7 +668,6 @@ tutorial.daggerfactory = Постройте[accent] завод по произв tutorial.router = Заводы нуждаются в ресурсах для работы.\nСоздайте маршрутизатор для разделения ресурсов конвейера. tutorial.dagger = Соедините силовой узел с заводом.\nПосле выполнения требований будет создан мех. \n\nПри необходимости создайте дополнительные буры, генераторы и конвейеры. tutorial.battle = [LIGHT_GRAY] Враг[] показал своё ядро.\nУничтожьте его своим мехом и вашой новой боевой единицой. -block.core.description = Самое главное здание в игре. block.copper-wall.description = Дешевый оборонительный блок.\nПолезно для защиты ядра и турелей во время первых волн. block.copper-wall-large.description = Большая стена самым маленьким запасом прочности.\n Хороша в начале игры. block.dense-alloy-wall.description = Стена с показателем прочности "ниже среднего". diff --git a/core/assets/bundles/bundle_tk.properties b/core/assets/bundles/bundle_tk.properties index 9bee717114..e0476393f0 100644 --- a/core/assets/bundles/bundle_tk.properties +++ b/core/assets/bundles/bundle_tk.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = Bilgisayar ve Site versiyonunun bulundugu Site text.link.google-play.description = Google Play magaza sayfasi text.link.wiki.description = Orjinal Mindustry Bilgilendirme Sayfasi text.linkfail = Link Acilamadi!\nLink sizin icin kopyalandi. -text.editor.web = The web version does not support the editor!\nDownload the game to use it. -text.web.unsupported = Site versiyonu bunu desteklemiyor! Bilgisayar versiyonunu indirmeniz gerek. text.gameover = Cekirdegin yok edildi. text.gameover.pvp = The[accent] {0}[] team is victorious! text.sector.gameover = Sektor kaybedildi. Geri gitmek ister misin? @@ -288,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 @@ -320,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 @@ -345,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 @@ -361,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 @@ -406,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 0a26b33e6d..d4e7a788b7 100644 --- a/core/assets/bundles/bundle_tr.properties +++ b/core/assets/bundles/bundle_tr.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = PC yüklemeleri ve web sürümü ile itch.io say text.link.google-play.description = Google Play mağaza sayfası text.link.wiki.description = Resmi Mindustry Wikipedi'si text.linkfail = Bağlantı açılamadı! URL, yazı tahtanıza kopyalandı. -text.editor.web = Web sürümü editörü desteklemiyor! Editörü kullanmak için oyunu indirin. -text.web.unsupported = The web version does not support this feature! Download the game to use it. text.gameover = Çekirdek yok edildi. text.gameover.pvp = The[accent] {0}[] team is victorious! text.sector.gameover = This sector has been lost. Re-deploy? @@ -288,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ış @@ -320,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 @@ -345,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 @@ -361,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 @@ -406,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 b119182495..f5d883551b 100644 --- a/core/assets/bundles/bundle_uk_UA.properties +++ b/core/assets/bundles/bundle_uk_UA.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = Itch.io сторінка з веб-версіє text.link.google-play.description = Скачати з Google Play для Android text.link.wiki.description = Офіційна Mindustry вікі (англ.) text.linkfail = Не вдалося відкрити посилання!\nURL-адреса скопійовано у ваш буфер обміну. -text.editor.web = Веб-версія не підтримує редактора! \nЗавантажте гру, щоб використовувати його. -text.web.unsupported = Веб-версія не підтримує цю функцію! Завантажте гру, щоб використовувати її. text.gameover = Гру закінчено text.gameover.pvp = [accent] {0}[] команда перемогла! text.sector.gameover = Цей сектор було втрачено. Повторно висадитися? @@ -288,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 = Енергія/постріл @@ -320,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 = Постріли @@ -345,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 = Необмежений @@ -361,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 = Показати енергетичні лазери @@ -406,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 1a539ca3fc..cc6dbb00bb 100644 --- a/core/assets/bundles/bundle_zh_CN.properties +++ b/core/assets/bundles/bundle_zh_CN.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = PC版下载和网页版(itch.io) text.link.google-play.description = 从谷歌商店获取安卓版 text.link.wiki.description = 官方 Mindustry 维基 text.linkfail = 打开链接失败!\nURL 已经复制到剪贴板。 -text.editor.web = 网页版不支持地图编辑器!\n下载以使用编辑器。 -text.web.unsupported = 网页版不支持此功能,请下载以使用此功能。 text.gameover = 你的核心被摧毁了! text.gameover.pvp = accent] {0}[] 队获胜! text.sector.gameover = 这个区域失守了,要重新部署吗? @@ -288,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 = 能量/发射 @@ -320,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 = 发射数 @@ -345,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 = 无 @@ -361,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 = 显示能量射线 @@ -406,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 @@ -495,6 +493,7 @@ 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}\n[LIGHT_GRAY](Constructing) block.spawn.name = 敌人出生点 block.core.name = 核心 block.metalfloor.name = 金属地板 diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 2fbc722f89..f9ccc2ea8c 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -9,8 +9,6 @@ text.link.itch.io.description = itch.io 電腦版下載與網頁版 text.link.google-play.description = Google Play 商店頁面 text.link.wiki.description = 官方 Mindustry 維基 text.linkfail = 無法打開連結!\n我們已將該網址複製到您的剪貼簿。 -text.editor.web = 線上版本不支援地圖編輯器!\n請下載遊戲以使用這項功能。 -text.web.unsupported = 線上版本不支援此功能!請下載遊戲以使用這項功能。 text.gameover = 核心已被摧毀。 text.gameover.pvp = [accent]{0}[]隊得到勝利! text.sector.gameover = 這個區域失守了,重新部署? @@ -288,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 = 能源/射擊 @@ -320,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 = 射擊數 @@ -345,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 = 没有 @@ -361,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 = 顯示雷射光束 @@ -406,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/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index e1afd2f5a9..e144699c38 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -6,5271 +6,5257 @@ filter: Nearest,Nearest repeat: none force-projector-top rotate: false - xy: 217, 208 + xy: 724, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 mend-projector-top rotate: false - xy: 555, 355 + xy: 261, 166 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 overdrive-projector-top rotate: false - xy: 573, 355 + xy: 243, 152 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 bridge-conveyor-bridge rotate: false - xy: 407, 366 + xy: 473, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridge-conveyor-end rotate: false - xy: 407, 356 + xy: 483, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-0-1 rotate: false - xy: 457, 371 + xy: 603, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-0-2 rotate: false - xy: 427, 331 + xy: 603, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-0-3 rotate: false - xy: 437, 341 + xy: 613, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-1-0 rotate: false - xy: 447, 351 + xy: 613, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-1-1 rotate: false - xy: 457, 361 + xy: 623, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-1-2 rotate: false - xy: 467, 371 + xy: 623, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-1-3 rotate: false - xy: 427, 321 + xy: 633, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-2-0 rotate: false - xy: 437, 331 + xy: 643, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-2-1 rotate: false - xy: 447, 341 + xy: 653, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-2-2 rotate: false - xy: 457, 351 + xy: 663, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-2-3 rotate: false - xy: 467, 361 + xy: 673, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-3-0 rotate: false - xy: 427, 311 + xy: 683, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-3-1 rotate: false - xy: 437, 321 + xy: 693, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-3-2 rotate: false - xy: 447, 331 + xy: 703, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-3-3 rotate: false - xy: 457, 341 + xy: 713, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-4-0 rotate: false - xy: 467, 351 + xy: 723, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-4-1 rotate: false - xy: 427, 301 + xy: 733, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-4-2 rotate: false - xy: 437, 311 + xy: 743, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-4-3 rotate: false - xy: 447, 321 + xy: 753, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-0-1 rotate: false - xy: 737, 285 + xy: 681, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-0-2 rotate: false - xy: 747, 295 + xy: 691, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-0-3 rotate: false - xy: 757, 305 + xy: 691, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-1-0 rotate: false - xy: 767, 315 + xy: 701, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-1-1 rotate: false - xy: 787, 325 + xy: 701, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-1-2 rotate: false - xy: 747, 285 + xy: 711, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-1-3 rotate: false - xy: 757, 295 + xy: 711, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-2-0 rotate: false - xy: 767, 305 + xy: 721, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-2-1 rotate: false - xy: 777, 315 + xy: 721, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-2-2 rotate: false - xy: 797, 325 + xy: 731, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-2-3 rotate: false - xy: 757, 285 + xy: 731, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-3-0 rotate: false - xy: 767, 295 + xy: 741, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-3-1 rotate: false - xy: 777, 305 + xy: 741, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-3-2 rotate: false - xy: 787, 315 + xy: 751, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-3-3 rotate: false - xy: 767, 285 + xy: 751, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-4-0 rotate: false - xy: 777, 295 + xy: 761, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-4-1 rotate: false - xy: 787, 305 + xy: 761, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-4-2 rotate: false - xy: 797, 315 + xy: 771, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-4-3 rotate: false - xy: 777, 285 + xy: 771, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 mass-driver-turret rotate: false - xy: 168, 46 + xy: 958, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 phase-conveyor-arrow rotate: false - xy: 687, 325 + xy: 953, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 phase-conveyor-bridge rotate: false - xy: 647, 285 + xy: 963, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 phase-conveyor-end rotate: false - xy: 657, 295 + xy: 973, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 +warp-gate + rotate: false + xy: 584, 427 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 warp-gate-top rotate: false - xy: 289, 308 + xy: 610, 427 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blast-drill rotate: false - xy: 79, 1 + xy: 204, 283 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blast-drill-rim rotate: false - xy: 860, 453 + xy: 233, 346 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blast-drill-rotator rotate: false - xy: 886, 453 + xy: 30, 80 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blast-drill-top rotate: false - xy: 912, 453 + xy: 285, 402 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 laser-drill rotate: false - xy: 663, 409 + xy: 205, 159 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 laser-drill-rotator rotate: false - xy: 645, 373 + xy: 205, 141 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 laser-drill-top rotate: false - xy: 663, 391 + xy: 261, 184 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 mechanical-drill rotate: false - xy: 663, 373 + xy: 243, 170 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 mechanical-drill-rotator rotate: false - xy: 519, 355 + xy: 225, 165 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 mechanical-drill-top rotate: false - xy: 537, 355 + xy: 223, 147 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 oil-extractor rotate: false - xy: 160, 20 + xy: 984, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 oil-extractor-liquid rotate: false - xy: 254, 310 + xy: 350, 425 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 oil-extractor-rotator rotate: false - xy: 265, 268 + xy: 376, 425 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 oil-extractor-top rotate: false - xy: 273, 242 + xy: 402, 425 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 plasma-drill rotate: false - xy: 153, 232 + xy: 25, 46 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 plasma-drill-rim rotate: false - xy: 213, 294 + xy: 59, 46 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 plasma-drill-rotator rotate: false - xy: 56, 95 + xy: 27, 12 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 plasma-drill-top rotate: false - xy: 56, 61 + xy: 61, 12 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pneumatic-drill rotate: false - xy: 681, 391 + xy: 225, 77 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 pneumatic-drill-rotator rotate: false - xy: 681, 373 + xy: 259, 112 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 pneumatic-drill-top rotate: false - xy: 681, 355 + xy: 243, 82 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 water-extractor rotate: false - xy: 771, 395 + xy: 315, 206 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 water-extractor-liquid rotate: false - xy: 771, 377 + xy: 297, 170 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 water-extractor-rotator rotate: false - xy: 771, 359 + xy: 315, 188 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 water-extractor-top rotate: false - xy: 789, 415 + xy: 297, 152 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blackrock1 rotate: false - xy: 212, 95 + xy: 214, 55 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-blackrock rotate: false - xy: 212, 95 + xy: 214, 55 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackrockshadow1 rotate: false - xy: 212, 85 + xy: 219, 21 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone1 rotate: false - xy: 212, 75 + xy: 219, 11 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-blackstone rotate: false - xy: 212, 75 + xy: 219, 11 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone2 rotate: false - xy: 212, 65 + xy: 219, 1 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone3 rotate: false - xy: 212, 55 + xy: 229, 49 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstoneedge rotate: false - xy: 271, 170 + xy: 283, 98 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 coal1 rotate: false - xy: 417, 366 + xy: 483, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coal2 rotate: false - xy: 407, 346 + xy: 493, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coal3 rotate: false - xy: 417, 356 + xy: 493, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 copper1 rotate: false - xy: 457, 331 + xy: 763, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 copper2 rotate: false - xy: 467, 341 + xy: 773, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 copper3 rotate: false - xy: 437, 301 + xy: 783, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt2 rotate: false - xy: 457, 301 + xy: 853, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt3 rotate: false - xy: 467, 311 + xy: 863, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirtedge rotate: false - xy: 377, 388 + xy: 966, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 generic-cliff-edge rotate: false - xy: 457, 291 + xy: 933, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice-cliff-edge rotate: false - xy: 457, 291 + xy: 933, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 generic-cliff-edge-1 rotate: false - xy: 467, 291 + xy: 943, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice-cliff-edge-1 rotate: false - xy: 467, 291 + xy: 943, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 generic-cliff-edge-2 rotate: false - xy: 427, 281 + xy: 953, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice-cliff-edge-2 rotate: false - xy: 427, 281 + xy: 953, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 generic-cliff-side rotate: false - xy: 437, 281 + xy: 963, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice-cliff-side rotate: false - xy: 437, 281 + xy: 963, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass-cliff-edge rotate: false - xy: 467, 281 + xy: 993, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass-cliff-edge-1 rotate: false - xy: 477, 359 + xy: 1003, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass-cliff-edge-2 rotate: false - xy: 487, 359 + xy: 1013, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass-cliff-side rotate: false - xy: 477, 349 + xy: 357, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass2 rotate: false - xy: 447, 281 + xy: 973, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass3 rotate: false - xy: 457, 281 + xy: 983, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grassedge rotate: false - xy: 699, 345 + xy: 95, 2 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 ice2 rotate: false - xy: 487, 349 + xy: 351, 376 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice3 rotate: false - xy: 477, 329 + xy: 351, 366 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 iceedge rotate: false - xy: 727, 345 + xy: 345, 118 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 icerock2 rotate: false - xy: 487, 339 + xy: 351, 356 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icerockshadow1 rotate: false - xy: 477, 319 + xy: 361, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rockshadow1 rotate: false - xy: 477, 319 + xy: 361, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icerockshadow2 rotate: false - xy: 477, 309 + xy: 371, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rockshadow2 rotate: false - xy: 477, 309 + xy: 371, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lavaedge rotate: false - xy: 769, 345 + xy: 345, 76 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 lead1 rotate: false - xy: 497, 280 + xy: 352, 346 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lead2 rotate: false - xy: 507, 290 + xy: 352, 336 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lead3 rotate: false - xy: 507, 280 + xy: 352, 326 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor2 rotate: false - xy: 537, 335 + xy: 372, 337 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor3 rotate: false - xy: 537, 325 + xy: 362, 327 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor4 rotate: false - xy: 517, 305 + xy: 392, 347 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor5 rotate: false - xy: 527, 315 + xy: 382, 337 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor6 rotate: false - xy: 547, 345 + xy: 372, 327 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalflooredge rotate: false - xy: 797, 349 + xy: 109, 2 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 rock2 rotate: false - xy: 687, 285 + xy: 471, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand2 rotate: false - xy: 697, 325 + xy: 481, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand3 rotate: false - xy: 707, 335 + xy: 491, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sandedge rotate: false - xy: 823, 373 + xy: 117, 49 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shrubshadow rotate: false - xy: 717, 315 + xy: 541, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow2 rotate: false - xy: 737, 335 + xy: 551, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow3 rotate: false - xy: 737, 325 + xy: 551, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snowedge rotate: false - xy: 811, 355 + xy: 145, 49 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 spaceedge rotate: false - xy: 825, 359 + xy: 159, 49 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 stone-cliff-edge rotate: false - xy: 757, 325 + xy: 611, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone-cliff-edge-1 rotate: false - xy: 717, 285 + xy: 621, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone-cliff-edge-2 rotate: false - xy: 727, 295 + xy: 621, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone-cliff-side rotate: false - xy: 737, 305 + xy: 631, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone2 rotate: false - xy: 737, 315 + xy: 601, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone3 rotate: false - xy: 757, 335 + xy: 611, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneedge rotate: false - xy: 811, 341 + xy: 113, 35 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 taredge rotate: false - xy: 839, 345 + xy: 127, 35 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 thorium1 rotate: false - xy: 737, 295 + xy: 651, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 thorium2 rotate: false - xy: 747, 305 + xy: 661, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 thorium3 rotate: false - xy: 757, 315 + xy: 661, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium1 rotate: false - xy: 777, 335 + xy: 671, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium2 rotate: false - xy: 787, 335 + xy: 671, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium3 rotate: false - xy: 777, 325 + xy: 681, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 water-cliff-edge rotate: false - xy: 797, 305 + xy: 781, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 water-cliff-edge-1 rotate: false - xy: 787, 285 + xy: 791, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 water-cliff-edge-2 rotate: false - xy: 797, 295 + xy: 791, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 water-cliff-side rotate: false - xy: 797, 285 + xy: 801, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 wateredge rotate: false - xy: 853, 387 + xy: 155, 21 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 block-border rotate: false - xy: 190, 188 + xy: 239, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-elevation rotate: false - xy: 200, 188 + xy: 259, 36 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 combustion-generator-top rotate: false - xy: 200, 188 + xy: 259, 36 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-middle rotate: false - xy: 397, 308 + xy: 443, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pump-liquid rotate: false - xy: 397, 308 + xy: 443, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-slope rotate: false - xy: 397, 298 + xy: 453, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 border rotate: false - xy: 397, 288 + xy: 453, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-liquid rotate: false - xy: 427, 361 + xy: 563, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 cross-1 rotate: false - xy: 447, 311 + xy: 793, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 cross-2 rotate: false - xy: 501, 396 + xy: 924, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 cross-3 rotate: false - xy: 165, 206 + xy: 672, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 cross-4 rotate: false - xy: 652, 479 + xy: 644, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 nuclearreactor-shadow rotate: false - xy: 776, 451 + xy: 66, 199 size: 26, 26 orig: 26, 26 offset: 0, 0 index: -1 place-arrow rotate: false - xy: 667, 305 + xy: 983, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ripples rotate: false - xy: 1011, 381 + xy: 207, 17 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 rubble-1-0 rotate: false - xy: 699, 395 + xy: 243, 64 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 rubble-1-1 rotate: false - xy: 717, 413 + xy: 261, 82 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 rubble-2-0 rotate: false - xy: 699, 377 + xy: 261, 64 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 rubble-2-1 rotate: false - xy: 717, 395 + xy: 243, 46 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 rubble-3-0 rotate: false - xy: 155, 178 + xy: 480, 427 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 rubble-3-1 rotate: false - xy: 155, 178 + xy: 480, 427 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 shadow-1 rotate: false - xy: 866, 367 + xy: 207, 5 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 shadow-2 rotate: false - xy: 299, 248 + xy: 716, 433 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 shadow-3 rotate: false - xy: 804, 451 + xy: 112, 135 size: 26, 26 orig: 26, 26 offset: 0, 0 index: -1 shadow-4 rotate: false - xy: 290, 454 + xy: 334, 477 size: 34, 34 orig: 34, 34 offset: 0, 0 index: -1 shadow-5 rotate: false - xy: 143, 266 + xy: 290, 469 size: 42, 42 orig: 42, 42 offset: 0, 0 index: -1 shadow-6 rotate: false - xy: 1, 165 + xy: 204, 414 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 shadow-corner rotate: false - xy: 854, 363 + xy: 217, 43 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 shadow-round-1 rotate: false - xy: 853, 351 + xy: 217, 31 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 shadow-round-2 rotate: false - xy: 299, 228 + xy: 736, 433 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 shadow-round-3 rotate: false - xy: 832, 451 + xy: 141, 165 size: 26, 26 orig: 26, 26 offset: 0, 0 index: -1 shadow-round-4 rotate: false - xy: 87, 228 + xy: 370, 477 size: 34, 34 orig: 34, 34 offset: 0, 0 index: -1 shadow-rounded-2 rotate: false - xy: 299, 208 + xy: 756, 433 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 shadow-shock-mine rotate: false - xy: 697, 295 + xy: 531, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridge-conduit-arrow rotate: false - xy: 345, 276 + xy: 463, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridge-conveyor-arrow rotate: false - xy: 345, 276 + xy: 463, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridge-conduit-bridge rotate: false - xy: 407, 376 + xy: 463, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridge-conduit-end rotate: false - xy: 417, 376 + xy: 473, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-bottom rotate: false - xy: 407, 316 + xy: 523, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-bottom-0 rotate: false - xy: 417, 326 + xy: 523, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-bottom-1 rotate: false - xy: 407, 306 + xy: 533, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-bottom-2 rotate: false - xy: 417, 316 + xy: 533, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-bottom-3 rotate: false - xy: 407, 296 + xy: 543, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-bottom-4 rotate: false - xy: 417, 306 + xy: 543, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-bottom-5 rotate: false - xy: 417, 296 + xy: 553, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-bottom-6 rotate: false - xy: 427, 371 + xy: 553, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-top-0 rotate: false - xy: 437, 371 + xy: 563, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-top-1 rotate: false - xy: 427, 351 + xy: 573, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-top-2 rotate: false - xy: 437, 361 + xy: 573, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-top-3 rotate: false - xy: 447, 371 + xy: 583, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-top-4 rotate: false - xy: 427, 341 + xy: 583, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-top-5 rotate: false - xy: 437, 351 + xy: 593, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-top-6 rotate: false - xy: 447, 361 + xy: 593, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-router-bottom rotate: false - xy: 527, 325 + xy: 372, 347 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-router-liquid rotate: false - xy: 517, 315 + xy: 362, 337 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-router-top rotate: false - xy: 537, 345 + xy: 382, 347 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-tank-bottom rotate: false - xy: 152, 124 + xy: 880, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 liquid-tank-liquid rotate: false - xy: 168, 98 + xy: 906, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 liquid-tank-top rotate: false - xy: 168, 72 + xy: 932, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 phase-conduit-arrow rotate: false - xy: 667, 315 + xy: 923, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 phase-conduit-bridge rotate: false - xy: 687, 345 + xy: 933, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 phase-conduit-end rotate: false - xy: 687, 335 + xy: 943, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulse-conduit-top-0 rotate: false - xy: 677, 315 + xy: 993, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulse-conduit-top-1 rotate: false - xy: 657, 285 + xy: 1003, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulse-conduit-top-2 rotate: false - xy: 667, 295 + xy: 1013, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulse-conduit-top-3 rotate: false - xy: 677, 305 + xy: 441, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulse-conduit-top-4 rotate: false - xy: 687, 315 + xy: 441, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulse-conduit-top-5 rotate: false - xy: 667, 285 + xy: 451, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulse-conduit-top-6 rotate: false - xy: 677, 295 + xy: 451, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 alpha-mech-pad rotate: false - xy: 123, 1 + xy: 814, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-alpha-mech-pad rotate: false - xy: 123, 1 + xy: 814, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 battery rotate: false - xy: 212, 105 + xy: 81, 2 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-battery rotate: false - xy: 212, 105 + xy: 81, 2 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 battery-large rotate: false - xy: 53, 1 + xy: 178, 284 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-battery-large rotate: false - xy: 53, 1 + xy: 178, 284 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 fusion-reactor rotate: false - xy: 720, 479 + xy: 712, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fusion-reactor-bottom rotate: false - xy: 754, 479 + xy: 746, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fusion-reactor-light rotate: false - xy: 788, 479 + xy: 780, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fusion-reactor-plasma-0 rotate: false - xy: 822, 479 + xy: 814, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fusion-reactor-plasma-1 rotate: false - xy: 856, 479 + xy: 848, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fusion-reactor-plasma-2 rotate: false - xy: 890, 479 + xy: 882, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fusion-reactor-plasma-3 rotate: false - xy: 924, 479 + xy: 916, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fusion-reactor-top rotate: false - xy: 958, 479 + xy: 950, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 rtg-generator-top rotate: false - xy: 697, 335 + xy: 481, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 thorium-reactor-center rotate: false - xy: 158, 152 + xy: 506, 427 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 thorium-reactor-lights rotate: false - xy: 289, 360 + xy: 532, 427 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 turbine-generator-top rotate: false - xy: 753, 377 + xy: 297, 206 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 -alloy-fuser - rotate: false - xy: 213, 268 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 alloy-smelter rotate: false - xy: 90, 28 + xy: 332, 433 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-alloy-smelter rotate: false - xy: 90, 28 + xy: 332, 433 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 alloy-smelter-top rotate: false - xy: 105, 1 + xy: 796, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 arc-smelter rotate: false - xy: 141, 1 + xy: 832, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-arc-smelter rotate: false - xy: 141, 1 + xy: 832, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 arc-smelter-top rotate: false - xy: 159, 1 + xy: 850, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 silicon-smelter-top rotate: false - xy: 159, 1 + xy: 850, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 biomattercompressor rotate: false - xy: 177, 1 + xy: 868, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 biomattercompressor-frame0 rotate: false - xy: 319, 250 + xy: 886, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 biomattercompressor-frame1 rotate: false - xy: 319, 232 + xy: 904, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 biomattercompressor-frame2 rotate: false - xy: 319, 214 + xy: 922, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 biomattercompressor-liquid rotate: false - xy: 315, 368 + xy: 940, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 biomattercompressor-top rotate: false - xy: 315, 350 + xy: 958, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blast-mixer rotate: false - xy: 315, 332 + xy: 976, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-blast-mixer rotate: false - xy: 315, 332 + xy: 976, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 centrifuge-liquid rotate: false - xy: 483, 387 + xy: 888, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 cryofluidmixer-bottom rotate: false - xy: 501, 378 + xy: 942, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 cryofluidmixer-liquid rotate: false - xy: 483, 369 + xy: 960, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 cryofluidmixer-top rotate: false - xy: 501, 360 + xy: 978, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 cultivator rotate: false - xy: 528, 427 + xy: 996, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 cultivator-middle rotate: false - xy: 546, 427 + xy: 112, 117 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 cultivator-top rotate: false - xy: 564, 427 + xy: 117, 99 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 lavasmelter rotate: false - xy: 507, 300 + xy: 431, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 oilrefinery rotate: false - xy: 537, 315 + xy: 372, 317 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 phase-weaver rotate: false - xy: 627, 355 + xy: 241, 134 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 phase-weaver-bottom rotate: false - xy: 645, 355 + xy: 259, 130 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 phase-weaver-weave rotate: false - xy: 663, 355 + xy: 241, 116 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 plastanium-compressor-top rotate: false - xy: 681, 409 + xy: 225, 95 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 pulverizer rotate: false - xy: 687, 305 + xy: 461, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulverizer-rotator rotate: false - xy: 677, 285 + xy: 461, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 separator-liquid rotate: false - xy: 727, 325 + xy: 531, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 core-open rotate: false - xy: 116, 46 + xy: 620, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 core-top rotate: false - xy: 139, 204 + xy: 646, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 sortedunloader rotate: false - xy: 747, 335 + xy: 581, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-1 rotate: false - xy: 201, 198 + xy: 239, 36 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-1-top rotate: false - xy: 211, 198 + xy: 249, 36 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-2 rotate: false - xy: 315, 314 + xy: 994, 435 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-2-top rotate: false - xy: 319, 196 + xy: 325, 388 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-3 rotate: false - xy: 938, 453 + xy: 311, 406 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-3-top rotate: false - xy: 964, 453 + xy: 289, 356 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-4 rotate: false - xy: 326, 456 + xy: 406, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 block-4-top rotate: false - xy: 360, 456 + xy: 440, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 arc rotate: false - xy: 77, 207 + xy: 1010, 454 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 arc-heat rotate: false - xy: 212, 115 + xy: 71, 2 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 cyclone rotate: false - xy: 191, 208 + xy: 698, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 duo rotate: false - xy: 447, 291 + xy: 923, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 fuse rotate: false - xy: 142, 46 + xy: 828, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 hail rotate: false - xy: 477, 339 + xy: 357, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 hail-heat rotate: false - xy: 516, 433 + xy: 141, 153 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 lancer rotate: false - xy: 627, 373 + xy: 225, 183 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 lancer-heat rotate: false - xy: 645, 391 + xy: 207, 177 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 meltdown rotate: false - xy: 428, 453 + xy: 984, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 meltdown-heat rotate: false - xy: 462, 453 + xy: 56, 80 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ripple rotate: false - xy: 247, 216 + xy: 428, 427 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ripple-heat rotate: false - xy: 273, 216 + xy: 454, 427 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 salvo rotate: false - xy: 735, 413 + xy: 261, 46 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 salvo-heat rotate: false - xy: 699, 359 + xy: 279, 220 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 salvo-panel-left rotate: false - xy: 717, 377 + xy: 279, 202 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 salvo-panel-right rotate: false - xy: 735, 395 + xy: 279, 184 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 scatter rotate: false - xy: 697, 305 + xy: 511, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 scorch rotate: false - xy: 707, 315 + xy: 521, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 scorch-shoot rotate: false - xy: 727, 335 + xy: 521, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 spectre rotate: false - xy: 652, 445 + xy: 77, 159 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 swarmer rotate: false - xy: 735, 377 + xy: 277, 130 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 wave rotate: false - xy: 789, 397 + xy: 315, 170 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 wave-liquid rotate: false - xy: 807, 415 + xy: 315, 152 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 dagger-factory-top rotate: false - xy: 582, 427 + xy: 130, 117 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 dagger-factory-top-open rotate: false - xy: 600, 427 + xy: 135, 99 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 fortress-factory rotate: false - xy: 108, 20 + xy: 750, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 fortress-factory-top rotate: false - xy: 142, 98 + xy: 776, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ghoul-factory-top rotate: false - xy: 142, 98 + xy: 776, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 titan-factory-top rotate: false - xy: 142, 98 + xy: 776, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 fortress-factory-top-open rotate: false - xy: 142, 72 + xy: 802, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ghoul-factory-top-open rotate: false - xy: 142, 72 + xy: 802, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 titan-factory-top-open rotate: false - xy: 142, 72 + xy: 802, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ghoul-factory rotate: false - xy: 134, 20 + xy: 854, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 phantom-factory-top rotate: false - xy: 591, 355 + xy: 261, 148 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 phantom-factory-top-open rotate: false - xy: 609, 355 + xy: 223, 129 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 reconstructor-open rotate: false - xy: 699, 413 + xy: 225, 59 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 repair-point-turret rotate: false - xy: 687, 295 + xy: 471, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 revenant-factory rotate: false - xy: 56, 27 + xy: 66, 227 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 revenant-factory-top rotate: false - xy: 516, 445 + xy: 100, 227 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 revenant-factory-top-open rotate: false - xy: 550, 445 + xy: 134, 227 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 spirit-factory-top rotate: false - xy: 753, 413 + xy: 279, 166 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 spirit-factory-top-open rotate: false - xy: 717, 359 + xy: 279, 148 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 titan-factory rotate: false - xy: 289, 334 + xy: 558, 427 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 wraith-factory-top rotate: false - xy: 789, 379 + xy: 279, 80 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 wraith-factory-top-open rotate: false - xy: 807, 397 + xy: 279, 62 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 deflector-wall rotate: false - xy: 467, 321 + xy: 843, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 deflector-wall-large rotate: false - xy: 618, 427 + xy: 117, 81 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 door-large-open rotate: false - xy: 636, 427 + xy: 135, 81 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 door-open rotate: false - xy: 437, 291 + xy: 913, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 beam rotate: false - xy: 1022, 499 + xy: 1018, 499 size: 1, 12 orig: 1, 12 offset: 0, 0 index: -1 beam-end rotate: false - xy: 496, 467 + xy: 285, 382 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 blank rotate: false - xy: 53, 27 + xy: 256, 417 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 bullet rotate: false - xy: 501, 432 + xy: 82, 114 size: 13, 13 orig: 13, 13 offset: 0, 0 index: -1 bullet-back rotate: false - xy: 307, 181 + xy: 1010, 464 size: 13, 13 orig: 13, 13 offset: 0, 0 index: -1 casing rotate: false - xy: 243, 228 + xy: 329, 146 size: 2, 4 orig: 2, 4 offset: 0, 0 index: -1 clear rotate: false - xy: 428, 487 + xy: 256, 414 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 command-attack rotate: false - xy: 407, 336 + xy: 503, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 command-idle rotate: false - xy: 417, 346 + xy: 503, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 command-patrol rotate: false - xy: 407, 326 + xy: 513, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 command-retreat rotate: false - xy: 417, 336 + xy: 513, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 enemyarrow rotate: false - xy: 853, 331 + xy: 289, 1 size: 8, 7 orig: 8, 7 offset: 0, 0 index: -1 error rotate: false - xy: 391, 388 + xy: 980, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 laser rotate: false - xy: 1022, 485 + xy: 111, 56 size: 1, 12 orig: 1, 12 offset: 0, 0 index: -1 laser-end rotate: false - xy: 80, 130 + xy: 656, 433 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 laserfull rotate: false - xy: 293, 288 + xy: 676, 433 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 minelaser rotate: false - xy: 851, 373 + xy: 114, 56 size: 1, 12 orig: 1, 12 offset: 0, 0 index: -1 minelaser-end rotate: false - xy: 291, 268 + xy: 696, 433 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 missile rotate: false - xy: 853, 340 + xy: 27, 1 size: 9, 9 orig: 9, 9 offset: 0, 0 index: -1 missile-back rotate: false - xy: 866, 356 + xy: 38, 1 size: 9, 9 orig: 9, 9 offset: 0, 0 index: -1 scorch1 rotate: false - xy: 1016, 452 + xy: 337, 406 size: 7, 25 orig: 7, 25 offset: 0, 0 index: -1 scorch2 rotate: false - xy: 186, 19 + xy: 90, 87 size: 7, 25 orig: 7, 25 offset: 0, 0 index: -1 scorch3 rotate: false - xy: 181, 179 + xy: 162, 200 size: 7, 25 orig: 7, 25 offset: 0, 0 index: -1 scorch4 rotate: false - xy: 280, 354 + xy: 99, 88 size: 7, 25 orig: 7, 25 offset: 0, 0 index: -1 scorch5 rotate: false - xy: 280, 327 + xy: 108, 88 size: 7, 25 orig: 7, 25 offset: 0, 0 index: -1 shell rotate: false - xy: 865, 345 + xy: 49, 1 size: 9, 9 orig: 9, 9 offset: 0, 0 index: -1 shell-back rotate: false - xy: 864, 334 + xy: 60, 1 size: 9, 9 orig: 9, 9 offset: 0, 0 index: -1 shot rotate: false - xy: 707, 305 + xy: 541, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 transfer rotate: false - xy: 204, 314 + xy: 187, 49 size: 1, 12 orig: 1, 12 offset: 0, 0 index: -1 transfer-arrow rotate: false - xy: 787, 295 + xy: 781, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 transfer-end rotate: false - xy: 311, 268 + xy: 776, 433 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 blackstone-cliff-edge rotate: false - xy: 213, 45 + xy: 229, 39 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone-cliff-edge-1 rotate: false - xy: 213, 35 + xy: 229, 29 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone-cliff-edge-2 rotate: false - xy: 213, 25 + xy: 229, 19 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone-cliff-side rotate: false - xy: 191, 198 + xy: 229, 9 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-arc rotate: false - xy: 210, 188 + xy: 239, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-biomattercompressor rotate: false - xy: 315, 296 + xy: 346, 407 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-blast-drill rotate: false - xy: 990, 453 + xy: 290, 330 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-bridge-conduit rotate: false - xy: 347, 376 + xy: 249, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridge-conduit rotate: false - xy: 347, 376 + xy: 249, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-bridge-conveyor rotate: false - xy: 347, 366 + xy: 269, 36 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridge-conveyor rotate: false - xy: 347, 366 + xy: 269, 36 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-centrifuge rotate: false - xy: 184, 161 + xy: 364, 407 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 centrifuge rotate: false - xy: 184, 161 + xy: 364, 407 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-combustion-generator rotate: false - xy: 347, 356 + xy: 249, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 combustion-generator rotate: false - xy: 347, 356 + xy: 249, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-command-center rotate: false - xy: 184, 143 + xy: 382, 407 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 command-center rotate: false - xy: 184, 143 + xy: 382, 407 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-conduit rotate: false - xy: 347, 346 + xy: 259, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-container rotate: false - xy: 178, 125 + xy: 400, 407 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 container rotate: false - xy: 178, 125 + xy: 400, 407 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-conveyor rotate: false - xy: 347, 336 + xy: 279, 36 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor-0-0 rotate: false - xy: 347, 336 + xy: 279, 36 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-copper-wall rotate: false - xy: 347, 326 + xy: 259, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 copper-wall rotate: false - xy: 347, 326 + xy: 259, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-copper-wall-large rotate: false - xy: 196, 125 + xy: 418, 407 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 copper-wall-large rotate: false - xy: 196, 125 + xy: 418, 407 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-core rotate: false - xy: 239, 268 + xy: 290, 304 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 core rotate: false - xy: 239, 268 + xy: 290, 304 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-cryofluidmixer rotate: false - xy: 194, 107 + xy: 436, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-cultivator rotate: false - xy: 194, 89 + xy: 454, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-cyclone rotate: false - xy: 247, 242 + xy: 290, 278 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-dagger-factory rotate: false - xy: 194, 71 + xy: 472, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-dart-ship-pad rotate: false - xy: 194, 53 + xy: 490, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 dart-ship-pad rotate: false - xy: 194, 53 + xy: 490, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-deepwater rotate: false - xy: 347, 316 + xy: 269, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 deepwater rotate: false - xy: 347, 316 + xy: 269, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-delta-mech-pad rotate: false - xy: 195, 35 + xy: 508, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 delta-mech-pad rotate: false - xy: 195, 35 + xy: 508, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-dense-alloy-wall rotate: false - xy: 347, 306 + xy: 269, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dense-alloy-wall rotate: false - xy: 347, 306 + xy: 269, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-dense-alloy-wall-large rotate: false - xy: 195, 17 + xy: 526, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 dense-alloy-wall-large rotate: false - xy: 195, 17 + xy: 526, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-dirt rotate: false - xy: 347, 296 + xy: 279, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt1 rotate: false - xy: 347, 296 + xy: 279, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-distributor rotate: false - xy: 321, 436 + xy: 544, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 distributor rotate: false - xy: 321, 436 + xy: 544, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-door rotate: false - xy: 357, 378 + xy: 279, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 door rotate: false - xy: 357, 378 + xy: 279, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-door-large rotate: false - xy: 321, 418 + xy: 562, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 door-large rotate: false - xy: 321, 418 + xy: 562, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-duo rotate: false - xy: 357, 368 + xy: 239, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-force-projector rotate: false - xy: 295, 386 + xy: 315, 356 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 force-projector rotate: false - xy: 295, 386 + xy: 315, 356 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-fortress-factory rotate: false - xy: 87, 202 + xy: 316, 330 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-fuse rotate: false - xy: 77, 176 + xy: 316, 304 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-fusion-reactor rotate: false - xy: 394, 456 + xy: 474, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 block-icon-ghoul-factory rotate: false - xy: 80, 150 + xy: 316, 278 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-glaive-ship-pad rotate: false - xy: 103, 176 + xy: 334, 451 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 glaive-ship-pad rotate: false - xy: 103, 176 + xy: 334, 451 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-grass rotate: false - xy: 367, 378 + xy: 249, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass1 rotate: false - xy: 367, 378 + xy: 249, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-hail rotate: false - xy: 357, 358 + xy: 259, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-ice rotate: false - xy: 367, 368 + xy: 269, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice1 rotate: false - xy: 367, 368 + xy: 269, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-icerock rotate: false - xy: 377, 378 + xy: 279, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icerock1 rotate: false - xy: 377, 378 + xy: 279, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-incinerator rotate: false - xy: 357, 348 + xy: 289, 30 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 incinerator rotate: false - xy: 357, 348 + xy: 289, 30 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-itemsource rotate: false - xy: 367, 358 + xy: 299, 30 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 itemsource rotate: false - xy: 367, 358 + xy: 299, 30 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-itemvoid rotate: false - xy: 377, 368 + xy: 289, 20 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 itemvoid rotate: false - xy: 377, 368 + xy: 289, 20 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-javelin-ship-pad rotate: false - xy: 321, 400 + xy: 580, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 javelin-ship-pad rotate: false - xy: 321, 400 + xy: 580, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-junction rotate: false - xy: 387, 378 + xy: 309, 30 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 junction rotate: false - xy: 387, 378 + xy: 309, 30 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-lancer rotate: false - xy: 339, 438 + xy: 598, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-laser-drill rotate: false - xy: 357, 438 + xy: 616, 409 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-lava rotate: false - xy: 357, 338 + xy: 289, 10 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lava rotate: false - xy: 357, 338 + xy: 289, 10 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-liquid-junction rotate: false - xy: 367, 348 + xy: 299, 20 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-junction rotate: false - xy: 367, 348 + xy: 299, 20 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-liquid-router rotate: false - xy: 377, 358 + xy: 299, 10 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-liquid-tank rotate: false - xy: 113, 202 + xy: 360, 451 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-liquidsource rotate: false - xy: 387, 368 + xy: 309, 20 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquidsource rotate: false - xy: 387, 368 + xy: 309, 20 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-mass-driver rotate: false - xy: 106, 150 + xy: 386, 451 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 mass-driver rotate: false - xy: 106, 150 + xy: 386, 451 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-mechanical-drill rotate: false - xy: 339, 420 + xy: 168, 243 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-mechanical-pump rotate: false - xy: 357, 328 + xy: 309, 10 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 mechanical-pump rotate: false - xy: 357, 328 + xy: 309, 10 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-meltdown rotate: false - xy: 516, 479 + xy: 508, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 block-icon-melter rotate: false - xy: 367, 338 + xy: 343, 396 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 melter rotate: false - xy: 367, 338 + xy: 343, 396 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-mend-projector rotate: false - xy: 375, 438 + xy: 171, 209 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 mend-projector rotate: false - xy: 375, 438 + xy: 171, 209 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-metalfloor rotate: false - xy: 377, 348 + xy: 353, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor1 rotate: false - xy: 377, 348 + xy: 353, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-oil-extractor rotate: false - xy: 100, 124 + xy: 412, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-omega-mech-pad rotate: false - xy: 90, 98 + xy: 438, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 omega-mech-pad rotate: false - xy: 90, 98 + xy: 438, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-overdrive-projector rotate: false - xy: 339, 402 + xy: 180, 266 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 overdrive-projector rotate: false - xy: 339, 402 + xy: 180, 266 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-overflow-gate rotate: false - xy: 387, 358 + xy: 363, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 overflow-gate rotate: false - xy: 387, 358 + xy: 363, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-phantom-factory rotate: false - xy: 357, 420 + xy: 198, 265 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-phase-conduit rotate: false - xy: 357, 318 + xy: 373, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 phase-conduit rotate: false - xy: 357, 318 + xy: 373, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-phase-conveyor rotate: false - xy: 367, 328 + xy: 383, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 phase-conveyor rotate: false - xy: 367, 328 + xy: 383, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-phase-wall rotate: false - xy: 377, 338 + xy: 393, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 phase-wall rotate: false - xy: 377, 338 + xy: 393, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-phase-wall-large rotate: false - xy: 393, 438 + xy: 171, 191 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 phase-wall-large rotate: false - xy: 393, 438 + xy: 171, 191 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-phase-weaver rotate: false - xy: 357, 402 + xy: 169, 173 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-plasma-drill rotate: false - xy: 550, 479 + xy: 542, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 block-icon-plastanium-compressor rotate: false - xy: 375, 420 + xy: 230, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 plastanium-compressor rotate: false - xy: 375, 420 + xy: 230, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-pneumatic-drill rotate: false - xy: 375, 402 + xy: 248, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-power-node rotate: false - xy: 387, 348 + xy: 403, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 power-node rotate: false - xy: 387, 348 + xy: 403, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-power-node-large rotate: false - xy: 393, 420 + xy: 266, 262 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 power-node-large rotate: false - xy: 393, 420 + xy: 266, 262 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-powerinfinite rotate: false - xy: 357, 308 + xy: 413, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 powerinfinite rotate: false - xy: 357, 308 + xy: 413, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-powervoid rotate: false - xy: 367, 318 + xy: 423, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 powervoid rotate: false - xy: 367, 318 + xy: 423, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-pulse-conduit rotate: false - xy: 377, 328 + xy: 343, 386 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-pulverizer rotate: false - xy: 387, 338 + xy: 353, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-pyratite-mixer rotate: false - xy: 393, 402 + xy: 284, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 pyratite-mixer rotate: false - xy: 393, 402 + xy: 284, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-reconstructor rotate: false - xy: 411, 422 + xy: 302, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 dagger-factory rotate: false - xy: 411, 422 + xy: 302, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 phantom-factory rotate: false - xy: 411, 422 + xy: 302, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 reconstructor rotate: false - xy: 411, 422 + xy: 302, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 spirit-factory rotate: false - xy: 411, 422 + xy: 302, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 wraith-factory rotate: false - xy: 411, 422 + xy: 302, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-repair-point rotate: false - xy: 357, 298 + xy: 363, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 repair-point rotate: false - xy: 357, 298 + xy: 363, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-revenant-factory rotate: false - xy: 584, 479 + xy: 576, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 block-icon-ripple rotate: false - xy: 90, 72 + xy: 464, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-rock rotate: false - xy: 367, 308 + xy: 373, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rock1 rotate: false - xy: 367, 308 + xy: 373, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-rotary-pump rotate: false - xy: 411, 404 + xy: 320, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 rotary-pump rotate: false - xy: 411, 404 + xy: 320, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-router rotate: false - xy: 377, 318 + xy: 383, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 router rotate: false - xy: 377, 318 + xy: 383, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-rtg-generator rotate: false - xy: 429, 435 + xy: 169, 155 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 rtg-generator rotate: false - xy: 429, 435 + xy: 169, 155 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-salvo rotate: false - xy: 429, 417 + xy: 636, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-sand rotate: false - xy: 387, 328 + xy: 393, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand1 rotate: false - xy: 387, 328 + xy: 393, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-scorch rotate: false - xy: 367, 298 + xy: 403, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-separator rotate: false - xy: 377, 308 + xy: 413, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 separator rotate: false - xy: 377, 308 + xy: 413, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-shock-mine rotate: false - xy: 387, 318 + xy: 423, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shock-mine rotate: false - xy: 387, 318 + xy: 423, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-shrub rotate: false - xy: 377, 298 + xy: 341, 376 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shrub rotate: false - xy: 377, 298 + xy: 341, 376 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-silicon-smelter rotate: false - xy: 447, 435 + xy: 654, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 silicon-smelter rotate: false - xy: 447, 435 + xy: 654, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-smelter rotate: false - xy: 387, 308 + xy: 341, 366 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 smelter rotate: false - xy: 387, 308 + xy: 341, 366 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-snow rotate: false - xy: 387, 298 + xy: 341, 356 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow1 rotate: false - xy: 387, 298 + xy: 341, 356 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-solar-panel rotate: false - xy: 347, 286 + xy: 342, 346 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 solar-panel rotate: false - xy: 347, 286 + xy: 342, 346 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-solar-panel-large rotate: false - xy: 90, 46 + xy: 490, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 solar-panel-large rotate: false - xy: 90, 46 + xy: 490, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-solidifer rotate: false - xy: 357, 288 + xy: 342, 336 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 solidifer rotate: false - xy: 357, 288 + xy: 342, 336 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-sorter rotate: false - xy: 367, 288 + xy: 342, 326 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sorter rotate: false - xy: 367, 288 + xy: 342, 326 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-space rotate: false - xy: 377, 288 + xy: 342, 316 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 space rotate: false - xy: 377, 288 + xy: 342, 316 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-spawn rotate: false - xy: 387, 288 + xy: 342, 306 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 spawn rotate: false - xy: 387, 288 + xy: 342, 306 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-spectre rotate: false - xy: 618, 479 + xy: 610, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 block-icon-spirit-factory rotate: false - xy: 447, 417 + xy: 672, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-stone rotate: false - xy: 397, 378 + xy: 342, 296 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone1 rotate: false - xy: 397, 378 + xy: 342, 296 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-surge-wall rotate: false - xy: 397, 368 + xy: 342, 286 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 surge-wall rotate: false - xy: 397, 368 + xy: 342, 286 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-surge-wall-large rotate: false - xy: 465, 435 + xy: 690, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 surge-wall-large rotate: false - xy: 465, 435 + xy: 690, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-swarmer rotate: false - xy: 465, 417 + xy: 708, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-tar rotate: false - xy: 397, 358 + xy: 1014, 432 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 tar rotate: false - xy: 397, 358 + xy: 1014, 432 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-tau-mech-pad rotate: false - xy: 429, 399 + xy: 726, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 tau-mech-pad rotate: false - xy: 429, 399 + xy: 726, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-thermal-generator rotate: false - xy: 447, 399 + xy: 744, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 thermal-generator rotate: false - xy: 447, 399 + xy: 744, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-thermal-pump rotate: false - xy: 465, 399 + xy: 762, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 thermal-pump rotate: false - xy: 465, 399 + xy: 762, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-thorium-reactor rotate: false - xy: 129, 176 + xy: 516, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 thorium-reactor rotate: false - xy: 129, 176 + xy: 516, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-thorium-wall rotate: false - xy: 397, 348 + xy: 1014, 422 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 thorium-wall rotate: false - xy: 397, 348 + xy: 1014, 422 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-thorium-wall-large rotate: false - xy: 411, 386 + xy: 780, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 thorium-wall-large rotate: false - xy: 411, 386 + xy: 780, 415 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-titan-factory rotate: false - xy: 132, 150 + xy: 542, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-titanium-conveyor rotate: false - xy: 397, 338 + xy: 433, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium-conveyor-0-0 rotate: false - xy: 397, 338 + xy: 433, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-trident-ship-pad rotate: false - xy: 429, 381 + xy: 798, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 trident-ship-pad rotate: false - xy: 429, 381 + xy: 798, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-turbine-generator rotate: false - xy: 447, 381 + xy: 816, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 turbine-generator rotate: false - xy: 447, 381 + xy: 816, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-unloader rotate: false - xy: 397, 328 + xy: 433, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 unloader rotate: false - xy: 397, 328 + xy: 433, 387 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-vault rotate: false - xy: 126, 124 + xy: 568, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 vault rotate: false - xy: 126, 124 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -block-icon-warp-gate - rotate: false - xy: 116, 98 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -warp-gate - rotate: false - xy: 116, 98 + xy: 568, 453 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 block-icon-water rotate: false - xy: 397, 318 + xy: 443, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 water rotate: false - xy: 397, 318 + xy: 443, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-icon-water-extractor rotate: false - xy: 465, 381 + xy: 834, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-wave rotate: false - xy: 483, 423 + xy: 852, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-icon-wraith-factory rotate: false - xy: 483, 405 + xy: 870, 417 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 deepwater-cliff-edge rotate: false - xy: 457, 321 + xy: 803, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 deepwater-cliff-edge-1 rotate: false - xy: 467, 331 + xy: 813, 391 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 deepwater-cliff-edge-2 rotate: false - xy: 447, 301 + xy: 823, 391 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 deepwater-cliff-side rotate: false - xy: 457, 311 + xy: 833, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt-cliff-edge rotate: false - xy: 467, 301 + xy: 873, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt-cliff-edge-1 rotate: false - xy: 407, 286 + xy: 883, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt-cliff-edge-2 rotate: false - xy: 417, 286 + xy: 893, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt-cliff-side rotate: false - xy: 427, 291 + xy: 903, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lava-cliff-edge rotate: false - xy: 507, 320 + xy: 421, 367 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lava-cliff-edge-1 rotate: false - xy: 497, 300 + xy: 411, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lava-cliff-edge-2 rotate: false - xy: 507, 310 + xy: 431, 367 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lava-cliff-side rotate: false - xy: 497, 290 + xy: 421, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-icon-cryofluid rotate: false - xy: 517, 335 + xy: 352, 306 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-icon-lava rotate: false - xy: 517, 325 + xy: 352, 296 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-icon-oil rotate: false - xy: 527, 345 + xy: 352, 286 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-icon-water rotate: false - xy: 527, 335 + xy: 362, 347 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 mech-icon-alpha-mech rotate: false - xy: 783, 345 + xy: 345, 62 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mech-icon-dart-ship rotate: false - xy: 825, 387 + xy: 345, 48 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mech-icon-delta-mech rotate: false - xy: 839, 387 + xy: 343, 34 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mech-icon-omega-mech rotate: false - xy: 243, 200 + xy: 311, 40 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 mech-icon-tau-mech rotate: false - xy: 259, 200 + xy: 329, 130 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 mech-icon-trident-ship rotate: false - xy: 275, 200 + xy: 329, 114 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 trident-ship rotate: false - xy: 275, 200 + xy: 329, 114 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 metalfloor-cliff-edge rotate: false - xy: 547, 335 + xy: 362, 317 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor-cliff-edge-1 rotate: false - xy: 547, 325 + xy: 402, 347 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor-cliff-edge-2 rotate: false - xy: 517, 295 + xy: 392, 337 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor-cliff-side rotate: false - xy: 527, 305 + xy: 382, 327 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-blackstone1 rotate: false - xy: 557, 345 + xy: 362, 307 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-blackstone2 rotate: false - xy: 557, 335 + xy: 412, 347 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-blackstone3 rotate: false - xy: 557, 325 + xy: 402, 337 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-grass1 rotate: false - xy: 517, 285 + xy: 392, 327 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-grass2 rotate: false - xy: 527, 295 + xy: 382, 317 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-grass3 rotate: false - xy: 537, 305 + xy: 372, 307 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-ice1 rotate: false - xy: 547, 315 + xy: 362, 297 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-ice2 rotate: false - xy: 567, 345 + xy: 422, 347 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-ice3 rotate: false - xy: 567, 335 + xy: 412, 337 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-sand1 rotate: false - xy: 567, 325 + xy: 402, 327 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-sand2 rotate: false - xy: 527, 285 + xy: 392, 317 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-sand3 rotate: false - xy: 537, 295 + xy: 382, 307 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-snow1 rotate: false - xy: 547, 305 + xy: 372, 297 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-snow2 rotate: false - xy: 557, 315 + xy: 362, 287 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-snow3 rotate: false - xy: 577, 345 + xy: 422, 337 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-stone1 rotate: false - xy: 577, 335 + xy: 412, 327 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-stone2 rotate: false - xy: 577, 325 + xy: 402, 317 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-coal-stone3 rotate: false - xy: 537, 285 + xy: 392, 307 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-blackstone1 rotate: false - xy: 547, 295 + xy: 382, 297 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-blackstone2 rotate: false - xy: 557, 305 + xy: 372, 287 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-blackstone3 rotate: false - xy: 567, 315 + xy: 422, 327 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-grass1 rotate: false - xy: 587, 345 + xy: 412, 317 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-grass2 rotate: false - xy: 587, 335 + xy: 402, 307 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-grass3 rotate: false - xy: 587, 325 + xy: 392, 297 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-ice1 rotate: false - xy: 547, 285 + xy: 382, 287 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-ice2 rotate: false - xy: 557, 295 + xy: 422, 317 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-ice3 rotate: false - xy: 567, 305 + xy: 412, 307 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-sand1 rotate: false - xy: 577, 315 + xy: 402, 297 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-sand2 rotate: false - xy: 597, 345 + xy: 392, 287 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-sand3 rotate: false - xy: 597, 335 + xy: 422, 307 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-snow1 rotate: false - xy: 597, 325 + xy: 412, 297 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-snow2 rotate: false - xy: 557, 285 + xy: 402, 287 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-snow3 rotate: false - xy: 567, 295 + xy: 422, 297 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-stone1 rotate: false - xy: 577, 305 + xy: 412, 287 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-stone2 rotate: false - xy: 587, 315 + xy: 422, 287 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-copper-stone3 rotate: false - xy: 607, 345 + xy: 432, 347 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-blackstone1 rotate: false - xy: 607, 335 + xy: 432, 337 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-blackstone2 rotate: false - xy: 607, 325 + xy: 432, 327 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-blackstone3 rotate: false - xy: 567, 285 + xy: 432, 317 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-grass1 rotate: false - xy: 577, 295 + xy: 432, 307 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-grass2 rotate: false - xy: 587, 305 + xy: 432, 297 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-grass3 rotate: false - xy: 597, 315 + xy: 432, 287 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-ice1 rotate: false - xy: 617, 345 + xy: 443, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-ice2 rotate: false - xy: 617, 335 + xy: 453, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-ice3 rotate: false - xy: 617, 325 + xy: 463, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-sand1 rotate: false - xy: 577, 285 + xy: 473, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-sand2 rotate: false - xy: 587, 295 + xy: 483, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-sand3 rotate: false - xy: 597, 305 + xy: 493, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-snow1 rotate: false - xy: 607, 315 + xy: 503, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-snow2 rotate: false - xy: 627, 345 + xy: 513, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-snow3 rotate: false - xy: 627, 335 + xy: 523, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-stone1 rotate: false - xy: 627, 325 + xy: 533, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-stone2 rotate: false - xy: 587, 285 + xy: 543, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-lead-stone3 rotate: false - xy: 597, 295 + xy: 553, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-blackstone1 rotate: false - xy: 607, 305 + xy: 563, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-blackstone2 rotate: false - xy: 617, 315 + xy: 573, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-blackstone3 rotate: false - xy: 637, 345 + xy: 583, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-grass1 rotate: false - xy: 637, 335 + xy: 593, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-grass2 rotate: false - xy: 637, 325 + xy: 603, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-grass3 rotate: false - xy: 597, 285 + xy: 613, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-ice1 rotate: false - xy: 607, 295 + xy: 623, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-ice2 rotate: false - xy: 617, 305 + xy: 633, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-ice3 rotate: false - xy: 627, 315 + xy: 643, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-sand1 rotate: false - xy: 647, 345 + xy: 653, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-sand2 rotate: false - xy: 647, 335 + xy: 663, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-sand3 rotate: false - xy: 647, 325 + xy: 673, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-snow1 rotate: false - xy: 607, 285 + xy: 683, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-snow2 rotate: false - xy: 617, 295 + xy: 693, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-snow3 rotate: false - xy: 627, 305 + xy: 703, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-stone1 rotate: false - xy: 637, 315 + xy: 713, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-stone2 rotate: false - xy: 657, 345 + xy: 723, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-thorium-stone3 rotate: false - xy: 657, 335 + xy: 733, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-blackstone1 rotate: false - xy: 657, 325 + xy: 743, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-blackstone2 rotate: false - xy: 617, 285 + xy: 753, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-blackstone3 rotate: false - xy: 627, 295 + xy: 763, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-grass1 rotate: false - xy: 637, 305 + xy: 773, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-grass2 rotate: false - xy: 647, 315 + xy: 783, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-grass3 rotate: false - xy: 667, 345 + xy: 793, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-ice1 rotate: false - xy: 667, 335 + xy: 803, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-ice2 rotate: false - xy: 667, 325 + xy: 813, 381 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-ice3 rotate: false - xy: 627, 285 + xy: 823, 381 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-sand1 rotate: false - xy: 637, 295 + xy: 833, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-sand2 rotate: false - xy: 647, 305 + xy: 843, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-sand3 rotate: false - xy: 657, 315 + xy: 853, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-snow1 rotate: false - xy: 677, 345 + xy: 863, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-snow2 rotate: false - xy: 677, 335 + xy: 873, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-snow3 rotate: false - xy: 677, 325 + xy: 883, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-stone1 rotate: false - xy: 637, 285 + xy: 893, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-stone2 rotate: false - xy: 647, 295 + xy: 903, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ore-titanium-stone3 rotate: false - xy: 657, 305 + xy: 913, 383 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand-cliff-edge rotate: false - xy: 707, 325 + xy: 491, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand-cliff-edge-1 rotate: false - xy: 697, 315 + xy: 501, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand-cliff-edge-2 rotate: false - xy: 717, 335 + xy: 501, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand-cliff-side rotate: false - xy: 717, 325 + xy: 511, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow-cliff-edge rotate: false - xy: 697, 285 + xy: 561, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow-cliff-edge-1 rotate: false - xy: 707, 295 + xy: 561, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow-cliff-edge-2 rotate: false - xy: 717, 305 + xy: 571, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow-cliff-side rotate: false - xy: 727, 315 + xy: 571, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 space-cliff-edge rotate: false - xy: 747, 325 + xy: 581, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 space-cliff-edge-1 rotate: false - xy: 707, 285 + xy: 591, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 space-cliff-edge-2 rotate: false - xy: 717, 295 + xy: 591, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 space-cliff-side rotate: false - xy: 727, 305 + xy: 601, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 tar-cliff-edge rotate: false - xy: 747, 315 + xy: 631, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 tar-cliff-edge-1 rotate: false - xy: 767, 335 + xy: 641, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 tar-cliff-edge-2 rotate: false - xy: 767, 325 + xy: 641, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 tar-cliff-side rotate: false - xy: 727, 285 + xy: 651, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 unit-icon-dagger rotate: false - xy: 825, 331 + xy: 141, 21 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 unit-icon-fortress rotate: false - xy: 753, 359 + xy: 315, 224 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 unit-icon-titan rotate: false - xy: 771, 413 + xy: 297, 188 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 unit-icon-wraith rotate: false - xy: 839, 331 + xy: 155, 35 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 wraith rotate: false - xy: 839, 331 + xy: 155, 35 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 item-biomatter rotate: false - xy: 487, 319 + xy: 371, 367 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-blast-compound rotate: false - xy: 487, 309 + xy: 361, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-coal rotate: false - xy: 477, 289 + xy: 391, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-copper rotate: false - xy: 487, 299 + xy: 381, 367 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-dense-alloy rotate: false - xy: 487, 289 + xy: 371, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-lead rotate: false - xy: 477, 279 + xy: 401, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-phase-fabric rotate: false - xy: 487, 279 + xy: 391, 367 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-plastanium rotate: false - xy: 497, 350 + xy: 381, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-pyratite rotate: false - xy: 507, 350 + xy: 411, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-sand rotate: false - xy: 497, 340 + xy: 401, 367 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-silicon rotate: false - xy: 497, 330 + xy: 391, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-stone rotate: false - xy: 507, 340 + xy: 421, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-surge-alloy rotate: false - xy: 497, 320 + xy: 411, 367 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-thorium rotate: false - xy: 507, 330 + xy: 401, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-titanium rotate: false - xy: 497, 310 + xy: 431, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquid-icon rotate: false - xy: 517, 345 + xy: 352, 316 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 alpha-mech rotate: false - xy: 321, 386 + xy: 166, 261 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 alpha-mech-base rotate: false - xy: 322, 182 + xy: 216, 269 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 alpha-mech-leg rotate: false - xy: 243, 170 + xy: 216, 255 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 delta-mech rotate: false - xy: 333, 302 + xy: 924, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 delta-mech-base rotate: false - xy: 349, 388 + xy: 938, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 delta-mech-leg rotate: false - xy: 363, 388 + xy: 952, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 omega-mech rotate: false - xy: 227, 192 + xy: 329, 98 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 omega-mech-armor rotate: false - xy: 243, 184 + xy: 329, 82 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 omega-mech-base rotate: false - xy: 259, 184 + xy: 329, 66 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 omega-mech-leg rotate: false - xy: 275, 184 + xy: 329, 50 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 tau-mech rotate: false - xy: 291, 176 + xy: 810, 401 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 tau-mech-base rotate: false - xy: 797, 335 + xy: 127, 21 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 tau-mech-leg rotate: false - xy: 811, 327 + xy: 141, 35 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 dart-ship rotate: false - xy: 333, 316 + xy: 910, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 glaive-ship rotate: false - xy: 247, 294 + xy: 168, 227 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 mech-icon-glaive-ship rotate: false - xy: 247, 294 + xy: 168, 227 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 javelin-ship rotate: false - xy: 741, 345 + xy: 345, 104 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mech-icon-javelin-ship rotate: false - xy: 741, 345 + xy: 345, 104 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 javelin-ship-shield rotate: false - xy: 755, 345 + xy: 345, 90 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -5284,14 +5270,14 @@ circle index: -1 shape-3 rotate: false - xy: 204, 378 + xy: 1, 198 size: 63, 63 orig: 63, 63 offset: 0, 0 index: -1 border rotate: false - xy: 30, 77 + xy: 204, 309 size: 24, 40 split: 5, 5, 5, 10 orig: 24, 40 @@ -5299,7 +5285,7 @@ border index: -1 button rotate: false - xy: 187, 268 + xy: 30, 106 size: 24, 40 split: 10, 10, 6, 10 orig: 24, 40 @@ -5307,7 +5293,7 @@ button index: -1 textarea rotate: false - xy: 187, 268 + xy: 30, 106 size: 24, 40 split: 10, 10, 9, 11 orig: 24, 40 @@ -5315,7 +5301,7 @@ textarea index: -1 button-down rotate: false - xy: 269, 401 + xy: 233, 372 size: 24, 40 split: 10, 10, 6, 10 orig: 24, 40 @@ -5323,7 +5309,7 @@ button-down index: -1 button-over rotate: false - xy: 269, 401 + xy: 233, 372 size: 24, 40 split: 10, 10, 6, 10 orig: 24, 40 @@ -5331,7 +5317,7 @@ button-over index: -1 button-select rotate: false - xy: 116, 72 + xy: 594, 453 size: 24, 24 split: 4, 4, 4, 4 orig: 24, 24 @@ -5339,826 +5325,854 @@ button-select index: -1 check-off rotate: false - xy: 992, 479 + xy: 230, 312 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 check-on rotate: false - xy: 123, 230 + xy: 230, 278 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 check-on-over rotate: false - xy: 187, 234 + xy: 260, 314 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 check-over rotate: false - xy: 217, 234 + xy: 260, 280 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 clear rotate: false - xy: 483, 441 + xy: 166, 275 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 cursor rotate: false - xy: 495, 441 + xy: 325, 382 size: 4, 4 orig: 4, 4 offset: 0, 0 index: -1 discord-banner rotate: false - xy: 204, 443 + xy: 1, 263 size: 84, 45 orig: 84, 45 offset: 0, 0 index: -1 empty-sector rotate: false - xy: 686, 479 + xy: 678, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -controller-cursor - rotate: false - xy: 501, 414 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-about - rotate: false - xy: 263, 294 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-add - rotate: false - xy: 195, 1 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-admin - rotate: false - xy: 211, 1 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-admin-small - rotate: false - xy: 313, 288 - size: 6, 6 - orig: 6, 6 - offset: 0, 0 - index: -1 -icon-areaDelete - rotate: false - xy: 1012, 440 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-arrow - rotate: false - xy: 708, 431 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-arrow-16 - rotate: false - xy: 708, 431 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-arrow-down - rotate: false - xy: 307, 196 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-arrow-left - rotate: false - xy: 811, 369 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-arrow-right - rotate: false - xy: 854, 375 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-arrow-up - rotate: false - xy: 825, 319 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-back - rotate: false - xy: 726, 431 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-ban - rotate: false - xy: 411, 440 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-break - rotate: false - xy: 744, 431 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-cancel - rotate: false - xy: 762, 431 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-chat - rotate: false - xy: 837, 319 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-check - rotate: false - xy: 780, 433 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 icon-crafting rotate: false - xy: 867, 391 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-cursor - rotate: false - xy: 879, 393 - size: 10, 10 - orig: 10, 10 + xy: 153, 81 + size: 16, 16 + orig: 16, 16 offset: 0, 0 index: -1 icon-defense rotate: false - xy: 891, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-dev-builds - rotate: false - xy: 825, 417 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-discord - rotate: false - xy: 789, 363 - size: 14, 14 - orig: 14, 14 + xy: 153, 63 + size: 16, 16 + orig: 16, 16 offset: 0, 0 index: -1 icon-distribution rotate: false - xy: 903, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-donate - rotate: false - xy: 807, 381 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-dots - rotate: false - xy: 825, 401 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-editor - rotate: false - xy: 841, 417 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-egg - rotate: false - xy: 841, 401 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-elevation - rotate: false - xy: 798, 433 + xy: 171, 99 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 -icon-eraser +icon-effect rotate: false - xy: 816, 433 + xy: 171, 81 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 -icon-exit - rotate: false - xy: 852, 435 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-file - rotate: false - xy: 834, 433 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-file-image - rotate: false - xy: 519, 409 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-file-text - rotate: false - xy: 868, 437 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-fill - rotate: false - xy: 519, 391 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-floppy - rotate: false - xy: 884, 437 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-floppy-16 - rotate: false - xy: 537, 409 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-folder - rotate: false - xy: 900, 437 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-folder-parent - rotate: false - xy: 916, 437 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-generated - rotate: false - xy: 204, 328 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -icon-github - rotate: false - xy: 932, 437 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-google-play - rotate: false - xy: 948, 437 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-grid - rotate: false - xy: 519, 373 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-hold - rotate: false - xy: 915, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-holdDelete - rotate: false - xy: 927, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-home - rotate: false - xy: 964, 437 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-host - rotate: false - xy: 980, 437 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-info - rotate: false - xy: 939, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-itch.io - rotate: false - xy: 996, 437 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-item - rotate: false - xy: 951, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-items-none - rotate: false - xy: 487, 329 - size: 8, 8 - orig: 8, 8 - offset: 0, 0 - index: -1 -icon-line - rotate: false - xy: 537, 391 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-link - rotate: false - xy: 857, 419 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 icon-liquid rotate: false - xy: 963, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-load - rotate: false - xy: 857, 403 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-load-image - rotate: false - xy: 555, 409 + xy: 189, 101 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 -icon-load-map - rotate: false - xy: 537, 373 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-loading - rotate: false - xy: 555, 391 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-locked - rotate: false - xy: 573, 409 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-logic - rotate: false - xy: 975, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-map - rotate: false - xy: 873, 421 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-menu - rotate: false - xy: 987, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-menu-large - rotate: false - xy: 555, 373 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-missing - rotate: false - xy: 999, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-mission-background - rotate: false - xy: 269, 381 - size: 18, 18 - orig: 18, 18 - offset: 0, 0 - index: -1 -icon-mission-battle - rotate: false - xy: 1011, 393 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-mission-defense - rotate: false - xy: 849, 319 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-mission-done - rotate: false - xy: 867, 379 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-none - rotate: false - xy: 879, 381 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-nullitem - rotate: false - xy: 477, 299 - size: 8, 8 - orig: 8, 8 - offset: 0, 0 - index: -1 -icon-pause - rotate: false - xy: 891, 381 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-pencil - rotate: false - xy: 573, 391 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-pencil-small - rotate: false - xy: 873, 405 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-pick - rotate: false - xy: 591, 409 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-play - rotate: false - xy: 903, 381 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-play-2 - rotate: false - xy: 889, 421 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-players - rotate: false - xy: 915, 381 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 icon-power rotate: false - xy: 927, 381 - size: 10, 10 - orig: 10, 10 + xy: 207, 195 + size: 16, 16 + orig: 16, 16 offset: 0, 0 index: -1 icon-production rotate: false - xy: 939, 381 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-quit - rotate: false - xy: 889, 405 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-redo - rotate: false - xy: 573, 373 + xy: 218, 237 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 -icon-refresh +icon-turret rotate: false - xy: 905, 421 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-rename - rotate: false - xy: 905, 405 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-resize - rotate: false - xy: 591, 391 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-rotate - rotate: false - xy: 921, 421 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-rotate-arrow - rotate: false - xy: 921, 405 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-rotate-left - rotate: false - xy: 937, 421 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-rotate-right - rotate: false - xy: 937, 405 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-save - rotate: false - xy: 953, 421 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-save-image - rotate: false - xy: 609, 409 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-save-map - rotate: false - xy: 591, 373 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-settings - rotate: false - xy: 951, 381 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-terrain - rotate: false - xy: 609, 391 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-tools - rotate: false - xy: 953, 405 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-touch - rotate: false - xy: 963, 381 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-touchDelete - rotate: false - xy: 975, 381 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-trash - rotate: false - xy: 969, 421 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-trash-16 - rotate: false - xy: 627, 409 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -icon-trello - rotate: false - xy: 969, 405 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-tutorial - rotate: false - xy: 985, 421 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-undo - rotate: false - xy: 609, 373 + xy: 225, 201 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-units rotate: false - xy: 987, 381 + xy: 243, 206 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-upgrade + rotate: false + xy: 261, 202 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +controller-cursor + rotate: false + xy: 906, 417 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-about + rotate: false + xy: 153, 149 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-add + rotate: false + xy: 153, 133 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-admin + rotate: false + xy: 148, 117 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-admin-small + rotate: false + xy: 186, 243 + size: 6, 6 + orig: 6, 6 + offset: 0, 0 + index: -1 +icon-areaDelete + rotate: false + xy: 140, 141 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 +icon-arrow + rotate: false + xy: 135, 63 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-arrow-16 + rotate: false + xy: 135, 63 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-arrow-down + rotate: false + xy: 272, 250 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-arrow-left + rotate: false + xy: 272, 238 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-arrow-right + rotate: false + xy: 259, 100 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-arrow-up + rotate: false + xy: 271, 100 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-back + rotate: false + xy: 95, 34 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-ban + rotate: false + xy: 164, 117 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-break + rotate: false + xy: 95, 16 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-cancel + rotate: false + xy: 169, 137 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-chat + rotate: false + xy: 1012, 442 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-check + rotate: false + xy: 153, 99 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-cursor + rotate: false + xy: 169, 37 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-dev-builds + rotate: false + xy: 184, 227 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-discord + rotate: false + xy: 200, 249 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-donate + rotate: false + xy: 225, 113 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-dots + rotate: false + xy: 243, 100 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-editor + rotate: false + xy: 279, 46 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-egg + rotate: false + xy: 333, 226 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-elevation + rotate: false + xy: 171, 63 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-eraser + rotate: false + xy: 189, 209 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-exit + rotate: false + xy: 333, 210 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-file + rotate: false + xy: 189, 191 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-file-image + rotate: false + xy: 187, 173 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-file-text + rotate: false + xy: 333, 194 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-fill + rotate: false + xy: 187, 155 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-floppy + rotate: false + xy: 333, 178 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-floppy-16 + rotate: false + xy: 187, 137 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-folder + rotate: false + xy: 333, 162 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-folder-parent + rotate: false + xy: 333, 146 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-generated + rotate: false + xy: 1, 148 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +icon-github + rotate: false + xy: 634, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-google-play + rotate: false + xy: 650, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-grid + rotate: false + xy: 180, 119 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-hold + rotate: false + xy: 169, 25 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-holdDelete + rotate: false + xy: 123, 9 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-home + rotate: false + xy: 666, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-host + rotate: false + xy: 682, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-info + rotate: false + xy: 135, 9 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-itch.io + rotate: false + xy: 698, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-item + rotate: false + xy: 147, 9 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-items-none + rotate: false + xy: 361, 367 + size: 8, 8 + orig: 8, 8 + offset: 0, 0 + index: -1 +icon-line + rotate: false + xy: 200, 231 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-link + rotate: false + xy: 714, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-liquid-small + rotate: false + xy: 159, 9 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-load + rotate: false + xy: 730, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-load-image + rotate: false + xy: 189, 83 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-load-map + rotate: false + xy: 189, 65 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-loading + rotate: false + xy: 198, 119 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-locked + rotate: false + xy: 207, 101 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-logic + rotate: false + xy: 181, 37 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-map + rotate: false + xy: 746, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-menu + rotate: false + xy: 181, 25 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-menu-large + rotate: false + xy: 207, 83 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-missing + rotate: false + xy: 171, 13 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-mission-background + rotate: false + xy: 636, 433 + size: 18, 18 + orig: 18, 18 + offset: 0, 0 + index: -1 +icon-mission-battle + rotate: false + xy: 171, 1 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-mission-defense + rotate: false + xy: 183, 13 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-mission-done + rotate: false + xy: 183, 1 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-none + rotate: false + xy: 190, 53 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-nullitem + rotate: false + xy: 381, 377 + size: 8, 8 + orig: 8, 8 + offset: 0, 0 + index: -1 +icon-pause + rotate: false + xy: 202, 53 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-pencil + rotate: false + xy: 207, 65 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-pencil-small + rotate: false + xy: 762, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-pick + rotate: false + xy: 207, 213 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-play + rotate: false + xy: 193, 41 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-play-2 + rotate: false + xy: 778, 399 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-players + rotate: false + xy: 193, 29 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-power-small + rotate: false + xy: 205, 41 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-quit + rotate: false + xy: 338, 262 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-redo + rotate: false + xy: 236, 242 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-refresh + rotate: false + xy: 338, 246 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-rename + rotate: false + xy: 297, 136 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-resize + rotate: false + xy: 254, 242 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-rotate + rotate: false + xy: 313, 136 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-rotate-arrow + rotate: false + xy: 295, 120 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-rotate-left + rotate: false + xy: 311, 120 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-rotate-right + rotate: false + xy: 297, 104 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-save + rotate: false + xy: 297, 88 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-save-image + rotate: false + xy: 284, 242 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-save-map + rotate: false + xy: 302, 242 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-settings + rotate: false + xy: 205, 29 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-terrain + rotate: false + xy: 320, 242 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-tools + rotate: false + xy: 297, 72 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-touch + rotate: false + xy: 195, 17 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-touchDelete + rotate: false + xy: 195, 5 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +icon-trash + rotate: false + xy: 313, 104 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-trash-16 + rotate: false + xy: 225, 219 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-trello + rotate: false + xy: 313, 88 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-tutorial + rotate: false + xy: 313, 72 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-undo + rotate: false + xy: 243, 224 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 icon-unlocked rotate: false - xy: 627, 391 + xy: 261, 220 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-unlocks rotate: false - xy: 985, 405 + xy: 297, 56 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 -icon-weapon - rotate: false - xy: 999, 381 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 icon-wiki rotate: false - xy: 1001, 421 + xy: 313, 56 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-zoom rotate: false - xy: 645, 409 + xy: 243, 188 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-zoom-small rotate: false - xy: 1001, 405 + xy: 295, 40 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 info-banner rotate: false - xy: 1, 217 + xy: 204, 466 size: 84, 45 orig: 84, 45 offset: 0, 0 index: -1 inventory rotate: false - xy: 54, 129 + xy: 259, 378 size: 24, 40 split: 10, 10, 10, 14 orig: 24, 40 @@ -6166,14 +6180,14 @@ inventory index: -1 logotext rotate: false - xy: 346, 490 + xy: 87, 287 size: 89, 21 orig: 89, 21 offset: 0, 0 index: -1 pane rotate: false - xy: 27, 1 + xy: 280, 428 size: 24, 36 split: 10, 10, 5, 5 orig: 24, 36 @@ -6189,7 +6203,7 @@ pane-button index: -1 scroll rotate: false - xy: 30, 40 + xy: 306, 432 size: 24, 35 split: 10, 10, 6, 5 orig: 24, 35 @@ -6197,7 +6211,7 @@ scroll index: -1 scroll-horizontal rotate: false - xy: 479, 487 + xy: 129, 261 size: 35, 24 split: 6, 5, 10, 10 orig: 35, 24 @@ -6205,7 +6219,7 @@ scroll-horizontal index: -1 scroll-knob-horizontal rotate: false - xy: 437, 487 + xy: 87, 261 size: 40, 24 split: 10, 6, 0, 24 pad: -1, -1, 10, 10 @@ -6214,7 +6228,7 @@ scroll-knob-horizontal index: -1 scroll-knob-vertical rotate: false - xy: 295, 412 + xy: 56, 114 size: 24, 40 split: 10, 10, 6, 10 orig: 24, 40 @@ -6222,7 +6236,7 @@ scroll-knob-vertical index: -1 scroll-knob-vertical-black rotate: false - xy: 254, 336 + xy: 51, 156 size: 24, 40 split: 10, 10, 6, 10 orig: 24, 40 @@ -6230,84 +6244,63 @@ scroll-knob-vertical-black index: -1 sector-edge rotate: false - xy: 584, 445 + xy: 94, 193 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 sector-select rotate: false - xy: 618, 445 + xy: 128, 193 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 selection rotate: false - xy: 77, 173 + xy: 230, 348 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 slider rotate: false - xy: 53, 30 + xy: 1020, 454 size: 1, 8 orig: 1, 8 offset: 0, 0 index: -1 slider-knob rotate: false - xy: 53, 171 + xy: 256, 420 size: 22, 44 orig: 22, 44 offset: 0, 0 index: -1 slider-knob-down rotate: false - xy: 30, 119 + xy: 1, 39 size: 22, 44 orig: 22, 44 offset: 0, 0 index: -1 slider-knob-over rotate: false - xy: 30, 119 + xy: 1, 39 size: 22, 44 orig: 22, 44 offset: 0, 0 index: -1 slider-vertical rotate: false - xy: 269, 378 + xy: 290, 466 size: 8, 1 orig: 8, 1 offset: 0, 0 index: -1 -text-sides - rotate: false - xy: 1, 287 - size: 140, 21 - orig: 140, 21 - offset: 0, 0 - index: -1 -text-sides-down - rotate: false - xy: 204, 490 - size: 140, 21 - orig: 140, 21 - offset: 0, 0 - index: -1 -text-sides-over - rotate: false - xy: 1, 264 - size: 140, 21 - orig: 140, 21 - offset: 0, 0 - index: -1 textfield rotate: false - xy: 746, 449 + xy: 82, 129 size: 28, 28 split: 6, 6, 6, 6 orig: 28, 28 @@ -6315,7 +6308,7 @@ textfield index: -1 textfield-over rotate: false - xy: 716, 449 + xy: 111, 163 size: 28, 28 split: 2, 2, 2, 2 orig: 28, 28 @@ -6323,14 +6316,14 @@ textfield-over index: -1 white rotate: false - xy: 290, 449 + xy: 25, 80 size: 3, 3 orig: 3, 3 offset: 0, 0 index: -1 window rotate: false - xy: 1, 39 + xy: 1, 85 size: 27, 61 split: 8, 8, 44, 11 orig: 27, 61 @@ -6338,7 +6331,7 @@ window index: -1 window-empty rotate: false - xy: 1, 102 + xy: 204, 351 size: 27, 61 split: 8, 8, 44, 11 orig: 27, 61 @@ -6346,210 +6339,210 @@ window-empty index: -1 alpha-drone rotate: false - xy: 279, 294 + xy: 97, 115 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 unit-icon-alpha-drone rotate: false - xy: 279, 294 + xy: 97, 115 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 dagger rotate: false - xy: 333, 358 + xy: 868, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 dagger-base rotate: false - xy: 333, 344 + xy: 882, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 dagger-leg rotate: false - xy: 333, 330 + xy: 896, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 fortress rotate: false - xy: 654, 427 + xy: 99, 70 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 fortress-base rotate: false - xy: 672, 427 + xy: 93, 52 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 titan-base rotate: false - xy: 672, 427 + xy: 93, 52 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 fortress-leg rotate: false - xy: 690, 431 + xy: 117, 63 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ghoul rotate: false - xy: 496, 447 + xy: 305, 382 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 unit-icon-ghoul rotate: false - xy: 496, 447 + xy: 305, 382 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 phantom rotate: false - xy: 291, 192 + xy: 327, 34 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 unit-icon-phantom rotate: false - xy: 291, 192 + xy: 327, 34 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 power-cell rotate: false - xy: 227, 176 + xy: 794, 399 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 revenant rotate: false - xy: 686, 449 + xy: 259, 348 size: 28, 28 orig: 28, 28 offset: 0, 0 index: -1 unit-icon-revenant rotate: false - xy: 686, 449 + xy: 259, 348 size: 28, 28 orig: 28, 28 offset: 0, 0 index: -1 spirit rotate: false - xy: 839, 359 + xy: 173, 49 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 unit-icon-spirit rotate: false - xy: 839, 359 + xy: 173, 49 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 titan rotate: false - xy: 753, 395 + xy: 277, 112 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 titan-leg rotate: false - xy: 735, 359 + xy: 297, 224 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 artillery-equip rotate: false - xy: 257, 170 + xy: 186, 251 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blaster-equip rotate: false - xy: 307, 167 + xy: 826, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 bomber-equip rotate: false - xy: 335, 386 + xy: 840, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 missiles-equip rotate: false - xy: 335, 386 + xy: 840, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 chain-blaster-equip rotate: false - xy: 333, 372 + xy: 854, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 flakgun-equip rotate: false - xy: 333, 288 + xy: 994, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 flamethrower-equip rotate: false - xy: 331, 274 + xy: 1008, 403 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 heal-blaster-equip rotate: false - xy: 713, 345 + xy: 345, 132 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shockgun-equip rotate: false - xy: 837, 373 + xy: 131, 49 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 swarmer-equip rotate: false - xy: 825, 345 + xy: 113, 21 size: 12, 12 orig: 12, 12 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 53901c92d1..205363eea1 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/assets/ui/uiskin.json b/core/assets/ui/uiskin.json index 32020b418f..ab630372a6 100644 --- a/core/assets/ui/uiskin.json +++ b/core/assets/ui/uiskin.json @@ -5,8 +5,7 @@ Color: { gray: {a: 1, b: 0.32, g: 0.32, r: 0.32 }, lightgray: {a: 1, b: 0.65, g: 0.65, r: 0.65 } orange: {hex: "FFA500"}, - accent: {hex: "f4ba6e"}, - accentDark: {hex: "f4ba6e"}, + accent: {hex: "ffd37f"} }, TintedDrawable: { dialogDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.9} }, @@ -15,12 +14,12 @@ TintedDrawable: { chatfield: {name: white, color: {r: 0, g: 0, b: 0, a: 0.2}}, clear: {name: white, color: {r: 0.1, g: 0.1, b: 0.1, a: 0.75}}, none: {name: white, color: {r: 0, g: 0, b: 0, a: 0}}, - clear-over: {name: white, color: {r: 1, g: 1, b: 1, a: 0.2} }, - clear-down: {name: white, color: {r: 1, g: 1, b: 1, a: 0.4} } + clear-over: {name: white, color: { hex: "#ffffff82" }}, + clear-alpha: {name: white, color: { hex: "#ffd37fff" }}, + clear-down: {name: white, color: { hex: "#ffd37fff" }} }, ButtonStyle: { default: {down: button-down, up: button }, - menu: {up: text-sides, over: text-sides-over, down: text-sides-down}, toggle: {checked: button-down, down: button-down, up: button } }, TextButtonStyle: { @@ -28,6 +27,7 @@ TextButtonStyle: { discord: {font: default-font, fontColor: white, up: discord-banner}, info: {font: default-font, fontColor: white, up: info-banner}, clear: {down: clear-down, up: clear, over: clear-over, font: default-font, fontColor: white, disabledFontColor: gray }, + clear-partial: {down: white, up: button-select, over: clear-down, font: default-font, fontColor: white, disabledFontColor: gray }, empty: {font: default-font}, toggle: {font: default-font, fontColor: white, checked: button-down, down: button-down, up: button, over: button-over, disabled: button, disabledFontColor: gray } }, @@ -40,6 +40,9 @@ ImageButtonStyle: { toggle: {checked: button-down, down: button-down, up: button, imageDisabledColor: gray, imageUpColor: white }, select: {checked: button-select, up: none }, clear: {down: clear-down, up: clear, over: clear-over}, + clear-partial: {down: clear-down, up: none, over: clear-over}, + clear-toggle: {down: clear-down, checked: clear-down, up: clear, over: clear-over}, + clear-toggle-partial: {down: clear-down, checked: clear-down, up: none, over: clear-over}, }, ScrollPaneStyle: { default: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical-black}, diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index ed21672801..14636b4abd 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; @@ -49,8 +50,7 @@ public class Vars{ public static final int maxNameLength = 40; public static final float itemSize = 5f; public static final int tilesize = 8; - public static final int sectorSize = 250; - public static final int mapPadding = 3; + public static final int sectorSize = 256; public static final int invalidSector = Integer.MAX_VALUE; public static Locale[] locales; public static final Color[] playerColors = { @@ -73,6 +73,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 +81,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 @@ -171,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/Recipes.java b/core/src/io/anuke/mindustry/content/Recipes.java index 08a7f8fac1..f236469ff9 100644 --- a/core/src/io/anuke/mindustry/content/Recipes.java +++ b/core/src/io/anuke/mindustry/content/Recipes.java @@ -43,43 +43,46 @@ public class Recipes implements ContentList{ new Recipe(defense, DefenseBlocks.surgeWallLarge, new ItemStack(Items.surgealloy, 12 * 4)); //projectors - new Recipe(defense, DefenseBlocks.mendProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 150), new ItemStack(Items.titanium, 50), new ItemStack(Items.silicon, 180)); - new Recipe(defense, DefenseBlocks.overdriveProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 150), new ItemStack(Items.titanium, 150), new ItemStack(Items.silicon, 250)); - new Recipe(defense, DefenseBlocks.forceProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 150), new ItemStack(Items.titanium, 150), new ItemStack(Items.silicon, 250)); + new Recipe(effect, DefenseBlocks.mendProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 150), new ItemStack(Items.titanium, 50), new ItemStack(Items.silicon, 180)); + new Recipe(effect, DefenseBlocks.overdriveProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 150), new ItemStack(Items.titanium, 150), new ItemStack(Items.silicon, 250)); + new Recipe(effect, DefenseBlocks.forceProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 150), new ItemStack(Items.titanium, 150), new ItemStack(Items.silicon, 250)); - //extra blocks - new Recipe(defense, DefenseBlocks.shockMine, new ItemStack(Items.lead, 50), new ItemStack(Items.silicon, 25)) + new Recipe(effect, StorageBlocks.unloader, new ItemStack(Items.densealloy, 50), new ItemStack(Items.silicon, 60)); + new Recipe(effect, StorageBlocks.container, new ItemStack(Items.densealloy, 200)); + new Recipe(effect, StorageBlocks.vault, new ItemStack(Items.densealloy, 500), new ItemStack(Items.thorium, 250)); + + new Recipe(effect, DefenseBlocks.shockMine, new ItemStack(Items.lead, 50), new ItemStack(Items.silicon, 25)) .setDependencies(Items.blastCompound); //TURRETS - new Recipe(weapon, TurretBlocks.duo, new ItemStack(Items.copper, 40)).setAlwaysUnlocked(true); - new Recipe(weapon, TurretBlocks.arc, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 30), new ItemStack(Items.silicon, 20)); - new Recipe(weapon, TurretBlocks.hail, new ItemStack(Items.copper, 60), new ItemStack(Items.densealloy, 35)); - new Recipe(weapon, TurretBlocks.lancer, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 90)); - new Recipe(weapon, TurretBlocks.wave, new ItemStack(Items.densealloy, 60), new ItemStack(Items.titanium, 70), new ItemStack(Items.lead, 150)); - new Recipe(weapon, TurretBlocks.salvo, new ItemStack(Items.copper, 210), new ItemStack(Items.densealloy, 190), new ItemStack(Items.thorium, 130)); - new Recipe(weapon, TurretBlocks.swarmer, new ItemStack(Items.densealloy, 70), new ItemStack(Items.titanium, 70), new ItemStack(Items.plastanium, 90), new ItemStack(Items.silicon, 60)); - new Recipe(weapon, TurretBlocks.ripple, new ItemStack(Items.copper, 300), new ItemStack(Items.densealloy, 220), new ItemStack(Items.thorium, 120)); - new Recipe(weapon, TurretBlocks.cyclone, new ItemStack(Items.copper, 400), new ItemStack(Items.densealloy, 400), new ItemStack(Items.surgealloy, 200), new ItemStack(Items.plastanium, 150)); - new Recipe(weapon, TurretBlocks.fuse, new ItemStack(Items.copper, 450), new ItemStack(Items.densealloy, 450), new ItemStack(Items.surgealloy, 250)); - new Recipe(weapon, TurretBlocks.spectre, new ItemStack(Items.copper, 700), new ItemStack(Items.densealloy, 600), new ItemStack(Items.surgealloy, 500), new ItemStack(Items.plastanium, 350), new ItemStack(Items.thorium, 500)); - new Recipe(weapon, TurretBlocks.meltdown, new ItemStack(Items.copper, 500), new ItemStack(Items.lead, 700), new ItemStack(Items.densealloy, 600), new ItemStack(Items.surgealloy, 650), new ItemStack(Items.silicon, 650)); + new Recipe(turret, TurretBlocks.duo, new ItemStack(Items.copper, 40)).setAlwaysUnlocked(true); + new Recipe(turret, TurretBlocks.arc, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 30), new ItemStack(Items.silicon, 20)); + new Recipe(turret, TurretBlocks.hail, new ItemStack(Items.copper, 60), new ItemStack(Items.densealloy, 35)); + new Recipe(turret, TurretBlocks.lancer, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 90)); + new Recipe(turret, TurretBlocks.wave, new ItemStack(Items.densealloy, 60), new ItemStack(Items.titanium, 70), new ItemStack(Items.lead, 150)); + new Recipe(turret, TurretBlocks.salvo, new ItemStack(Items.copper, 210), new ItemStack(Items.densealloy, 190), new ItemStack(Items.thorium, 130)); + new Recipe(turret, TurretBlocks.swarmer, new ItemStack(Items.densealloy, 70), new ItemStack(Items.titanium, 70), new ItemStack(Items.plastanium, 90), new ItemStack(Items.silicon, 60)); + new Recipe(turret, TurretBlocks.ripple, new ItemStack(Items.copper, 300), new ItemStack(Items.densealloy, 220), new ItemStack(Items.thorium, 120)); + new Recipe(turret, TurretBlocks.cyclone, new ItemStack(Items.copper, 400), new ItemStack(Items.densealloy, 400), new ItemStack(Items.surgealloy, 200), new ItemStack(Items.plastanium, 150)); + new Recipe(turret, TurretBlocks.fuse, new ItemStack(Items.copper, 450), new ItemStack(Items.densealloy, 450), new ItemStack(Items.surgealloy, 250)); + new Recipe(turret, TurretBlocks.spectre, new ItemStack(Items.copper, 700), new ItemStack(Items.densealloy, 600), new ItemStack(Items.surgealloy, 500), new ItemStack(Items.plastanium, 350), new ItemStack(Items.thorium, 500)); + new Recipe(turret, TurretBlocks.meltdown, new ItemStack(Items.copper, 500), new ItemStack(Items.lead, 700), new ItemStack(Items.densealloy, 600), new ItemStack(Items.surgealloy, 650), new ItemStack(Items.silicon, 650)); //DISTRIBUTION new Recipe(distribution, DistributionBlocks.conveyor, new ItemStack(Items.copper, 1)).setAlwaysUnlocked(true); new Recipe(distribution, DistributionBlocks.titaniumconveyor, new ItemStack(Items.copper, 2), new ItemStack(Items.titanium, 1)); new Recipe(distribution, DistributionBlocks.phaseConveyor, new ItemStack(Items.phasefabric, 10), new ItemStack(Items.silicon, 15), new ItemStack(Items.lead, 20), new ItemStack(Items.densealloy, 20)); - //starter lead transportation + //starter transport new Recipe(distribution, DistributionBlocks.junction, new ItemStack(Items.copper, 2)).setAlwaysUnlocked(true); new Recipe(distribution, DistributionBlocks.router, new ItemStack(Items.copper, 6)).setAlwaysUnlocked(true); - //advanced densealloy transporation + //advanced densealloy transporat new Recipe(distribution, DistributionBlocks.distributor, new ItemStack(Items.densealloy, 8), new ItemStack(Items.copper, 8)); new Recipe(distribution, DistributionBlocks.sorter, new ItemStack(Items.densealloy, 4), new ItemStack(Items.copper, 4)); new Recipe(distribution, DistributionBlocks.overflowGate, new ItemStack(Items.densealloy, 4), new ItemStack(Items.copper, 8)); new Recipe(distribution, DistributionBlocks.itemBridge, new ItemStack(Items.densealloy, 8), new ItemStack(Items.copper, 8)); - new Recipe(distribution, DistributionBlocks.massDriver, new ItemStack(Items.densealloy, 400), new ItemStack(Items.silicon, 300), new ItemStack(Items.lead, 400), new ItemStack(Items.thorium, 250)); + new Recipe(distribution, DistributionBlocks.massDriver, new ItemStack(Items.densealloy, 250), new ItemStack(Items.silicon, 150), new ItemStack(Items.lead, 250), new ItemStack(Items.thorium, 100)); //CRAFTING @@ -131,9 +134,6 @@ public class Recipes implements ContentList{ new Recipe(power, PowerBlocks.thoriumReactor, new ItemStack(Items.lead, 600), new ItemStack(Items.silicon, 400), new ItemStack(Items.densealloy, 300), new ItemStack(Items.thorium, 300)); new Recipe(power, PowerBlocks.rtgGenerator, new ItemStack(Items.lead, 200), new ItemStack(Items.silicon, 150), new ItemStack(Items.phasefabric, 50), new ItemStack(Items.plastanium, 150), new ItemStack(Items.thorium, 100)); - new Recipe(distribution, StorageBlocks.unloader, new ItemStack(Items.densealloy, 50), new ItemStack(Items.silicon, 60)); - new Recipe(distribution, StorageBlocks.container, new ItemStack(Items.densealloy, 200)); - new Recipe(distribution, StorageBlocks.vault, new ItemStack(Items.densealloy, 500), new ItemStack(Items.thorium, 250)); //core disabled due to being broken /*new Recipe(distribution, StorageBlocks.core, new ItemStack(Items.copper, 2000), new ItemStack(Items.densealloy, 1500), @@ -153,16 +153,16 @@ public class Recipes implements ContentList{ //UNITS - //bodies - new Recipe(units, UpgradeBlocks.dartPad, new ItemStack(Items.lead, 150), new ItemStack(Items.copper, 150), new ItemStack(Items.silicon, 200), new ItemStack(Items.titanium, 240)).setVisible(RecipeVisibility.desktopOnly); - new Recipe(units, UpgradeBlocks.tridentPad, new ItemStack(Items.lead, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250), new ItemStack(Items.titanium, 300), new ItemStack(Items.plastanium, 200)); - new Recipe(units, UpgradeBlocks.javelinPad, new ItemStack(Items.lead, 350), new ItemStack(Items.silicon, 450), new ItemStack(Items.titanium, 500), new ItemStack(Items.plastanium, 400), new ItemStack(Items.phasefabric, 200)); - new Recipe(units, UpgradeBlocks.glaivePad, new ItemStack(Items.lead, 450), new ItemStack(Items.silicon, 650), new ItemStack(Items.titanium, 700), new ItemStack(Items.plastanium, 600), new ItemStack(Items.surgealloy, 200)); + //upgrades + new Recipe(upgrade, UpgradeBlocks.dartPad, new ItemStack(Items.lead, 150), new ItemStack(Items.copper, 150), new ItemStack(Items.silicon, 200), new ItemStack(Items.titanium, 240)).setVisible(RecipeVisibility.desktopOnly); + new Recipe(upgrade, UpgradeBlocks.tridentPad, new ItemStack(Items.lead, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250), new ItemStack(Items.titanium, 300), new ItemStack(Items.plastanium, 200)); + new Recipe(upgrade, UpgradeBlocks.javelinPad, new ItemStack(Items.lead, 350), new ItemStack(Items.silicon, 450), new ItemStack(Items.titanium, 500), new ItemStack(Items.plastanium, 400), new ItemStack(Items.phasefabric, 200)); + new Recipe(upgrade, UpgradeBlocks.glaivePad, new ItemStack(Items.lead, 450), new ItemStack(Items.silicon, 650), new ItemStack(Items.titanium, 700), new ItemStack(Items.plastanium, 600), new ItemStack(Items.surgealloy, 200)); - new Recipe(units, UpgradeBlocks.alphaPad, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 100), new ItemStack(Items.copper, 150)).setVisible(RecipeVisibility.mobileOnly); - new Recipe(units, UpgradeBlocks.tauPad, new ItemStack(Items.lead, 250), new ItemStack(Items.densealloy, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250)); - new Recipe(units, UpgradeBlocks.deltaPad, new ItemStack(Items.lead, 350), new ItemStack(Items.densealloy, 350), new ItemStack(Items.copper, 400), new ItemStack(Items.silicon, 450), new ItemStack(Items.thorium, 300)); - new Recipe(units, UpgradeBlocks.omegaPad, new ItemStack(Items.lead, 450), new ItemStack(Items.densealloy, 550), new ItemStack(Items.silicon, 650), new ItemStack(Items.thorium, 600), new ItemStack(Items.surgealloy, 240)); + new Recipe(upgrade, UpgradeBlocks.alphaPad, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 100), new ItemStack(Items.copper, 150)).setVisible(RecipeVisibility.mobileOnly); + new Recipe(upgrade, UpgradeBlocks.tauPad, new ItemStack(Items.lead, 250), new ItemStack(Items.densealloy, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250)); + new Recipe(upgrade, UpgradeBlocks.deltaPad, new ItemStack(Items.lead, 350), new ItemStack(Items.densealloy, 350), new ItemStack(Items.copper, 400), new ItemStack(Items.silicon, 450), new ItemStack(Items.thorium, 300)); + new Recipe(upgrade, UpgradeBlocks.omegaPad, new ItemStack(Items.lead, 450), new ItemStack(Items.densealloy, 550), new ItemStack(Items.silicon, 650), new ItemStack(Items.thorium, 600), new ItemStack(Items.surgealloy, 240)); //actual unit related stuff new Recipe(units, UnitBlocks.spiritFactory, new ItemStack(Items.copper, 70), new ItemStack(Items.lead, 110), new ItemStack(Items.silicon, 130)); 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/DistributionBlocks.java b/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java index 15904f7e09..4739347791 100644 --- a/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java @@ -33,9 +33,9 @@ public class DistributionBlocks extends BlockList implements ContentList{ }}; phaseConveyor = new ItemBridge("phase-conveyor"){{ - range = 11; + range = 12; hasPower = true; - consumes.powerDirect(0.05f); + consumes.powerDirect(0.03f); }}; sorter = new Sorter("sorter"); @@ -50,8 +50,8 @@ public class DistributionBlocks extends BlockList implements ContentList{ massDriver = new MassDriver("mass-driver"){{ size = 3; - itemCapacity = 80; - range = 340f; + itemCapacity = 60; + range = 440f; }}; } } diff --git a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java index b489a21611..1e3b9933fb 100644 --- a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java @@ -69,9 +69,9 @@ public class LiquidBlocks extends BlockList implements ContentList{ }}; phaseConduit = new LiquidBridge("phase-conduit"){{ - range = 11; + range = 12; hasPower = true; - consumes.powerDirect(0.05f); + consumes.powerDirect(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 6e3fc0dc03..4655f8fa12 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 = 7 / 30f; + powerUsed = 10f; consumes.powerBuffered(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/blocks/UnitBlocks.java b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java index 54560e6ab9..22717f12ef 100644 --- a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java @@ -21,7 +21,7 @@ public class UnitBlocks extends BlockList implements ContentList{ produceTime = 5700; size = 2; consumes.powerDirect(0.08f); - consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)}); + consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)); }}; phantomFactory = new UnitFactory("phantom-factory"){{ @@ -29,7 +29,7 @@ public class UnitBlocks extends BlockList implements ContentList{ produceTime = 7300; size = 2; consumes.powerDirect(0.2f); - consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 70), new ItemStack(Items.lead, 80), new ItemStack(Items.titanium, 80)}); + consumes.items(new ItemStack(Items.silicon, 70), new ItemStack(Items.lead, 80), new ItemStack(Items.titanium, 80)); }}; wraithFactory = new UnitFactory("wraith-factory"){{ @@ -37,7 +37,7 @@ public class UnitBlocks extends BlockList implements ContentList{ produceTime = 1800; size = 2; consumes.powerDirect(0.1f); - consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 10), new ItemStack(Items.titanium, 10)}); + consumes.items(new ItemStack(Items.silicon, 10), new ItemStack(Items.titanium, 10)); }}; ghoulFactory = new UnitFactory("ghoul-factory"){{ @@ -46,7 +46,7 @@ public class UnitBlocks extends BlockList implements ContentList{ size = 3; consumes.powerDirect(0.2f); shadow = "shadow-round-3"; - consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 30), new ItemStack(Items.titanium, 30), new ItemStack(Items.plastanium, 20)}); + consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.titanium, 30), new ItemStack(Items.plastanium, 20)); }}; revenantFactory = new UnitFactory("revenant-factory"){{ @@ -55,7 +55,7 @@ public class UnitBlocks extends BlockList implements ContentList{ size = 4; consumes.powerDirect(0.3f); shadow = "shadow-round-4"; - consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 80), new ItemStack(Items.titanium, 80), new ItemStack(Items.plastanium, 50)}); + consumes.items(new ItemStack(Items.silicon, 80), new ItemStack(Items.titanium, 80), new ItemStack(Items.plastanium, 50)); }}; daggerFactory = new UnitFactory("dagger-factory"){{ @@ -63,7 +63,7 @@ public class UnitBlocks extends BlockList implements ContentList{ produceTime = 1700; size = 2; consumes.powerDirect(0.05f); - consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 10)}); + consumes.items(new ItemStack(Items.silicon, 10)); }}; titanFactory = new UnitFactory("titan-factory"){{ @@ -72,7 +72,7 @@ public class UnitBlocks extends BlockList implements ContentList{ size = 3; consumes.powerDirect(0.15f); shadow = "shadow-round-3"; - consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 20), new ItemStack(Items.thorium, 30)}); + consumes.items(new ItemStack(Items.silicon, 20), new ItemStack(Items.thorium, 30)); }}; fortressFactory = new UnitFactory("fortress-factory"){{ @@ -81,7 +81,7 @@ public class UnitBlocks extends BlockList implements ContentList{ size = 3; consumes.powerDirect(0.2f); shadow = "shadow-round-3"; - consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 40), new ItemStack(Items.thorium, 50)}); + consumes.items(new ItemStack(Items.silicon, 40), new ItemStack(Items.thorium, 50)); }}; repairPoint = new RepairPoint("repair-point"){{ 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 450773f1d3..0db265aa67 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -89,7 +89,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 ); @@ -111,15 +111,6 @@ public class Control extends Module{ } state.set(State.playing); - - if(world.getSector() == null && !Settings.getBool("custom-warning-for-real-1", false)){ - threads.runGraphics(() -> ui.showInfo("$mode.custom.warning", () -> - ui.showInfo("$mode.custom.warning.read", () -> { - Settings.putBool("custom-warning-for-real-1", true); - Settings.save(); - }))); - - } }); Events.on(WorldLoadGraphicsEvent.class, event -> { @@ -382,6 +373,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 08b9f9de43..efc8b0a500 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -1,10 +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; @@ -33,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; @@ -378,4 +385,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 ab1c29244c..27e8fd3569 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -28,6 +28,7 @@ import io.anuke.ucore.scene.ui.TextField.TextFieldFilter; import io.anuke.ucore.scene.ui.TooltipManager; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Unit; +import io.anuke.ucore.util.Strings; import static io.anuke.mindustry.Vars.*; import static io.anuke.ucore.scene.actions.Actions.*; @@ -122,6 +123,8 @@ public class UI extends SceneModule{ @Override public void update(){ + if(disableUI) return; + if(Graphics.drawing()) Graphics.end(); act(); @@ -293,4 +296,16 @@ public class UI extends SceneModule{ dialog.keyDown(Keys.BACK, dialog::hide); dialog.show(); } + + public String formatAmount(int number){ + if(number >= 1000000){ + return Strings.toFixed(number / 1000000f, 1) + "[gray]mil[]"; + }else if(number >= 10000){ + return number / 1000 + "[gray]k[]"; + }else if(number >= 1000){ + return Strings.toFixed(number / 1000f, 1) + "[gray]k[]"; + }else{ + return number + ""; + } + } } 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 376a8591de..a83bfcc18f 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 || !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 35c254ce2a..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); } @@ -350,19 +334,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{ @Override public void drawOver(){ trail.draw(Palette.lightTrail, 3f); - - 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(); - } - drawBuilding(this); } diff --git a/core/src/io/anuke/mindustry/game/ContentUnlockSet.java b/core/src/io/anuke/mindustry/game/ContentUnlockSet.java deleted file mode 100644 index a779c52509..0000000000 --- a/core/src/io/anuke/mindustry/game/ContentUnlockSet.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.anuke.mindustry.game; - -import com.badlogic.gdx.utils.ObjectMap; -import com.badlogic.gdx.utils.ObjectSet; -import io.anuke.mindustry.game.EventType.UnlockEvent; -import io.anuke.mindustry.type.ContentType; -import io.anuke.ucore.core.Events; - -public class ContentUnlockSet { - private ObjectMap> unlocked = new ObjectMap<>(); - private boolean dirty; - - public boolean isUnlocked(UnlockableContent content){ - if(content.alwaysUnlocked()) return true; - - if(!unlocked.containsKey(content.getContentType())){ - unlocked.put(content.getContentType(), new ObjectSet<>()); - } - - ObjectSet set = unlocked.get(content.getContentType()); - - return set.contains(content.getContentName()); - } - - public boolean unlockContent(UnlockableContent content){ - if(!content.canBeUnlocked() || content.alwaysUnlocked()) return false; - - if(!unlocked.containsKey(content.getContentType())){ - unlocked.put(content.getContentType(), new ObjectSet<>()); - } - - boolean ret = unlocked.get(content.getContentType()).add(content.getContentName()); - - //fire unlock event so other classes can use it - if(ret){ - content.onUnlock(); - Events.fire(new UnlockEvent(content)); - dirty = true; - } - - return ret; - } - - public boolean isDirty() { - return dirty; - } - - public ObjectMap> getUnlocked() { - return unlocked; - } -} diff --git a/core/src/io/anuke/mindustry/game/Unlocks.java b/core/src/io/anuke/mindustry/game/Unlocks.java index e2bbd5984b..ff2853f59b 100644 --- a/core/src/io/anuke/mindustry/game/Unlocks.java +++ b/core/src/io/anuke/mindustry/game/Unlocks.java @@ -4,16 +4,15 @@ import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap.Entry; import com.badlogic.gdx.utils.ObjectSet; -import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.game.EventType.UnlockEvent; import io.anuke.mindustry.type.ContentType; +import io.anuke.ucore.core.Events; import io.anuke.ucore.core.Settings; -import static io.anuke.mindustry.Vars.*; - /**Stores player unlocks. Clientside only.*/ public class Unlocks{ - private ObjectMap sets = new ObjectMap<>(); + private ObjectMap> unlocked = new ObjectMap<>(); + private boolean dirty; static{ Settings.setSerializer(ContentType.class, (stream, t) -> stream.writeInt(t.ordinal()), stream -> ContentType.values()[stream.readInt()]); @@ -21,7 +20,15 @@ public class Unlocks{ /** Returns whether or not this piece of content is unlocked yet.*/ public boolean isUnlocked(UnlockableContent content){ - return rootSet().isUnlocked(content) || currentSet().isUnlocked(content); + if(content.alwaysUnlocked()) return true; + + if(!unlocked.containsKey(content.getContentType())){ + unlocked.put(content.getContentType(), new ObjectSet<>()); + } + + ObjectSet set = unlocked.get(content.getContentType()); + + return set.contains(content.getContentName()); } /** @@ -32,77 +39,59 @@ public class Unlocks{ * @return whether or not this content was newly unlocked. */ public boolean unlockContent(UnlockableContent content){ - return !rootSet().isUnlocked(content) && currentSet().unlockContent(content); - } + if(!content.canBeUnlocked() || content.alwaysUnlocked()) return false; - private ContentUnlockSet currentSet(){ - //client connected to server: always return the IP-specific set - if(Net.client()){ - return getSet(Net.getLastIP()); - }else if((world.getSector() != null || state.mode.infiniteResources) || state.is(State.menu)){ //sector-sandbox have shared set - return rootSet(); - }else{ //per-mode set - return getSet(state.mode.name()); + if(!unlocked.containsKey(content.getContentType())){ + unlocked.put(content.getContentType(), new ObjectSet<>()); } - } - private ContentUnlockSet rootSet(){ - return getSet("root"); - } + boolean ret = unlocked.get(content.getContentType()).add(content.getContentName()); - private ContentUnlockSet getSet(String name){ - if(!sets.containsKey(name)){ - sets.put(name, new ContentUnlockSet()); + //fire unlock event so other classes can use it + if(ret){ + content.onUnlock(); + Events.fire(new UnlockEvent(content)); + dirty = true; } - return sets.get(name); + + return ret; } /** Returns whether unlockables have changed since the last save.*/ public boolean isDirty(){ - for(ContentUnlockSet set : sets.values()){ - if(set.isDirty()){ - return true; - } - } - return false; + return dirty; } /** Clears all unlocked content. Automatically saves.*/ public void reset(){ - sets.clear(); save(); } - public void load(){ - sets.clear(); - - ObjectMap>> result = Settings.getObject("content-sets", ObjectMap.class, ObjectMap::new); - - for(Entry>> outer : result.entries()){ - ContentUnlockSet cset = new ContentUnlockSet(); - for (Entry> entry : outer.value.entries()){ - ObjectSet set = new ObjectSet<>(); - set.addAll(entry.value); - cset.getUnlocked().put(entry.key, set); + /**Loads 'legacy' unlocks. Will be removed in final release.*/ + public void tryLoadLegacy(){ + try{ + ObjectMap>> sets = Settings.getObject("content-sets", ObjectMap.class, ObjectMap::new); + for(Entry> entry : sets.get("root").entries()){ + unlocked.put(entry.key, new ObjectSet<>()); + unlocked.get(entry.key).addAll(entry.value); } - sets.put(outer.key, cset); + }catch(Throwable t){ + t.printStackTrace(); + } + Settings.prefs().remove("content-sets"); + Settings.save(); + } + + public void load(){ + unlocked = Settings.getObject("unlockset", ObjectMap.class, ObjectMap::new); + + if(Settings.has("content-sets")){ + tryLoadLegacy(); } } public void save(){ - ObjectMap>> output = new ObjectMap<>(); - - for(Entry centry : sets.entries()){ - ObjectMap> write = new ObjectMap<>(); - - for(Entry> entry : centry.value.getUnlocked().entries()){ - write.put(entry.key, entry.value.iterator().toArray()); - } - - output.put(centry.key, write); - } - - Settings.putObject("content-sets", output); + Settings.putObject("unlockset", unlocked); Settings.save(); } 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 2b34127e2a..5b679ccdf4 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -21,7 +21,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; private FloorRenderer floorRenderer; diff --git a/core/src/io/anuke/mindustry/graphics/CacheLayer.java b/core/src/io/anuke/mindustry/graphics/CacheLayer.java index e83d65df6a..4a13487541 100644 --- a/core/src/io/anuke/mindustry/graphics/CacheLayer.java +++ b/core/src/io/anuke/mindustry/graphics/CacheLayer.java @@ -65,7 +65,7 @@ public enum CacheLayer{ protected void beginShader(){ //renderer.getBlocks().endFloor(); - renderer.effectSurface.getBuffer().bind(); + renderer.effectSurface.getBuffer().begin(); Graphics.clear(Color.CLEAR); //renderer.getBlocks().beginFloor(); } @@ -73,7 +73,9 @@ public enum CacheLayer{ public void endShader(Shader shader){ renderer.blocks.endFloor(); - renderer.pixelSurface.getBuffer().bind(); + //renderer.effectSurface.getBuffer().end(); + + renderer.pixelSurface.getBuffer().begin(); Graphics.shader(shader); Graphics.begin(); diff --git a/core/src/io/anuke/mindustry/graphics/Palette.java b/core/src/io/anuke/mindustry/graphics/Palette.java index 645df794e6..437a36034c 100644 --- a/core/src/io/anuke/mindustry/graphics/Palette.java +++ b/core/src/io/anuke/mindustry/graphics/Palette.java @@ -29,6 +29,7 @@ public class Palette{ lightishGray = Color.valueOf("a2a2a2"), darkishGray = new Color(0.3f, 0.3f, 0.3f, 1f), + darkerGray = new Color(0.2f, 0.2f, 0.2f, 1f), boostTo = Color.valueOf("ffad4d"), boostFrom = Color.valueOf("ff7f57"), 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 84b1563b22..111b2f9718 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -25,7 +25,7 @@ import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Timers; -import io.anuke.ucore.scene.Group; +import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Translator; @@ -145,7 +145,7 @@ public abstract class InputHandler extends InputAdapter{ return false; } - public void buildUI(Group group){ + public void buildUI(Table table){ } @@ -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 0197d323e0..ea26deb6b0 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -30,8 +30,7 @@ import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.*; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; -import io.anuke.ucore.scene.Group; -import io.anuke.ucore.scene.event.Touchable; +import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; @@ -208,78 +207,53 @@ public class MobileInput extends InputHandler implements GestureListener{ //region UI and drawing @Override - public void buildUI(Group group){ + public void buildUI(Table table){ + table.addImage("blank").color(Palette.accent).height(3f).colspan(4).growX(); + table.row(); + table.left().margin(0f).defaults().size(48f); - //Create confirm/cancel table - group.fill(c -> { - c.bottom().left().visible(() -> !state.is(State.menu)); + table.addImageButton("icon-break", "clear-toggle-partial", 16 * 2f, () -> { + mode = mode == breaking ? recipe == null ? none : placing : breaking; + lastRecipe = recipe; + if(mode == breaking){ + showGuide("deconstruction"); + } + }).update(l -> l.setChecked(mode == breaking)); - c.table("pane", act -> { - act.margin(5); - act.defaults().size(60f); + //rotate button + table.addImageButton("icon-arrow", "clear-partial", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4)) + .update(i -> i.getImage().setRotationOrigin(rotation * 90, Align.center)) + .visible(() -> recipe != null && recipe.result.rotate); - //Add a cancel button - act.addImageButton("icon-cancel", 16*2f, () -> { - mode = none; - recipe = null; - }); + //cancel button + table.addImageButton("icon-cancel", "clear-partial", 16 * 2f, () -> { + player.clearBuilding(); + mode = none; + recipe = null; + }).visible(() -> player.isBuilding() || recipe != null || mode == breaking); - act.row(); + //confirm button + table.addImageButton("icon-check", "clear-partial", 16 * 2f, () -> { + for(PlaceRequest request : selection){ + Tile tile = request.tile(); - //Add an accept button, which places everything. - act.addImageButton("icon-check", 16 * 2f, () -> { - for(PlaceRequest request : selection){ - Tile tile = request.tile(); - - //actually place/break all selected blocks - if(tile != null){ - if(!request.remove){ - rotation = request.rotation; - recipe = request.recipe; - tryPlaceBlock(tile.x, tile.y); - }else{ - tryBreakBlock(tile.x, tile.y); - } - } + //actually place/break all selected blocks + if(tile != null){ + if(!request.remove){ + rotation = request.rotation; + recipe = request.recipe; + tryPlaceBlock(tile.x, tile.y); + }else{ + tryBreakBlock(tile.x, tile.y); } + } + } - //move all current requests to removal array so they fade out - removals.addAll(selection); - selection.clear(); - selecting = false; - }).disabled(i -> selection.size == 0); - - act.row(); - - //Add a rotate button - act.addImageButton("icon-arrow", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4)) - .update(i -> i.getImage().setRotationOrigin(rotation * 90, Align.center)) - .disabled(i -> recipe == null || !recipe.result.rotate); - }).visible(() -> mode != none).touchable(Touchable.enabled); - - c.row(); - - c.table("pane", remove -> { - remove.defaults().size(60f); - - //Add a break button. - remove.addImageButton("icon-break", "toggle", 16 * 2f, () -> { - mode = mode == breaking ? recipe == null ? none : placing : breaking; - lastRecipe = recipe; - if(mode == breaking){ - showGuide("deconstruction"); - } - }).update(l -> l.setChecked(mode == breaking)); - }).margin(5).touchable(Touchable.enabled); - - c.table("pane", cancel -> { - cancel.defaults().size(60f); - - //Add a 'cancel building' button. - cancel.addImageButton("icon-cancel", 16 * 2f, player::clearBuilding); - - }).left().colspan(2).margin(5).touchable(Touchable.enabled).visible(() -> player.getPlaceQueue().size > 0); - }); + //move all current requests to removal array so they fade out + removals.addAll(selection); + selection.clear(); + selecting = false; + }).visible(() -> !selection.isEmpty()); } @Override @@ -554,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)){ @@ -574,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 14ab812242..bdf55a0888 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -66,7 +66,7 @@ public class Net{ }else if(error.contains("connection refused") || error.contains("route to host") || type.contains("unknownhost")){ error = Bundles.get("text.error.unreachable"); }else if(type.contains("timeout")){ - error = Bundles.get("text.error.timeout"); + error = Bundles.get("text.error.timedout"); }else if(error.equals("alreadyconnected")){ error = Bundles.get("text.error.alreadyconnected"); }else if(!error.isEmpty()){ @@ -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/Category.java b/core/src/io/anuke/mindustry/type/Category.java index 6d75054b2f..6e5f7a621a 100644 --- a/core/src/io/anuke/mindustry/type/Category.java +++ b/core/src/io/anuke/mindustry/type/Category.java @@ -1,5 +1,24 @@ package io.anuke.mindustry.type; public enum Category{ - weapon, production, distribution, liquid, power, defense, crafting, units + /**Offensive turrets.*/ + turret, + /**Blocks that produce raw resources, such as drills.*/ + production, + /**Blocks that move items around.*/ + distribution, + /**Blocks that move liquids around.*/ + liquid, + /**Blocks that generate or transport power.*/ + power, + /**Walls and other defensive structures.*/ + defense, + /**Blocks that craft things.*/ + crafting, + /**Blocks that create units.*/ + units, + /**Things that upgrade the player such as mech pads.*/ + upgrade, + /**Things for storage or passive effects.*/ + effect } 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/type/Recipe.java b/core/src/io/anuke/mindustry/type/Recipe.java index eed821961c..daa84726e7 100644 --- a/core/src/io/anuke/mindustry/type/Recipe.java +++ b/core/src/io/anuke/mindustry/type/Recipe.java @@ -23,6 +23,7 @@ import static io.anuke.mindustry.Vars.*; public class Recipe extends UnlockableContent{ private static ObjectMap recipeMap = new ObjectMap<>(); + private static Array returnArray = new Array<>(); public final Block result; public final ItemStack[] requirements; @@ -55,34 +56,15 @@ public class Recipe extends UnlockableContent{ recipeMap.put(result, this); } - /** - * Returns unlocked recipes in a category. - * Do not call on the server backend, as unlocking does not exist! - */ - public static void getUnlockedByCategory(Category category, Array arr){ - if(headless){ - throw new RuntimeException("Not implemented on the headless backend!"); - } - - arr.clear(); - for(Recipe r : content.recipes()){ - if(r.category == category && (control.unlocks.isUnlocked(r)) && - !((r.mode != null && r.mode != state.mode) || !r.visibility.shown())){ - arr.add(r); - } - } - } - - /** - * Returns all recipes in a category. - */ - public static void getByCategory(Category category, Array r){ - r.clear(); + /**Returns all non-hidden recipes in a category.*/ + public static Array getByCategory(Category category){ + returnArray.clear(); for(Recipe recipe : content.recipes()){ - if(recipe.category == category){ - r.add(recipe); + if(recipe.category == category && recipe.visibility.shown() && (recipe.mode == state.mode || recipe.mode == null)){ + returnArray.add(recipe); } } + return returnArray; } public static Recipe getByResult(Block block){ @@ -109,7 +91,6 @@ public class Recipe extends UnlockableContent{ return this; } - @Override public boolean alwaysUnlocked(){ return alwaysUnlocked; diff --git a/core/src/io/anuke/mindustry/ui/ImageStack.java b/core/src/io/anuke/mindustry/ui/ImageStack.java new file mode 100644 index 0000000000..2ca0063e48 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/ImageStack.java @@ -0,0 +1,14 @@ +package io.anuke.mindustry.ui; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import io.anuke.ucore.scene.ui.Image; +import io.anuke.ucore.scene.ui.layout.Stack; + +public class ImageStack extends Stack{ + + public ImageStack(TextureRegion... regions){ + for(TextureRegion region : regions){ + add(new Image(region)); + } + } +} diff --git a/core/src/io/anuke/mindustry/ui/ItemDisplay.java b/core/src/io/anuke/mindustry/ui/ItemDisplay.java new file mode 100644 index 0000000000..4530d606f0 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/ItemDisplay.java @@ -0,0 +1,18 @@ +package io.anuke.mindustry.ui; + +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.ItemStack; +import io.anuke.ucore.scene.ui.layout.Table; + +/**An item image with text.*/ +public class ItemDisplay extends Table{ + + public ItemDisplay(Item item){ + this(item, 0); + } + + public ItemDisplay(Item item, int amount){ + add(new ItemImage(new ItemStack(item, amount))).size(8*3); + add(item.localizedName()).padLeft(4); + } +} diff --git a/core/src/io/anuke/mindustry/ui/ItemImage.java b/core/src/io/anuke/mindustry/ui/ItemImage.java index 709c2903c2..130916cb26 100644 --- a/core/src/io/anuke/mindustry/ui/ItemImage.java +++ b/core/src/io/anuke/mindustry/ui/ItemImage.java @@ -18,10 +18,12 @@ public class ItemImage extends Stack{ } public ItemImage(ItemStack stack){ - Table t = new Table().left().bottom(); - t.add(stack.amount + ""); - add(new Image(stack.item.region)); - add(t); + + if(stack.amount != 0){ + Table t = new Table().left().bottom(); + t.add(stack.amount + ""); + add(t); + } } } diff --git a/core/src/io/anuke/mindustry/ui/LiquidDisplay.java b/core/src/io/anuke/mindustry/ui/LiquidDisplay.java new file mode 100644 index 0000000000..f639dfe1c5 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/LiquidDisplay.java @@ -0,0 +1,14 @@ +package io.anuke.mindustry.ui; + +import io.anuke.mindustry.type.Liquid; +import io.anuke.ucore.scene.ui.Image; +import io.anuke.ucore.scene.ui.layout.Table; + +/**An ItemDisplay, but for liquids.*/ +public class LiquidDisplay extends Table{ + + public LiquidDisplay(Liquid liquid){ + add(new Image(liquid.getContentIcon())).size(8*3); + add(liquid.localizedName()).padLeft(3); + } +} diff --git a/core/src/io/anuke/mindustry/ui/SelectionTable.java b/core/src/io/anuke/mindustry/ui/SelectionTable.java deleted file mode 100644 index 27e41eeb43..0000000000 --- a/core/src/io/anuke/mindustry/ui/SelectionTable.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.anuke.mindustry.ui; - -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.OreBlock; -import io.anuke.ucore.core.Graphics; -import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.scene.style.TextureRegionDrawable; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.layout.Table; -import io.anuke.ucore.util.Mathf; - -import static io.anuke.mindustry.Vars.world; - -public class SelectionTable extends Table{ - Tile lastTile; - - public SelectionTable(){ - super("clear"); - - margin(5f); - - update(() -> { - Block result; - Tile tile = world.tileWorld(Graphics.mouseWorld().x, Graphics.mouseWorld().y); - if(tile != null){ - tile = tile.target(); - result = tile.block().synthetic() ? tile.block() : tile.floor() instanceof OreBlock ? tile.floor() : null; - }else{ - result = null; - } - - if(result != null){ - lastTile = tile; - } - - getTranslation().y = Mathf.lerp(getTranslation().y, result == null ? -getHeight() : 0f, 0.2f); - }); - - Image image = new Image(new TextureRegionDrawable(new TextureRegion(Draw.region("clear")))); - image.update(() -> - ((TextureRegionDrawable)image.getDrawable()).setRegion(lastTile == null ? Draw.getBlankRegion() : - (lastTile.block().synthetic() ? lastTile.block() : lastTile.floor()).getDisplayIcon(lastTile))); - - add(image).size(8*5).padRight(4); - label(() -> lastTile == null ? "" : (lastTile.block().synthetic() ? lastTile.block() : lastTile.floor()).getDisplayName(lastTile)); - - pack(); - getTranslation().y = - getHeight(); - } -} 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/dialogs/UnlocksDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java index 4d9411c4df..8b46947740 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java @@ -6,10 +6,10 @@ import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.type.ContentType; -import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.scene.event.HandCursorListener; import io.anuke.ucore.scene.ui.Image; import io.anuke.ucore.scene.ui.ScrollPane; +import io.anuke.ucore.scene.ui.Tooltip; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.utils.UIUtils; @@ -65,7 +65,10 @@ public class UnlocksDialog extends FloatingDialog{ if(control.unlocks.isUnlocked(unlock)){ image.clicked(() -> Vars.ui.content.show(unlock)); - StatValue.addToolTip(image, unlock); + image.addListener(new Tooltip<>(new Table("clear"){{ + add(unlock.localizedName()); + margin(4); + }})); } if((++count) % maxWidth == 0){ diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java index 6faed6e1ba..e193b04ed2 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java @@ -180,7 +180,9 @@ public class BlockInventoryFragment extends Fragment{ private String round(float f){ f = (int) f; - if(f >= 1000){ + if(f >= 1000000){ + return Strings.toFixed(f / 1000000f, 1) + "[gray]mil[]"; + }else if(f >= 1000){ return Strings.toFixed(f / 1000, 1) + "k"; }else{ return (int) f + ""; diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java deleted file mode 100644 index 50c63e4596..0000000000 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ /dev/null @@ -1,349 +0,0 @@ -package io.anuke.mindustry.ui.fragments; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.math.Interpolation; -import com.badlogic.gdx.utils.Array; -import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.game.EventType.WorldLoadEvent; -import io.anuke.mindustry.input.InputHandler; -import io.anuke.mindustry.type.Category; -import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.type.Recipe; -import io.anuke.ucore.core.Core; -import io.anuke.ucore.core.Events; -import io.anuke.ucore.core.Graphics; -import io.anuke.ucore.scene.Element; -import io.anuke.ucore.scene.Group; -import io.anuke.ucore.scene.actions.Actions; -import io.anuke.ucore.scene.event.ClickListener; -import io.anuke.ucore.scene.event.InputEvent; -import io.anuke.ucore.scene.event.Touchable; -import io.anuke.ucore.scene.ui.*; -import io.anuke.ucore.scene.ui.layout.Stack; -import io.anuke.ucore.scene.ui.layout.Table; -import io.anuke.ucore.util.Mathf; -import io.anuke.ucore.util.Strings; - -import static io.anuke.mindustry.Vars.*; - -public class BlocksFragment extends Fragment{ - //number of block icon rows - private static final int rows = 4; - //number of category button rows - private static final int secrows = 4; - //size of each block icon - private static final float size = 48; - //maximum recipe rows - private static final int maxrow = 3; - /** Table containing description that is shown on top.*/ - private Table descTable; - /** Main table containing the whole menu.*/ - private Table mainTable; - /** Table for all section buttons and blocks.*/ - private Table selectTable; - /** Whether the whole thing is shown or hidden by the popup button.*/ - private boolean shown = true; - /** Recipe currently hovering over.*/ - private Recipe hoverRecipe; - /** Last category selected.*/ - private Category lastCategory; - /** Last block pane scroll Y position.*/ - private float lastScroll; - /** Temporary recipe array for storage*/ - private Array recipes = new Array<>(); - - public void build(Group parent){ - InputHandler input = control.input(0); - - parent.fill(container -> { - container.bottom().right().visible(() -> !state.is(State.menu)); - - mainTable = container.table(main -> { - - //add top description table - descTable = new Table("button"); - descTable.visible(() -> (hoverRecipe != null || input.recipe != null) && shown); //make sure it's visible when necessary - descTable.update(() -> { - if(state.is(State.menu)){ - descTable.clear(); - control.input(0).recipe = null; - } - // note: This is required because there is no direct connection between input.recipe and the description ui. - // If input.recipe gets set to null, a proper cleanup of the ui elements is required. - boolean anyRecipeShown = input.recipe != null || hoverRecipe != null; - boolean descriptionTableClean = descTable.getChildren().size == 0; - boolean cleanupRequired = (!anyRecipeShown && !descriptionTableClean); - if(cleanupRequired){ - descTable.clear(); - } - }); - - float w = 246f; - - main.add(descTable).width(w); - - main.row(); - - //now add the block selection menu - selectTable = main.table("pane", select -> {}) - .margin(10f).marginLeft(0f).marginRight(0f).marginTop(-5) - .touchable(Touchable.enabled).right().bottom().width(w).get(); - - }).bottom().right().get(); - }); - - Events.on(WorldLoadEvent.class, event -> rebuild()); - - rebuild(); - } - - /**Rebuilds the whole placement menu, attempting to preserve previous state.*/ - void rebuild(){ - selectTable.clear(); - - InputHandler input = control.input(0); - Stack stack = new Stack(); - ButtonGroup group = new ButtonGroup<>(); - Table catTable = selectTable; - - int cati = 0; - int checkedi = 0; - int rowsUsed = 0; - - //add categories - for(Category cat : Category.values()){ - //get recipes out by category - Recipe.getUnlockedByCategory(cat, recipes); - - //empty section, nothing to see here - if(recipes.size == 0){ - continue; - } - - //table where actual recipes go - Table recipeTable = new Table(); - recipeTable.margin(4).top().left().marginRight(15); - - //add a new row here when needed - if(cati % secrows == 0){ - catTable = new Table(); - selectTable.row(); - selectTable.add(catTable).colspan(secrows).padTop(-5).growX(); - } - - //add category button - ImageButton catb = catTable.addImageButton("icon-" + cat.name(), "toggle", 40, () -> { - if(!recipeTable.isVisible() && input.recipe != null){ - input.recipe = null; - } - lastCategory = cat; - stack.act(Gdx.graphics.getDeltaTime()); - stack.act(Gdx.graphics.getDeltaTime()); - }).growX().height(54).group(group) - .name("sectionbutton" + cat.name()).get(); - - if(lastCategory == cat || lastCategory == null){ - checkedi = cati; - lastCategory = cat; - } - - //scrollpane for recipes - ScrollPane pane = new ScrollPane(recipeTable, "clear-black"); - pane.setOverscroll(false, false); - pane.visible(catb::isChecked); - pane.setScrollYForce(lastScroll); - pane.update(() -> { - Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true); - if(e != null && e.isDescendantOf(pane)){ - Core.scene.setScrollFocus(pane); - }else if(Core.scene.getScrollFocus() == pane){ - Core.scene.setScrollFocus(null); - } - - if(lastCategory == cat){ - lastScroll = pane.getVisualScrollY(); - } - }); - stack.add(pane); - - int i = 0; - - //add actual recipes - for(Recipe r : recipes){ - if((r.mode != null && r.mode != state.mode) || !r.visibility.shown()) continue; - - ImageButton image = new ImageButton(new TextureRegion(), "select"); - - TextureRegion[] regions = r.result.getCompactIcon(); - Stack istack = new Stack(); - for(TextureRegion region : regions){ - Image u = new Image(region); - u.update(() -> u.setColor(istack.getColor())); - istack.add(u); - } - - image.getImageCell().setActor(istack).size(size); - image.addChild(istack); - image.setTouchable(Touchable.enabled); - image.getImage().remove(); - - image.addListener(new ClickListener(){ - @Override - public void enter(InputEvent event, float x, float y, int pointer, Element fromActor){ - super.enter(event, x, y, pointer, fromActor); - if(hoverRecipe != r){ - hoverRecipe = r; - updateRecipe(r); - } - } - - @Override - public void exit(InputEvent event, float x, float y, int pointer, Element toActor){ - super.exit(event, x, y, pointer, toActor); - hoverRecipe = null; - updateRecipe(input.recipe); - } - }); - - image.clicked(() -> { - // note: input.recipe only gets set here during a click. - // during a hover only the visual description will be updated. - InputHandler handler = mobile ? input : control.input(0); - - boolean nothingSelectedYet = handler.recipe == null; - boolean selectedSomethingElse = !nothingSelectedYet && handler.recipe != r; - boolean shouldMakeSelection = nothingSelectedYet || selectedSomethingElse; - if(shouldMakeSelection){ - handler.recipe = r; - hoverRecipe = r; - updateRecipe(r); - }else{ - handler.recipe = null; - hoverRecipe = null; - updateRecipe(null); - } - }); - - recipeTable.add(image).size(size + 8); - - image.update(() -> { - image.setChecked(r == control.input(0).recipe); - TileEntity entity = players[0].getClosestCore(); - - if(entity == null) return; - - if(!state.mode.infiniteResources){ - for(ItemStack s : r.requirements){ - if(!entity.items.has(s.item, Mathf.ceil(s.amount))){ - istack.setColor(Color.GRAY); - return; - } - } - } - istack.setColor(Color.WHITE); - }); - - if(i % rows == rows - 1){ - rowsUsed = Math.max((i + 1) / rows, rowsUsed); - recipeTable.row(); - } - - i++; - } - - cati++; - } - - if(group.getButtons().size > 0){ - group.getButtons().get(checkedi).setChecked(true); - } - - selectTable.row(); - selectTable.add(stack).growX().left().top().colspan(Category.values().length).padBottom(-5).height((size + 12) * Math.min(rowsUsed, 3)); - } - - void toggle(float t, Interpolation ip){ - if(shown){ - shown = false; - mainTable.actions(Actions.translateBy(0, mainTable.getTranslation().y + (-mainTable.getHeight() - descTable.getHeight()), t, ip)); - }else{ - shown = true; - mainTable.actions(Actions.translateBy(0, -mainTable.getTranslation().y, t, ip)); - } - } - - private void updateRecipe(Recipe recipe){ - if(recipe == null){ - descTable.clear(); - return; - } - - descTable.clear(); - descTable.setTouchable(Touchable.enabled); - - descTable.defaults().left(); - descTable.left(); - descTable.margin(12); - - Table header = new Table(); - - descTable.add(header).left(); - - descTable.row(); - - TextureRegion[] regions = recipe.result.getCompactIcon(); - - Stack istack = new Stack(); - - for(TextureRegion region : regions) istack.add(new Image(region)); - - header.add(istack).size(8 * 5).padTop(4); - Label nameLabel = new Label(recipe.result.formalName); - nameLabel.setWrap(true); - header.add(nameLabel).padLeft(2).width(120f); - - header.addButton("?", () -> ui.content.show(recipe)).expandX().padLeft(3).top().right().size(40f, 44f).padTop(-2); - - descTable.add().pad(2); - - Table requirements = new Table(); - - descTable.row(); - - descTable.left(); - descTable.add(requirements); - - for(ItemStack stack : recipe.requirements){ - requirements.addImage(stack.item.region).size(8 * 3); - Label reqlabel = new Label(() -> { - TileEntity core = players[0].getClosestCore(); - if(core == null || state.mode.infiniteResources) return "*/*"; - - int amount = core.items.get(stack.item); - String color = (amount < stack.amount / 2f ? "[red]" : amount < stack.amount ? "[accent]" : "[white]"); - - return color + format(amount) + "[white]/" + stack.amount; - }); - - requirements.add(reqlabel).left(); - requirements.row(); - } - - descTable.row(); - } - - String format(int number){ - if(number >= 1000000){ - return Strings.toFixed(number / 1000000f, 1) + "[gray]mil[]"; - }else if(number >= 10000){ - return number / 1000 + "[gray]k[]"; - }else if(number >= 1000){ - return Strings.toFixed(number / 1000f, 1) + "[gray]k[]"; - }else{ - return number + ""; - } - } -} \ No newline at end of file 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/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 3da203e15a..0aa55b3a29 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -16,7 +16,6 @@ import io.anuke.mindustry.net.Packets.AdminAction; import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.ui.IntFormat; import io.anuke.mindustry.ui.Minimap; -import io.anuke.mindustry.ui.SelectionTable; import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.ucore.core.*; import io.anuke.ucore.graphics.Hue; @@ -33,7 +32,7 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; public class HudFragment extends Fragment{ - public final BlocksFragment blockfrag = new BlocksFragment(); + public final PlacementFragment blockfrag = new PlacementFragment(); private ImageButton menu, flip; private Stack wavetable; @@ -199,12 +198,6 @@ public class HudFragment extends Fragment{ t.add("$text.saveload"); }); - //tapped block indicator - parent.fill(t -> { - t.bottom().visible(() -> !state.is(State.menu)); - t.add(new SelectionTable()); - }); - blockfrag.build(Core.scene.getRoot()); } @@ -231,7 +224,6 @@ public class HudFragment extends Fragment{ /**Show unlock notification for a new recipe.*/ public void showUnlock(Recipe recipe){ - blockfrag.rebuild(); //if there's currently no unlock notification... if(lastUnlockTable == null){ 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/OverlayFragment.java b/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java index fd861518ad..f19ec137a4 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java @@ -31,7 +31,7 @@ public class OverlayFragment extends Fragment{ config.build(group); consume.build(group); - input.buildUI(group); + //input.buildUI(group); } public void remove(){ diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java new file mode 100644 index 0000000000..6388b3ee28 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java @@ -0,0 +1,242 @@ +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; +import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.input.InputHandler; +import io.anuke.mindustry.type.Category; +import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.type.Recipe; +import io.anuke.mindustry.ui.ImageStack; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.OreBlock; +import io.anuke.ucore.core.Events; +import io.anuke.ucore.core.Graphics; +import io.anuke.ucore.scene.Group; +import io.anuke.ucore.scene.actions.Actions; +import io.anuke.ucore.scene.event.Touchable; +import io.anuke.ucore.scene.ui.ButtonGroup; +import io.anuke.ucore.scene.ui.Image; +import io.anuke.ucore.scene.ui.ImageButton; +import io.anuke.ucore.scene.ui.layout.Table; +import io.anuke.ucore.util.Bundles; + +import static io.anuke.mindustry.Vars.*; + +public class PlacementFragment extends Fragment{ + final int rowWidth = 4; + + Category currentCategory = Category.turret; + Block hovered, lastDisplay; + Tile hoverTile; + Table blockTable, toggler, topTable; + boolean shown = true; + + public PlacementFragment(){ + Events.on(WorldLoadGraphicsEvent.class, event -> { + Group group = toggler.getParent(); + toggler.remove(); + build(group); + }); + } + + @Override + public void build(Group parent){ + parent.fill(full -> { + toggler = full; + full.bottom().right().visible(() -> !state.is(State.menu)); + + full.table(frame -> { + InputHandler input = control.input(0); + + //rebuilds the category table with the correct recipes + Runnable rebuildCategory = () -> { + blockTable.clear(); + blockTable.top().margin(5); + + int index = 0; + + ButtonGroup group = new ButtonGroup<>(); + group.setMinCheckCount(0); + + for(Recipe recipe : Recipe.getByCategory(currentCategory)){ + + if(index++ % rowWidth == 0){ + blockTable.row(); + } + + boolean[] unlocked = {false}; + + ImageButton button = blockTable.addImageButton("icon-locked", "select", 8*4, () -> { + if(control.unlocks.isUnlocked(recipe)){ + input.recipe = input.recipe == recipe ? null : recipe; + } + }).size(46f).group(group).get(); + + button.update(() -> { //color unplacable things gray + boolean ulock = control.unlocks.isUnlocked(recipe); + TileEntity core = players[0].getClosestCore(); + Color color = core != null && (core.items.has(recipe.requirements) || state.mode.infiniteResources) ? Color.WHITE : ulock ? Color.GRAY : Color.WHITE; + button.forEach(elem -> elem.setColor(color)); + button.setChecked(input.recipe == recipe); + + if(ulock == unlocked[0]) return; + unlocked[0] = ulock; + + if(!ulock){ + button.replaceImage(new Image("icon-locked")); + }else{ + button.replaceImage(new ImageStack(recipe.result.getCompactIcon())); + } + }); + + button.hovered(() -> hovered = recipe.result); + button.exited(() -> { + if(hovered == recipe.result){ + hovered = null; + } + }); + } + blockTable.act(0f); + }; + + //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; + + topTable.clear(); + topTable.top().left().margin(5); + + lastDisplay = getSelected(); + + if(lastDisplay != null){ //show selected recipe + topTable.table(header -> { + header.left(); + header.add(new ImageStack(lastDisplay.getCompactIcon())).size(8*4); + header.labelWrap(() -> + !control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay)) ? Bundles.get("text.blocks.unknown") : lastDisplay.formalName) + .left().width(190f).padLeft(5); + header.add().growX(); + if(control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay))){ + header.addButton("?", "clear-partial", () -> ui.content.show(Recipe.getByResult(lastDisplay))) + .size(8 * 5).padTop(-5).padRight(-5).right().grow(); + } + }).growX().left(); + topTable.row(); + //add requirement table + topTable.table(req -> { + req.top().left(); + + for(ItemStack stack : Recipe.getByResult(lastDisplay).requirements){ + req.table(line -> { + line.left(); + line.addImage(stack.item.region).size(8*2); + line.add(stack.item.localizedName()).color(Color.LIGHT_GRAY).padLeft(2).left(); + line.labelWrap(() -> { + TileEntity core = players[0].getClosestCore(); + if(core == null || state.mode.infiniteResources) return "*/*"; + + int amount = core.items.get(stack.item); + String color = (amount < stack.amount / 2f ? "[red]" : amount < stack.amount ? "[accent]" : "[white]"); + + return color + ui.formatAmount(amount) + "[white]/" + stack.amount; + }).padLeft(5); + }).left(); + req.row(); + } + }).growX().left().margin(3); + + }else if(tileDisplayBlock() != null){ //show selected tile + lastDisplay = tileDisplayBlock(); + topTable.add(new ImageStack(lastDisplay.getDisplayIcon(hoverTile))).size(8*4); + topTable.labelWrap(lastDisplay.getDisplayName(hoverTile)).left().width(190f).padLeft(5); + } + }); + top.row(); + top.addImage("blank").growX().color(Palette.accent).height(3f); + }).colspan(3).fillX().visible(() -> getSelected() != null || tileDisplayBlock() != null).touchable(Touchable.enabled); + frame.row(); + frame.table("clear", blocksSelect -> { + blocksSelect.table(blocks -> blockTable = blocks).grow(); + blocksSelect.row(); + blocksSelect.table(input::buildUI).growX(); + }).fillY().bottom().touchable(Touchable.enabled); + frame.addImage("blank").width(3f).fillY().color(Palette.accent); + frame.table(categories -> { + categories.defaults().size(50f); + + ButtonGroup group = new ButtonGroup<>(); + + for(Category cat : Category.values()){ + if(Recipe.getByCategory(cat).isEmpty()) continue; + + categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16*2, () -> { + currentCategory = cat; + rebuildCategory.run(); + }).group(group); + + if(cat.ordinal() %2 == 1) categories.row(); + } + }).touchable(Touchable.enabled); + + rebuildCategory.run(); + }); + }); + } + + /**Returns the currently displayed block in the top box.*/ + Block getSelected(){ + Block toDisplay = null; + + Vector2 v = topTable.stageToLocalCoordinates(Graphics.mouse()); + + //setup hovering tile + 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(); + }else{ + hoverTile = null; + } + }else{ + hoverTile = null; + } + + //block currently selected + if(control.input(0).recipe != null){ + toDisplay = control.input(0).recipe.result; + } + + //block hovered on in build menu + if(hovered != null){ + toDisplay = hovered; + } + + return toDisplay; + } + + /**Returns the block currently being hovered over in the world.*/ + Block tileDisplayBlock(){ + return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.floor() instanceof OreBlock ? hoverTile.floor() : null; + } + + /**Show or hide the placement menu.*/ + void toggle(float t, Interpolation ip){ + toggler.clearActions(); + if(shown){ + shown = false; + toggler.actions(Actions.translateBy(toggler.getTranslation().x + toggler.getWidth(), 0, t, ip)); + }else{ + shown = true; + toggler.actions(Actions.translateBy(-toggler.getTranslation().x, 0, t, ip)); + } + } +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index 9a1b7dbfb1..a18292309b 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -46,7 +46,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 e00bd316d4..21ee395822 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -154,7 +154,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); } } @@ -336,7 +336,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(consumes.has(ConsumePower.class)){ bars.add(new BlockBar(BarType.power, true, tile -> tile.entity.power.satisfaction)); 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/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java index f5a1ba14e9..2d23ec889b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java @@ -42,7 +42,7 @@ public class BuildBlock extends Block{ super(name); update = true; size = Integer.parseInt(name.charAt(name.length() - 1) + ""); - health = 1; + health = 10; layer = Layer.placement; consumesTap = true; solidifes = true; @@ -118,15 +118,6 @@ public class BuildBlock extends Block{ } } - @Override - public void afterDestroyed(Tile tile, TileEntity e){ - BuildEntity entity = (BuildEntity) e; - - if(entity.previous != null && entity.previous.synthetic()){ - tile.setBlock(entity.previous); - } - } - @Override public void draw(Tile tile){ BuildEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/Floor.java b/core/src/io/anuke/mindustry/world/blocks/Floor.java index fd4d581f2d..8c27abc074 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/Floor.java @@ -181,7 +181,7 @@ public class Floor extends Block{ Floor floor = other.floor(); - if((floor.id <= this.id && !(tile.getElevation() != -1 && other.getElevation() > tile.getElevation())) || (!blends.test(floor) && !tileBlends.test(tile, other)) || (floor.cacheLayer.ordinal() > this.cacheLayer.ordinal() && !sameLayer) || + if(floor.edgeRegions == null || (floor.id <= this.id && !(tile.getElevation() != -1 && other.getElevation() > tile.getElevation())) || (!blends.test(floor) && !tileBlends.test(tile, other)) || (floor.cacheLayer.ordinal() > this.cacheLayer.ordinal() && !sameLayer) || (sameLayer && floor.cacheLayer == this.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 4e7e57cc03..07f16b8767 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/Drill.java b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java index f0232c5cf3..212a71168b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java @@ -16,14 +16,11 @@ import io.anuke.mindustry.world.consumers.ConsumeLiquid; import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; -import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.layout.Cell; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.content; @@ -135,8 +132,9 @@ public class Drill extends Block{ for(int i = 0; i < list.size; i++){ Item item = list.get(i); - Cell imageCell = table.addImage(item.name + "1").size(8 * 3).padRight(2).padLeft(2).padTop(3).padBottom(3); - StatValue.addToolTip(imageCell.getElement(), item); + + table.addImage(item.name + "1").size(8 * 3).padRight(2).padLeft(2).padTop(3).padBottom(3); + table.add(item.localizedName()); if(i != list.size - 1){ table.add("/"); } 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 9aec5498de..2fd27ace54 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java @@ -52,7 +52,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/consumers/Consumers.java b/core/src/io/anuke/mindustry/world/consumers/Consumers.java index 75b91a98e4..6d602da3e3 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consumers.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consumers.java @@ -87,7 +87,7 @@ public class Consumers{ return i; } - public ConsumeItems items(ItemStack[] items){ + public ConsumeItems items(ItemStack... items){ ConsumeItems i = new ConsumeItems(items); add(i); return i; 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/core/src/io/anuke/mindustry/world/meta/StatValue.java b/core/src/io/anuke/mindustry/world/meta/StatValue.java index ef3e51acef..df53cc2947 100644 --- a/core/src/io/anuke/mindustry/world/meta/StatValue.java +++ b/core/src/io/anuke/mindustry/world/meta/StatValue.java @@ -1,10 +1,5 @@ package io.anuke.mindustry.world.meta; -import io.anuke.mindustry.game.UnlockableContent; -import io.anuke.ucore.scene.Element; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.Tooltip; -import io.anuke.ucore.scene.ui.layout.Cell; import io.anuke.ucore.scene.ui.layout.Table; /** @@ -13,37 +8,7 @@ import io.anuke.ucore.scene.ui.layout.Table; public interface StatValue{ /** * This method should provide all elements necessary to display this stat to the specified table. - * For example, a stat that is just text would add label to the table. + * For example, a stat that is just text would add a label to the table. */ void display(Table table); - - /** - * This method adds an icon image together with a tool tip which contains the name of the item. - * @param table the table to add the image cell to. - * @param item The item which provides the tool tip content. - * @return the image cell which was created. The cell is not yet sized or padded. - */ - static Cell addImageWithToolTip(Table table, UnlockableContent item){ - - // Create a table cell with a new image as provided by the item - Cell imageCell = table.addImage(item.getContentIcon()); - - // Retrieve the image and add a tool tip with the item's name - addToolTip(imageCell.getElement(), item); - - // Return the table cell for further processing (sizing, padding, ...) - return imageCell; - } - - /** - * Adds a tool tip containing the item's localized name to the given element. - * @param element The element to assign the tool tip to. - * @param item The item which provides the tool tip content. - */ - static void addToolTip(Element element, UnlockableContent item){ - element.addListener(new Tooltip<>(new Table("clear"){{ - add(item.localizedName()); - margin(4); - }})); - } } diff --git a/core/src/io/anuke/mindustry/world/meta/values/ItemFilterValue.java b/core/src/io/anuke/mindustry/world/meta/values/ItemFilterValue.java index 669f5baa2c..0f917dda71 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/ItemFilterValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/ItemFilterValue.java @@ -2,12 +2,12 @@ package io.anuke.mindustry.world.meta.values; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.ui.ItemDisplay; import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.function.Predicate; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.layout.Cell; import io.anuke.ucore.scene.ui.layout.Table; -import static io.anuke.mindustry.Vars.*; + +import static io.anuke.mindustry.Vars.content; public class ItemFilterValue implements StatValue{ private final Predicate filter; @@ -27,10 +27,7 @@ public class ItemFilterValue implements StatValue{ for(int i = 0; i < list.size; i++){ Item item = list.get(i); - Cell imageCell = table.addImage(item.region); - imageCell.size(8 * 3).padRight(2).padLeft(2); - - StatValue.addToolTip(imageCell.getElement(), item); + table.add(new ItemDisplay(item)).padRight(5); if(i != list.size - 1){ table.add("/"); diff --git a/core/src/io/anuke/mindustry/world/meta/values/ItemListValue.java b/core/src/io/anuke/mindustry/world/meta/values/ItemListValue.java index 7cb237296f..af9ab67af2 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/ItemListValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/ItemListValue.java @@ -3,11 +3,8 @@ package io.anuke.mindustry.world.meta.values; import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.ui.ItemImage; +import io.anuke.mindustry.ui.ItemDisplay; import io.anuke.mindustry.world.meta.ContentStatValue; -import io.anuke.mindustry.world.meta.StatValue; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.layout.Cell; import io.anuke.ucore.scene.ui.layout.Table; public class ItemListValue implements ContentStatValue{ @@ -41,17 +38,11 @@ public class ItemListValue implements ContentStatValue{ public void display(Table table){ if(items != null){ for(Item item : items){ - Cell imageCell = table.addImage(item.region); - imageCell.size(8 * 3).padRight(5); - - StatValue.addToolTip(imageCell.getElement(), item); + table.add(new ItemDisplay(item)).padRight(5); } }else{ for(ItemStack stack : stacks){ - ItemImage image = new ItemImage(stack); - table.add(image).size(8 * 3).padRight(5); - - StatValue.addToolTip(image, stack.item); + table.add(new ItemDisplay(stack.item, stack.amount)).padRight(5); } } } diff --git a/core/src/io/anuke/mindustry/world/meta/values/ItemValue.java b/core/src/io/anuke/mindustry/world/meta/values/ItemValue.java index 269c537dc5..2b54142976 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/ItemValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/ItemValue.java @@ -3,9 +3,8 @@ package io.anuke.mindustry.world.meta.values; import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.ui.ItemImage; +import io.anuke.mindustry.ui.ItemDisplay; import io.anuke.mindustry.world.meta.ContentStatValue; -import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.scene.ui.layout.Table; public class ItemValue implements ContentStatValue{ @@ -22,9 +21,6 @@ public class ItemValue implements ContentStatValue{ @Override public void display(Table table){ - //TODO better implementation, quantity support - ItemImage image = new ItemImage(item); - table.add(image).size(8 * 3); - StatValue.addToolTip(image, item.item); + table.add(new ItemDisplay(item.item, item.amount)); } } diff --git a/core/src/io/anuke/mindustry/world/meta/values/LiquidFilterValue.java b/core/src/io/anuke/mindustry/world/meta/values/LiquidFilterValue.java index 9dc6a6bd0b..7c5d638be9 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/LiquidFilterValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/LiquidFilterValue.java @@ -2,13 +2,12 @@ package io.anuke.mindustry.world.meta.values; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.type.Liquid; +import io.anuke.mindustry.ui.LiquidDisplay; import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.function.Predicate; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.Tooltip; -import io.anuke.ucore.scene.ui.layout.Cell; import io.anuke.ucore.scene.ui.layout.Table; -import static io.anuke.mindustry.Vars.*; + +import static io.anuke.mindustry.Vars.content; public class LiquidFilterValue implements StatValue{ private final Predicate filter; @@ -26,10 +25,7 @@ public class LiquidFilterValue implements StatValue{ } for(int i = 0; i < list.size; i++){ - Liquid item = list.get(i); - - Cell imageCell = StatValue.addImageWithToolTip(table, item); - imageCell.size(8 * 3).padRight(2).padLeft(2).padTop(2).padBottom(2); + table.add(new LiquidDisplay(list.get(i))).padRight(5); if(i != list.size - 1){ table.add("/"); diff --git a/core/src/io/anuke/mindustry/world/meta/values/LiquidValue.java b/core/src/io/anuke/mindustry/world/meta/values/LiquidValue.java index d4d6734511..0dcc6c03c7 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/LiquidValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/LiquidValue.java @@ -2,10 +2,8 @@ package io.anuke.mindustry.world.meta.values; import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.type.Liquid; +import io.anuke.mindustry.ui.LiquidDisplay; import io.anuke.mindustry.world.meta.ContentStatValue; -import io.anuke.mindustry.world.meta.StatValue; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.layout.Cell; import io.anuke.ucore.scene.ui.layout.Table; public class LiquidValue implements ContentStatValue{ @@ -22,7 +20,6 @@ public class LiquidValue implements ContentStatValue{ @Override public void display(Table table){ - Cell imageCell = StatValue.addImageWithToolTip(table, liquid); - imageCell.size(8 * 3); + table.add(new LiquidDisplay(liquid)); } } 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."); }