diff --git a/.gitignore b/.gitignore index d568a38105..71869acd34 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /desktop/packr-out/ /desktop/packr-export/ /desktop/mindustry-saves/ +/destkop/mindustry-maps/ /core/lib/ *.gif diff --git a/TODO.md b/TODO.md index 1c87bdf52c..88459d4093 100644 --- a/TODO.md +++ b/TODO.md @@ -16,6 +16,8 @@ _Keep in mind that this is just a basic outline of planned features, and will be - [DONE] Add link to Mindustry discord everywhere - Balancing to slow down progression - Map editor +- Delete saves +- Display playtime ### Major Bugs - Black screen when tabbing out on Android diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index dfaef6fadf..8c14141445 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="38" + android:versionName="3.1.2" > diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java index 15ca88286c..698b5697f9 100644 --- a/android/src/io/anuke/mindustry/AndroidLauncher.java +++ b/android/src/io/anuke/mindustry/AndroidLauncher.java @@ -52,7 +52,7 @@ public class AndroidLauncher extends AndroidApplication{ Mindustry.donationsCallable = new Callable(){ @Override public void run(){ showDonations(); } }; if(doubleScaleTablets && isTablet(this.getContext())){ - Unit.dp.addition = 1f; + Unit.dp.addition = 0.5f; } config.hideStatusBar = true; diff --git a/core/assets-raw/sprites/ui/icon-terrain.png b/core/assets-raw/sprites/ui/icon-terrain.png new file mode 100644 index 0000000000..92dc447567 Binary files /dev/null and b/core/assets-raw/sprites/ui/icon-terrain.png differ diff --git a/core/assets-raw/sprites/ui/slider.png b/core/assets-raw/sprites/ui/slider.png index 7986f4f53b..a722706e2b 100644 Binary files a/core/assets-raw/sprites/ui/slider.png and b/core/assets-raw/sprites/ui/slider.png differ diff --git a/core/assets-raw/sprites/ui/text-editor.png b/core/assets-raw/sprites/ui/text-editor.png new file mode 100644 index 0000000000..55954c3371 Binary files /dev/null and b/core/assets-raw/sprites/ui/text-editor.png differ diff --git a/core/assets/maps/islands.png b/core/assets/maps/island.png similarity index 100% rename from core/assets/maps/islands.png rename to core/assets/maps/island.png diff --git a/core/assets/maps/maps.json b/core/assets/maps/maps.json new file mode 100644 index 0000000000..fcfbde3d3d --- /dev/null +++ b/core/assets/maps/maps.json @@ -0,0 +1,95 @@ +{ + "maps": [ + { + "id": 0, + "name": "maze", + "visible": true, + "flipBase": false, + "backgroundColor": "646464" + }, + { + "id": 1, + "name": "fortress", + "visible": true, + "flipBase": false, + "backgroundColor": "646464" + }, + { + "id": 2, + "name": "sinkhole", + "visible": true, + "flipBase": false, + "backgroundColor": "646464" + }, + { + "id": 3, + "name": "caves", + "visible": true, + "flipBase": false, + "backgroundColor": "646464" + }, + { + "id": 4, + "name": "volcano", + "visible": true, + "flipBase": true, + "backgroundColor": "646464" + }, + { + "id": 5, + "name": "caldera", + "visible": true, + "flipBase": false, + "backgroundColor": "646464" + }, + { + "id": 6, + "name": "scorch", + "visible": true, + "flipBase": false, + "backgroundColor": "e5d8bb" + }, + { + "id": 7, + "name": "desert", + "visible": true, + "flipBase": false, + "backgroundColor": "646464" + }, + { + "id": 8, + "name": "island", + "visible": true, + "flipBase": false, + "backgroundColor": "e5d8bb" + }, + { + "id": 9, + "name": "grassland", + "visible": true, + "flipBase": false, + "backgroundColor": "5ab464" + }, + { + "id": 10, + "name": "tundra", + "visible": true, + "flipBase": false, + "backgroundColor": "646464" + }, + { + "id": 11, + "name": "spiral", + "visible": true, + "flipBase": false, + "backgroundColor": "f7feff" + }, + { + "id": 12, + "name": "tutorial", + "visible": true, + "flipBase": false, + "backgroundColor": "646464" + } + ] +} diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 1a9999603e..cd2882139d 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -20,1183 +20,1183 @@ blank index: -1 blocks/blackrock1 rotate: false - xy: 519, 179 + xy: 349, 79 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackrockshadow1 rotate: false - xy: 722, 381 + xy: 361, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone1 rotate: false - xy: 734, 406 + xy: 229, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone2 rotate: false - xy: 734, 396 + xy: 239, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone3 rotate: false - xy: 724, 371 + xy: 249, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock1 rotate: false - xy: 724, 361 + xy: 259, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock2 rotate: false - xy: 724, 351 + xy: 269, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock3 rotate: false - xy: 734, 386 + xy: 279, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneedge rotate: false - xy: 1011, 499 + xy: 178, 94 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/block rotate: false - xy: 734, 366 + xy: 299, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/block-2x2 rotate: false - xy: 428, 113 + xy: 661, 292 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/block-3x3 rotate: false - xy: 224, 105 + xy: 125, 38 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/chainturret rotate: false - xy: 747, 430 + xy: 679, 292 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/chainturret-icon rotate: false - xy: 529, 177 + xy: 558, 177 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/coal1 rotate: false - xy: 734, 346 + xy: 319, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal2 rotate: false - xy: 165, 76 + xy: 329, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal3 rotate: false - xy: 175, 79 + xy: 339, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coaldrill rotate: false - xy: 185, 79 + xy: 349, 69 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator rotate: false - xy: 195, 79 + xy: 370, 103 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator-top rotate: false - xy: 205, 79 + xy: 380, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalpurifier rotate: false - xy: 215, 79 + xy: 390, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/combustiongenerator rotate: false - xy: 225, 83 + xy: 400, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/compositewall rotate: false - xy: 235, 83 + xy: 410, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduit rotate: false - xy: 245, 83 + xy: 420, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitbottom rotate: false - xy: 255, 83 + xy: 430, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitliquid rotate: false - xy: 265, 83 + xy: 440, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduittop rotate: false - xy: 275, 83 + xy: 450, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyor rotate: false - xy: 285, 83 + xy: 460, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyormove rotate: false - xy: 295, 83 + xy: 470, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyortunnel rotate: false - xy: 305, 83 + xy: 480, 105 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/core rotate: false - xy: 276, 105 + xy: 524, 219 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/cross rotate: false - xy: 315, 83 + xy: 371, 93 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/crucible rotate: false - xy: 325, 83 + xy: 381, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/deepwater rotate: false - xy: 335, 83 + xy: 391, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt1 rotate: false - xy: 345, 83 + xy: 401, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt2 rotate: false - xy: 355, 83 + xy: 411, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt3 rotate: false - xy: 365, 83 + xy: 421, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirtedge rotate: false - xy: 1011, 485 + xy: 529, 147 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/door rotate: false - xy: 375, 83 + xy: 431, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/door-large rotate: false - xy: 446, 113 + xy: 697, 291 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/door-large-icon rotate: false - xy: 385, 83 + xy: 441, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/door-large-open rotate: false - xy: 464, 113 + xy: 234, 113 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/door-open rotate: false - xy: 395, 83 + xy: 451, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/doubleturret rotate: false - xy: 514, 124 + xy: 582, 177 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/duriumwall rotate: false - xy: 809, 430 + xy: 461, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/duriumwall-large rotate: false - xy: 661, 292 + xy: 252, 113 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/duriumwall-large-icon rotate: false - xy: 514, 114 + xy: 471, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/flameturret rotate: false - xy: 188, 89 + xy: 226, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/fluxpump rotate: false - xy: 406, 99 + xy: 225, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass1 rotate: false - xy: 416, 99 + xy: 235, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass2 rotate: false - xy: 428, 103 + xy: 245, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass3 rotate: false - xy: 438, 103 + xy: 255, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock1 rotate: false - xy: 448, 103 + xy: 265, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock2 rotate: false - xy: 458, 103 + xy: 275, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassedge rotate: false - xy: 795, 426 + xy: 211, 55 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/ice1 rotate: false - xy: 468, 103 + xy: 285, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice2 rotate: false - xy: 225, 73 + xy: 295, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice3 rotate: false - xy: 235, 73 + xy: 305, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iceedge rotate: false - xy: 524, 217 + xy: 563, 189 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/icerock1 rotate: false - xy: 245, 73 + xy: 315, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerock2 rotate: false - xy: 255, 73 + xy: 325, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow1 rotate: false - xy: 265, 73 + xy: 335, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow1 rotate: false - xy: 265, 73 + xy: 335, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow2 rotate: false - xy: 275, 73 + xy: 495, 126 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow2 rotate: false - xy: 275, 73 + xy: 495, 126 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron1 rotate: false - xy: 355, 73 + xy: 510, 116 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron2 rotate: false - xy: 365, 73 + xy: 510, 106 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron3 rotate: false - xy: 375, 73 + xy: 491, 96 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/irondrill rotate: false - xy: 385, 73 + xy: 501, 96 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ironwall rotate: false - xy: 395, 73 + xy: 511, 96 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/junction rotate: false - xy: 809, 420 + xy: 525, 127 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/laserturret rotate: false - xy: 709, 279 + xy: 322, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/lava rotate: false - xy: 478, 103 + xy: 520, 116 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/lavaedge rotate: false - xy: 538, 217 + xy: 559, 163 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/lavasmelter rotate: false - xy: 488, 105 + xy: 520, 106 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquiditemjunction rotate: false - xy: 592, 238 + xy: 521, 96 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidjunction rotate: false - xy: 602, 238 + xy: 151, 54 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidrouter rotate: false - xy: 612, 238 + xy: 151, 44 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/machineturret rotate: false - xy: 721, 281 + xy: 301, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/megarepairturret rotate: false - xy: 541, 177 + xy: 313, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mortarturret rotate: false - xy: 163, 26 + xy: 334, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mossblock rotate: false - xy: 632, 238 + xy: 171, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/mossstone rotate: false - xy: 632, 238 + xy: 171, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/nuclearreactor rotate: false - xy: 302, 105 + xy: 550, 219 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/nuclearreactor-center rotate: false - xy: 328, 105 + xy: 727, 422 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/nuclearreactor-icon rotate: false - xy: 591, 228 + xy: 171, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/nuclearreactor-lights rotate: false - xy: 354, 105 + xy: 753, 422 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/nuclearreactor-small rotate: false - xy: 679, 292 + xy: 270, 113 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/oil rotate: false - xy: 601, 228 + xy: 181, 52 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/oiledge rotate: false - xy: 519, 189 + xy: 577, 189 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/oilrefinery rotate: false - xy: 611, 228 + xy: 345, 57 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/omnidrill rotate: false - xy: 621, 228 + xy: 539, 137 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/plasmaturret rotate: false - xy: 498, 108 + xy: 313, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/powerbooster rotate: false - xy: 631, 228 + xy: 535, 127 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyor rotate: false - xy: 641, 228 + xy: 530, 117 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyormove rotate: false - xy: 595, 218 + xy: 530, 107 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaser rotate: false - xy: 605, 218 + xy: 531, 97 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlasercorner rotate: false - xy: 615, 218 + xy: 540, 117 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaserrouter rotate: false - xy: 625, 218 + xy: 540, 107 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduit rotate: false - xy: 635, 218 + xy: 545, 127 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduitbottom rotate: false - xy: 645, 218 + xy: 541, 97 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduittop rotate: false - xy: 651, 228 + xy: 550, 117 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pump rotate: false - xy: 655, 218 + xy: 550, 107 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/repairturret rotate: false - xy: 704, 263 + xy: 325, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/rock1 rotate: false - xy: 671, 234 + xy: 161, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rock2 rotate: false - xy: 665, 224 + xy: 171, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/router rotate: false - xy: 665, 214 + xy: 181, 42 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator rotate: false - xy: 675, 224 + xy: 157, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator-top rotate: false - xy: 675, 214 + xy: 167, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand1 rotate: false - xy: 405, 89 + xy: 191, 45 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand2 rotate: false - xy: 405, 79 + xy: 201, 45 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand3 rotate: false - xy: 415, 89 + xy: 211, 45 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock1 rotate: false - xy: 415, 79 + xy: 181, 32 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock2 rotate: false - xy: 405, 69 + xy: 191, 35 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock3 rotate: false - xy: 415, 69 + xy: 201, 35 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandedge rotate: false - xy: 533, 203 + xy: 587, 163 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/shadow rotate: false - xy: 704, 251 + xy: 346, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shieldgenerator rotate: false - xy: 185, 69 + xy: 159, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shotgunturret rotate: false - xy: 704, 239 + xy: 325, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shrub rotate: false - xy: 215, 69 + xy: 169, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shrubshadow rotate: false - xy: 173, 59 + xy: 221, 45 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/smelter rotate: false - xy: 183, 59 + xy: 221, 35 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sniperturret rotate: false - xy: 722, 415 + xy: 337, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/snow1 rotate: false - xy: 193, 59 + xy: 231, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow2 rotate: false - xy: 203, 59 + xy: 231, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow3 rotate: false - xy: 213, 59 + xy: 241, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock1 rotate: false - xy: 173, 49 + xy: 241, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock2 rotate: false - xy: 183, 49 + xy: 251, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock3 rotate: false - xy: 193, 49 + xy: 251, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowedge rotate: false - xy: 533, 189 + xy: 117, 8 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/sorter rotate: false - xy: 203, 49 + xy: 261, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyor rotate: false - xy: 213, 49 + xy: 261, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyormove rotate: false - xy: 171, 39 + xy: 271, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelwall rotate: false - xy: 181, 39 + xy: 271, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelwall-large rotate: false - xy: 697, 291 + xy: 288, 113 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/steelwall-large-icon rotate: false - xy: 191, 39 + xy: 281, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone1 rotate: false - xy: 201, 39 + xy: 281, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone2 rotate: false - xy: 211, 39 + xy: 291, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone3 rotate: false - xy: 175, 29 + xy: 291, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock1 rotate: false - xy: 185, 29 + xy: 301, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock2 rotate: false - xy: 195, 29 + xy: 301, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock3 rotate: false - xy: 205, 29 + xy: 311, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonedrill rotate: false - xy: 215, 29 + xy: 311, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneedge rotate: false - xy: 555, 213 + xy: 131, 8 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/stoneformer rotate: false - xy: 221, 39 + xy: 321, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonewall rotate: false - xy: 225, 29 + xy: 321, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter rotate: false - xy: 225, 63 + xy: 331, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter-top rotate: false - xy: 235, 63 + xy: 331, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/thermalgenerator rotate: false - xy: 245, 63 + xy: 341, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titancannon rotate: false - xy: 380, 105 + xy: 779, 430 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blocks/titancannon-icon rotate: false - xy: 722, 403 + xy: 358, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/titanium1 rotate: false - xy: 255, 63 + xy: 341, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium2 rotate: false - xy: 265, 63 + xy: 351, 47 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium3 rotate: false - xy: 275, 63 + xy: 351, 37 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumdrill rotate: false - xy: 285, 63 + xy: 802, 420 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumpurifier rotate: false - xy: 295, 63 + xy: 802, 410 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumshieldwall rotate: false - xy: 305, 63 + xy: 802, 400 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumwall rotate: false - xy: 315, 63 + xy: 802, 390 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumwall-large rotate: false - xy: 881, 495 + xy: 360, 113 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 blocks/titaniumwall-large-icon rotate: false - xy: 325, 63 + xy: 802, 380 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/turret rotate: false - xy: 722, 391 + xy: 337, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/uranium1 rotate: false - xy: 355, 63 + xy: 211, 25 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium2 rotate: false - xy: 365, 63 + xy: 221, 25 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium3 rotate: false - xy: 375, 63 + xy: 231, 27 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uraniumdrill rotate: false - xy: 385, 63 + xy: 241, 27 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/water rotate: false - xy: 395, 63 + xy: 251, 27 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/wateredge rotate: false - xy: 569, 213 + xy: 145, 8 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/waveturret rotate: false - xy: 734, 416 + xy: 349, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 bullet rotate: false - xy: 734, 356 + xy: 309, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1210,7 +1210,7 @@ chainbullet index: -1 circle rotate: false - xy: 169, 89 + xy: 519, 178 size: 17, 17 orig: 17, 17 offset: 0, 0 @@ -1224,238 +1224,238 @@ circle2 index: -1 enemies/blastenemy-t1 rotate: false - xy: 899, 497 + xy: 378, 115 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/blastenemy-t2 rotate: false - xy: 915, 497 + xy: 394, 115 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/blastenemy-t3 rotate: false - xy: 931, 497 + xy: 410, 115 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/empenemy-t1 rotate: false - xy: 947, 497 + xy: 426, 115 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/empenemy-t2 rotate: false - xy: 963, 497 + xy: 442, 115 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/empenemy-t3 rotate: false - xy: 979, 497 + xy: 458, 115 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/enemy-t1 rotate: false - xy: 995, 497 + xy: 474, 115 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/targetenemy-t1 rotate: false - xy: 995, 497 + xy: 474, 115 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/enemy-t2 rotate: false - xy: 157, 38 + xy: 545, 163 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 enemies/enemy-t3 rotate: false - xy: 781, 426 + xy: 197, 55 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 enemies/fastenemy-t1 rotate: false - xy: 765, 432 + xy: 881, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/fastenemy-t2 rotate: false - xy: 482, 115 + xy: 897, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/fastenemy-t3 rotate: false - xy: 715, 293 + xy: 913, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/flamerenemy-t1 rotate: false - xy: 498, 120 + xy: 929, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/flamerenemy-t2 rotate: false - xy: 115, 14 + xy: 945, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/flamerenemy-t3 rotate: false - xy: 141, 52 + xy: 961, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/fortressenemy-t1 rotate: false - xy: 125, 72 + xy: 95, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 enemies/fortressenemy-t2 rotate: false - xy: 147, 86 + xy: 519, 197 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 enemies/fortressenemy-t3 rotate: false - xy: 406, 109 + xy: 541, 197 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 enemies/healerenemy-t1 rotate: false - xy: 141, 36 + xy: 977, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/healerenemy-t2 rotate: false - xy: 131, 20 + xy: 993, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/healerenemy-t3 rotate: false - xy: 147, 20 + xy: 1009, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t1 rotate: false - xy: 656, 260 + xy: 197, 69 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t2 rotate: false - xy: 672, 260 + xy: 213, 85 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t3 rotate: false - xy: 656, 244 + xy: 213, 69 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t1 rotate: false - xy: 672, 244 + xy: 125, 22 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t2 rotate: false - xy: 688, 259 + xy: 141, 22 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t3 rotate: false - xy: 688, 243 + xy: 786, 414 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t1 rotate: false - xy: 781, 440 + xy: 786, 398 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t2 rotate: false - xy: 797, 440 + xy: 786, 382 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t3 rotate: false - xy: 157, 52 + xy: 529, 161 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/titanenemy-t1 rotate: false - xy: 555, 227 + xy: 306, 113 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 enemies/titanenemy-t2 rotate: false - xy: 573, 227 + xy: 324, 113 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 enemies/titanenemy-t3 rotate: false - xy: 147, 68 + xy: 342, 113 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -1469,105 +1469,105 @@ enemyarrow index: -1 icon-coal rotate: false - xy: 285, 73 + xy: 505, 126 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-dirium rotate: false - xy: 295, 73 + xy: 515, 126 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-iron rotate: false - xy: 305, 73 + xy: 529, 137 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-steel rotate: false - xy: 315, 73 + xy: 490, 116 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-stone rotate: false - xy: 325, 73 + xy: 490, 106 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-titanium rotate: false - xy: 335, 73 + xy: 500, 116 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-uranium rotate: false - xy: 345, 73 + xy: 500, 106 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laser rotate: false - xy: 552, 217 + xy: 805, 442 size: 1, 12 orig: 1, 12 offset: 0, 0 index: -1 laserend rotate: false - xy: 727, 428 + xy: 538, 177 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 laserfull rotate: false - xy: 95, 10 + xy: 576, 225 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 mechs/mech-standard rotate: false - xy: 519, 203 + xy: 573, 163 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shell rotate: false - xy: 175, 69 + xy: 211, 35 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot rotate: false - xy: 195, 69 + xy: 159, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot-long rotate: false - xy: 205, 69 + xy: 169, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanshell rotate: false - xy: 335, 63 + xy: 191, 25 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1630,7 +1630,7 @@ ui/button-map-over index: -1 ui/button-select rotate: false - xy: 250, 105 + xy: 155, 68 size: 24, 24 split: 4, 4, 4, 4 orig: 24, 24 @@ -1659,56 +1659,56 @@ ui/check-over index: -1 ui/clear rotate: false - xy: 583, 215 + xy: 570, 177 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/cursor rotate: false - xy: 125, 30 + xy: 579, 203 size: 4, 4 orig: 4, 4 offset: 0, 0 index: -1 ui/icon-areaDelete rotate: false - xy: 200, 89 + xy: 238, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-arrow rotate: false - xy: 597, 280 + xy: 563, 203 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-arrow-left rotate: false - xy: 212, 89 + xy: 229, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-arrow-right rotate: false - xy: 224, 93 + xy: 250, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-cancel rotate: false - xy: 613, 280 + xy: 715, 293 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-check rotate: false - xy: 629, 280 + xy: 722, 406 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1736,203 +1736,210 @@ ui/icon-close-over index: -1 ui/icon-crafting rotate: false - xy: 236, 93 + xy: 229, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-cursor rotate: false - xy: 248, 93 + xy: 241, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-defense rotate: false - xy: 260, 93 + xy: 262, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-discord rotate: false - xy: 645, 280 + xy: 722, 390 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-distribution rotate: false - xy: 272, 93 + xy: 241, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-donate rotate: false - xy: 661, 276 + xy: 738, 406 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-hold rotate: false - xy: 284, 93 + xy: 253, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-holdDelete rotate: false - xy: 296, 93 + xy: 274, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-info rotate: false - xy: 308, 93 + xy: 253, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-load rotate: false - xy: 677, 276 + xy: 738, 390 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-menu rotate: false - xy: 320, 93 + xy: 265, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-none rotate: false - xy: 332, 93 + xy: 286, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-pause rotate: false - xy: 344, 93 + xy: 265, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-play rotate: false - xy: 356, 93 + xy: 277, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-play-2 rotate: false - xy: 592, 264 + xy: 754, 406 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-power rotate: false - xy: 368, 93 + xy: 298, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-production rotate: false - xy: 380, 93 + xy: 277, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-quit rotate: false - xy: 592, 248 + xy: 754, 390 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-rotate rotate: false - xy: 608, 264 + xy: 181, 78 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-rotate-arrow rotate: false - xy: 608, 248 + xy: 579, 209 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-rotate-left rotate: false - xy: 624, 264 + xy: 181, 62 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-rotate-right rotate: false - xy: 624, 248 + xy: 770, 406 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-save rotate: false - xy: 640, 264 + xy: 770, 390 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-settings rotate: false - xy: 392, 93 + xy: 289, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 +ui/icon-terrain + rotate: false + xy: 194, 101 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 ui/icon-tools rotate: false - xy: 640, 248 + xy: 210, 101 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-touch rotate: false - xy: 131, 8 + xy: 310, 101 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-touchDelete rotate: false - xy: 143, 8 + xy: 289, 77 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-tutorial rotate: false - xy: 693, 275 + xy: 197, 85 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-weapon rotate: false - xy: 155, 8 + xy: 301, 89 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1977,7 +1984,7 @@ ui/scroll index: -1 ui/scroll-horizontal rotate: false - xy: 125, 36 + xy: 592, 251 size: 6, 34 split: 2, 2, 0, 34 pad: 0, 5, 5, 4 @@ -1986,7 +1993,7 @@ ui/scroll-horizontal index: -1 ui/scroll-knob-horizontal rotate: false - xy: 133, 36 + xy: 521, 142 size: 6, 34 split: 2, 2, 0, 34 pad: 0, 5, 13, 12 @@ -2003,21 +2010,21 @@ ui/scroll-knob-vertical index: -1 ui/selection rotate: false - xy: 495, 133 + xy: 576, 222 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 ui/separator rotate: false - xy: 169, 86 + xy: 576, 219 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 ui/slider rotate: false - xy: 652, 238 + xy: 177, 28 size: 1, 8 orig: 1, 8 offset: 0, 0 @@ -2045,11 +2052,18 @@ ui/slider-knob-over index: -1 ui/slider-vertical rotate: false - xy: 724, 348 + xy: 151, 41 size: 8, 1 orig: 8, 1 offset: 0, 0 index: -1 +ui/text-editor + rotate: false + xy: 194, 117 + size: 38, 12 + orig: 38, 12 + offset: 0, 0 + index: -1 ui/text-exit rotate: false xy: 855, 499 @@ -2066,7 +2080,7 @@ ui/text-load index: -1 ui/text-play rotate: false - xy: 524, 231 + xy: 147, 94 size: 29, 12 orig: 29, 12 offset: 0, 0 @@ -2108,7 +2122,7 @@ ui/text-tutorial index: -1 ui/textfield rotate: false - xy: 194, 101 + xy: 125, 64 size: 28, 28 split: 6, 6, 6, 6 orig: 28, 28 @@ -2124,7 +2138,7 @@ ui/textfield-over index: -1 ui/white rotate: false - xy: 592, 282 + xy: 519, 219 size: 3, 3 orig: 3, 3 offset: 0, 0 @@ -2147,42 +2161,42 @@ ui/window-empty index: -1 weapons/blaster rotate: false - xy: 734, 376 + xy: 289, 67 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/flamer rotate: false - xy: 115, 4 + xy: 481, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/mortar rotate: false - xy: 622, 238 + xy: 161, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/multigun rotate: false - xy: 642, 238 + xy: 161, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/railgun rotate: false - xy: 661, 234 + xy: 551, 97 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/triblaster rotate: false - xy: 345, 63 + xy: 201, 25 size: 8, 8 orig: 8, 8 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 4e303b5ec6..7790dd39e3 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 fb3350a1b2..1292905b42 100644 --- a/core/assets/ui/uiskin.json +++ b/core/assets/ui/uiskin.json @@ -49,6 +49,7 @@ io.anuke.ucore.scene.ui.ImageTextButton$ImageTextButtonStyle: { }, io.anuke.ucore.scene.ui.ScrollPane$ScrollPaneStyle: { default: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical}, + volume: {background: button-map, vScroll: scroll, vScrollKnob: scroll-knob-vertical}, clear: {vScroll: scroll, vScrollKnob: scroll-knob-vertical} }, io.anuke.ucore.scene.ui.Window$WindowStyle: { diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 1ec0230adc..e379e1cbfc 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -2,6 +2,7 @@ package io.anuke.mindustry; import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.I18NBundle; import io.anuke.mindustry.core.*; @@ -20,14 +21,18 @@ public class Vars{ public static final float respawnduration = 60*4; //time between waves in frames (on normal mode) public static final float wavespace = 60*60*(android ? 1 : 1); - //waves can last no longer than 2 minutes, otherwise the next one spawns - public static final float maxwavespace = 60*60*2; + //waves can last no longer than 3 minutes, otherwise the next one spawns + public static final float maxwavespace = 60*60*4f; //advance time the pathfinding starts at public static final float aheadPathfinding = 60*20; //how far away from spawn points the player can't place blocks public static final float enemyspawnspace = 65; //discord group URL public static final String discordURL = "https://discord.gg/r8BkXNd"; + //directory for user-created map data + public static final FileHandle customMapDirectory = Gdx.files.local("mindustry-maps/"); + //save file directory + public static final FileHandle saveDirectory = Gdx.files.local("mindustry-saves/"); //scale of the font public static float fontscale = Unit.dp.inPixels(1f)/2f; //camera zoom displayed on startup diff --git a/core/src/io/anuke/mindustry/ai/Pathfind.java b/core/src/io/anuke/mindustry/ai/Pathfind.java index 8940d60625..3987c0ef4c 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfind.java +++ b/core/src/io/anuke/mindustry/ai/Pathfind.java @@ -42,11 +42,10 @@ public class Pathfind{ if(Vars.world.raycastWorld(enemy.x, enemy.y, target.worldx(), target.worldy()) != null){ if(enemy.node > 1) enemy.node = enemy.node - 1; + enemy.idletime = 0; }else{ - //must be blocked by a playermade block + //must be blocked by a playermade block, do nothing } - - enemy.idletime = 0; } //-1 is only possible here if both pathfindings failed, which should NOT happen diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 99996f4bf0..4cebf9df83 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -118,8 +118,8 @@ public class Control extends Module{ Settings.loadAll("io.anuke.moment"); - for(Map map : Map.values()){ - Settings.defaults("hiscore" + map.name(), 0); + for(Map map : Vars.world.maps().list()){ + Settings.defaults("hiscore" + map.name, 0); } player = new Player(); @@ -278,10 +278,10 @@ public class Control extends Module{ wave ++; - int last = Settings.getInt("hiscore" + world.getMap().name()); + int last = Settings.getInt("hiscore" + world.getMap().name); if(wave > last && mode != GameMode.sandbox){ - Settings.putInt("hiscore" + world.getMap().name(), wave); + Settings.putInt("hiscore" + world.getMap().name, wave); Settings.save(); hiscore = true; } @@ -518,7 +518,6 @@ public class Control extends Module{ } if(!tutorial.active() && mode != GameMode.sandbox){ - extrawavetime -= delta(); if(enemies <= 0){ wavetime -= delta(); @@ -531,10 +530,12 @@ public class Control extends Module{ world.pathfinder().updatePath(); lastUpdated = wave + 1; } + }else{ + extrawavetime -= delta(); } } - if(wavetime <= 0){ + if(wavetime <= 0 || extrawavetime <= 0){ runWave(); } diff --git a/core/src/io/anuke/mindustry/core/Tutorial.java b/core/src/io/anuke/mindustry/core/Tutorial.java index 91f9eb5de0..f26c6cb968 100644 --- a/core/src/io/anuke/mindustry/core/Tutorial.java +++ b/core/src/io/anuke/mindustry/core/Tutorial.java @@ -9,7 +9,6 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Map; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.*; import io.anuke.ucore.core.Timers; @@ -33,7 +32,7 @@ public class Tutorial{ } public boolean active(){ - return world.getMap() == Map.tutorial && !GameState.is(State.menu); + return world.getMap().name.equals("tutorial") && !GameState.is(State.menu); } public void buildUI(table table){ diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index c434d44d7b..04f47ce952 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -15,6 +15,8 @@ import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Mindustry; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; +import io.anuke.mindustry.mapeditor.MapEditor; +import io.anuke.mindustry.mapeditor.MapEditorDialog; import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.fragments.*; import io.anuke.mindustry.world.Tile; @@ -38,11 +40,13 @@ public class UI extends SceneModule{ Table loadingtable, desctable, configtable; MindustrySettingsDialog prefs; MindustryKeybindDialog keys; + MapEditorDialog editorDialog; Dialog about, restart, levels, upgrades, load, settingserror, gameerror, discord; MenuDialog menu; Tooltip tooltip; Tile configTile; Array statlist = new Array<>(); + MapEditor editor = new MapEditor(); boolean wasPaused = false; private Fragment blockfrag = new BlocksFragment(), @@ -118,7 +122,7 @@ public class UI extends SceneModule{ Draw.color(); TextureRegion back = Draw.region("background"); - float backscl = 5f; + float backscl = Unit.dp.inPixels(5f); Draw.alpha(0.7f); Core.batch.draw(back, w/2 - back.getRegionWidth()*backscl/2 +240f, h/2 - back.getRegionHeight()*backscl/2 + 250f, @@ -158,6 +162,8 @@ public class UI extends SceneModule{ configtable = new Table(); scene.add(configtable); + editorDialog = new MapEditorDialog(editor); + settingserror = new Dialog("Warning", "dialog"); settingserror.content().add("[crimson]Failed to access local storage.\nSettings will not be saved."); settingserror.content().pad(10f); @@ -438,6 +444,10 @@ public class UI extends SceneModule{ public void showDiscord(){ discord.show(); } + + public void showEditor(){ + editorDialog.show(); + } public void updateItems(){ ((HudFragment)hudfrag).updateItems(); diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index bed99810ba..0d80a5cb9d 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -2,9 +2,6 @@ package io.anuke.mindustry.core; import static io.anuke.mindustry.Vars.*; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; @@ -25,15 +22,15 @@ import io.anuke.ucore.util.Tmp; public class World extends Module{ private int seed; - private Pixmap[] mapPixmaps; - private Texture[] mapTextures; private Map currentMap; private Tile[][] tiles; private Tile[] temptiles = new Tile[4]; private Pathfind pathfind = new Pathfind(); + private Maps maps = new Maps(); public World(){ - loadMaps(); + maps.loadMaps(); + currentMap = maps.getMap(0); } @Override @@ -43,13 +40,11 @@ public class World extends Module{ @Override public void dispose(){ - for(Texture texture : mapTextures){ - texture.dispose(); - } - - for(Pixmap pix : mapPixmaps){ - pix.dispose(); - } + maps.dispose(); + } + + public Maps maps(){ + return maps; } public Pathfind pathfinder(){ @@ -82,11 +77,11 @@ public class World extends Module{ } public int width(){ - return currentMap.width; + return currentMap.getWidth(); } public int height(){ - return currentMap.height; + return currentMap.getHeight(); } public Tile tile(int x, int y){ @@ -115,25 +110,6 @@ public class World extends Module{ return temptiles; } - public Texture getTexture(Map map){ - return mapTextures[map.ordinal()]; - } - - public void loadMaps(){ - Map[] maps = Map.values(); - - mapPixmaps = new Pixmap[maps.length]; - mapTextures = new Texture[maps.length]; - - for(int i = 0; i < maps.length; i ++){ - Pixmap pix = new Pixmap(Gdx.files.internal("maps/"+maps[i]+".png")); - mapPixmaps[i] = pix; - mapTextures[i] = new Texture(pix); - maps[i].width = pix.getWidth(); - maps[i].height = pix.getHeight(); - } - } - private void createTiles(){ for(int x = 0; x < tiles.length; x ++){ for(int y = 0; y < tiles[0].length; y ++){ @@ -164,28 +140,28 @@ public class World extends Module{ if(tiles != null){ clearTileEntities(); - if(tiles.length != map.width || tiles[0].length != map.height){ - tiles = new Tile[map.width][map.height]; + if(tiles.length != map.getWidth() || tiles[0].length != map.getHeight()){ + tiles = new Tile[map.getWidth()][map.getHeight()]; } createTiles(); }else{ - tiles = new Tile[map.width][map.height]; + tiles = new Tile[map.getWidth()][map.getHeight()]; createTiles(); } Vars.control.getSpawnPoints().clear(); - Entities.resizeTree(0, 0, map.width * tilesize, map.height * tilesize); + Entities.resizeTree(0, 0, map.getWidth() * tilesize, map.getHeight() * tilesize); this.seed = seed; - Generator.generate(mapPixmaps[map.ordinal()], tiles); + Generator.generate(map.pixmap, tiles); //TODO multiblock core control.getInput().placeBlock(control.getCore().x, control.getCore().y, ProductionBlocks.core, 0, false, false); - if(map != Map.tutorial){ + if(!map.name.equals("tutorial")){ setDefaultBlocks(); }else{ Vars.control.getTutorial().setDefaultBlocks(control.getCore().x, control.getCore().y); diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java index 53acde1bf3..19cb49bd0b 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java @@ -17,7 +17,7 @@ public class Enemy extends DestructibleEntity{ public final static Color[] tierColors = { Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"), Color.valueOf("ff2d86") }; public final static int maxtier = 4; public final static float maxIdle = 60*1.5f; - public final static float maxIdleLife = 60f*15f; //15 seconds idle = death + public final static float maxIdleLife = 60f*13f; //13 seconds idle = death protected int timeid; protected Timer timer = new Timer(5); @@ -238,7 +238,7 @@ public class Enemy extends DestructibleEntity{ xvelocity = (x - lastx) / Timers.delta(); yvelocity = (y - lasty) / Timers.delta(); - float minv = 0.08f; + float minv = 0.09f; if(xvelocity < minv && yvelocity < minv && node > 0 && target == null){ idletime += Timers.delta(); diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index f31b7e1a4d..5646a82431 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.Date; -import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; @@ -163,14 +162,14 @@ public class SaveIO{ stream.readInt(); //read version stream.readLong(); //read last saved time stream.readByte(); //read the gamemode - return Map.values()[stream.readByte()]; //read the map + return Vars.world.maps().getMap(stream.readByte()); //read the map }catch (IOException e){ throw new RuntimeException(e); } } public static FileHandle fileFor(int slot){ - return Gdx.files.local("mindustry-saves/" + slot + ".mins"); + return Vars.saveDirectory.child(slot + ".mins"); } public static void write(FileHandle file){ @@ -183,7 +182,7 @@ public class SaveIO{ //--GENERAL STATE-- stream.writeByte(Vars.control.getMode().ordinal()); //gamemode - stream.writeByte(Vars.world.getMap().ordinal()); //map ID + stream.writeByte(Vars.world.getMap().id); //map ID stream.writeInt(Vars.control.getWave()); //wave stream.writeFloat(Vars.control.getWaveCountdown()); //wave countdown @@ -399,7 +398,7 @@ public class SaveIO{ int seed = stream.readInt(); int tiles = stream.readInt(); - Vars.world.loadMap(Map.values()[mapid], seed); + Vars.world.loadMap(Vars.world.maps().getMap(mapid), seed); Vars.renderer.clearTiles(); for(Enemy enemy : enemiesToUpdate){ diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditor.java b/core/src/io/anuke/mindustry/mapeditor/MapEditor.java new file mode 100644 index 0000000000..6d1feb782f --- /dev/null +++ b/core/src/io/anuke/mindustry/mapeditor/MapEditor.java @@ -0,0 +1,123 @@ +package io.anuke.mindustry.mapeditor; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Pixmap.Format; +import com.badlogic.gdx.graphics.Texture; + +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.ColorMapper; +import io.anuke.mindustry.world.Map; +import io.anuke.mindustry.world.blocks.Blocks; +import io.anuke.ucore.graphics.Pixmaps; + +public class MapEditor{ + public static final int[] validMapSizes = {64, 128, 256}; + public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15}; + + private Pixmap[] brushPixmaps = new Pixmap[brushSizes.length]; + + private Map map; + private Pixmap pixmap; + private Texture texture; + private int brushSize = 1; + private Block drawBlock = Blocks.stone; + + public MapEditor(){ + for(int i = 0; i < brushSizes.length; i ++){ + int s = brushSizes[i]; + brushPixmaps[i] = new Pixmap(s*2-1, s*2-1, Format.RGB888); + } + } + + public void beginEdit(Map map){ + this.map = map; + this.brushSize = 1; + if(map.pixmap == null){ + pixmap = new Pixmap(256, 256, Format.RGB888); + pixmap.setColor(ColorMapper.getColor(Blocks.stone)); + pixmap.fill(); + texture = new Texture(pixmap); + }else{ + pixmap = map.pixmap; + pixmap.setColor(ColorMapper.getColor(Blocks.stone)); + texture = map.texture; + } + + } + + public Block getDrawBlock(){ + return drawBlock; + } + + public void setDrawBlock(Block block){ + this.drawBlock = block; + pixmap.setColor(ColorMapper.getColor(block)); + } + + public void setBrushSize(int size){ + this.brushSize = size; + } + + public void draw(int dx, int dy){ + if(dx < 0 || dy < 0 || dx >= pixmap.getWidth() || dy >= pixmap.getHeight()){ + return; + } + + Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, texture.getTextureObjectHandle()); + + int dstWidth = brushSize*2-1; + int dstHeight = brushSize*2-1; + int width = pixmap.getWidth(), height = pixmap.getHeight(); + + int x = dx - dstWidth/2; + int y = dy - dstHeight/2; + + if (x + dstWidth > width){ + //x = width - dstWidth; + dstWidth = width - x; + }else if (x < 0){ + dstWidth += x; + x = 0; + } + + //System.out.println(x + " " + y + " " + dstWidth + " " + dstHeight); + + if (y + dstHeight > height){ + //y = height - dstHeight; + dstHeight = height - y; + }else if (y < 0){ + dstHeight += y; + y = 0; + } + + pixmap.fillCircle(dx, dy, brushSize); + + Pixmap dst = brush(brushSize); + dst.drawPixmap(pixmap, x, y, dstWidth, dstHeight, 0, 0, dstWidth, dstHeight); + + Gdx.gl.glTexSubImage2D(GL20.GL_TEXTURE_2D, 0, x, y, dstWidth, dstHeight, + dst.getGLFormat(), dst.getGLType(), dst.getPixels()); + } + + private Pixmap brush(int size){ + for(int i = 0; i < brushSizes.length; i ++){ + if(brushSizes[i] == size){ + return brushPixmaps[i]; + } + } + return null; + } + + public Texture texture(){ + return texture; + } + + public void resize(int mapSize){ + Pixmap out = Pixmaps.resize(pixmap, mapSize, mapSize); + pixmap.dispose(); + pixmap = out; + texture.draw(pixmap, 0, 0); + } +} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java new file mode 100644 index 0000000000..0627ddd01a --- /dev/null +++ b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java @@ -0,0 +1,142 @@ +package io.anuke.mindustry.mapeditor; + +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.ColorMapper; +import io.anuke.mindustry.world.ColorMapper.BlockPair; +import io.anuke.mindustry.world.Map; +import io.anuke.mindustry.world.blocks.Blocks; +import io.anuke.ucore.core.Draw; +import io.anuke.ucore.scene.builders.*; +import io.anuke.ucore.scene.ui.*; +import io.anuke.ucore.scene.ui.layout.Table; +import io.anuke.ucore.scene.ui.layout.Unit; + +public class MapEditorDialog extends Dialog{ + private MapEditor editor; + private MapView view; + + public MapEditorDialog(MapEditor editor){ + super("Map Editor", "dialog"); + this.editor = editor; + view = new MapView(editor); + + setFillParent(true); + + clearChildren(); + pad(0); + build.begin(this); + build(); + build.end(); + + shown(() -> { + editor.beginEdit(new Map()); + }); + } + + public void build(){ + + new table(){{ + float isize = Unit.dp.inPixels(14*3f); + aleft(); + + new table(){{ + defaults().growY().width(130f).units(Unit.dp).padBottom(-6); + + new imagebutton("icon-load", isize, () -> { + + }).text("load map"); + + row(); + + new imagebutton("icon-save", isize, ()->{ + + }).text("save map"); + + row(); + + new imagebutton("icon-load", isize, () -> { + + }).text("load image"); + + row(); + + new imagebutton("icon-save", isize, () -> { + + }).text("save image"); + + row(); + + new imagebutton("icon-cursor", 10f*3f, () -> { + + }).text("resize").padTop(4f); + + row(); + + new imagebutton("icon-arrow-left", isize, () -> { + + }).padBottom(0).text("back"); + + }}.left().growY().end(); + + new table("button"){{ + add(view).grow(); + }}.grow().end(); + + new table(){{ + new imagebutton("icon-terrain", isize, () -> { + + }).margin(12f).text("generate...").width(148f).units(Unit.dp); + + row(); + + new table("button"){{ + margin(10f); + Slider slider = new Slider(0, MapEditor.brushSizes.length-1, 1, false); + slider.moved(f -> { + editor.setBrushSize(MapEditor.brushSizes[(int)(float)f]); + }); + new label(() -> "Brush size: " + MapEditor.brushSizes[(int)slider.getValue()]).left(); + row(); + add(slider).growX().padTop(4f).units(Unit.dp); + }}.growX().end(); + + row(); + + addBlockSelection(get()); + + row(); + + }}.right().growY().end(); + }}.grow().end(); + } + + private void addBlockSelection(Table table){ + Table content = new Table(); + ScrollPane pane = new ScrollPane(content, "volume"); + pane.setFadeScrollBars(false); + pane.setOverscroll(true, false); + ButtonGroup group = new ButtonGroup<>(); + + int i = 0; + + for(BlockPair pair : ColorMapper.getPairs()){ + Block block = pair.wall == Blocks.air ? pair.floor : pair.wall; + + ImageButton button = new ImageButton(Draw.hasRegion(block.name) ? Draw.region(block.name) : Draw.region(block.name + "1"), "toggle"); + button.clicked(() -> editor.setDrawBlock(block)); + button.resizeImage(Unit.dp.inPixels(8*4f)); + group.add(button); + content.add(button).pad(4f).size(53f, 58f).units(Unit.dp); + + if(i++ % 2 == 1){ + content.row(); + } + } + + Table extra = new Table("button"); + extra.addWrap(() -> editor.getDrawBlock().name).width(120f).center(); + table.add(extra).growX(); + table.row(); + table.add(pane).growY().fillX(); + } +} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapFilter.java b/core/src/io/anuke/mindustry/mapeditor/MapFilter.java new file mode 100644 index 0000000000..728630f4eb --- /dev/null +++ b/core/src/io/anuke/mindustry/mapeditor/MapFilter.java @@ -0,0 +1,214 @@ +package io.anuke.mindustry.mapeditor; + +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.ObjectMap; +import com.badlogic.gdx.utils.OrderedMap; + +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.ColorMapper; +import io.anuke.mindustry.world.ColorMapper.BlockPair; +import io.anuke.mindustry.world.blocks.Blocks; +import io.anuke.mindustry.world.blocks.types.Floor; +import io.anuke.ucore.graphics.Pixmaps; +import io.anuke.ucore.noise.RidgedPerlin; +import io.anuke.ucore.noise.Simplex; +import io.anuke.ucore.util.Mathf; + +public class MapFilter{ + private ObjectMap prefs = new OrderedMap(){ + { + put("replace", true); + put("terrain", false); + put("circle", false); + put("distort", false); + put("sand", false); + put("grass", false); + put("stone", false); + put("allgrass", false); + put("allsnow", false); + put("allsand", false); + put("lavarock", false); + put("water", false); + put("oil", false); + put("lavariver", false); + put("slavariver", false); + put("river", false); + put("iceriver", false); + put("oilriver", false); + } + }; + private Simplex sim = new Simplex(); + private RidgedPerlin rid = new RidgedPerlin(1, 10, 20f); + private RidgedPerlin rid2 = new RidgedPerlin(1, 6, 1f); + private RidgedPerlin rid3 = new RidgedPerlin(1, 6, 1f); + + public void randomize(){ + sim.setSeed(Mathf.random(999999)); + rid.setSeed(Mathf.random(999999)); + rid2.setSeed(Mathf.random(999999)); + rid3.setSeed(Mathf.random(999999)); + } + + public ObjectMap getPrefs(){ + return prefs; + } + + public Pixmap process(Pixmap pixmap){ + if(prefs.get("terrain")){ + for(int x = 0; x < pixmap.getWidth(); x++){ + for(int y = 0; y < pixmap.getHeight(); y++){ + float dist = Vector2.dst((float) x / pixmap.getWidth(), (float) y / pixmap.getHeight(), 0.5f, 0.5f) * 2f; + double noise = sim.octaveNoise2D(6, 0.6, 1 / 180.0, x, y + 9999) / (prefs.get("circle") ? 1.7 : 1f) + dist / 10f; + + if(dist > 0.8){ + noise += 2 * (dist - 0.8); + } + + Block block = noise > 0.6 ? Blocks.stoneblock : Blocks.stone; + + pixmap.drawPixel(x, y, ColorMapper.getColor(block)); + } + } + } + + Pixmap src = Pixmaps.copy(pixmap); + + for(int x = 0; x < pixmap.getWidth(); x++){ + for(int y = 0; y < pixmap.getHeight(); y++){ + int dx = 0, dy = 0; + + if(prefs.get("distort")){ + double intensity = 12; + double scale = 80; + double octaves = 4; + double falloff = 0.6; + double nx = (sim.octaveNoise2D(octaves, falloff, 1 / scale, x, y) - 0.5f) * intensity; + double ny = (sim.octaveNoise2D(octaves, falloff, 1 / scale, x, y + 99999) - 0.5f) * intensity; + dx = (int) nx; + dy = (int) ny; + } + + int pix = src.getPixel(x + dx, y + dy); + + BlockPair pair = ColorMapper.get(pix); + Block block = pair == null ? null : pair.wall == Blocks.air ? pair.floor : pair.wall; + + if(block == null) + continue; + + boolean floor = block instanceof Floor; + + double noise = sim.octaveNoise2D(4, 0.6, 1 / 170.0, x, y) + sim.octaveNoise2D(1, 1.0, 1 / 5.0, x, y) / 18.0; + double nwater = sim.octaveNoise2D(1, 1.0, 1 / 130.0, x, y); + noise += nwater / 5.0; + + double noil = sim.octaveNoise2D(1, 1.0, 1 / 150.0, x + 9999, y) + sim.octaveNoise2D(1, 1.0, 1 / 2.0, x, y) / 290.0; + + if(!floor || prefs.get("replace")){ + + if(prefs.get("allgrass")){ + block = floor ? Blocks.grass : Blocks.grassblock; + }else if(prefs.get("allsnow")){ + block = floor ? Blocks.snow : Blocks.snowblock; + }else if(prefs.get("allsand")){ + block = floor ? Blocks.sand : Blocks.sandblock; + }else if(prefs.get("replace")){ + block = floor ? Blocks.stone : Blocks.stoneblock; + } + + if(noise > 0.7 && prefs.get("grass")){ + block = floor ? Blocks.grass : Blocks.grassblock; + } + if(noise > 0.7 && prefs.get("lavarock")){ + block = floor ? Blocks.blackstone : Blocks.blackstoneblock; + } + if(noise > 0.7 && prefs.get("sand")){ + block = floor ? Blocks.sand : Blocks.sandblock; + } + if(noise > 0.8 && prefs.get("stone")){ + block = floor ? Blocks.stone : Blocks.stoneblock; + } + } + + if(floor){ + if(nwater > 0.93 && prefs.get("water")){ + block = Blocks.water; + if(nwater > 0.943){ + block = Blocks.deepwater; + } + } + + if(noil > 0.95 && prefs.get("oil")){ + block = Blocks.dirt; + if(noil > 0.955){ + block = Blocks.oil; + } + } + } + + if(floor && prefs.get("lavariver")){ + double lava = rid.getValue(x, y, 1 / 100f); + double t = 0.6; + if(lava > t){ + block = Blocks.lava; + }else if(lava > t - 0.2){ + block = Blocks.blackstone; + } + } + + if(floor && prefs.get("slavariver")){ + double lava = rid.getValue(x, y, 1 / 40f); + double t = 0.7; + if(lava > t){ + block = Blocks.lava; + }else if(lava > t - 0.3){ + block = Blocks.blackstone; + } + } + + if(floor && prefs.get("oilriver")){ + double lava = rid3.getValue(x, y, 1 / 100f); + double t = 0.9; + if(lava > t){ + block = Blocks.oil; + }else if(lava > t - 0.2){ + block = Blocks.dirt; + } + } + + if(floor && prefs.get("river")){ + double riv = rid2.getValue(x, y, 1 / 140f); + double t = 0.4; + + if(riv > t + 0.1){ + block = Blocks.deepwater; + }else if(riv > t){ + block = Blocks.water; + }else if(riv > t - 0.2){ + block = Blocks.grass; + } + } + + if(floor && prefs.get("iceriver")){ + double riv = rid2.getValue(x, y, 1 / 140f); + double t = 0.4; + + if(riv > t + 0.1){ + block = Blocks.ice; + }else if(riv > t){ + block = Blocks.ice; + }else if(riv > t - 0.2){ + block = Blocks.snow; + } + } + + pixmap.drawPixel(x, y, ColorMapper.getColor(block)); + } + } + + src.dispose(); + + return pixmap; + } +} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapView.java b/core/src/io/anuke/mindustry/mapeditor/MapView.java new file mode 100644 index 0000000000..8fda57d2f6 --- /dev/null +++ b/core/src/io/anuke/mindustry/mapeditor/MapView.java @@ -0,0 +1,66 @@ +package io.anuke.mindustry.mapeditor; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.math.Bresenham2; +import com.badlogic.gdx.math.GridPoint2; +import com.badlogic.gdx.utils.Array; + +import io.anuke.ucore.scene.Element; +import io.anuke.ucore.scene.event.InputEvent; +import io.anuke.ucore.scene.event.InputListener; +import io.anuke.ucore.util.Tmp; + +public class MapView extends Element{ + private MapEditor editor; + private Bresenham2 br = new Bresenham2(); + + public MapView(MapEditor editor){ + this.editor = editor; + addListener(new InputListener(){ + int lastx, lasty; + boolean drawing; + + @Override + public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { + GridPoint2 p = project(x, y); + lastx = p.x; + lasty = p.y; + editor.draw(p.x, p.y); + return true; + } + + @Override + public void touchUp (InputEvent event, float x, float y, int pointer, int button) { + drawing = false; + } + + @Override + public void touchDragged (InputEvent event, float x, float y, int pointer) { + GridPoint2 p = project(x, y); + + if(drawing){ + Array points = br.line(lastx, lasty, p.x, p.y); + for(GridPoint2 point : points){ + editor.draw(point.x, point.y); + } + } + drawing = true; + lastx = p.x; + lasty = p.y; + } + }); + } + + private GridPoint2 project(float x, float y){ + float size = Math.min(width, height); + x = (x - getWidth()/2 + size/2) / size * editor.texture().getWidth(); + y = (y - getHeight()/2 + size/2) / size * editor.texture().getHeight(); + return Tmp.g1.set((int)x, editor.texture().getHeight() - 1 - (int)y); + } + + @Override + public void draw(Batch batch, float alpha){ + float size = Math.min(width, height); + batch.draw(editor.texture(), x + width/2 - size/2, y + height/2 - size/2, size, size); + } +} diff --git a/core/src/io/anuke/mindustry/ui/LevelDialog.java b/core/src/io/anuke/mindustry/ui/LevelDialog.java index 180bc2469b..9ed61d1b81 100644 --- a/core/src/io/anuke/mindustry/ui/LevelDialog.java +++ b/core/src/io/anuke/mindustry/ui/LevelDialog.java @@ -16,7 +16,7 @@ import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.utils.Elements; public class LevelDialog extends FloatingDialog{ - private Map selectedMap = Map.maze; + private Map selectedMap = Vars.world.maps().getMap(0); private TextureRegion region = new TextureRegion(); public LevelDialog(){ @@ -49,8 +49,8 @@ public class LevelDialog extends FloatingDialog{ content().add(selmode); content().row(); - for(int i = 0; i < Map.values().length; i ++){ - Map map = Map.values()[i]; + int i = 0; + for(Map map : Vars.world.maps().list()){ if(!map.visible && !Vars.debug) continue; @@ -59,9 +59,9 @@ public class LevelDialog extends FloatingDialog{ } Table inset = new Table("pane-button"); - inset.add("[accent]"+map.name()).pad(3f).units(Unit.dp); + inset.add("[accent]"+map.name).pad(3f).units(Unit.dp); inset.row(); - inset.add((StringSupplier)(()->"High Score: [accent]" + Settings.getInt("hiscore" + map.name()))) + inset.add((StringSupplier)(()->"High Score: [accent]" + Settings.getInt("hiscore" + map.name))) .pad(3f).units(Unit.dp); inset.pack(); @@ -72,7 +72,7 @@ public class LevelDialog extends FloatingDialog{ Image back = new Image("white"); back.setColor(map.backgroundColor); - ImageButton image = new ImageButton(new TextureRegion(Vars.world.getTexture(map)), "togglemap"); + ImageButton image = new ImageButton(new TextureRegion(map.texture), "togglemap"); image.row(); image.add(inset).width(images+6).units(Unit.dp); image.clicked(()->{ @@ -88,6 +88,8 @@ public class LevelDialog extends FloatingDialog{ maps.add(stack).width(170).pad(4f).units(Unit.dp); maps.padRight(Unit.dp.inPixels(26)); + + i ++; } content().add(pane).uniformX(); diff --git a/core/src/io/anuke/mindustry/ui/LoadDialog.java b/core/src/io/anuke/mindustry/ui/LoadDialog.java index a094b7d3dc..e8b24740c3 100644 --- a/core/src/io/anuke/mindustry/ui/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/LoadDialog.java @@ -55,7 +55,9 @@ public class LoadDialog extends FloatingDialog{ button.row(); - Label info = new Label("[gray]" + (!SaveIO.isSaveValid(i) ? "" : SaveIO.getMode(slot) + ", " + SaveIO.getMap(slot) + ", Wave " + SaveIO.getWave(slot) + "\nLast Saved: " + SaveIO.getTimeString(i))); + Label info = new Label("[gray]" + (!SaveIO.isSaveValid(i) ? "" : SaveIO.getMode(slot) + ", " + + SaveIO.getMap(slot).name + ", Wave " + SaveIO.getWave(slot) + + "\nLast Saved: " + SaveIO.getTimeString(i))); info.setAlignment(Align.center, Align.center); button.add(info).padBottom(3).padTop(7); diff --git a/core/src/io/anuke/mindustry/ui/MapEditor.java b/core/src/io/anuke/mindustry/ui/MapEditor.java deleted file mode 100644 index 33ff2caf4a..0000000000 --- a/core/src/io/anuke/mindustry/ui/MapEditor.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.anuke.mindustry.ui; - -public class MapEditor{ - -} diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index b6f6f778dc..550f442d7d 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -1,5 +1,7 @@ package io.anuke.mindustry.ui.fragments; +import static io.anuke.mindustry.Vars.*; + import com.badlogic.gdx.Gdx; import io.anuke.mindustry.Mindustry; @@ -7,16 +9,10 @@ import io.anuke.mindustry.core.GameState; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.ui.MenuButton; import io.anuke.mindustry.ui.PressGroup; -import io.anuke.mindustry.world.Map; import io.anuke.ucore.scene.builders.imagebutton; import io.anuke.ucore.scene.builders.table; import io.anuke.ucore.scene.ui.layout.Unit; -import static io.anuke.mindustry.Vars.android; -import static io.anuke.mindustry.Vars.control; -import static io.anuke.mindustry.Vars.gwt; -import static io.anuke.mindustry.Vars.ui; - public class MenuFragment implements Fragment{ public void build(){ @@ -30,22 +26,25 @@ public class MenuFragment implements Fragment{ float scale = 4f; defaults().size(100*scale, 21*scale).pad(-10f).units(Unit.dp); - add(new MenuButton("text-play", group, ()-> ui.showLevels())); + add(new MenuButton("text-play", group, ui::showLevels)); row(); - add(new MenuButton("text-tutorial", group, ()-> control.playMap(Map.tutorial))); + add(new MenuButton("text-tutorial", group, ()-> control.playMap(world.maps().getMap("tutorial")))); row(); if(!gwt){ - add(new MenuButton("text-load", group, ()-> ui.showLoadGame())); + add(new MenuButton("text-load", group, ui::showLoadGame)); + row(); + + add(new MenuButton("text-editor", group, ui::showEditor)); row(); } - add(new MenuButton("text-settings", group, ()-> ui.showPrefs())); + add(new MenuButton("text-settings", group, ui::showPrefs)); row(); if(!gwt){ - add(new MenuButton("text-exit", group, ()-> Gdx.app.exit())); + add(new MenuButton("text-exit", group, Gdx.app::exit)); } get().pad(Unit.dp.inPixels(16)); }}.end(); @@ -60,9 +59,13 @@ public class MenuFragment implements Fragment{ new imagebutton("icon-play-2", isize, () -> ui.showLevels()).text("Play").padTop(4f); - new imagebutton("icon-tutorial", isize, ()-> control.playMap(Map.tutorial)).text("Tutorial").padTop(4f); + new imagebutton("icon-tutorial", isize, () -> control.playMap(world.maps().getMap("tutorial"))).text("Tutorial").padTop(4f); new imagebutton("icon-load", isize, () -> ui.showLoadGame()).text("Load").padTop(4f); + + row(); + + new imagebutton("icon-terrain", isize, () -> ui.showEditor()).text("Editor").padTop(4f); new imagebutton("icon-tools", isize, () -> ui.showPrefs()).text("Settings").padTop(4f); diff --git a/core/src/io/anuke/mindustry/world/ColorMapper.java b/core/src/io/anuke/mindustry/world/ColorMapper.java new file mode 100644 index 0000000000..e73dbf60f1 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/ColorMapper.java @@ -0,0 +1,77 @@ +package io.anuke.mindustry.world; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.IntMap; +import com.badlogic.gdx.utils.IntMap.Entry; +import com.badlogic.gdx.utils.ObjectIntMap; + +import io.anuke.mindustry.world.blocks.Blocks; + +public class ColorMapper{ + private static ObjectIntMap reverseColors = new ObjectIntMap<>(); + private static Array pairs = new Array<>(); + private static IntMap colors = map( + "323232", pair(Blocks.stone), + "646464", pair(Blocks.stone, Blocks.stoneblock), + "50965a", pair(Blocks.grass), + "5ab464", pair(Blocks.grass, Blocks.grassblock), + "506eb4", pair(Blocks.water), + "465a96", pair(Blocks.deepwater), + "252525", pair(Blocks.blackstone), + "575757", pair(Blocks.blackstone, Blocks.blackstoneblock), + "988a67", pair(Blocks.sand), + "e5d8bb", pair(Blocks.sand, Blocks.sandblock), + "c2d1d2", pair(Blocks.snow), + "c4e3e7", pair(Blocks.ice), + "f7feff", pair(Blocks.snow, Blocks.snowblock), + "6e501e", pair(Blocks.dirt), + "ed5334", pair(Blocks.lava), + "292929", pair(Blocks.oil) + ); + + public static BlockPair get(int color){ + return colors.get(color); + } + + public static IntMap getColors(){ + return colors; + } + + public static Array getPairs(){ + return pairs; + } + + public static int getColor(Block block){ + return reverseColors.get(block, 0); + } + + private static BlockPair pair(Block floor, Block wall){ + return new BlockPair(floor, wall); + } + + private static BlockPair pair(Block floor){ + return new BlockPair(floor, Blocks.air); + } + + private static IntMap map(Object...objects){ + IntMap colors = new IntMap<>(); + for(int i = 0; i < objects.length/2; i ++){ + colors.put(Color.rgba8888(Color.valueOf((String)objects[i*2])), (BlockPair)objects[i*2+1]); + pairs.add((BlockPair)objects[i*2+1]); + } + for(Entry e : colors.entries()){ + reverseColors.put(e.value.wall == Blocks.air ? e.value.floor : e.value.wall, e.key); + } + return colors; + } + + public static class BlockPair{ + public final Block floor, wall; + + private BlockPair(Block floor, Block wall){ + this.floor = floor; + this.wall = wall; + } + } +} diff --git a/core/src/io/anuke/mindustry/world/Generator.java b/core/src/io/anuke/mindustry/world/Generator.java index 9ec6a425bf..ceff64f2e8 100644 --- a/core/src/io/anuke/mindustry/world/Generator.java +++ b/core/src/io/anuke/mindustry/world/Generator.java @@ -2,42 +2,26 @@ package io.anuke.mindustry.world; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.IntMap; +import com.badlogic.gdx.utils.ObjectMap; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.enemies.TargetEnemy; -import io.anuke.mindustry.world.blocks.*; -import io.anuke.mindustry.world.blocks.types.Floor; +import io.anuke.mindustry.world.ColorMapper.BlockPair; +import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.ucore.graphics.Hue; import io.anuke.ucore.noise.Noise; import io.anuke.ucore.util.Mathf; public class Generator{ - public static boolean debugBlockspam = false; - static final int spawn = Color.rgba8888(Color.RED); static final int start = Color.rgba8888(Color.GREEN); - - public static IntMap colors = map( - Hue.rgb(80, 150, 90), Blocks.grass, - Hue.rgb(90, 180, 100), Blocks.grassblock, - Hue.rgb(80, 110, 180), Blocks.water, - Hue.rgb(70, 90, 150), Blocks.deepwater, - Hue.rgb(110, 80, 30), Blocks.dirt, - Hue.rgb(160, 120, 70), Blocks.dirtblock, - Hue.rgb(100, 100, 100), Blocks.stoneblock, - Color.valueOf("323232"), Blocks.stone, - Color.valueOf("575757"), Blocks.blackstoneblock, - Color.valueOf("252525"), Blocks.blackstone, - Color.valueOf("ed5334"), Blocks.lava, - Color.valueOf("292929"), Blocks.oil, - Color.valueOf("e5d8bb"), Blocks.sandblock, - Color.valueOf("988a67"), Blocks.sand, - Color.valueOf("f7feff"), Blocks.snowblock, - Color.valueOf("c2d1d2"), Blocks.snow, - Color.valueOf("c4e3e7"), Blocks.ice - ); + static final ObjectMap rocks = new ObjectMap(){{ + put(Blocks.stone, Blocks.rock); + put(Blocks.snow, Blocks.icerock); + put(Blocks.grass, Blocks.shrub); + put(Blocks.blackstone, Blocks.blackrock); + }}; /**Returns world size.*/ public static void generate(Pixmap pixmap, Tile[][] tiles){ @@ -50,14 +34,11 @@ public class Generator{ Block block = Blocks.air; int color = pixmap.getPixel(x, pixmap.getHeight()-1-y); + BlockPair pair = ColorMapper.get(color); - if(colors.containsKey(color)){ - //TODO less hacky method - if(!(colors.get(color) instanceof Floor)){ - block = colors.get(color); - }else{ - floor = colors.get(color); - } + if(pair != null){ + block = pair.wall; + floor = pair.floor; }else if(color == start){ Vars.control.setCore(Vars.world.tile(x, y)); }else if(color == spawn){ @@ -65,18 +46,8 @@ public class Generator{ floor = Blocks.dirt; } - if(block == Blocks.air){ - if(floor == Blocks.stone && Mathf.chance(0.02)){ - block = Blocks.rock; - } - - if(floor == Blocks.snow && Mathf.chance(0.02)){ - block = Blocks.icerock; - } - - if(floor == Blocks.blackstone && Mathf.chance(0.03)){ - block = Blocks.blackrock; - } + if(block == Blocks.air && Mathf.chance(0.025) && rocks.containsKey(floor)){ + block = rocks.get(floor); } if(floor == Blocks.stone || floor == Blocks.grass || floor == Blocks.blackstone || @@ -98,32 +69,11 @@ public class Generator{ } } - if(block == Blocks.grassblock){ - floor = Blocks.grass; - } - - if(block == Blocks.snowblock){ - floor = Blocks.snow; - } - - if(block == Blocks.sandblock){ - floor = Blocks.sand; - } - - if(floor == Blocks.grass && Mathf.chance(0.03) && block == Blocks.air){ - block = Blocks.shrub; - } - if(color == Hue.rgb(Color.PURPLE)){ if(!Vars.android) new TargetEnemy().set(x * Vars.tilesize, y * Vars.tilesize).add(); floor = Blocks.stone; } - //preformance debugging - if(debugBlockspam && Vector2.dst(0, 0, x, y) < 260){ - block = Mathf.choose(ProductionBlocks.omnidrill, DistributionBlocks.conveyor, DistributionBlocks.router, WeaponBlocks.turret); - } - tiles[x][y].setBlock(block, 0); tiles[x][y].setFloor(floor); } diff --git a/core/src/io/anuke/mindustry/world/Map.java b/core/src/io/anuke/mindustry/world/Map.java index 8dace847cb..34047f06d8 100644 --- a/core/src/io/anuke/mindustry/world/Map.java +++ b/core/src/io/anuke/mindustry/world/Map.java @@ -1,49 +1,25 @@ package io.anuke.mindustry.world; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; -public enum Map{ - maze("desc"), - fortress("desc"), - sinkhole("desc"), - caves("desc"), - volcano("desc", true), - caldera("desc"), - scorch("desc", Color.valueOf("e5d8bb")), - desert("desc"), - islands("desc", Color.valueOf("e5d8bb")), - grassland("desc", Color.valueOf("5ab464")), - tundra("desc"), - spiral("desc", Color.valueOf("f7feff")), - tutorial(false), - test1(false), - test2(false), - test3(false); - - public final boolean visible; - public final String description; - public final boolean flipBase; - public int width, height; +public class Map{ + public int id; + public String name; + public boolean visible = true; + public boolean flipBase = false; + public boolean custom = false; public Color backgroundColor = Color.valueOf("646464"); - private Map(boolean visible){ - this.visible = visible; - this.flipBase = false; - this.description = "Test map!"; + public transient Pixmap pixmap; + public transient Texture texture; + + public int getWidth(){ + return pixmap.getWidth(); } - private Map(String description){ - this(description, false); - } - - private Map(String description, boolean flipBase){ - this.visible = true; - this.flipBase = flipBase; - this.description = description; - } - - private Map(String description, Color background){ - this(description); - backgroundColor = background; + public int getHeight(){ + return pixmap.getHeight(); } } diff --git a/core/src/io/anuke/mindustry/world/Maps.java b/core/src/io/anuke/mindustry/world/Maps.java new file mode 100644 index 0000000000..2fc96f679b --- /dev/null +++ b/core/src/io/anuke/mindustry/world/Maps.java @@ -0,0 +1,119 @@ +package io.anuke.mindustry.world; + +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.Texture; +import com.badlogic.gdx.utils.*; +import com.badlogic.gdx.utils.Json.Serializer; +import com.badlogic.gdx.utils.JsonWriter.OutputType; + +import io.anuke.mindustry.Vars; +import io.anuke.ucore.graphics.Pixmaps; + +public class Maps implements Disposable{ + private IntMap maps = new IntMap<>(); + private ObjectMap mapNames = new ObjectMap<>(); + private int lastID; + private Json json = new Json(); + + public Maps() { + json.setOutputType(OutputType.json); + json.setElementType(ArrayContainer.class, "maps", Map.class); + json.setSerializer(Color.class, new ColorSerializer()); + } + + public Iterable list(){ + return maps.values(); + } + + public Map getMap(int id){ + return maps.get(id); + } + + public Map getMap(String name){ + return mapNames.get(name); + } + + public void loadMaps(){ + if(!loadMapFile(Gdx.files.internal("maps/maps.json"))){ + throw new RuntimeException("Failed to load maps!"); + } + + if(!loadMapFile(Vars.customMapDirectory.child("maps.json"))){ + try{ + Vars.customMapDirectory.child("maps.json").writeString("{}", false); + }catch(Exception e){ + throw new RuntimeException("Failed to create custom map directory!"); + } + } + } + + public void saveMaps(Array array, FileHandle file){ + json.toJson(new ArrayContainer(array), file); + } + + public void saveCustomMap(Map toSave){ + Array out = new Array<>(); + for(Map map : maps.values()){ + if(map.custom) + out.add(map); + } + Pixmaps.write(toSave.pixmap, Vars.customMapDirectory.child(toSave.name + ".png")); + saveMaps(out, Vars.customMapDirectory.child("maps.json")); + } + + private boolean loadMapFile(FileHandle file){ + try{ + Array arr = json.fromJson(ArrayContainer.class, file).maps; + if(arr != null){ //can be an empty map file + for(Map map : arr){ + map.pixmap = new Pixmap(file.sibling(map.name + ".png")); + map.texture = new Texture(map.pixmap); + maps.put(map.id, map); + mapNames.put(map.name, map); + } + } + return true; + }catch(Exception e){ + e.printStackTrace(); + Gdx.app.error("Mindustry-Maps", "Failed loading map file: " + file); + return false; + } + } + + @Override + public void dispose(){ + for(Map map : maps.values()){ + map.texture.dispose(); + map.pixmap.dispose(); + } + maps.clear(); + } + + private static class ArrayContainer{ + Array maps; + + ArrayContainer() { + } + + ArrayContainer(Array maps) { + this.maps = maps; + } + } + + private class ColorSerializer implements Serializer{ + + @Override + public void write(Json json, Color object, Class knownType){ + json.writeValue(object.toString().substring(0, 6)); + } + + @Override + public Color read(Json json, JsonValue jsonData, Class type){ + return Color.valueOf(jsonData.asString()); + } + + } +} diff --git a/desktop/mindustry-maps/maps.json b/desktop/mindustry-maps/maps.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/desktop/mindustry-maps/maps.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index eb6289de1b..5a21731502 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -23,7 +23,7 @@ public class DesktopLauncher { config.setMaximized(true); config.setWindowedMode(960, 540); config.setWindowIcon("sprites/icon.png"); - config.useVsync(false); + config.useVsync(true); Mindustry.platforms = new PlatformFunction(){ SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm");