mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-03-13 19:39:04 +07:00
Added all export/import menus, fixed bad icons for editor blocks
This commit is contained in:
parent
b20f026c7b
commit
c920fa6740
BIN
core/assets-raw/sprites/ui/icons/icon-file-image.png
Normal file
BIN
core/assets-raw/sprites/ui/icons/icon-file-image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 198 B |
BIN
core/assets-raw/sprites/ui/icons/icon-file.png
Normal file
BIN
core/assets-raw/sprites/ui/icons/icon-file.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 184 B |
BIN
core/assets-raw/sprites/ui/icons/icon-floppy-16.png
Normal file
BIN
core/assets-raw/sprites/ui/icons/icon-floppy-16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 199 B |
@ -150,8 +150,8 @@ text.enemies={0} Enemies
|
|||||||
text.enemies.single={0} Enemy
|
text.enemies.single={0} Enemy
|
||||||
text.loadimage=Load Image
|
text.loadimage=Load Image
|
||||||
text.saveimage=Save Image
|
text.saveimage=Save Image
|
||||||
text.oregen=Ore Generation
|
|
||||||
text.unknown=Unknown
|
text.unknown=Unknown
|
||||||
|
text.editor.oregen=Ore Generation
|
||||||
text.editor.mapinfo=Map Info
|
text.editor.mapinfo=Map Info
|
||||||
text.editor.author=Author:
|
text.editor.author=Author:
|
||||||
text.editor.description=Description:
|
text.editor.description=Description:
|
||||||
@ -164,8 +164,21 @@ text.editor.generate=Generate
|
|||||||
text.editor.resize=Resize
|
text.editor.resize=Resize
|
||||||
text.editor.loadmap=Load Map
|
text.editor.loadmap=Load Map
|
||||||
text.editor.savemap=Save 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.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.loadimage=Import Terrain
|
||||||
text.editor.saveimage=Export Terrain
|
text.editor.saveimage=Export Terrain
|
||||||
text.editor.unsaved=[scarlet]You have unsaved changes![]\nAre you sure you want to exit?
|
text.editor.unsaved=[scarlet]You have unsaved changes![]\nAre you sure you want to exit?
|
||||||
@ -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.resizebig=[scarlet]Warning!\n[]Maps larger than 256 units may be laggy and unstable.
|
||||||
text.editor.mapname=Map Name:
|
text.editor.mapname=Map Name:
|
||||||
text.editor.overwrite=[accent]Warning!\nThis overwrites an existing map.
|
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.editor.selectmap=Select a map to load:
|
||||||
text.width=Width:
|
text.width=Width:
|
||||||
text.height=Height:
|
text.height=Height:
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 108 KiB |
@ -1,16 +1,12 @@
|
|||||||
package io.anuke.mindustry.content.blocks;
|
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.Block;
|
||||||
import io.anuke.mindustry.world.blocks.types.units.RepairPoint;
|
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.ResupplyPoint;
|
||||||
import io.anuke.mindustry.world.blocks.types.units.UnitFactory;
|
|
||||||
|
|
||||||
public class UnitBlocks {
|
public class UnitBlocks {
|
||||||
public static final Block
|
public static final Block
|
||||||
|
/*
|
||||||
droneFactory = new UnitFactory("dronefactory"){{
|
droneFactory = new UnitFactory("dronefactory"){{
|
||||||
type = UnitTypes.drone;
|
type = UnitTypes.drone;
|
||||||
produceTime = 200;
|
produceTime = 200;
|
||||||
@ -36,7 +32,7 @@ public class UnitBlocks {
|
|||||||
requirements = new ItemStack[]{
|
requirements = new ItemStack[]{
|
||||||
new ItemStack(Items.stone, 1)
|
new ItemStack(Items.stone, 1)
|
||||||
};
|
};
|
||||||
}},
|
}},*/
|
||||||
|
|
||||||
resupplyPoint = new ResupplyPoint("resupplypoint"){{
|
resupplyPoint = new ResupplyPoint("resupplypoint"){{
|
||||||
shadow = "shadow-round-1";
|
shadow = "shadow-round-1";
|
||||||
|
@ -269,6 +269,7 @@ public class Control extends Module{
|
|||||||
public void dispose(){
|
public void dispose(){
|
||||||
Platform.instance.onGameExit();
|
Platform.instance.onGameExit();
|
||||||
Net.dispose();
|
Net.dispose();
|
||||||
|
ui.editor.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -23,11 +23,13 @@ import io.anuke.ucore.graphics.Draw;
|
|||||||
import io.anuke.ucore.modules.SceneModule;
|
import io.anuke.ucore.modules.SceneModule;
|
||||||
import io.anuke.ucore.scene.Group;
|
import io.anuke.ucore.scene.Group;
|
||||||
import io.anuke.ucore.scene.Skin;
|
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.builders.build;
|
||||||
import io.anuke.ucore.scene.ui.Dialog;
|
import io.anuke.ucore.scene.ui.Dialog;
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
import io.anuke.ucore.scene.ui.TextField;
|
||||||
import io.anuke.ucore.scene.ui.TextField.TextFieldFilter;
|
import io.anuke.ucore.scene.ui.TextField.TextFieldFilter;
|
||||||
import io.anuke.ucore.scene.ui.TooltipManager;
|
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.scene.ui.layout.Unit;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
@ -239,6 +241,14 @@ public class UI extends SceneModule{
|
|||||||
showTextInput(title, text, def, (field, c) -> true, confirmed);
|
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){
|
public void showInfo(String info){
|
||||||
new Dialog("$text.info.title", "dialog"){{
|
new Dialog("$text.info.title", "dialog"){{
|
||||||
content().margin(15).add(info).width(600f).get().setWrap(true);
|
content().margin(15).add(info).width(600f).get().setWrap(true);
|
||||||
|
@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.graphics.Pixmap;
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
import io.anuke.mindustry.content.blocks.Blocks;
|
import io.anuke.mindustry.content.blocks.Blocks;
|
||||||
import io.anuke.mindustry.game.Team;
|
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.Graphics;
|
||||||
import io.anuke.ucore.core.Inputs;
|
import io.anuke.ucore.core.Inputs;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.function.Listenable;
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
import io.anuke.ucore.graphics.Pixmaps;
|
||||||
import io.anuke.ucore.input.Input;
|
import io.anuke.ucore.input.Input;
|
||||||
import io.anuke.ucore.scene.Element;
|
import io.anuke.ucore.scene.Element;
|
||||||
@ -39,7 +41,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class MapEditorDialog extends Dialog{
|
public class MapEditorDialog extends Dialog implements Disposable{
|
||||||
private MapEditor editor;
|
private MapEditor editor;
|
||||||
private MapView view;
|
private MapView view;
|
||||||
private MapInfoDialog infoDialog;
|
private MapInfoDialog infoDialog;
|
||||||
@ -72,7 +74,7 @@ public class MapEditorDialog extends Dialog{
|
|||||||
if(!editor.getTags().containsKey("name")){
|
if(!editor.getTags().containsKey("name")){
|
||||||
tags.put("name", result.nameWithoutExtension());
|
tags.put("name", result.nameWithoutExtension());
|
||||||
}
|
}
|
||||||
MapIO.writeMap(result, editor.getTags(), editor.getMap());
|
MapIO.writeMap(result.write(false), editor.getTags(), editor.getMap());
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
|
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
@ -128,9 +130,30 @@ public class MapEditorDialog extends Dialog{
|
|||||||
menu.addCloseButton();
|
menu.addCloseButton();
|
||||||
|
|
||||||
float isize = 16*2f;
|
float isize = 16*2f;
|
||||||
|
float swidth = 180f;
|
||||||
|
|
||||||
menu.content().table(t -> {
|
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, () -> {
|
t.addImageTextButton("$text.editor.mapinfo", "icon-pencil", isize, () -> {
|
||||||
infoDialog.show();
|
infoDialog.show();
|
||||||
@ -144,40 +167,18 @@ public class MapEditorDialog extends Dialog{
|
|||||||
|
|
||||||
t.row();
|
t.row();
|
||||||
|
|
||||||
t.addImageTextButton("$text.editor.savemap", "icon-save-map", isize, () -> {
|
t.addImageTextButton("$text.editor.import", "icon-load-map", isize, () ->
|
||||||
saveDialog.show();
|
createDialog("$text.editor.import",
|
||||||
menu.hide();
|
"$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, () -> {
|
t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export",
|
||||||
loadDialog.show();
|
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Listenable)saveFile::show,
|
||||||
menu.hide();
|
"$text.editor.exportimage", "$text.editor.exportimage.description", "icon-file-image", (Listenable)saveImage::show));
|
||||||
});
|
|
||||||
|
|
||||||
t.row();
|
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();
|
t.row();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -190,7 +191,7 @@ public class MapEditorDialog extends Dialog{
|
|||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
menu.hide();
|
menu.hide();
|
||||||
}).size(470f, 60f);
|
}).padTop(-5).size(swidth*2f + 10, 60f);
|
||||||
|
|
||||||
resizeDialog = new MapResizeDialog(editor, (x, y) -> {
|
resizeDialog = new MapResizeDialog(editor, (x, y) -> {
|
||||||
if(!(editor.getMap().width() == x && editor.getMap().height() == y)){
|
if(!(editor.getMap().width() == x && editor.getMap().height() == y)){
|
||||||
@ -259,12 +260,63 @@ public class MapEditorDialog extends Dialog{
|
|||||||
hidden(() -> Platform.instance.updateRPC());
|
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
|
@Override
|
||||||
public Dialog show(){
|
public Dialog show(){
|
||||||
return super.show(Core.scene, Actions.sequence(Actions.alpha(0f), Actions.scaleTo(1f, 1f), Actions.fadeIn(0.3f)));
|
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() {
|
public MapView getView() {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@ -449,12 +501,9 @@ public class MapEditorDialog extends Dialog{
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for(Block block : Block.getAllBlocks()){
|
for(Block block : Block.getAllBlocks()){
|
||||||
TextureRegion[] regions;
|
TextureRegion[] regions = block.getCompactIcon();
|
||||||
try {
|
|
||||||
regions = block.getCompactIcon();
|
if(regions.length == 0) continue;
|
||||||
}catch (Exception e){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack stack = new Stack();
|
Stack stack = new Stack();
|
||||||
|
|
||||||
|
@ -60,6 +60,13 @@ public class MapInfoDialog extends FloatingDialog{
|
|||||||
}).size(400, 55f).get();
|
}).size(400, 55f).get();
|
||||||
author.setMessageText("$text.unknown");
|
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(name, 50);
|
||||||
Platform.instance.addDialog(author, 50);
|
Platform.instance.addDialog(author, 50);
|
||||||
Platform.instance.addDialog(description, 1000);
|
Platform.instance.addDialog(description, 1000);
|
||||||
|
@ -1,29 +1,99 @@
|
|||||||
package io.anuke.mindustry.editor;
|
package io.anuke.mindustry.editor;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
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.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;
|
||||||
import com.badlogic.gdx.utils.IntSet.IntSetIterator;
|
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.game.Team;
|
||||||
import io.anuke.mindustry.io.MapTileData.TileDataMarker;
|
import io.anuke.mindustry.io.MapTileData.TileDataMarker;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.core.Graphics;
|
import io.anuke.ucore.core.Graphics;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.graphics.IndexedRenderer;
|
import io.anuke.ucore.graphics.IndexedRenderer;
|
||||||
|
import io.anuke.ucore.util.Log;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.tilesize;
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public class MapRenderer {
|
public class MapRenderer implements Disposable{
|
||||||
private static final int chunksize = 64;
|
private static final int chunksize = 64;
|
||||||
private IndexedRenderer[][] chunks;
|
private IndexedRenderer[][] chunks;
|
||||||
private IntSet updates = new IntSet();
|
private IntSet updates = new IntSet();
|
||||||
private MapEditor editor;
|
private MapEditor editor;
|
||||||
private int width, height;
|
private int width, height;
|
||||||
|
|
||||||
|
private ObjectMap<Block, TextureRegion> blockIcons = new ObjectMap<>();
|
||||||
|
private ObjectMap<String, TextureRegion> regions = new ObjectMap<>();
|
||||||
|
private Texture blockTexture;
|
||||||
|
|
||||||
public MapRenderer(MapEditor editor){
|
public MapRenderer(MapEditor editor){
|
||||||
this.editor = 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){
|
public void resize(int width, int height){
|
||||||
@ -68,7 +138,7 @@ public class MapRenderer {
|
|||||||
th / (height * tilesize), 1f);
|
th / (height * tilesize), 1f);
|
||||||
mesh.setProjectionMatrix(Core.batch.getProjectionMatrix());
|
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 offsetx = -(wall.size-1)/2;
|
||||||
int offsety = -(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 = blockIcons.get(floor, regions.get("clear"));
|
||||||
|
|
||||||
TextureRegion region = Draw.region(fregion);
|
|
||||||
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize, region, wx * tilesize, wy * tilesize, 8, 8);
|
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 = blockIcons.get(wall, regions.get("clear"));
|
||||||
|
|
||||||
region = wregion;
|
|
||||||
|
|
||||||
if(wall.rotate){
|
if(wall.rotate){
|
||||||
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region,
|
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region,
|
||||||
@ -119,15 +185,25 @@ public class MapRenderer {
|
|||||||
|
|
||||||
if(wall.update || wall.destructible) {
|
if(wall.update || wall.destructible) {
|
||||||
mesh.setColor(Team.values()[data.team].color);
|
mesh.setColor(Team.values()[data.team].color);
|
||||||
region = Draw.region("block-border");
|
region = regions.get("block-border");
|
||||||
}else{
|
}else{
|
||||||
region = Draw.region("clear");
|
region = regions.get("clear");
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize*2, region,
|
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize*2, region,
|
||||||
wx * tilesize + offsetx*tilesize, wy * tilesize + offsety * tilesize,
|
wx * tilesize + offsetx*tilesize, wy * tilesize + offsety * tilesize,
|
||||||
region.getRegionWidth(), region.getRegionHeight());
|
region.getRegionWidth(), region.getRegionHeight());
|
||||||
mesh.setColor(Color.WHITE);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
import com.badlogic.gdx.graphics.Pixmap.Format;
|
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;
|
||||||
import io.anuke.mindustry.world.ColorMapper.BlockPair;
|
import io.anuke.mindustry.world.ColorMapper.BlockPair;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.*;
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.customMapDirectory;
|
import static io.anuke.mindustry.Vars.customMapDirectory;
|
||||||
import static io.anuke.mindustry.Vars.mapExtension;
|
import static io.anuke.mindustry.Vars.mapExtension;
|
||||||
@ -80,10 +76,10 @@ public class MapIO {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeMap(FileHandle file, ObjectMap<String, String> tags, MapTileData data) throws IOException{
|
public static void writeMap(OutputStream stream, ObjectMap<String, String> tags, MapTileData data) throws IOException{
|
||||||
MapMeta meta = new MapMeta(version, tags, data.width(), data.height(), defaultBlockMap);
|
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);
|
writeMapMeta(ds, meta);
|
||||||
ds.write(data.toArray());
|
ds.write(data.toArray());
|
||||||
|
@ -3,18 +3,12 @@ package io.anuke.mindustry.io;
|
|||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.*;
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
|
||||||
import com.badlogic.gdx.utils.Json;
|
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
import io.anuke.ucore.function.Supplier;
|
import io.anuke.ucore.function.Supplier;
|
||||||
import io.anuke.ucore.util.Log;
|
import io.anuke.ucore.util.Log;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.*;
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@ -32,6 +26,8 @@ public class Maps implements Disposable{
|
|||||||
private Array<Map> returnArray = new Array<>();
|
private Array<Map> returnArray = new Array<>();
|
||||||
/**Used for writing a list of custom map names on GWT.*/
|
/**Used for writing a list of custom map names on GWT.*/
|
||||||
private Json json = new Json();
|
private Json json = new Json();
|
||||||
|
/**Used for storing a list of custom map names for GWT.*/
|
||||||
|
private Array<String> customMapNames;
|
||||||
|
|
||||||
public Maps(){
|
public Maps(){
|
||||||
|
|
||||||
@ -80,7 +76,33 @@ public class Maps implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void saveAndReload(String name, MapTileData data, ObjectMap<String, String> tags){
|
public void saveAndReload(String name, MapTileData data, ObjectMap<String, String> 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
|
//todo implement
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +110,9 @@ public class Maps implements Disposable{
|
|||||||
try(DataInputStream ds = new DataInputStream(supplier.get())) {
|
try(DataInputStream ds = new DataInputStream(supplier.get())) {
|
||||||
MapMeta meta = MapIO.readMapMeta(ds);
|
MapMeta meta = MapIO.readMapMeta(ds);
|
||||||
Map map = new Map(name, meta, custom, supplier);
|
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);
|
maps.put(map.name, map);
|
||||||
allMaps.add(map);
|
allMaps.add(map);
|
||||||
@ -109,12 +133,12 @@ public class Maps implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
Array<String> 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{
|
try{
|
||||||
String data = Settings.getString("map-data-" + name);
|
String data = Settings.getString("map-data-" + name);
|
||||||
byte[] bytes = data.getBytes();
|
byte[] bytes = Base64Coder.decode(data);
|
||||||
loadMap(name, () -> new ByteArrayInputStream(bytes), true);
|
loadMap(name, () -> new ByteArrayInputStream(bytes), true);
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
Log.err("Failed to load custom map '{0}'!", name);
|
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<InputStream> 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
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package io.anuke.mindustry.ui.dialogs;
|
package io.anuke.mindustry.ui.dialogs;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.Input.Keys;
|
import com.badlogic.gdx.Input.Keys;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
import io.anuke.mindustry.graphics.Palette;
|
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.Dialog;
|
||||||
|
import io.anuke.ucore.scene.ui.ScrollPane;
|
||||||
|
|
||||||
public class FloatingDialog extends Dialog{
|
public class FloatingDialog extends Dialog{
|
||||||
|
|
||||||
@ -14,13 +17,25 @@ public class FloatingDialog extends Dialog{
|
|||||||
getTitleTable().row();
|
getTitleTable().row();
|
||||||
getTitleTable().addImage("white", Palette.accent)
|
getTitleTable().addImage("white", Palette.accent)
|
||||||
.growX().height(3f).pad(4f);
|
.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
|
@Override
|
||||||
public void addCloseButton(){
|
public void addCloseButton(){
|
||||||
buttons().addImageTextButton("$text.back", "icon-arrow-left", 30f, this::hide).size(230f, 64f);
|
buttons().addImageTextButton("$text.back", "icon-arrow-left", 30f, this::hide).size(230f, 64f);
|
||||||
|
|
||||||
keyDown(key->{
|
keyDown(key -> {
|
||||||
if(key == Keys.ESCAPE || key == Keys.BACK)
|
if(key == Keys.ESCAPE || key == Keys.BACK)
|
||||||
hide();
|
hide();
|
||||||
});
|
});
|
||||||
|
@ -5,9 +5,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
|||||||
import io.anuke.mindustry.game.Difficulty;
|
import io.anuke.mindustry.game.Difficulty;
|
||||||
import io.anuke.mindustry.game.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.io.Map;
|
import io.anuke.mindustry.io.Map;
|
||||||
import io.anuke.ucore.core.Core;
|
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.scene.event.Touchable;
|
import io.anuke.ucore.scene.event.Touchable;
|
||||||
import io.anuke.ucore.scene.ui.*;
|
import io.anuke.ucore.scene.ui.*;
|
||||||
import io.anuke.ucore.scene.ui.layout.Stack;
|
import io.anuke.ucore.scene.ui.layout.Stack;
|
||||||
@ -26,15 +24,12 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
getTitleTable().getCell(title()).growX().center();
|
getTitleTable().getCell(title()).growX().center();
|
||||||
getTitleTable().center();
|
getTitleTable().center();
|
||||||
addCloseButton();
|
addCloseButton();
|
||||||
setup();
|
shown(this::setup);
|
||||||
}
|
|
||||||
|
|
||||||
public void reload(){
|
|
||||||
content().clear();
|
|
||||||
setup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(){
|
void setup(){
|
||||||
|
content().clear();
|
||||||
|
|
||||||
Table maps = new Table();
|
Table maps = new Table();
|
||||||
pane = new ScrollPane(maps);
|
pane = new ScrollPane(maps);
|
||||||
pane.setFadeScrollBars(false);
|
pane.setFadeScrollBars(false);
|
||||||
@ -126,13 +121,6 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
content().add(pane).uniformX();
|
content().add(pane).uniformX();
|
||||||
|
|
||||||
shown(()->{
|
|
||||||
//this is necessary for some reason?
|
|
||||||
Timers.run(2f, ()->{
|
|
||||||
Core.scene.setScrollFocus(pane);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayGameModeHelp() {
|
private void displayGameModeHelp() {
|
||||||
|
@ -316,9 +316,11 @@ public class Block extends BaseBlock {
|
|||||||
icon = new TextureRegion[]{Draw.region(name + "-icon")};
|
icon = new TextureRegion[]{Draw.region(name + "-icon")};
|
||||||
} else if (Draw.hasRegion(name + "1")) {
|
} else if (Draw.hasRegion(name + "1")) {
|
||||||
icon = new TextureRegion[]{Draw.region(name + "1")};
|
icon = new TextureRegion[]{Draw.region(name + "1")};
|
||||||
} else {
|
} else if (Draw.hasRegion(name)){
|
||||||
icon = new TextureRegion[]{Draw.region(name)};
|
icon = new TextureRegion[]{Draw.region(name)};
|
||||||
}
|
}else{
|
||||||
|
icon = new TextureRegion[]{};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return icon;
|
return icon;
|
||||||
|
Loading…
Reference in New Issue
Block a user