diff --git a/core/assets-raw/sprites/ui/icons/icon-file-image.png b/core/assets-raw/sprites/ui/icons/icon-file-image.png new file mode 100644 index 0000000000..a16c5170a7 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-file-image.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-file.png b/core/assets-raw/sprites/ui/icons/icon-file.png new file mode 100644 index 0000000000..f91d5a46a7 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-file.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-floppy-16.png b/core/assets-raw/sprites/ui/icons/icon-floppy-16.png new file mode 100644 index 0000000000..7993fad275 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-floppy-16.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index fa563d3683..7ac6bde411 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -150,8 +150,8 @@ text.enemies={0} Enemies text.enemies.single={0} Enemy text.loadimage=Load Image text.saveimage=Save Image -text.oregen=Ore Generation text.unknown=Unknown +text.editor.oregen=Ore Generation text.editor.mapinfo=Map Info text.editor.author=Author: text.editor.description=Description: @@ -164,8 +164,21 @@ text.editor.generate=Generate text.editor.resize=Resize text.editor.loadmap=Load Map text.editor.savemap=Save Map +text.editor.saved=Saved! +text.editor.save.noname=Your map does not have a name! Set one in the 'map info' menu. +text.editor.save.overwrite=Your map overwrites a built-in map! Pick a different name in the 'map info' menu. +text.editor.import=Import... text.editor.importmap=Import Map -text.editor.exportmap=Export Map +text.editor.importmap.description=Import an already existing map +text.editor.importfile=Import File +text.editor.importfile.description=Import an external map file +text.editor.importimage=Import Terrain Image +text.editor.importimage.description=Import an external map image file +text.editor.export=Export... +text.editor.exportfile=Export File +text.editor.exportfile.description=Export a map file +text.editor.exportimage=Export Terrain Image +text.editor.exportimage.description=Export a map image file text.editor.loadimage=Import Terrain text.editor.saveimage=Export Terrain text.editor.unsaved=[scarlet]You have unsaved changes![]\nAre you sure you want to exit? @@ -177,7 +190,6 @@ text.editor.resizemap=Resize Map text.editor.resizebig=[scarlet]Warning!\n[]Maps larger than 256 units may be laggy and unstable. text.editor.mapname=Map Name: text.editor.overwrite=[accent]Warning!\nThis overwrites an existing map. -text.editor.failoverwrite=[crimson]Cannot overwrite default map! text.editor.selectmap=Select a map to load: text.width=Width: text.height=Height: diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index b91950b162..5ef7d30cc5 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -13,98 +13,98 @@ background index: -1 bridgeconduit rotate: false - xy: 683, 307 + xy: 745, 338 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridgeconduit-arrow rotate: false - xy: 693, 307 + xy: 745, 328 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridgeconduit-bridge rotate: false - xy: 703, 307 + xy: 755, 339 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridgeconduit-end rotate: false - xy: 481, 174 + xy: 755, 329 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridgeconveyor rotate: false - xy: 811, 427 + xy: 695, 313 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridgeconveyor-arrow rotate: false - xy: 811, 417 + xy: 705, 315 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridgeconveyor-bridge rotate: false - xy: 811, 407 + xy: 715, 318 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bridgeconveyor-end rotate: false - xy: 811, 397 + xy: 725, 318 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-bottom rotate: false - xy: 427, 93 + xy: 485, 100 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-top rotate: false - xy: 426, 73 + xy: 808, 389 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduittunnel rotate: false - xy: 426, 63 + xy: 808, 379 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor rotate: false - xy: 427, 53 + xy: 808, 369 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyormove rotate: false - xy: 427, 43 + xy: 808, 359 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyortunnel rotate: false - xy: 427, 33 + xy: 808, 349 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -118,98 +118,98 @@ core index: -1 junction rotate: false - xy: 514, 189 + xy: 652, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laserconduit rotate: false - xy: 524, 189 + xy: 658, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laserconduit-arrow rotate: false - xy: 534, 189 + xy: 662, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laserconduit-bridge rotate: false - xy: 544, 189 + xy: 668, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laserconduit-end rotate: false - xy: 554, 195 + xy: 672, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laserconveyor rotate: false - xy: 564, 195 + xy: 678, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laserconveyor-arrow rotate: false - xy: 554, 185 + xy: 682, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laserconveyor-bridge rotate: false - xy: 564, 185 + xy: 688, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laserconveyor-end rotate: false - xy: 815, 457 + xy: 692, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquidjunction rotate: false - xy: 885, 459 + xy: 728, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquidrouter rotate: false - xy: 895, 459 + xy: 732, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquidrouter-bottom rotate: false - xy: 905, 459 + xy: 738, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquidrouter-liquid rotate: false - xy: 915, 459 + xy: 742, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquidrouter-top rotate: false - xy: 925, 459 + xy: 748, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -237,84 +237,84 @@ liquidtank-top index: -1 multiplexer rotate: false - xy: 228, 32 + xy: 772, 372 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 overflowgate rotate: false - xy: 825, 449 + xy: 735, 298 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 poweredconveyor rotate: false - xy: 845, 449 + xy: 798, 275 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 poweredconveyormove rotate: false - xy: 855, 449 + xy: 808, 279 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulseconduit-bottom rotate: false - xy: 895, 449 + xy: 798, 265 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulseconduit-top rotate: false - xy: 905, 449 + xy: 808, 259 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 router rotate: false - xy: 821, 427 + xy: 557, 185 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sortedunloader rotate: false - xy: 994, 439 + xy: 895, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sorter rotate: false - xy: 1004, 439 + xy: 905, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 splitter rotate: false - xy: 828, 377 + xy: 925, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steelconveyor rotate: false - xy: 828, 367 + xy: 935, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steelconveyormove rotate: false - xy: 828, 357 + xy: 945, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -328,7 +328,7 @@ teleporter-top index: -1 unloader rotate: false - xy: 871, 399 + xy: 1005, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -342,7 +342,7 @@ vault index: -1 weaponfactory rotate: false - xy: 455, 106 + xy: 481, 166 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -356,49 +356,49 @@ blackrock1 index: -1 blackrockshadow1 rotate: false - xy: 467, 124 + xy: 499, 174 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone1 rotate: false - xy: 477, 124 + xy: 695, 343 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone2 rotate: false - xy: 417, 53 + xy: 695, 333 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone3 rotate: false - xy: 417, 43 + xy: 695, 323 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstoneblock1 rotate: false - xy: 241, 4 + xy: 705, 345 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstoneblock2 rotate: false - xy: 719, 314 + xy: 705, 335 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstoneblock3 rotate: false - xy: 729, 314 + xy: 705, 325 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -412,49 +412,49 @@ blackstoneedge index: -1 coal1 rotate: false - xy: 808, 365 + xy: 755, 319 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coal2 rotate: false - xy: 808, 355 + xy: 245, 9 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coal3 rotate: false - xy: 808, 345 + xy: 651, 310 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 deepwater rotate: false - xy: 416, 23 + xy: 765, 344 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt1 rotate: false - xy: 426, 23 + xy: 775, 344 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt2 rotate: false - xy: 437, 86 + xy: 765, 334 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt3 rotate: false - xy: 447, 86 + xy: 765, 324 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -468,525 +468,525 @@ dirtedge index: -1 grass1 rotate: false - xy: 437, 56 + xy: 775, 314 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass2 rotate: false - xy: 437, 46 + xy: 785, 315 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass3 rotate: false - xy: 447, 56 + xy: 795, 315 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grassblock1 rotate: false - xy: 437, 36 + xy: 805, 319 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grassblock2 rotate: false - xy: 447, 46 + xy: 755, 309 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grassedge rotate: false - xy: 163, 2 + xy: 149, 2 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 ice1 rotate: false - xy: 447, 36 + xy: 765, 305 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice2 rotate: false - xy: 457, 56 + xy: 775, 304 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice3 rotate: false - xy: 457, 46 + xy: 785, 305 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 iceedge rotate: false - xy: 177, 2 + xy: 163, 2 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 icerock1 rotate: false - xy: 457, 36 + xy: 795, 305 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icerock2 rotate: false - xy: 467, 90 + xy: 805, 309 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icerockshadow1 rotate: false - xy: 477, 90 + xy: 805, 299 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rockshadow1 rotate: false - xy: 477, 90 + xy: 805, 299 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icerockshadow2 rotate: false - xy: 466, 71 + xy: 437, 96 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rockshadow2 rotate: false - xy: 466, 71 + xy: 437, 96 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 iron1 rotate: false - xy: 437, 26 + xy: 467, 96 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 iron2 rotate: false - xy: 447, 26 + xy: 811, 427 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 iron3 rotate: false - xy: 457, 26 + xy: 811, 417 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lava rotate: false - xy: 825, 459 + xy: 698, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lavaedge rotate: false - xy: 191, 2 + xy: 177, 2 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 lead1 rotate: false - xy: 845, 459 + xy: 708, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lead2 rotate: false - xy: 855, 459 + xy: 712, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lead3 rotate: false - xy: 865, 459 + xy: 718, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor1 rotate: false - xy: 955, 459 + xy: 772, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor2 rotate: false - xy: 965, 459 + xy: 758, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor3 rotate: false - xy: 975, 459 + xy: 768, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor4 rotate: false - xy: 985, 459 + xy: 778, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor5 rotate: false - xy: 995, 459 + xy: 782, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalfloor6 rotate: false - xy: 1005, 459 + xy: 792, 285 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 metalflooredge rotate: false - xy: 410, 95 + xy: 191, 2 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mossblock rotate: false - xy: 1015, 457 + xy: 788, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 oil rotate: false - xy: 815, 447 + xy: 715, 298 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 oiledge rotate: false - xy: 266, 47 + xy: 410, 95 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 rock1 rotate: false - xy: 1005, 449 + xy: 557, 195 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rock2 rotate: false - xy: 1015, 447 + xy: 567, 195 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand1 rotate: false - xy: 821, 397 + xy: 567, 175 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand2 rotate: false - xy: 821, 387 + xy: 577, 188 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand3 rotate: false - xy: 818, 377 + xy: 587, 188 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sandblock1 rotate: false - xy: 818, 367 + xy: 577, 178 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sandblock2 rotate: false - xy: 818, 357 + xy: 597, 188 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sandblock3 rotate: false - xy: 818, 347 + xy: 587, 178 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sandedge rotate: false - xy: 280, 47 + xy: 266, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shrub rotate: false - xy: 884, 439 + xy: 607, 170 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shrubshadow rotate: false - xy: 894, 439 + xy: 617, 170 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow1 rotate: false - xy: 924, 439 + xy: 825, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow2 rotate: false - xy: 934, 439 + xy: 835, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow3 rotate: false - xy: 944, 439 + xy: 845, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snowblock1 rotate: false - xy: 954, 439 + xy: 855, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snowblock2 rotate: false - xy: 964, 439 + xy: 865, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snowblock3 rotate: false - xy: 974, 439 + xy: 875, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snowedge rotate: false - xy: 336, 47 + xy: 322, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 space rotate: false - xy: 1014, 437 + xy: 915, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 spaceedge rotate: false - xy: 350, 47 + xy: 336, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 stone1 rotate: false - xy: 831, 397 + xy: 995, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone2 rotate: false - xy: 831, 387 + xy: 1005, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone3 rotate: false - xy: 841, 429 + xy: 1015, 457 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneblock1 rotate: false - xy: 841, 419 + xy: 815, 447 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneblock2 rotate: false - xy: 851, 429 + xy: 814, 437 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneblock3 rotate: false - xy: 841, 409 + xy: 825, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneedge rotate: false - xy: 392, 47 + xy: 378, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 thorium1 rotate: false - xy: 861, 419 + xy: 875, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 thorium2 rotate: false - xy: 871, 429 + xy: 885, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 thorium3 rotate: false - xy: 841, 389 + xy: 895, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium1 rotate: false - xy: 851, 399 + xy: 905, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium2 rotate: false - xy: 861, 409 + xy: 915, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium3 rotate: false - xy: 871, 419 + xy: 925, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 water rotate: false - xy: 901, 429 + xy: 821, 417 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 wateredge rotate: false - xy: 308, 33 + xy: 528, 195 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 block-border rotate: false - xy: 406, 29 + xy: 735, 338 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-middle rotate: false - xy: 417, 33 + xy: 725, 328 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pump-liquid rotate: false - xy: 417, 33 + xy: 725, 328 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 border rotate: false - xy: 673, 307 + xy: 735, 328 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit-liquid rotate: false - xy: 426, 83 + xy: 497, 104 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 cross-1 rotate: false - xy: 251, 7 + xy: 808, 339 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1014,7 +1014,7 @@ cross-4 index: -1 enemyspawn rotate: false - xy: 456, 76 + xy: 785, 325 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1028,42 +1028,42 @@ nuclearreactor-shadow index: -1 playerspawn rotate: false - xy: 835, 449 + xy: 745, 298 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ripples rotate: false - xy: 743, 324 + xy: 653, 204 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 rubble-1-0 rotate: false - xy: 466, 184 + xy: 281, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 rubble-1-1 rotate: false - xy: 463, 166 + xy: 299, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 rubble-2-0 rotate: false - xy: 263, 109 + xy: 317, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 rubble-2-1 rotate: false - xy: 281, 109 + xy: 335, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -1084,7 +1084,7 @@ rubble-3-1 index: -1 shadow-1 rotate: false - xy: 755, 336 + xy: 653, 192 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1119,7 +1119,7 @@ shadow-5 index: -1 shadow-round-1 rotate: false - xy: 755, 324 + xy: 718, 348 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1140,14 +1140,14 @@ batterylarge index: -1 combustiongenerator rotate: false - xy: 437, 96 + xy: 661, 310 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 combustiongenerator-top rotate: false - xy: 447, 96 + xy: 497, 124 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1217,7 +1217,7 @@ largesolarpanel index: -1 liquidcombustiongenerator rotate: false - xy: 875, 459 + xy: 722, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1245,21 +1245,21 @@ nuclearreactor-lights index: -1 powerinfinite rotate: false - xy: 865, 449 + xy: 818, 279 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 powernode rotate: false - xy: 875, 449 + xy: 808, 269 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 powernodelarge rotate: false - xy: 790, 381 + xy: 466, 184 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -1273,42 +1273,42 @@ powernodelarge-shadow index: -1 powervoid rotate: false - xy: 885, 449 + xy: 818, 269 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rtgenerator rotate: false - xy: 821, 417 + xy: 557, 175 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rtgenerator-top rotate: false - xy: 821, 407 + xy: 567, 185 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shieldgenerator rotate: false - xy: 844, 439 + xy: 617, 180 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shieldprojector rotate: false - xy: 299, 109 + xy: 353, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 solarpanel rotate: false - xy: 984, 439 + xy: 885, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1329,7 +1329,7 @@ teleporter-top index: -1 thermalgenerator rotate: false - xy: 851, 409 + xy: 865, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1441,105 +1441,105 @@ cultivator-top index: -1 extractor rotate: false - xy: 446, 66 + xy: 795, 325 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 fluxpump rotate: false - xy: 456, 66 + xy: 805, 329 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 incinerator rotate: false - xy: 476, 70 + xy: 457, 96 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 irondrill rotate: false - xy: 609, 190 + xy: 811, 407 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 irondrill-rotator rotate: false - xy: 619, 190 + xy: 815, 329 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumdrill-rotator rotate: false - xy: 619, 190 + xy: 815, 329 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 irondrill-top rotate: false - xy: 322, 25 + xy: 815, 319 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 itemsource rotate: false - xy: 494, 189 + xy: 815, 289 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 itemvoid rotate: false - xy: 504, 189 + xy: 648, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laserdrill rotate: false - xy: 156, 34 + xy: 155, 16 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 laserdrill-rotator rotate: false - xy: 174, 34 + xy: 173, 16 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 laserdrill-top rotate: false - xy: 192, 34 + xy: 191, 16 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 lavasmelter rotate: false - xy: 835, 459 + xy: 702, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquidsource rotate: false - xy: 935, 459 + xy: 752, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 melter rotate: false - xy: 945, 459 + xy: 762, 285 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1602,7 +1602,7 @@ oilextractor-top index: -1 oilrefinery rotate: false - xy: 814, 437 + xy: 725, 298 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1637,210 +1637,210 @@ plasmadrill-top index: -1 plasticformer rotate: false - xy: 209, 14 + xy: 772, 354 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 plasticformer-top rotate: false - xy: 227, 14 + xy: 790, 381 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 poweralloysmelter rotate: false - xy: 772, 372 + xy: 790, 363 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 poweralloysmelter-top rotate: false - xy: 772, 354 + xy: 790, 345 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 powersmelter rotate: false - xy: 790, 363 + xy: 463, 166 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 powersmelter-top rotate: false - xy: 790, 345 + xy: 263, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 siliconsmelter-top rotate: false - xy: 790, 345 + xy: 263, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 pulverizer rotate: false - xy: 915, 449 + xy: 818, 259 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulverizer-rotator rotate: false - xy: 925, 449 + xy: 609, 190 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pump rotate: false - xy: 935, 449 + xy: 619, 190 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 reinforceddrill rotate: false - xy: 945, 449 + xy: 410, 53 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 reinforceddrill-rotator rotate: false - xy: 955, 449 + xy: 420, 53 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 reinforceddrill-top rotate: false - xy: 965, 449 + xy: 410, 43 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 separator rotate: false - xy: 824, 437 + xy: 597, 178 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 separator-liquid rotate: false - xy: 834, 439 + xy: 607, 180 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 siliconextractor rotate: false - xy: 904, 439 + xy: 495, 94 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 siliconsmelter rotate: false - xy: 317, 109 + xy: 371, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 smelter rotate: false - xy: 914, 439 + xy: 815, 457 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steeldrill rotate: false - xy: 828, 347 + xy: 955, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steeldrill-rotator rotate: false - xy: 831, 427 + xy: 965, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steeldrill-top rotate: false - xy: 831, 417 + xy: 975, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stonedrill rotate: false - xy: 851, 419 + xy: 835, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneformer rotate: false - xy: 861, 429 + xy: 845, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumdrill rotate: false - xy: 881, 429 + xy: 935, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumdrill-top rotate: false - xy: 851, 389 + xy: 945, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 waterextractor rotate: false - xy: 371, 109 + xy: 437, 106 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 waterextractor-liquid rotate: false - xy: 389, 109 + xy: 455, 106 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 waterextractor-rotator rotate: false - xy: 407, 109 + xy: 467, 148 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 waterextractor-top rotate: false - xy: 437, 106 + xy: 467, 130 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 block-1 rotate: false - xy: 759, 314 + xy: 715, 328 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1882,7 +1882,7 @@ chainturret index: -1 doubleturret rotate: false - xy: 446, 76 + xy: 785, 335 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1952,77 +1952,77 @@ gatlingturret-heat index: -1 laserturret rotate: false - xy: 719, 336 + xy: 386, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 laserturret-heat rotate: false - xy: 719, 324 + xy: 398, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 liquidturret rotate: false - xy: 155, 16 + xy: 210, 32 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 liquidturret-liquid rotate: false - xy: 173, 16 + xy: 228, 32 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 megarepairturret rotate: false - xy: 191, 16 + xy: 209, 14 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 missileturret rotate: false - xy: 210, 32 + xy: 227, 14 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 railgunturret rotate: false - xy: 731, 336 + xy: 653, 240 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 railgunturret-heat rotate: false - xy: 731, 324 + xy: 653, 228 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 repairturret rotate: false - xy: 743, 336 + xy: 653, 216 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 teslaturret rotate: false - xy: 473, 112 + xy: 730, 348 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 teslaturret-heat rotate: false - xy: 473, 100 + xy: 742, 348 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2078,35 +2078,35 @@ walkerfactory-top-open index: -1 repairpoint rotate: false - xy: 975, 449 + xy: 420, 43 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 repairpoint-turret rotate: false - xy: 985, 449 + xy: 410, 33 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 resupplypoint rotate: false - xy: 995, 449 + xy: 420, 33 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 compositewall rotate: false - xy: 457, 96 + xy: 497, 114 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 door rotate: false - xy: 457, 86 + xy: 775, 334 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -2127,14 +2127,14 @@ door-large-open index: -1 door-open rotate: false - xy: 436, 76 + xy: 775, 324 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 duriumwall rotate: false - xy: 436, 66 + xy: 795, 335 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -2148,49 +2148,49 @@ duriumwall-large index: -1 ironwall rotate: false - xy: 332, 25 + xy: 815, 309 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steelwall rotate: false - xy: 831, 407 + xy: 985, 459 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steelwall-large rotate: false - xy: 335, 109 + xy: 389, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 stonewall rotate: false - xy: 841, 399 + xy: 855, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumshieldwall rotate: false - xy: 861, 399 + xy: 955, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumwall rotate: false - xy: 871, 409 + xy: 965, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumwall-large rotate: false - xy: 353, 109 + xy: 407, 109 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -2218,14 +2218,14 @@ blank index: -1 bullet rotate: false - xy: 707, 344 + xy: 489, 198 size: 9, 9 orig: 9, 9 offset: 0, 0 index: -1 bullet-back rotate: false - xy: 651, 309 + xy: 498, 184 size: 9, 9 orig: 9, 9 offset: 0, 0 @@ -2246,14 +2246,14 @@ clear index: -1 enemyarrow rotate: false - xy: 467, 81 + xy: 765, 315 size: 8, 7 orig: 8, 7 offset: 0, 0 index: -1 laser rotate: false - xy: 811, 437 + xy: 406, 47 size: 1, 12 orig: 1, 12 offset: 0, 0 @@ -2274,35 +2274,35 @@ laserfull index: -1 shell rotate: false - xy: 662, 309 + xy: 754, 349 size: 9, 9 orig: 9, 9 offset: 0, 0 index: -1 shell-back rotate: false - xy: 406, 50 + xy: 246, 30 size: 9, 9 orig: 9, 9 offset: 0, 0 index: -1 shot rotate: false - xy: 874, 439 + xy: 597, 168 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 transfer rotate: false - xy: 808, 385 + xy: 811, 437 size: 1, 12 orig: 1, 12 offset: 0, 0 index: -1 transfer-arrow rotate: false - xy: 881, 419 + xy: 975, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -2316,105 +2316,105 @@ transfer-end index: -1 item-biomatter rotate: false - xy: 342, 25 + xy: 815, 299 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-coal rotate: false - xy: 352, 25 + xy: 715, 308 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-densealloy rotate: false - xy: 362, 25 + xy: 725, 308 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-iron rotate: false - xy: 372, 25 + xy: 735, 308 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-lead rotate: false - xy: 382, 25 + xy: 745, 308 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-plastic rotate: false - xy: 392, 25 + xy: 705, 305 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-rdx rotate: false - xy: 484, 192 + xy: 755, 299 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-sand rotate: false - xy: 494, 199 + xy: 765, 295 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-silicon rotate: false - xy: 504, 199 + xy: 775, 294 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-steel rotate: false - xy: 514, 199 + xy: 785, 295 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-stone rotate: false - xy: 524, 199 + xy: 795, 295 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-thorium rotate: false - xy: 534, 199 + xy: 642, 284 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 item-titanium rotate: false - xy: 544, 199 + xy: 805, 289 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 standard-mech rotate: false - xy: 364, 47 + xy: 350, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 standard-ship rotate: false - xy: 378, 47 + xy: 364, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -2647,28 +2647,28 @@ icon-arrow-16 index: -1 icon-arrow-down rotate: false - xy: 205, 2 + xy: 542, 197 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-left rotate: false - xy: 217, 2 + xy: 509, 183 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-right rotate: false - xy: 229, 2 + xy: 521, 183 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-up rotate: false - xy: 322, 35 + xy: 533, 183 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2696,42 +2696,42 @@ icon-cancel index: -1 icon-chat rotate: false - xy: 334, 35 + xy: 509, 171 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-check rotate: false - xy: 467, 150 + xy: 485, 150 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-crafting rotate: false - xy: 346, 35 + xy: 521, 171 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-cursor rotate: false - xy: 358, 35 + xy: 533, 171 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-defense rotate: false - xy: 370, 35 + xy: 205, 2 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-dev-builds rotate: false - xy: 467, 134 + xy: 485, 134 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2745,7 +2745,7 @@ icon-discord index: -1 icon-distribution rotate: false - xy: 382, 35 + xy: 217, 2 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2785,6 +2785,20 @@ icon-exit orig: 14, 14 offset: 0, 0 index: -1 +icon-file + rotate: false + xy: 853, 469 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-file-image + rotate: false + xy: 871, 469 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 icon-file-text rotate: false xy: 266, 61 @@ -2794,7 +2808,7 @@ icon-file-text index: -1 icon-fill rotate: false - xy: 853, 469 + xy: 889, 469 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -2806,6 +2820,13 @@ icon-floppy orig: 14, 14 offset: 0, 0 index: -1 +icon-floppy-16 + rotate: false + xy: 907, 469 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 icon-folder rotate: false xy: 298, 93 @@ -2836,21 +2857,21 @@ icon-google-play index: -1 icon-grid rotate: false - xy: 871, 469 + xy: 925, 469 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-hold rotate: false - xy: 394, 35 + xy: 229, 2 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-holdDelete rotate: false - xy: 653, 240 + xy: 545, 185 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2871,7 +2892,7 @@ icon-host index: -1 icon-info rotate: false - xy: 653, 228 + xy: 545, 173 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2885,14 +2906,14 @@ icon-itch.io index: -1 icon-items-none rotate: false - xy: 477, 80 + xy: 447, 96 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-line rotate: false - xy: 889, 469 + xy: 943, 469 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -2906,7 +2927,7 @@ icon-link index: -1 icon-liquid rotate: false - xy: 653, 216 + xy: 473, 118 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2920,63 +2941,63 @@ icon-load index: -1 icon-load-image rotate: false - xy: 907, 469 + xy: 961, 469 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-load-map rotate: false - xy: 925, 469 + xy: 979, 469 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-loading rotate: false - xy: 943, 469 + xy: 997, 469 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-logic rotate: false - xy: 653, 204 + xy: 485, 122 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-menu rotate: false - xy: 653, 192 + xy: 473, 106 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-menu-large rotate: false - xy: 961, 469 + xy: 630, 266 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-none rotate: false - xy: 718, 348 + xy: 485, 110 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-pause rotate: false - xy: 730, 348 + xy: 266, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-pencil rotate: false - xy: 979, 469 + xy: 635, 234 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -2990,14 +3011,14 @@ icon-pencil-small index: -1 icon-pick rotate: false - xy: 997, 469 + xy: 635, 216 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-play rotate: false - xy: 742, 348 + xy: 278, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -3011,21 +3032,21 @@ icon-play-2 index: -1 icon-players rotate: false - xy: 754, 348 + xy: 290, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-power rotate: false - xy: 246, 29 + xy: 302, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-production rotate: false - xy: 245, 17 + xy: 314, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -3039,7 +3060,7 @@ icon-quit index: -1 icon-redo rotate: false - xy: 630, 266 + xy: 635, 198 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -3060,7 +3081,7 @@ icon-rename index: -1 icon-resize rotate: false - xy: 635, 234 + xy: 119, 25 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -3102,28 +3123,28 @@ icon-save index: -1 icon-save-image rotate: false - xy: 635, 216 + xy: 138, 38 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-save-map rotate: false - xy: 635, 198 + xy: 137, 20 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-settings rotate: false - xy: 695, 341 + xy: 326, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-terrain rotate: false - xy: 119, 25 + xy: 131, 2 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -3137,14 +3158,14 @@ icon-tools index: -1 icon-touch rotate: false - xy: 695, 329 + xy: 338, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-touchDelete rotate: false - xy: 695, 317 + xy: 350, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -3158,7 +3179,7 @@ icon-trash index: -1 icon-trash-16 rotate: false - xy: 138, 38 + xy: 156, 34 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -3179,21 +3200,21 @@ icon-tutorial index: -1 icon-undo rotate: false - xy: 137, 20 + xy: 174, 34 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-units rotate: false - xy: 707, 332 + xy: 362, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-weapon rotate: false - xy: 707, 320 + xy: 374, 35 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -3207,7 +3228,7 @@ icon-wiki index: -1 icon-zoom rotate: false - xy: 131, 2 + xy: 192, 34 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -3387,70 +3408,70 @@ window-empty index: -1 drone rotate: false - xy: 149, 2 + xy: 484, 184 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 scout rotate: false - xy: 294, 47 + xy: 280, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 scout-base rotate: false - xy: 308, 47 + xy: 294, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 standard-mech-base rotate: false - xy: 308, 47 + xy: 294, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 scout-leg rotate: false - xy: 322, 47 + xy: 308, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 standard-mech-leg rotate: false - xy: 322, 47 + xy: 308, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 vtol rotate: false - xy: 266, 33 + xy: 392, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 vtol-booster-1 rotate: false - xy: 280, 33 + xy: 500, 195 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 vtol-booster-2 rotate: false - xy: 294, 33 + xy: 514, 195 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 vtol-flame rotate: false - xy: 406, 39 + xy: 245, 19 size: 9, 9 orig: 9, 9 offset: 0, 0 @@ -3464,70 +3485,70 @@ beam-equip index: -1 blaster rotate: false - xy: 739, 314 + xy: 715, 338 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blaster-equip rotate: false - xy: 749, 314 + xy: 725, 338 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 clustergun rotate: false - xy: 811, 387 + xy: 735, 318 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 clustergun-equip rotate: false - xy: 808, 375 + xy: 745, 318 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shockgun rotate: false - xy: 854, 439 + xy: 577, 168 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shockgun-equip rotate: false - xy: 864, 439 + xy: 587, 168 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 triblaster rotate: false - xy: 891, 429 + xy: 985, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 triblaster-equip rotate: false - xy: 861, 389 + xy: 995, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 vulcan rotate: false - xy: 881, 409 + xy: 1015, 447 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 vulcan-equip rotate: false - xy: 891, 419 + xy: 821, 427 size: 8, 8 orig: 8, 8 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index efbad9b85d..8429efbc99 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java index 85c57ab858..bab6d9167c 100644 --- a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java @@ -1,16 +1,12 @@ package io.anuke.mindustry.content.blocks; -import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.content.UnitTypes; -import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.blocks.types.units.RepairPoint; import io.anuke.mindustry.world.blocks.types.units.ResupplyPoint; -import io.anuke.mindustry.world.blocks.types.units.UnitFactory; public class UnitBlocks { public static final Block - +/* droneFactory = new UnitFactory("dronefactory"){{ type = UnitTypes.drone; produceTime = 200; @@ -36,7 +32,7 @@ public class UnitBlocks { requirements = new ItemStack[]{ new ItemStack(Items.stone, 1) }; - }}, + }},*/ resupplyPoint = new ResupplyPoint("resupplypoint"){{ shadow = "shadow-round-1"; diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index ae5eb6e4fa..0617a898f2 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -269,6 +269,7 @@ public class Control extends Module{ public void dispose(){ Platform.instance.onGameExit(); Net.dispose(); + ui.editor.dispose(); } @Override diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index a4bc1378f7..598ef37494 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -23,11 +23,13 @@ import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.modules.SceneModule; import io.anuke.ucore.scene.Group; import io.anuke.ucore.scene.Skin; +import io.anuke.ucore.scene.actions.Actions; import io.anuke.ucore.scene.builders.build; import io.anuke.ucore.scene.ui.Dialog; import io.anuke.ucore.scene.ui.TextField; import io.anuke.ucore.scene.ui.TextField.TextFieldFilter; import io.anuke.ucore.scene.ui.TooltipManager; +import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.util.Mathf; @@ -239,6 +241,14 @@ public class UI extends SceneModule{ showTextInput(title, text, def, (field, c) -> true, confirmed); } + public void showInfoFade(String info){ + Table table = new Table(); + table.setFillParent(true); + table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor()); + table.top().add(info).padTop(8); + Core.scene.add(table); + } + public void showInfo(String info){ new Dialog("$text.info.title", "dialog"){{ content().margin(15).add(info).width(600f).get().setWrap(true); diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 751e930f82..fe69b08ef6 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.ObjectMap; import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.game.Team; @@ -18,6 +19,7 @@ import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Timers; +import io.anuke.ucore.function.Listenable; import io.anuke.ucore.graphics.Pixmaps; import io.anuke.ucore.input.Input; import io.anuke.ucore.scene.Element; @@ -39,7 +41,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class MapEditorDialog extends Dialog{ +public class MapEditorDialog extends Dialog implements Disposable{ private MapEditor editor; private MapView view; private MapInfoDialog infoDialog; @@ -72,7 +74,7 @@ public class MapEditorDialog extends Dialog{ if(!editor.getTags().containsKey("name")){ tags.put("name", result.nameWithoutExtension()); } - MapIO.writeMap(result, editor.getTags(), editor.getMap()); + MapIO.writeMap(result.write(false), editor.getTags(), editor.getMap()); }catch (Exception e){ ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); Log.err(e); @@ -128,9 +130,30 @@ public class MapEditorDialog extends Dialog{ menu.addCloseButton(); float isize = 16*2f; + float swidth = 180f; menu.content().table(t -> { - t.defaults().size(230f, 60f).padBottom(5).padRight(5).padLeft(5); + t.defaults().size(swidth, 60f).padBottom(5).padRight(5).padLeft(5); + + t.addImageTextButton("$text.editor.savemap", "icon-floppy-16", isize, () -> { + String name = editor.getTags().get("name", ""); + + if(name.isEmpty()){ + ui.showError("$text.editor.save.noname"); + }else{ + Map map = world.maps().getByName(name); + if(map != null && !map.custom){ + ui.showError("$text.editor.save.overwrite"); + }else{ + world.maps().saveAndReload(name, editor.getMap(), editor.getTags()); + ui.showInfoFade("$text.editor.saved"); + } + } + + menu.hide(); + }).size(swidth*2f + 10, 60f).colspan(2); + + t.row(); t.addImageTextButton("$text.editor.mapinfo", "icon-pencil", isize, () -> { infoDialog.show(); @@ -144,40 +167,18 @@ public class MapEditorDialog extends Dialog{ t.row(); - t.addImageTextButton("$text.editor.savemap", "icon-save-map", isize, () -> { - saveDialog.show(); - menu.hide(); - }); + t.addImageTextButton("$text.editor.import", "icon-load-map", isize, () -> + createDialog("$text.editor.import", + "$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Listenable)loadDialog::show, + "$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Listenable)openFile::show, + "$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Listenable)openImage::show)); - t.addImageTextButton("$text.editor.loadmap", "icon-load-map", isize, () -> { - loadDialog.show(); - menu.hide(); - }); + t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export", + "$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Listenable)saveFile::show, + "$text.editor.exportimage", "$text.editor.exportimage.description", "icon-file-image", (Listenable)saveImage::show)); t.row(); - t.addImageTextButton("$text.editor.importmap", "icon-save-map", isize, () -> { - saveFile.show(); - menu.hide(); - }); - - t.addImageTextButton("$text.editor.exportmap", "icon-load-map", isize, () -> { - openFile.show(); - menu.hide(); - }); - - t.row(); - - t.addImageTextButton("$text.editor.saveimage", "icon-save-map", isize, () -> { - saveImage.show(); - menu.hide(); - }); - - t.addImageTextButton("$text.editor.loadimage", "icon-load-map", isize, () -> { - openImage.show(); - menu.hide(); - }); - t.row(); }); @@ -190,7 +191,7 @@ public class MapEditorDialog extends Dialog{ hide(); } menu.hide(); - }).size(470f, 60f); + }).padTop(-5).size(swidth*2f + 10, 60f); resizeDialog = new MapResizeDialog(editor, (x, y) -> { if(!(editor.getMap().width() == x && editor.getMap().height() == y)){ @@ -259,12 +260,63 @@ public class MapEditorDialog extends Dialog{ hidden(() -> Platform.instance.updateRPC()); } + /**Argument format: + * 0) button name + * 1) description + * 2) icon name + * 3) listener + */ + private FloatingDialog createDialog(String title, Object... arguments){ + FloatingDialog dialog = new FloatingDialog(title); + + float h = 90f; + + dialog.content().defaults().size(360f, h).padBottom(5).padRight(5).padLeft(5); + + for(int i = 0; i < arguments.length; i += 4){ + String name = (String)arguments[i]; + String description = (String)arguments[i + 1]; + String iconname = (String)arguments[i + 2]; + Listenable listenable = (Listenable)arguments[i + 3]; + + TextButton button = dialog.content().addButton(name, () -> { + listenable.listen(); + dialog.hide(); + menu.hide(); + }).left().get(); + + button.clearChildren(); + button.table("button", t -> { + t.addImage(iconname).size(16*3); + t.update(() -> t.background(button.getClickListener().isOver() ? "button-over" : "button")); + }).padLeft(-10).padBottom(-3).size(h); + button.table(t -> { + t.add(name).growX().wrap(); + t.row(); + t.add(description).color(Color.GRAY).growX().wrap(); + }).growX().padLeft(8); + + button.row(); + + dialog.content().row(); + } + + dialog.addCloseButton(); + dialog.show(); + + return dialog; + } @Override public Dialog show(){ return super.show(Core.scene, Actions.sequence(Actions.alpha(0f), Actions.scaleTo(1f, 1f), Actions.fadeIn(0.3f))); } + @Override + public void dispose(){ + editor.renderer().dispose(); + } + public MapView getView() { return view; } @@ -449,12 +501,9 @@ public class MapEditorDialog extends Dialog{ int i = 0; for(Block block : Block.getAllBlocks()){ - TextureRegion[] regions; - try { - regions = block.getCompactIcon(); - }catch (Exception e){ - continue; - } + TextureRegion[] regions = block.getCompactIcon(); + + if(regions.length == 0) continue; Stack stack = new Stack(); diff --git a/core/src/io/anuke/mindustry/editor/MapInfoDialog.java b/core/src/io/anuke/mindustry/editor/MapInfoDialog.java index fc0723dbe5..2a62eece07 100644 --- a/core/src/io/anuke/mindustry/editor/MapInfoDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapInfoDialog.java @@ -60,6 +60,13 @@ public class MapInfoDialog extends FloatingDialog{ }).size(400, 55f).get(); author.setMessageText("$text.unknown"); + content().row(); + + content().add().padRight(8).left(); + content().addCheck("$text.editor.oregen", enabled -> { + tags.put("oregen", enabled ? "1" : "0"); + }).left(); + Platform.instance.addDialog(name, 50); Platform.instance.addDialog(author, 50); Platform.instance.addDialog(description, 1000); diff --git a/core/src/io/anuke/mindustry/editor/MapRenderer.java b/core/src/io/anuke/mindustry/editor/MapRenderer.java index 393bb1fe03..4a57c92f2c 100644 --- a/core/src/io/anuke/mindustry/editor/MapRenderer.java +++ b/core/src/io/anuke/mindustry/editor/MapRenderer.java @@ -1,29 +1,99 @@ package io.anuke.mindustry.editor; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Pixmap.Format; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.Texture.TextureFilter; +import com.badlogic.gdx.graphics.g2d.PixmapPacker; +import com.badlogic.gdx.graphics.g2d.PixmapPacker.Page; import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.IntSet; import com.badlogic.gdx.utils.IntSet.IntSetIterator; -import io.anuke.mindustry.content.blocks.Blocks; +import com.badlogic.gdx.utils.ObjectMap; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.MapTileData.TileDataMarker; import io.anuke.mindustry.world.Block; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Graphics; +import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.IndexedRenderer; +import io.anuke.ucore.util.Log; import static io.anuke.mindustry.Vars.tilesize; -public class MapRenderer { +public class MapRenderer implements Disposable{ private static final int chunksize = 64; private IndexedRenderer[][] chunks; private IntSet updates = new IntSet(); private MapEditor editor; private int width, height; + private ObjectMap blockIcons = new ObjectMap<>(); + private ObjectMap regions = new ObjectMap<>(); + private Texture blockTexture; + public MapRenderer(MapEditor editor){ this.editor = editor; + createTexture(); + } + + + private void createTexture(){ + Timers.mark(); + + PixmapPacker packer = new PixmapPacker(512, 512, Format.RGBA8888, 2, true); + Pixmap pixmap = Core.atlas.getPixmapOf("blank"); + + for(Block block : Block.getAllBlocks()){ + TextureRegion[] regions = block.getBlockIcon(); + if(regions.length > 0){ + Pixmap result = new Pixmap(regions[0].getRegionWidth(), regions[0].getRegionHeight(), Format.RGBA8888); + for(TextureRegion region : regions){ + result.drawPixmap(pixmap, 0, 0, region.getRegionX(), region.getRegionY(), region.getRegionWidth(), region.getRegionHeight()); + } + + packer.pack(block.name, result); + result.dispose(); + } + } + + add("clear", packer); + add("block-border", packer); + + if(packer.getPages().size > 1){ + throw new IllegalArgumentException("Pixmap packer may not have more than 1 page!"); + } + + Page page = packer.getPages().first(); + page.updateTexture(TextureFilter.Nearest, TextureFilter.Nearest, false); + blockTexture = page.getTexture(); + for(String str : page.getRects().keys()){ + if(Block.getByName(str) == null) continue; + Rectangle rect = page.getRects().get(str); + blockIcons.put(Block.getByName(str), + new TextureRegion(blockTexture, + (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height)); + } + + packer.dispose(); + + Core.atlas.disposePixmaps(); + + Log.info("Packing elapsed: {0}", Timers.elapsed()); + } + + private void add(String name, PixmapPacker packer){ + TextureRegion region = Draw.region(name); + Pixmap result = new Pixmap(region.getRegionWidth(), region.getRegionHeight(), Format.RGBA8888); + result.drawPixmap(Core.atlas.getPixmapOf(region), 0, 0, region.getRegionX(), region.getRegionY(), region.getRegionWidth(), region.getRegionHeight()); + Rectangle rect = packer.pack(name, result); + result.dispose(); + Gdx.app.postRunnable(() -> regions.put(name, new TextureRegion(packer.getPages().first().getTexture(), (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height))); } public void resize(int width, int height){ @@ -68,7 +138,7 @@ public class MapRenderer { th / (height * tilesize), 1f); mesh.setProjectionMatrix(Core.batch.getProjectionMatrix()); - mesh.render(Core.atlas.getTextures().first()); + mesh.render(blockTexture); } } @@ -98,14 +168,10 @@ public class MapRenderer { int offsetx = -(wall.size-1)/2; int offsety = -(wall.size-1)/2; - String fregion = Draw.hasRegion(floor.name) ? floor.name : (Draw.hasRegion(floor.name + "1") ? (floor.name + "1") : "clear"); - - TextureRegion region = Draw.region(fregion); + TextureRegion region = blockIcons.get(floor, regions.get("clear")); mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize, region, wx * tilesize, wy * tilesize, 8, 8); - TextureRegion wregion = (wall == Blocks.air || wall == Blocks.blockpart) ? Draw.region("clear"): wall.getBlockIcon()[wall.getBlockIcon().length-1]; - - region = wregion; + region = blockIcons.get(wall, regions.get("clear")); if(wall.rotate){ mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region, @@ -119,15 +185,25 @@ public class MapRenderer { if(wall.update || wall.destructible) { mesh.setColor(Team.values()[data.team].color); - region = Draw.region("block-border"); + region = regions.get("block-border"); }else{ - region = Draw.region("clear"); + region = regions.get("clear"); } mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize*2, region, wx * tilesize + offsetx*tilesize, wy * tilesize + offsety * tilesize, region.getRegionWidth(), region.getRegionHeight()); mesh.setColor(Color.WHITE); + } + @Override + public void dispose() { + for(int x = 0; x < chunks.length; x ++){ + for(int y = 0; y < chunks[0].length; y ++){ + if(chunks[x][y] != null){ + chunks[x][y].dispose(); + } + } + } } } diff --git a/core/src/io/anuke/mindustry/io/MapIO.java b/core/src/io/anuke/mindustry/io/MapIO.java index 8a3746d514..676abfad5d 100644 --- a/core/src/io/anuke/mindustry/io/MapIO.java +++ b/core/src/io/anuke/mindustry/io/MapIO.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.io; 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.Pixmap.Format; @@ -15,10 +14,7 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.ColorMapper.BlockPair; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import static io.anuke.mindustry.Vars.customMapDirectory; import static io.anuke.mindustry.Vars.mapExtension; @@ -80,10 +76,10 @@ public class MapIO { return data; } - public static void writeMap(FileHandle file, ObjectMap tags, MapTileData data) throws IOException{ + public static void writeMap(OutputStream stream, ObjectMap tags, MapTileData data) throws IOException{ MapMeta meta = new MapMeta(version, tags, data.width(), data.height(), defaultBlockMap); - DataOutputStream ds = new DataOutputStream(file.write(false)); + DataOutputStream ds = new DataOutputStream(stream); writeMapMeta(ds, meta); ds.write(data.toArray()); diff --git a/core/src/io/anuke/mindustry/io/Maps.java b/core/src/io/anuke/mindustry/io/Maps.java index 7189bb5a8f..0f315a50c1 100644 --- a/core/src/io/anuke/mindustry/io/Maps.java +++ b/core/src/io/anuke/mindustry/io/Maps.java @@ -3,18 +3,12 @@ package io.anuke.mindustry.io; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.Disposable; -import com.badlogic.gdx.utils.Json; -import com.badlogic.gdx.utils.ObjectMap; +import com.badlogic.gdx.utils.*; import io.anuke.ucore.core.Settings; import io.anuke.ucore.function.Supplier; import io.anuke.ucore.util.Log; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import static io.anuke.mindustry.Vars.*; @@ -32,6 +26,8 @@ public class Maps implements Disposable{ private Array returnArray = new Array<>(); /**Used for writing a list of custom map names on GWT.*/ private Json json = new Json(); + /**Used for storing a list of custom map names for GWT.*/ + private Array customMapNames; public Maps(){ @@ -80,7 +76,33 @@ public class Maps implements Disposable{ } public void saveAndReload(String name, MapTileData data, ObjectMap tags){ - FileHandle file = customMapDirectory.child(name + "." + mapExtension); + try { + if (!gwt) { + FileHandle file = customMapDirectory.child(name + "." + mapExtension); + MapIO.writeMap(file.write(false), tags, data); + } else { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + MapIO.writeMap(stream, tags, data); + Settings.putString("map-data-" + name, new String(Base64Coder.encode(stream.toByteArray()))); + if(!customMapNames.contains(name, false)){ + customMapNames.add(name); + Settings.putString("custom-maps", json.toJson(customMapNames)); + } + Settings.save(); + } + + if(maps.containsKey(name)){ + maps.get(name).texture.dispose(); + } + + Map map = new Map(name, new MapMeta(version, tags, data.width(), data.height(), null), true, getStreamFor(name)); + if (!headless){ + map.texture = new Texture(MapIO.generatePixmap(data)); + } + maps.put(name, map); + }catch (IOException e){ + throw new RuntimeException(e); + } //todo implement } @@ -88,7 +110,9 @@ public class Maps implements Disposable{ try(DataInputStream ds = new DataInputStream(supplier.get())) { MapMeta meta = MapIO.readMapMeta(ds); Map map = new Map(name, meta, custom, supplier); - if (!headless) map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true))); + if (!headless){ + map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true))); + } maps.put(map.name, map); allMaps.add(map); @@ -109,12 +133,12 @@ public class Maps implements Disposable{ } }else{ - Array maps = json.fromJson(Array.class, Settings.getString("custom-maps", "{}")); + customMapNames = json.fromJson(Array.class, Settings.getString("custom-maps", "{}")); - for(String name : maps){ + for(String name : customMapNames){ try{ String data = Settings.getString("map-data-" + name); - byte[] bytes = data.getBytes(); + byte[] bytes = Base64Coder.decode(data); loadMap(name, () -> new ByteArrayInputStream(bytes), true); }catch (Exception e){ Log.err("Failed to load custom map '{0}'!", name); @@ -124,6 +148,17 @@ public class Maps implements Disposable{ } } + /**Returns an input stream supplier for a given map name.*/ + private Supplier getStreamFor(String name){ + if(!gwt){ + return customMapDirectory.child(name + "." + mapExtension)::read; + }else{ + String data = Settings.getString("map-data-" + name); + byte[] bytes = Base64Coder.decode(data); + return () -> new ByteArrayInputStream(bytes); + } + } + @Override public void dispose() { diff --git a/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java index 2ef481be19..c1adf26795 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java @@ -1,9 +1,12 @@ package io.anuke.mindustry.ui.dialogs; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.utils.Align; import io.anuke.mindustry.graphics.Palette; +import io.anuke.ucore.core.Core; import io.anuke.ucore.scene.ui.Dialog; +import io.anuke.ucore.scene.ui.ScrollPane; public class FloatingDialog extends Dialog{ @@ -14,13 +17,25 @@ public class FloatingDialog extends Dialog{ getTitleTable().row(); getTitleTable().addImage("white", Palette.accent) .growX().height(3f).pad(4f); + + boolean[] done = {false}; + + shown(() -> Gdx.app.postRunnable(() -> + forEach(child -> { + if (done[0]) return; + + if (child instanceof ScrollPane) { + Core.scene.setScrollFocus(child); + done[0] = true; + } + }))); } @Override public void addCloseButton(){ buttons().addImageTextButton("$text.back", "icon-arrow-left", 30f, this::hide).size(230f, 64f); - keyDown(key->{ + keyDown(key -> { if(key == Keys.ESCAPE || key == Keys.BACK) hide(); }); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java index 98d4bb5d17..7a9b134d76 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java @@ -5,9 +5,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.io.Map; -import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Settings; -import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.event.Touchable; import io.anuke.ucore.scene.ui.*; import io.anuke.ucore.scene.ui.layout.Stack; @@ -26,15 +24,12 @@ public class LevelDialog extends FloatingDialog{ getTitleTable().getCell(title()).growX().center(); getTitleTable().center(); addCloseButton(); - setup(); - } - - public void reload(){ - content().clear(); - setup(); + shown(this::setup); } void setup(){ + content().clear(); + Table maps = new Table(); pane = new ScrollPane(maps); pane.setFadeScrollBars(false); @@ -126,13 +121,6 @@ public class LevelDialog extends FloatingDialog{ } content().add(pane).uniformX(); - - shown(()->{ - //this is necessary for some reason? - Timers.run(2f, ()->{ - Core.scene.setScrollFocus(pane); - }); - }); } private void displayGameModeHelp() { diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 301f336eea..fb787af03e 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -316,9 +316,11 @@ public class Block extends BaseBlock { icon = new TextureRegion[]{Draw.region(name + "-icon")}; } else if (Draw.hasRegion(name + "1")) { icon = new TextureRegion[]{Draw.region(name + "1")}; - } else { + } else if (Draw.hasRegion(name)){ icon = new TextureRegion[]{Draw.region(name)}; - } + }else{ + icon = new TextureRegion[]{}; + } } return icon;