diff --git a/TODO.md b/TODO.md index 2bcf9d426e..30004d9774 100644 --- a/TODO.md +++ b/TODO.md @@ -86,7 +86,7 @@ _(not necessarily planned!)_ - Spawn points changed into enemy bases with hostile turrets - Unit production -### Optmiziation +### Optimization - Look into uses for `IntMap` - Spread updating over multiple frames for large groups of specific tile entities (?) - Optimize enemy + bullet code and check quadtree leaf parameters diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java index 18b98c3c97..80bddad31f 100644 --- a/android/src/io/anuke/mindustry/AndroidLauncher.java +++ b/android/src/io/anuke/mindustry/AndroidLauncher.java @@ -1,5 +1,6 @@ package io.anuke.mindustry; +import java.text.DateFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Date; @@ -21,7 +22,6 @@ import io.anuke.ucore.scene.ui.layout.Unit; public class AndroidLauncher extends AndroidApplication{ boolean doubleScaleTablets = true; - @SuppressLint("SimpleDateFormat") @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); @@ -30,7 +30,7 @@ public class AndroidLauncher extends AndroidApplication{ Mindustry.hasDiscord = isPackageInstalled("com.discord"); Mindustry.platforms = new PlatformFunction(){ - SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm"); + DateFormat format = SimpleDateFormat.getDateTimeInstance(); @Override public String format(Date date){ diff --git a/android/src/io/anuke/mindustry/TextFieldDialogListener.java b/android/src/io/anuke/mindustry/TextFieldDialogListener.java index bb2e935d59..7ad3ce9df5 100644 --- a/android/src/io/anuke/mindustry/TextFieldDialogListener.java +++ b/android/src/io/anuke/mindustry/TextFieldDialogListener.java @@ -9,8 +9,8 @@ import io.anuke.mindustry.AndroidTextFieldDialog.TextPromptListener; import io.anuke.ucore.scene.event.InputEvent; import io.anuke.ucore.scene.event.InputListener; import io.anuke.ucore.scene.ui.TextField; -import io.anuke.ucore.scene.utils.ChangeListener; -import io.anuke.ucore.scene.utils.ClickListener; +import io.anuke.ucore.scene.event.ChangeListener; +import io.anuke.ucore.scene.event.ClickListener; public class TextFieldDialogListener extends ClickListener{ private TextField field; diff --git a/core/assets-raw/sprites/ui/check-on-over.png b/core/assets-raw/sprites/ui/check-on-over.png new file mode 100644 index 0000000000..710e173506 Binary files /dev/null and b/core/assets-raw/sprites/ui/check-on-over.png differ diff --git a/core/assets-raw/sprites/ui/check-on.png b/core/assets-raw/sprites/ui/check-on.png index f1d36ec60c..a067b42e28 100644 Binary files a/core/assets-raw/sprites/ui/check-on.png and b/core/assets-raw/sprites/ui/check-on.png differ diff --git a/core/assets-raw/sprites/ui/check-over.png b/core/assets-raw/sprites/ui/check-over.png index d0fe60dbba..812f0c222e 100644 Binary files a/core/assets-raw/sprites/ui/check-over.png and b/core/assets-raw/sprites/ui/check-over.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-add.png b/core/assets-raw/sprites/ui/icons/icon-add.png new file mode 100644 index 0000000000..eb325782ec Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-add.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-dots.png b/core/assets-raw/sprites/ui/icons/icon-dots.png new file mode 100644 index 0000000000..8b597e0dd4 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-dots.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-floppy.png b/core/assets-raw/sprites/ui/icons/icon-floppy.png new file mode 100644 index 0000000000..8455ee3b44 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-floppy.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-rename.png b/core/assets-raw/sprites/ui/icons/icon-rename.png new file mode 100644 index 0000000000..73f3fb8391 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-rename.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-trash.png b/core/assets-raw/sprites/ui/icons/icon-trash.png new file mode 100644 index 0000000000..0f1c0ab56b Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-trash.png differ diff --git a/core/assets-raw/sprites/ui/scroll-knob-vertical-black.9.png b/core/assets-raw/sprites/ui/scroll-knob-vertical-black.9.png new file mode 100644 index 0000000000..80ace6e0c2 Binary files /dev/null and b/core/assets-raw/sprites/ui/scroll-knob-vertical-black.9.png differ diff --git a/core/assets-raw/sprites/ui/scroll-knob-vertical.9.png b/core/assets-raw/sprites/ui/scroll-knob-vertical.9.png index eb8e698147..7e8f69bce7 100644 Binary files a/core/assets-raw/sprites/ui/scroll-knob-vertical.9.png and b/core/assets-raw/sprites/ui/scroll-knob-vertical.9.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index fd7fe00c2c..c237bb4e45 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -11,14 +11,31 @@ text.level.mode=Gamemode: text.savegame=Save Game text.loadgame=Load Game text.quit=Quit +text.tutorial.back=< Prev +text.tutorial.next=Next > +text.save.new=New Save text.save.overwrite=Are you sure you want to overwrite\nthis save slot? text.overwrite=Overwrite text.saveload=[accent]Saving... text.savefail=Failed to save game! -text.selectslot=Select a save slot. +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=[orange]This save is invalid! +text.save.import.fail=[crimson]Failed to import save: [orange]{0} +text.save.export.fail=[crimson]Failed to export save: [orange]{0} +text.save.import=Import Save +text.save.newslot=Save name: +text.save.rename=Rename +text.save.rename.text=New name: +text.selectslot=Select a save. text.slot=[accent]Slot {0} text.save.corrupted=[orange]Save file corrupted or invalid! text.empty= +text.on=On +text.off=Off +text.save.autosave=Autosave: {0} +text.save.map=Map: {0} text.save.wave=Wave {0} text.save.date=Last Saved: {0} text.confirm=Confirm diff --git a/core/assets/mindustry-saves/1.mins b/core/assets/mindustry-saves/1.mins index 7b8e2ebb64..f110400b08 100644 Binary files a/core/assets/mindustry-saves/1.mins and b/core/assets/mindustry-saves/1.mins differ diff --git a/core/assets/mindustry-saves/2.mins b/core/assets/mindustry-saves/2.mins index e93e4b6fb7..c825924f54 100644 Binary files a/core/assets/mindustry-saves/2.mins and b/core/assets/mindustry-saves/2.mins differ diff --git a/core/assets/mindustry-saves/3.mins b/core/assets/mindustry-saves/3.mins new file mode 100644 index 0000000000..87c41d61fd Binary files /dev/null and b/core/assets/mindustry-saves/3.mins differ diff --git a/core/assets/mindustry-saves/4.mins b/core/assets/mindustry-saves/4.mins new file mode 100644 index 0000000000..47854a9109 Binary files /dev/null and b/core/assets/mindustry-saves/4.mins differ diff --git a/core/assets/mindustry-saves/5.mins b/core/assets/mindustry-saves/5.mins new file mode 100644 index 0000000000..833aa4a201 Binary files /dev/null and b/core/assets/mindustry-saves/5.mins differ diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 25f37e416b..d436516674 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -13,1218 +13,1218 @@ backgrounds/background index: -1 blank rotate: false - xy: 191, 105 + xy: 189, 105 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 blocks/blackrock1 rotate: false - xy: 263, 95 + xy: 519, 179 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackrockshadow1 rotate: false - xy: 646, 238 + xy: 564, 203 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone1 rotate: false - xy: 646, 228 + xy: 574, 203 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone2 rotate: false - xy: 263, 85 + xy: 501, 104 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone3 rotate: false - xy: 748, 254 + xy: 511, 104 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock1 rotate: false - xy: 575, 205 + xy: 869, 473 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock2 rotate: false - xy: 575, 195 + xy: 869, 463 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock3 rotate: false - xy: 533, 125 + xy: 869, 453 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneedge rotate: false - xy: 537, 137 + xy: 722, 382 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/block rotate: false - xy: 533, 105 + xy: 869, 433 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/block-2x2 rotate: false - xy: 761, 404 + xy: 900, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/block-3x3 rotate: false - xy: 393, 105 + xy: 698, 313 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/chainturret rotate: false - xy: 742, 385 + xy: 918, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/chainturret-icon rotate: false - xy: 1012, 501 + xy: 261, 93 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/coal1 rotate: false - xy: 543, 117 + xy: 779, 417 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal2 rotate: false - xy: 543, 107 + xy: 789, 417 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal3 rotate: false - xy: 813, 449 + xy: 547, 197 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coaldrill rotate: false - xy: 813, 439 + xy: 547, 187 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator rotate: false - xy: 813, 429 + xy: 543, 177 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator-top rotate: false - xy: 813, 419 + xy: 774, 407 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalpurifier rotate: false - xy: 333, 79 + xy: 774, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/combustiongenerator rotate: false - xy: 343, 79 + xy: 784, 407 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/compositewall rotate: false - xy: 353, 79 + xy: 784, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduit rotate: false - xy: 363, 79 + xy: 794, 407 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitbottom rotate: false - xy: 373, 79 + xy: 794, 397 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitliquid rotate: false - xy: 383, 79 + xy: 804, 409 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduittop rotate: false - xy: 393, 83 + xy: 804, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyor rotate: false - xy: 403, 83 + xy: 814, 409 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyormove rotate: false - xy: 413, 83 + xy: 814, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyortunnel rotate: false - xy: 423, 83 + xy: 824, 409 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/core rotate: false - xy: 445, 105 + xy: 727, 422 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/cross rotate: false - xy: 433, 83 + xy: 824, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/crucible rotate: false - xy: 443, 83 + xy: 834, 409 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/deepwater rotate: false - xy: 453, 83 + xy: 834, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt1 rotate: false - xy: 463, 83 + xy: 844, 409 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt2 rotate: false - xy: 473, 83 + xy: 844, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt3 rotate: false - xy: 483, 83 + xy: 854, 409 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirtedge rotate: false - xy: 519, 121 + xy: 127, 64 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/door rotate: false - xy: 575, 185 + xy: 854, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/door-large rotate: false - xy: 742, 367 + xy: 954, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/door-large-icon rotate: false - xy: 393, 73 + xy: 864, 409 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/door-large-open rotate: false - xy: 724, 346 + xy: 972, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/door-open rotate: false - xy: 403, 73 + xy: 864, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/doubleturret rotate: false - xy: 833, 487 + xy: 552, 219 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/duriumwall rotate: false - xy: 413, 73 + xy: 774, 314 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/duriumwall-large rotate: false - xy: 742, 349 + xy: 990, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/duriumwall-large-icon rotate: false - xy: 423, 73 + xy: 774, 304 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/enemyspawn rotate: false - xy: 433, 73 + xy: 125, 31 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/flameturret rotate: false - xy: 845, 487 + xy: 261, 81 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/fluxpump rotate: false - xy: 453, 73 + xy: 153, 76 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass1 rotate: false - xy: 463, 73 + xy: 141, 66 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass2 rotate: false - xy: 473, 73 + xy: 141, 56 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass3 rotate: false - xy: 483, 73 + xy: 151, 66 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock1 rotate: false - xy: 598, 222 + xy: 151, 56 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock2 rotate: false - xy: 608, 222 + xy: 163, 76 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassedge rotate: false - xy: 670, 230 + xy: 127, 50 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/ice1 rotate: false - xy: 618, 222 + xy: 161, 66 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice2 rotate: false - xy: 628, 222 + xy: 161, 56 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice3 rotate: false - xy: 881, 485 + xy: 173, 78 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iceedge rotate: false - xy: 684, 229 + xy: 524, 217 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/icerock1 rotate: false - xy: 891, 485 + xy: 141, 46 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerock2 rotate: false - xy: 901, 485 + xy: 151, 46 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow1 rotate: false - xy: 911, 485 + xy: 161, 46 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow1 rotate: false - xy: 911, 485 + xy: 161, 46 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow2 rotate: false - xy: 921, 485 + xy: 273, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow2 rotate: false - xy: 921, 485 + xy: 273, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron1 rotate: false - xy: 1001, 485 + xy: 353, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron2 rotate: false - xy: 748, 244 + xy: 363, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron3 rotate: false - xy: 513, 97 + xy: 373, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/irondrill rotate: false - xy: 523, 97 + xy: 383, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ironwall rotate: false - xy: 533, 95 + xy: 393, 79 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/junction rotate: false - xy: 543, 97 + xy: 403, 79 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/laserturret rotate: false - xy: 465, 93 + xy: 552, 207 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/lava rotate: false - xy: 801, 413 + xy: 413, 79 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/lavaedge rotate: false - xy: 698, 229 + xy: 538, 217 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/lavasmelter rotate: false - xy: 800, 403 + xy: 423, 79 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquiditemjunction rotate: false - xy: 811, 409 + xy: 433, 79 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidjunction rotate: false - xy: 810, 399 + xy: 443, 79 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidrouter rotate: false - xy: 1011, 479 + xy: 453, 83 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/machineturret rotate: false - xy: 477, 93 + xy: 576, 213 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/megarepairturret rotate: false - xy: 1012, 489 + xy: 588, 216 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mortarturret rotate: false - xy: 551, 203 + xy: 600, 216 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mossblock rotate: false - xy: 112, 84 + xy: 708, 220 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/mossstone rotate: false - xy: 112, 84 + xy: 708, 220 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/nuclearreactor rotate: false - xy: 471, 105 + xy: 753, 422 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/nuclearreactor-center rotate: false - xy: 779, 464 + xy: 779, 427 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/nuclearreactor-icon rotate: false - xy: 132, 84 + xy: 479, 99 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/nuclearreactor-lights rotate: false - xy: 727, 422 + xy: 722, 396 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/nuclearreactor-small rotate: false - xy: 227, 87 + xy: 615, 278 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/oil rotate: false - xy: 142, 84 + xy: 489, 99 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/oiledge rotate: false - xy: 726, 229 + xy: 519, 189 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/oilrefinery rotate: false - xy: 152, 84 + xy: 553, 177 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/omnidrill rotate: false - xy: 162, 84 + xy: 393, 69 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/plasmaturret rotate: false - xy: 551, 191 + xy: 612, 216 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/playerspawn rotate: false - xy: 172, 80 + xy: 403, 69 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerbooster rotate: false - xy: 95, 74 + xy: 413, 69 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyor rotate: false - xy: 95, 64 + xy: 423, 69 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyormove rotate: false - xy: 105, 74 + xy: 433, 69 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaser rotate: false - xy: 95, 54 + xy: 443, 69 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlasercorner rotate: false - xy: 105, 64 + xy: 453, 73 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaserrouter rotate: false - xy: 115, 74 + xy: 463, 73 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduit rotate: false - xy: 95, 44 + xy: 473, 83 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduitbottom rotate: false - xy: 105, 54 + xy: 473, 73 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduittop rotate: false - xy: 115, 64 + xy: 594, 203 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pump rotate: false - xy: 125, 74 + xy: 604, 206 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/repairturret rotate: false - xy: 556, 215 + xy: 624, 216 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/rock1 rotate: false - xy: 105, 44 + xy: 624, 206 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rock2 rotate: false - xy: 115, 54 + xy: 634, 206 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/router rotate: false - xy: 125, 64 + xy: 453, 63 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator rotate: false - xy: 135, 74 + xy: 463, 63 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator-top rotate: false - xy: 95, 24 + xy: 473, 63 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand1 rotate: false - xy: 105, 34 + xy: 483, 89 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand2 rotate: false - xy: 115, 44 + xy: 483, 79 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand3 rotate: false - xy: 125, 54 + xy: 483, 69 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock1 rotate: false - xy: 135, 64 + xy: 493, 89 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock2 rotate: false - xy: 145, 74 + xy: 493, 79 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock3 rotate: false - xy: 95, 14 + xy: 493, 69 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandedge rotate: false - xy: 751, 301 + xy: 533, 203 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/shadow rotate: false - xy: 568, 215 + xy: 636, 216 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shieldgenerator rotate: false - xy: 115, 34 + xy: 493, 59 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shotgunturret rotate: false - xy: 563, 203 + xy: 648, 218 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shrub rotate: false - xy: 145, 64 + xy: 503, 74 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shrubshadow rotate: false - xy: 155, 74 + xy: 503, 64 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/smelter rotate: false - xy: 105, 14 + xy: 513, 94 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sniperturret rotate: false - xy: 563, 191 + xy: 660, 218 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/snow1 rotate: false - xy: 115, 24 + xy: 513, 84 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow2 rotate: false - xy: 125, 34 + xy: 513, 74 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow3 rotate: false - xy: 135, 44 + xy: 513, 64 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock1 rotate: false - xy: 145, 54 + xy: 503, 54 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock2 rotate: false - xy: 155, 64 + xy: 513, 54 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock3 rotate: false - xy: 115, 14 + xy: 644, 206 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowedge rotate: false - xy: 805, 485 + xy: 533, 189 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/sorter rotate: false - xy: 125, 24 + xy: 654, 208 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyor rotate: false - xy: 135, 34 + xy: 664, 208 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyormove rotate: false - xy: 145, 44 + xy: 674, 208 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelwall rotate: false - xy: 155, 54 + xy: 684, 208 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelwall-large rotate: false - xy: 245, 87 + xy: 633, 278 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/steelwall-large-icon rotate: false - xy: 125, 14 + xy: 694, 208 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone1 rotate: false - xy: 135, 24 + xy: 521, 104 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone2 rotate: false - xy: 145, 34 + xy: 523, 94 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone3 rotate: false - xy: 155, 44 + xy: 523, 84 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock1 rotate: false - xy: 135, 14 + xy: 523, 74 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock2 rotate: false - xy: 145, 24 + xy: 523, 64 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock3 rotate: false - xy: 155, 34 + xy: 523, 54 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonedrill rotate: false - xy: 145, 14 + xy: 704, 208 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneedge rotate: false - xy: 805, 471 + xy: 95, 2 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/stoneformer rotate: false - xy: 155, 24 + xy: 704, 291 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonewall rotate: false - xy: 155, 14 + xy: 714, 291 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter rotate: false - xy: 95, 4 + xy: 724, 291 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter-top rotate: false - xy: 105, 4 + xy: 874, 484 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/thermalgenerator rotate: false - xy: 115, 4 + xy: 884, 484 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titancannon rotate: false - xy: 753, 422 + xy: 748, 396 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/titancannon-icon rotate: false - xy: 736, 263 + xy: 672, 218 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/titanium1 rotate: false - xy: 125, 4 + xy: 879, 474 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium2 rotate: false - xy: 135, 4 + xy: 879, 464 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium3 rotate: false - xy: 145, 4 + xy: 879, 454 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumdrill rotate: false - xy: 155, 4 + xy: 879, 444 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumpurifier rotate: false - xy: 165, 70 + xy: 879, 434 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumshieldwall rotate: false - xy: 165, 60 + xy: 879, 424 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumwall rotate: false - xy: 165, 50 + xy: 894, 484 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumwall-large rotate: false - xy: 746, 331 + xy: 610, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/titaniumwall-large-icon rotate: false - xy: 165, 40 + xy: 889, 474 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/turret rotate: false - xy: 736, 251 + xy: 684, 218 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/uranium1 rotate: false - xy: 165, 10 + xy: 889, 444 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium2 rotate: false - xy: 175, 70 + xy: 889, 434 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium3 rotate: false - xy: 175, 60 + xy: 889, 424 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uraniumdrill rotate: false - xy: 175, 50 + xy: 904, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/water rotate: false - xy: 175, 40 + xy: 914, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/wateredge rotate: false - xy: 819, 485 + xy: 529, 175 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/waveturret rotate: false - xy: 748, 264 + xy: 696, 218 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 bullet rotate: false - xy: 543, 127 + xy: 869, 423 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 chainbullet rotate: false - xy: 69, 1 + xy: 800, 490 size: 8, 7 orig: 8, 7 offset: 0, 0 index: -1 circle rotate: false - xy: 742, 403 + xy: 881, 494 size: 17, 17 orig: 17, 17 offset: 0, 0 @@ -1238,350 +1238,350 @@ circle2 index: -1 enemies/blastenemy-t1 rotate: false - xy: 746, 315 + xy: 1008, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/blastenemy-t2 rotate: false - xy: 582, 229 + xy: 628, 262 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/blastenemy-t3 rotate: false - xy: 497, 98 + xy: 644, 262 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/empenemy-t1 rotate: false - xy: 597, 280 + xy: 660, 262 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/empenemy-t2 rotate: false - xy: 613, 280 + xy: 592, 244 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/empenemy-t3 rotate: false - xy: 629, 280 + xy: 608, 244 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/enemy-t1 rotate: false - xy: 645, 280 + xy: 676, 262 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/targetenemy-t1 rotate: false - xy: 645, 280 + xy: 676, 262 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/enemy-t2 rotate: false - xy: 519, 107 + xy: 95, 16 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 enemies/enemy-t3 rotate: false - xy: 656, 230 + xy: 111, 32 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 enemies/fastenemy-t1 rotate: false - xy: 661, 276 + xy: 810, 483 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/fastenemy-t2 rotate: false - xy: 677, 276 + xy: 826, 483 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/fastenemy-t3 rotate: false - xy: 592, 264 + xy: 842, 483 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/flamerenemy-t1 rotate: false - xy: 592, 248 + xy: 858, 483 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/flamerenemy-t2 rotate: false - xy: 608, 264 + xy: 805, 467 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/flamerenemy-t3 rotate: false - xy: 608, 248 + xy: 805, 451 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/fortressenemy-t1 rotate: false - xy: 779, 442 + xy: 479, 109 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 enemies/fortressenemy-t2 rotate: false - xy: 779, 420 + xy: 501, 114 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 enemies/fortressenemy-t3 rotate: false - xy: 497, 114 + xy: 147, 86 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 enemies/healerenemy-t1 rotate: false - xy: 624, 264 + xy: 821, 467 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/healerenemy-t2 rotate: false - xy: 624, 248 + xy: 805, 435 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/healerenemy-t3 rotate: false - xy: 640, 264 + xy: 821, 451 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t1 rotate: false - xy: 519, 199 + xy: 696, 230 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t2 rotate: false - xy: 519, 183 + xy: 95, 78 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t3 rotate: false - xy: 535, 199 + xy: 95, 62 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t1 rotate: false - xy: 535, 183 + xy: 111, 78 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t2 rotate: false - xy: 521, 167 + xy: 95, 46 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t3 rotate: false - xy: 521, 151 + xy: 111, 62 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t1 rotate: false - xy: 521, 135 + xy: 127, 78 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t2 rotate: false - xy: 537, 167 + xy: 95, 30 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t3 rotate: false - xy: 537, 151 + xy: 111, 46 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/titanenemy-t1 rotate: false - xy: 728, 328 + xy: 651, 278 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 enemies/titanenemy-t2 rotate: false - xy: 728, 310 + xy: 669, 278 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 enemies/titanenemy-t3 rotate: false - xy: 733, 292 + xy: 592, 260 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 enemyarrow rotate: false - xy: 79, 1 + xy: 127, 41 size: 8, 7 orig: 8, 7 offset: 0, 0 index: -1 icon-coal rotate: false - xy: 931, 485 + xy: 283, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-dirium rotate: false - xy: 941, 485 + xy: 293, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-iron rotate: false - xy: 951, 485 + xy: 303, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-steel rotate: false - xy: 961, 485 + xy: 313, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-stone rotate: false - xy: 971, 485 + xy: 323, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-titanium rotate: false - xy: 981, 485 + xy: 333, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-uranium rotate: false - xy: 991, 485 + xy: 343, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laser rotate: false - xy: 797, 406 + xy: 687, 282 size: 1, 12 orig: 1, 12 offset: 0, 0 index: -1 laserend rotate: false - xy: 722, 402 + xy: 169, 88 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 laserfull rotate: false - xy: 722, 382 + xy: 564, 225 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 mechs/mech-standard rotate: false - xy: 712, 229 + xy: 519, 203 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shell rotate: false - xy: 105, 24 + xy: 483, 59 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot rotate: false - xy: 125, 44 + xy: 503, 94 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot-long rotate: false - xy: 135, 54 + xy: 503, 84 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanshell rotate: false - xy: 165, 30 + xy: 889, 464 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1644,7 +1644,7 @@ ui/button-map-over index: -1 ui/button-select rotate: false - xy: 419, 105 + xy: 453, 105 size: 24, 24 split: 4, 4, 4, 4 orig: 24, 24 @@ -1652,105 +1652,119 @@ ui/button-select index: -1 ui/check-off rotate: false - xy: 698, 309 + xy: 273, 97 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 ui/check-on rotate: false - xy: 273, 97 + xy: 303, 97 + size: 28, 32 + orig: 28, 32 + offset: 0, 0 + index: -1 +ui/check-on-over + rotate: false + xy: 333, 97 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 ui/check-over rotate: false - xy: 303, 97 + xy: 363, 97 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 ui/clear rotate: false - xy: 819, 473 + xy: 724, 370 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/cursor rotate: false - xy: 513, 108 + xy: 736, 372 size: 4, 4 orig: 4, 4 offset: 0, 0 index: -1 ui/icons/controller-cursor rotate: false - xy: 724, 364 + xy: 936, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 +ui/icons/icon-add + rotate: false + xy: 837, 467 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 ui/icons/icon-areaDelete rotate: false - xy: 857, 487 + xy: 273, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-arrow rotate: false - xy: 640, 248 + xy: 821, 435 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-arrow-down rotate: false - xy: 869, 487 + xy: 285, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-arrow-left rotate: false - xy: 805, 459 + xy: 297, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-arrow-right rotate: false - xy: 801, 447 + xy: 309, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-arrow-up rotate: false - xy: 801, 435 + xy: 321, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-back rotate: false - xy: 779, 402 + xy: 189, 87 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-cancel rotate: false - xy: 598, 232 + xy: 837, 451 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-check rotate: false - xy: 614, 232 + xy: 853, 467 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1778,343 +1792,371 @@ ui/icons/icon-close-over index: -1 ui/icons/icon-crafting rotate: false - xy: 801, 423 + xy: 333, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-cursor rotate: false - xy: 273, 85 + xy: 345, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-defense rotate: false - xy: 285, 85 + xy: 357, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-discord rotate: false - xy: 630, 232 + xy: 837, 435 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-distribution rotate: false - xy: 297, 85 + xy: 369, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-donate rotate: false - xy: 693, 275 + xy: 853, 451 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +ui/icons/icon-dots + rotate: false + xy: 853, 435 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-editor rotate: false - xy: 709, 275 + xy: 742, 308 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-file-text rotate: false - xy: 656, 260 + xy: 758, 308 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-fill rotate: false - xy: 661, 292 + xy: 207, 87 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 +ui/icons/icon-floppy + rotate: false + xy: 584, 228 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 ui/icons/icon-folder rotate: false - xy: 672, 260 + xy: 600, 228 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-folder-parent rotate: false - xy: 656, 244 + xy: 805, 419 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-grid rotate: false - xy: 679, 292 + xy: 225, 87 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-hold rotate: false - xy: 309, 85 + xy: 381, 85 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-holdDelete rotate: false - xy: 321, 85 + xy: 393, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-home rotate: false - xy: 672, 244 + xy: 821, 419 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-info rotate: false - xy: 333, 89 + xy: 405, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-line rotate: false - xy: 697, 291 + xy: 243, 87 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-load rotate: false - xy: 688, 259 + xy: 837, 419 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-load-image rotate: false - xy: 564, 227 + xy: 736, 378 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-load-map rotate: false - xy: 886, 495 + xy: 754, 378 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-loading rotate: false - xy: 904, 495 + xy: 724, 352 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-menu rotate: false - xy: 345, 89 + xy: 417, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-none rotate: false - xy: 357, 89 + xy: 429, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-pause rotate: false - xy: 369, 89 + xy: 441, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-pencil rotate: false - xy: 922, 495 + xy: 724, 334 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-pick rotate: false - xy: 940, 495 + xy: 724, 316 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-play rotate: false - xy: 381, 89 + xy: 453, 93 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-play-2 rotate: false - xy: 704, 259 + xy: 853, 419 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-power rotate: false - xy: 393, 93 + xy: 465, 93 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-production rotate: false - xy: 405, 93 + xy: 692, 298 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-quit rotate: false - xy: 688, 243 + xy: 616, 228 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-redo rotate: false - xy: 958, 495 + xy: 742, 360 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 +ui/icons/icon-rename + rotate: false + xy: 624, 244 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 ui/icons/icon-resize rotate: false - xy: 976, 495 + xy: 742, 342 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-rotate rotate: false - xy: 704, 243 + xy: 640, 246 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-rotate-arrow rotate: false - xy: 725, 275 + xy: 656, 246 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-rotate-left rotate: false - xy: 720, 259 + xy: 672, 246 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-rotate-right rotate: false - xy: 720, 243 + xy: 632, 228 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-save rotate: false - xy: 741, 276 + xy: 648, 230 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-save-image rotate: false - xy: 994, 495 + xy: 742, 324 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-save-map rotate: false - xy: 173, 90 + xy: 760, 360 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-settings rotate: false - xy: 417, 93 + xy: 704, 301 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-terrain rotate: false - xy: 715, 291 + xy: 760, 342 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-tools rotate: false - xy: 524, 215 + xy: 664, 230 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-touch rotate: false - xy: 429, 93 + xy: 716, 301 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-touchDelete rotate: false - xy: 441, 93 + xy: 728, 304 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 +ui/icons/icon-trash + rotate: false + xy: 680, 230 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 ui/icons/icon-tutorial rotate: false - xy: 540, 215 + xy: 688, 246 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-undo rotate: false - xy: 191, 87 + xy: 760, 324 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 ui/icons/icon-weapon rotate: false - xy: 453, 93 + xy: 564, 213 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-zoom rotate: false - xy: 209, 87 + xy: 597, 278 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -2135,7 +2177,7 @@ ui/logotext-gray index: -1 ui/pane rotate: false - xy: 69, 47 + xy: 69, 9 size: 24, 36 split: 10, 10, 5, 5 orig: 24, 36 @@ -2143,7 +2185,7 @@ ui/pane index: -1 ui/pane-button rotate: false - xy: 698, 343 + xy: 69, 47 size: 24, 36 split: 10, 10, 5, 5 orig: 24, 36 @@ -2151,7 +2193,7 @@ ui/pane-button index: -1 ui/scroll rotate: false - xy: 69, 10 + xy: 779, 453 size: 24, 35 split: 10, 10, 6, 5 orig: 24, 35 @@ -2175,6 +2217,14 @@ ui/scroll-knob-horizontal offset: 0, 0 index: -1 ui/scroll-knob-vertical + rotate: false + xy: 698, 339 + size: 24, 40 + split: 10, 10, 6, 10 + orig: 24, 40 + offset: 0, 0 + index: -1 +ui/scroll-knob-vertical-black rotate: false xy: 495, 136 size: 24, 40 @@ -2184,14 +2234,14 @@ ui/scroll-knob-vertical index: -1 ui/selection rotate: false - xy: 724, 343 + xy: 92, 91 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 ui/slider rotate: false - xy: 489, 95 + xy: 547, 207 size: 1, 8 orig: 1, 8 offset: 0, 0 @@ -2219,7 +2269,7 @@ ui/slider-knob-over index: -1 ui/slider-vertical rotate: false - xy: 92, 91 + xy: 588, 213 size: 8, 1 orig: 8, 1 offset: 0, 0 @@ -2233,7 +2283,7 @@ ui/text-editor index: -1 ui/text-exit rotate: false - xy: 147, 94 + xy: 855, 499 size: 24, 12 orig: 24, 12 offset: 0, 0 @@ -2247,7 +2297,7 @@ ui/text-load index: -1 ui/text-play rotate: false - xy: 855, 499 + xy: 661, 296 size: 29, 12 orig: 29, 12 offset: 0, 0 @@ -2289,7 +2339,7 @@ ui/text-tutorial index: -1 ui/textfield rotate: false - xy: 363, 101 + xy: 423, 101 size: 28, 28 split: 6, 6, 6, 6 orig: 28, 28 @@ -2297,7 +2347,7 @@ ui/textfield index: -1 ui/textfield-over rotate: false - xy: 333, 101 + xy: 393, 101 size: 28, 28 split: 2, 2, 2, 2 orig: 28, 28 @@ -2328,42 +2378,42 @@ ui/window-empty index: -1 weapons/blaster rotate: false - xy: 533, 115 + xy: 869, 443 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/flamer rotate: false - xy: 443, 73 + xy: 143, 76 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/mortar rotate: false - xy: 102, 84 + xy: 463, 83 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/multigun rotate: false - xy: 122, 84 + xy: 584, 203 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/railgun rotate: false - xy: 95, 34 + xy: 614, 206 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/triblaster rotate: false - xy: 165, 20 + xy: 889, 454 size: 8, 8 orig: 8, 8 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 28737b07b5..adf821b168 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/assets/ui/title-font.png b/core/assets/ui/title-font.png index 9c6981db83..4542c3905f 100644 Binary files a/core/assets/ui/title-font.png and b/core/assets/ui/title-font.png differ diff --git a/core/assets/ui/uiskin.json b/core/assets/ui/uiskin.json index 8b55f5cb2a..442e2256ef 100644 --- a/core/assets/ui/uiskin.json +++ b/core/assets/ui/uiskin.json @@ -13,6 +13,7 @@ com.badlogic.gdx.graphics.Color: { red: {a: 1, b: 0, g: 0, r: 1 }, blue: {a: 1, b: 1, g: 0, r: 0 }, grey: {a: 1, b: 0.32, g: 0.32, r: 0.32 }, + lightgray: {a: 1, b: 0.3, g: 0.3, r: 0.3 }, orange: {hex: "#FFA500"}, accent: {hex: "f4ba6e"}, vis-blue: {a: 1, b: 0.886, g: 0.631, r: 0.105 }, @@ -21,8 +22,12 @@ com.badlogic.gdx.graphics.Color: { link-label: {a: 1, b: 0.886, g: 0.631, r: 0.105 } }, io.anuke.ucore.scene.Skin$TintedDrawable: { - dialogDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.9} } - loadDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.8} } + dialogDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.9} }, + invis: {name: white, color: {r: 0, g: 0, b: 0, a: 0} } + loadDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.8} }, + clear: {name: white, color: {r: 0.1, g: 0.1, b: 0.1, a: 0.7}}, + 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} } }, io.anuke.ucore.scene.ui.Button$ButtonStyle: { default: {down: button-down, up: button }, @@ -31,11 +36,14 @@ io.anuke.ucore.scene.ui.Button$ButtonStyle: { }, io.anuke.ucore.scene.ui.TextButton$TextButtonStyle: { default: {over: button-over, disabled: button, font: default-font, fontColor: white, disabledFontColor: grey, down: button-down, up: button, transition: 0 }, + clear: {down: clear-down, up: clear, over: clear-over, font: default-font, fontColor: white, disabledFontColor: grey }, + empty: {font: default-font}, toggle: {font: default-font, fontColor: white, checked: button-down, down: button-down, up: button, over: button-over, disabled: button, disabledFontColor: grey } }, io.anuke.ucore.scene.ui.ImageButton$ImageButtonStyle: { default: {down: button-down, up: button, over: button-over }, - empty: {}, + empty: { imageDownColor: accent, imageUpColor: white}, + emptytoggle: {imageCheckedColor: white, imageDownColor: white, imageUpColor: lightgray}, static: {up: button }, static-down: {up: button-down }, toggle: {checked: button-down, down: button-down, up: button }, @@ -51,14 +59,15 @@ io.anuke.ucore.scene.ui.ScrollPane$ScrollPaneStyle: { default: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical}, horizontal: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical, hScroll: scroll-horizontal, hScrollKnob: scroll-knob-horizontal}, volume: {background: button-map, vScroll: scroll, vScrollKnob: scroll-knob-vertical}, - clear: {vScroll: scroll, vScrollKnob: scroll-knob-vertical} + clear: {vScroll: scroll, vScrollKnob: scroll-knob-vertical}, + clear-black: {vScroll: scroll, vScrollKnob: scroll-knob-vertical-black} }, io.anuke.ucore.scene.ui.Window$WindowStyle: { - default: {titleFont: default-font, background: window, titleFontColor: orange }, + default: {titleFont: default-font, background: window, titleFontColor: accent }, dialog: {stageBackground: dialogDim, titleFont: default-font, background: window-empty, titleFontColor: accent } }, io.anuke.ucore.scene.ui.KeybindDialog$KeybindDialogStyle: { - default: {keyColor: red, keyNameColor: white, paneStyle: clear}, + default: {keyColor: accent, keyNameColor: white, paneStyle: clear}, }, io.anuke.ucore.scene.ui.Slider$SliderStyle: { default-horizontal: {background: slider, knob: slider-knob, knobOver: slider-knob-over, knobDown: slider-knob-down}, @@ -74,7 +83,7 @@ io.anuke.ucore.scene.ui.TextField$TextFieldStyle: { default: {font: default-font, fontColor: white, disabledFontColor: grey, selection: selection, background: button, cursor: cursor, messageFont: default-font, messageFontColor: grey } } io.anuke.ucore.scene.ui.CheckBox$CheckBoxStyle: { - default: {checkboxOn: check-on, checkboxOff: check-off, checkboxOver: check-over, font: default-font, fontColor: white, disabledFontColor: grey } + default: {checkboxOn: check-on, checkboxOff: check-off, checkboxOnOver: check-on-over, checkboxOver: check-over, font: default-font, fontColor: white, disabledFontColor: grey } }, io.anuke.ucore.scene.ui.List$ListStyle: { default: {fontColorUnselected: white, fontColorSelected: white, font: default-font } diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 673eb697a5..e10eebe103 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -58,7 +58,7 @@ public class Vars{ public static float baseControllerSpeed = 11f; - public static final int saveSlots = 10; + public static final int saveSlots = 16; //amount of drops that are left when breaking a block public static final float breakDropAmount = 0.5f; diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 3d199c9529..7b90a468ef 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -23,6 +23,7 @@ import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.input.AndroidInput; import io.anuke.mindustry.input.DesktopInput; import io.anuke.mindustry.input.InputHandler; +import io.anuke.mindustry.io.Saves; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.Weapon; @@ -64,7 +65,9 @@ public class Control extends Module{ Array spawnpoints = new Array<>(); boolean shouldUpdateItems = false; boolean wasPaused = false; - + + Saves saves; + float respawntime; InputHandler input; @@ -76,6 +79,8 @@ public class Control extends Module{ if(Mindustry.args.contains("-debug", false)) Vars.debug = true; + saves = new Saves(); + Inputs.useControllers(false); log("Total blocks loaded: " + Block.getAllBlocks().size); @@ -177,7 +182,8 @@ public class Control extends Module{ ); for(int i = 0; i < Vars.saveSlots; i ++){ - Settings.defaults("saveslot" + i, "empty"); + Settings.defaults("save-" + i + "-autosave", true); + Settings.defaults("save-" + i + "-name", "untitled"); } Settings.loadAll("io.anuke.moment"); @@ -189,7 +195,12 @@ public class Control extends Module{ player = new Player(); spawns = WaveCreator.getSpawns(); - //WaveCreator.testWaves(1, 30); + + saves.load(); + } + + public Saves getSaves(){ + return saves; } public boolean showCursor(){ diff --git a/core/src/io/anuke/mindustry/core/Tutorial.java b/core/src/io/anuke/mindustry/core/Tutorial.java index e3fd04eecf..e6ac638aec 100644 --- a/core/src/io/anuke/mindustry/core/Tutorial.java +++ b/core/src/io/anuke/mindustry/core/Tutorial.java @@ -49,12 +49,12 @@ public class Tutorial{ row(); - prev = new button("< Prev", ()->{ + prev = new button("$text.tutorial.back", ()->{ if(!prev.isDisabled()) move(false); }).left().get(); - next = new button("Next >", ()->{ + next = new button("$text.tutorial.next", ()->{ if(!next.isDisabled()) move(true); }).right().get(); diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 84472a7412..2761af9515 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -30,12 +30,14 @@ import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.ucore.UCore; import io.anuke.ucore.core.*; import io.anuke.ucore.core.Inputs.DeviceType; +import io.anuke.ucore.function.Consumer; import io.anuke.ucore.function.Listenable; import io.anuke.ucore.function.VisibilityProvider; import io.anuke.ucore.modules.SceneModule; import io.anuke.ucore.scene.Element; import io.anuke.ucore.scene.Skin; import io.anuke.ucore.scene.builders.build; +import io.anuke.ucore.scene.builders.field; import io.anuke.ucore.scene.builders.label; import io.anuke.ucore.scene.builders.table; import io.anuke.ucore.scene.event.Touchable; @@ -367,12 +369,28 @@ public class UI extends SceneModule{ public void hideConfig(){ configtable.setVisible(false); } - + + public void showTextInput(String title, String text, String def, Consumer confirmed){ + new Dialog(title, "dialog"){{ + content().margin(30); + content().add(text).padRight(6f); + TextField field = content().addField(def, t->{}).size(170f, 50f).get(); + field.setTextFieldFilter((f, c) -> field.getText().length() < 12); + Mindustry.platforms.addDialog(field); + buttons().defaults().size(120, 54).pad(4); + buttons().addButton("$text.ok", () -> { + confirmed.accept(field.getText()); + hide(); + }).disabled(b -> field.getText().isEmpty()); + buttons().addButton("$text.cancel", this::hide); + }}.show(); + } + public void showError(String text){ new Dialog("$text.error.title", "dialog"){{ content().margin(15); content().add(text); - getButtonTable().addButton("$text.ok", this::hide).size(90, 50).pad(4); + buttons().addButton("$text.ok", this::hide).size(90, 50).pad(4); }}.show(); } @@ -380,7 +398,7 @@ public class UI extends SceneModule{ new Dialog("$text.error.title", "dialog"){{ content().margin(15); content().add(text); - getButtonTable().addButton("$text.quit", Gdx.app::exit).size(90, 50).pad(4); + buttons().addButton("$text.quit", Gdx.app::exit).size(90, 50).pad(4); }}.show(); } diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index 0994a93c8d..a7089e0cf8 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -115,7 +115,11 @@ public class SaveIO{ } public static boolean isSaveValid(int slot){ - try(DataInputStream stream = new DataInputStream(fileFor(slot).read())){ + return isSaveValid(fileFor(slot)); + } + + public static boolean isSaveValid(FileHandle file){ + try(DataInputStream stream = new DataInputStream(file.read())){ int version = stream.readInt(); //read version stream.readLong(); //read last saved time stream.readByte(); //read the gamemode @@ -340,6 +344,7 @@ public class SaveIO{ Vars.control.getWeapons().clear(); Vars.control.getWeapons().add(Weapon.blaster); + Vars.player.weapon = Weapon.blaster; int weapons = stream.readByte(); diff --git a/core/src/io/anuke/mindustry/io/Saves.java b/core/src/io/anuke/mindustry/io/Saves.java index 4678fc51d8..4d1f0ee0e1 100644 --- a/core/src/io/anuke/mindustry/io/Saves.java +++ b/core/src/io/anuke/mindustry/io/Saves.java @@ -1,10 +1,107 @@ package io.anuke.mindustry.io; -import com.badlogic.gdx.utils.IntArray; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.world.GameMode; +import io.anuke.mindustry.world.Map; +import io.anuke.ucore.core.Settings; -import java.lang.reflect.Array; +import java.io.IOException; public class Saves { - private int lastSlot; - private IntArray saves; + private int nextSlot; + private Array saves = new Array<>(); + + public void load(){ + saves.clear(); + for(int i = 0; i < Vars.saveSlots; i ++){ + if(SaveIO.isSaveValid(i)){ + saves.add(new SaveSlot(i)); + nextSlot = i + 1; + } + } + } + + public boolean canAddSave(){ + return nextSlot <= Vars.saveSlots; + } + + public void addSave(String name){ + SaveSlot slot = new SaveSlot(nextSlot); + nextSlot ++; + slot.setName(name); + saves.add(slot); + SaveIO.saveToSlot(slot.index); + } + + public Array getSaveSlots(){ + return saves; + } + + public class SaveSlot{ + public final int index; + + public SaveSlot(int index){ + this.index = index; + } + + public String getDate(){ + return SaveIO.getTimeString(index); + } + + public Map getMap(){ + return SaveIO.getMap(index); + } + + public String getName(){ + return Settings.getString("save-"+index+"-name"); + } + + public void setName(String name){ + Settings.putString("save-"+index+"-name", name); + Settings.save(); + } + + public int getWave(){ + return SaveIO.getWave(index); + } + + public GameMode getMode(){ + return SaveIO.getMode(index); + } + + public boolean isAutosave(){ + return Settings.getBool("save-"+index+"-autosave"); + } + + public void setAutosave(boolean save){ + Settings.putBool("save-"+index + "-autosave", save); + Settings.save(); + } + + public void importFile(FileHandle file) throws IOException{ + try{ + file.copyTo(SaveIO.fileFor(index)); + }catch (Exception e){ + throw new IOException(e); + } + } + + public void exportFile(FileHandle file) throws IOException{ + try{ + if(!file.extension().equals("mins")){ + file = file.parent().child(file.nameWithoutExtension() + ".mins"); + } + SaveIO.fileFor(index).copyTo(file); + }catch (Exception e){ + throw new IOException(e); + } + } + + public void delete(){ + SaveIO.fileFor(index).delete(); + load(); + } + } } diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java index ae6103336a..c068a6aa7b 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java @@ -233,7 +233,7 @@ public class MapEditorDialog extends Dialog{ ImageButton undo = tools.addIButton("icon-undo", 16*2f, () -> view.undo()).get(); ImageButton redo = tools.addIButton("icon-redo", 16*2f, () -> view.redo()).get(); - tools.addIButton("toggle", "icon-grid", 16*2f, () -> view.setGrid(!view.isGrid())).get(); + tools.addIButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get(); undo.setDisabled(() -> !view.getStack().canUndo()); redo.setDisabled(() -> !view.getStack().canRedo()); diff --git a/core/src/io/anuke/mindustry/resource/Weapon.java b/core/src/io/anuke/mindustry/resource/Weapon.java index 524f21068f..2ea71c536e 100644 --- a/core/src/io/anuke/mindustry/resource/Weapon.java +++ b/core/src/io/anuke/mindustry/resource/Weapon.java @@ -53,7 +53,7 @@ public enum Weapon{ Effects.effect(Fx.shoot2, p.x + vector.x, p.y+vector.y); } }, - flamer(5, BulletType.flame, stack(Item.steel, 60), stack(Item.coal, 60)){ + flamer(5, BulletType.flame, stack(Item.steel, 60), stack(Item.iron, 120)){ { shootsound = "flame2"; diff --git a/core/src/io/anuke/mindustry/ui/FileChooser.java b/core/src/io/anuke/mindustry/ui/FileChooser.java index 0427588377..17f33c854f 100644 --- a/core/src/io/anuke/mindustry/ui/FileChooser.java +++ b/core/src/io/anuke/mindustry/ui/FileChooser.java @@ -59,7 +59,7 @@ public class FileChooser extends FloatingDialog{ if(!open) Mindustry.platforms.addDialog(filefield); filefield.setDisabled(open); - ok = new TextButton(open ? "$text.save" : "$text.save"); + ok = new TextButton(open ? "$text.load" : "$text.save"); ok.clicked(() -> { if(ok.isDisabled()) return; diff --git a/core/src/io/anuke/mindustry/ui/LevelDialog.java b/core/src/io/anuke/mindustry/ui/LevelDialog.java index f176d9f760..bd1198edbb 100644 --- a/core/src/io/anuke/mindustry/ui/LevelDialog.java +++ b/core/src/io/anuke/mindustry/ui/LevelDialog.java @@ -12,7 +12,7 @@ import io.anuke.ucore.scene.event.InputEvent; 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.scene.utils.ClickListener; +import io.anuke.ucore.scene.event.ClickListener; import io.anuke.ucore.scene.utils.Elements; import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Tmp; diff --git a/core/src/io/anuke/mindustry/ui/LoadDialog.java b/core/src/io/anuke/mindustry/ui/LoadDialog.java index f4796e27a6..f03a3dfa18 100644 --- a/core/src/io/anuke/mindustry/ui/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/LoadDialog.java @@ -1,21 +1,28 @@ package io.anuke.mindustry.ui; -import com.badlogic.gdx.utils.Align; - +import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.io.SaveIO; +import io.anuke.mindustry.io.Saves.SaveSlot; +import io.anuke.ucore.UCore; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Timers; -import io.anuke.ucore.scene.ui.Label; +import io.anuke.ucore.scene.builders.button; +import io.anuke.ucore.scene.builders.dialog; +import io.anuke.ucore.scene.ui.Dialog; import io.anuke.ucore.scene.ui.ScrollPane; import io.anuke.ucore.scene.ui.TextButton; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Bundles; +import io.anuke.ucore.util.Strings; + +import java.io.IOException; public class LoadDialog extends FloatingDialog{ ScrollPane pane; + Table slots; public LoadDialog() { this("$text.loadgame"); @@ -33,37 +40,112 @@ public class LoadDialog extends FloatingDialog{ addCloseButton(); } - private void setup(){ + protected void setup(){ content().clear(); - content().add("$text.selectslot").padBottom(2); - content().row(); - - Table slots = new Table(); - pane = new ScrollPane(slots); + slots = new Table(); + pane = new ScrollPane(slots, "clear-black"); pane.setFadeScrollBars(false); + pane.setScrollingDisabled(true, false); slots.marginRight(24); - for(int i = 0; i < Vars.saveSlots; i++){ + Timers.runTask(2f, () -> Core.scene.setScrollFocus(pane)); - TextButton button = new TextButton(Bundles.format("text.slot", (i + 1))); - button.margin(12); + Array array = Vars.control.getSaves().getSaveSlots(); + + for(SaveSlot slot : array){ + + TextButton button = new TextButton("[accent]" + slot.getName(), "clear"); + button.getLabelCell().growX().left(); + button.getLabelCell().padBottom(8f); button.getLabelCell().top().left().growX(); - button.row(); + button.defaults().left(); - Label info = new Label("[gray]" + (!SaveIO.isSaveValid(i) ? Bundles.get("text.empty") : SaveIO.getMode(i) + ", " - + Bundles.get("map."+SaveIO.getMap(i).name+".name", SaveIO.getMap(i).name) + ", " + Bundles.format("text.save.wave", SaveIO.getWave(i)) + "\n" - + Bundles.format("text.save.date", SaveIO.getTimeString(i)))); - info.setAlignment(Align.center, Align.center); + button.table(t -> { + t.right(); - button.add(info).padBottom(3).padTop(7); - button.row(); - button.row(); - modifyButton(button, i); + t.addIButton("icon-floppy", "emptytoggle", 14*3, () -> { + slot.setAutosave(!slot.isAutosave()); + }).checked(slot.isAutosave()).right(); - slots.add(button).size(404, 104).pad(4); + t.addIButton("icon-trash", "empty", 14*3, () -> { + Vars.ui.showConfirm("$text.confirm", "$text.save.delete.confirm", () -> { + slot.delete(); + setup(); + }); + }).size(14*3).right(); + + t.addIButton("icon-dots", "empty", 14*3, () -> { + FloatingDialog dialog = new FloatingDialog("Save Options"); + dialog.addCloseButton(); + + dialog.content().defaults().left().uniformX().size(230f, 60f); + + dialog.content().addImageTextButton("$text.save.rename", "icon-rename", 14*3, () -> { + Vars.ui.showTextInput("$text.save.rename", "$text.save.rename.text", slot.getName(), text -> { + slot.setName(text); + dialog.hide(); + setup(); + }); + }); + + dialog.content().row(); + + dialog.content().addImageTextButton("$text.save.import", "icon-save", 14*3, () -> { + new FileChooser("$text.save.import", f -> f.extension().equals("mins"), true, file -> { + if(SaveIO.isSaveValid(file)){ + try{ + slot.importFile(file); + setup(); + }catch (IOException e){ + Vars.ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false))); + } + }else{ + Vars.ui.showError("$text.save.import.invalid"); + } + dialog.hide(); + }).show(); + }); + + dialog.content().row(); + + dialog.content().addImageTextButton("$text.save.export", "icon-load", 14*3, () -> { + new FileChooser("$text.save.export", false, file -> { + try{ + slot.exportFile(file); + setup(); + }catch (IOException e){ + Vars.ui.showError(Bundles.format("text.save.export.fail", Strings.parseException(e, false))); + } + dialog.hide(); + }).show(); + }); + + dialog.show(); + }).size(14*3).right(); + + }).padRight(-10).growX(); + + String color = "[lightgray]"; + + button.defaults().padBottom(3); + button.row(); + button.add(Bundles.format("text.save.map", color+slot.getMap().localized())); + button.row(); + button.add(Bundles.get("text.level.mode") + " " +color+ slot.getMode()); + button.row(); + button.add(Bundles.format("text.save.wave", color+slot.getWave())); + button.row(); + button.label(() -> Bundles.format("text.save.autosave", color + Bundles.get(slot.isAutosave() ? "text.on" : "text.off"))); + button.row(); + button.add(); + button.add(Bundles.format("text.save.date", color+slot.getDate())); + button.row(); + modifyButton(button, slot); + + slots.add(button).uniformX().fillX().pad(4).padRight(-4).margin(10f).marginLeft(20f).marginRight(20f); slots.row(); } @@ -71,17 +153,16 @@ public class LoadDialog extends FloatingDialog{ } - public void modifyButton(TextButton button, int slot){ - button.setDisabled(!SaveIO.isSaveValid(slot)); + public void modifyButton(TextButton button, SaveSlot slot){ button.clicked(() -> { - if(!button.isDisabled()){ + if(!button.childrenPressed()){ Vars.ui.showLoading(); Timers.runTask(3f, () -> { Vars.ui.hideLoading(); hide(); try{ - SaveIO.loadFromSlot(slot); + SaveIO.loadFromSlot(slot.index); GameState.set(State.playing); Vars.ui.hideMenu(); }catch(Exception e){ @@ -90,7 +171,6 @@ public class LoadDialog extends FloatingDialog{ GameState.set(State.menu); Vars.control.reset(); Vars.ui.showError("$text.save.corrupted"); - return; } }); } diff --git a/core/src/io/anuke/mindustry/ui/SaveDialog.java b/core/src/io/anuke/mindustry/ui/SaveDialog.java index b3dcab8a6e..4e4f050562 100644 --- a/core/src/io/anuke/mindustry/ui/SaveDialog.java +++ b/core/src/io/anuke/mindustry/ui/SaveDialog.java @@ -4,8 +4,12 @@ import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.Vars; import io.anuke.mindustry.io.SaveIO; +import io.anuke.mindustry.io.Saves; +import io.anuke.mindustry.io.Saves.SaveSlot; import io.anuke.ucore.core.Timers; +import io.anuke.ucore.scene.builders.button; import io.anuke.ucore.scene.ui.ConfirmDialog; +import io.anuke.ucore.scene.ui.Dialog; import io.anuke.ucore.scene.ui.TextButton; import io.anuke.ucore.scene.ui.layout.Cell; import io.anuke.ucore.util.Bundles; @@ -17,21 +21,31 @@ public class SaveDialog extends LoadDialog{ } @Override - public void modifyButton(TextButton button, int slot){ + protected void setup(){ + super.setup(); + + if(!Vars.control.getSaves().canAddSave()){ + return; + } + + slots.row(); + slots.addImageTextButton("$text.save.new", "icon-add", "clear", 14*3, () -> { + Vars.ui.showTextInput("$text.save", "$text.save.newslot", "", text -> { + Vars.control.getSaves().addSave(text); + setup(); + }); + }).fillX().margin(10f).height(70f).pad(4f).padRight(-4); + } + + + @Override + public void modifyButton(TextButton button, SaveSlot slot){ button.clicked(() -> { - if(SaveIO.isSaveValid(slot)){ - new ConfirmDialog("$text.overwrite", "$text.save.overwrite", () -> { - save(slot); - }){ - { - content().margin(16); - for(Cell cell : getButtonTable().getCells()) - cell.size(110, 45).pad(4); - } - }.show(); - }else{ - save(slot); - } + if(button.childrenPressed()) return; + + Vars.ui.showConfirm("$text.overwrite", "$text.save.overwrite", () -> { + save(slot.index); + }); }); } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index 3b222d1932..caae58971a 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -220,7 +220,7 @@ public class Tile{ public void changed(){ if(entity != null){ - if(entity.added) entity.remove(); + entity.remove(); entity = null; } diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index de9324b816..4ca906fa7d 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -3,6 +3,7 @@ package io.anuke.mindustry.desktop; import java.awt.Desktop; import java.io.IOException; import java.net.URI; +import java.text.DateFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -30,7 +31,7 @@ public class DesktopLauncher { config.setWindowIcon("sprites/icon.png"); Mindustry.platforms = new PlatformFunction(){ - SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm"); + DateFormat format = SimpleDateFormat.getDateTimeInstance(); @Override public String format(Date date){