Finished most of new save system, added new localized strings

This commit is contained in:
Anuken 2017-12-29 15:54:59 -05:00
parent 6774ea67ce
commit 036a246769
37 changed files with 681 additions and 379 deletions

View File

@ -86,7 +86,7 @@ _(not necessarily planned!)_
- Spawn points changed into enemy bases with hostile turrets
- Unit production
### Optmiziation
### Optimization
- Look into uses for `IntMap`
- Spread updating over multiple frames for large groups of specific tile entities (?)
- Optimize enemy + bullet code and check quadtree leaf parameters

View File

@ -1,5 +1,6 @@
package io.anuke.mindustry;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -21,7 +22,6 @@ import io.anuke.ucore.scene.ui.layout.Unit;
public class AndroidLauncher extends AndroidApplication{
boolean doubleScaleTablets = true;
@SuppressLint("SimpleDateFormat")
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
@ -30,7 +30,7 @@ public class AndroidLauncher extends AndroidApplication{
Mindustry.hasDiscord = isPackageInstalled("com.discord");
Mindustry.platforms = new PlatformFunction(){
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm");
DateFormat format = SimpleDateFormat.getDateTimeInstance();
@Override
public String format(Date date){

View File

@ -9,8 +9,8 @@ import io.anuke.mindustry.AndroidTextFieldDialog.TextPromptListener;
import io.anuke.ucore.scene.event.InputEvent;
import io.anuke.ucore.scene.event.InputListener;
import io.anuke.ucore.scene.ui.TextField;
import io.anuke.ucore.scene.utils.ChangeListener;
import io.anuke.ucore.scene.utils.ClickListener;
import io.anuke.ucore.scene.event.ChangeListener;
import io.anuke.ucore.scene.event.ClickListener;
public class TextFieldDialogListener extends ClickListener{
private TextField field;

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 209 B

View File

@ -11,14 +11,31 @@ text.level.mode=Gamemode:
text.savegame=Save Game
text.loadgame=Load Game
text.quit=Quit
text.tutorial.back=< Prev
text.tutorial.next=Next >
text.save.new=New Save
text.save.overwrite=Are you sure you want to overwrite\nthis save slot?
text.overwrite=Overwrite
text.saveload=[accent]Saving...
text.savefail=Failed to save game!
text.selectslot=Select a save slot.
text.save.delete.confirm=Are you sure you want to delete this save?
text.save.delete=Delete
text.save.export=Export Save
text.save.import.invalid=[orange]This save is invalid!
text.save.import.fail=[crimson]Failed to import save: [orange]{0}
text.save.export.fail=[crimson]Failed to export save: [orange]{0}
text.save.import=Import Save
text.save.newslot=Save name:
text.save.rename=Rename
text.save.rename.text=New name:
text.selectslot=Select a save.
text.slot=[accent]Slot {0}
text.save.corrupted=[orange]Save file corrupted or invalid!
text.empty=<empty>
text.on=On
text.off=Off
text.save.autosave=Autosave: {0}
text.save.map=Map: {0}
text.save.wave=Wave {0}
text.save.date=Last Saved: {0}
text.confirm=Confirm

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -13,6 +13,7 @@ com.badlogic.gdx.graphics.Color: {
red: {a: 1, b: 0, g: 0, r: 1 },
blue: {a: 1, b: 1, g: 0, r: 0 },
grey: {a: 1, b: 0.32, g: 0.32, r: 0.32 },
lightgray: {a: 1, b: 0.3, g: 0.3, r: 0.3 },
orange: {hex: "#FFA500"},
accent: {hex: "f4ba6e"},
vis-blue: {a: 1, b: 0.886, g: 0.631, r: 0.105 },
@ -21,8 +22,12 @@ com.badlogic.gdx.graphics.Color: {
link-label: {a: 1, b: 0.886, g: 0.631, r: 0.105 }
},
io.anuke.ucore.scene.Skin$TintedDrawable: {
dialogDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.9} }
loadDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.8} }
dialogDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.9} },
invis: {name: white, color: {r: 0, g: 0, b: 0, a: 0} }
loadDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.8} },
clear: {name: white, color: {r: 0.1, g: 0.1, b: 0.1, a: 0.7}},
clear-over: {name: white, color: {r: 1, g: 1, b: 1, a: 0.2} },
clear-down: {name: white, color: {r: 1, g: 1, b: 1, a: 0.4} }
},
io.anuke.ucore.scene.ui.Button$ButtonStyle: {
default: {down: button-down, up: button },
@ -31,11 +36,14 @@ io.anuke.ucore.scene.ui.Button$ButtonStyle: {
},
io.anuke.ucore.scene.ui.TextButton$TextButtonStyle: {
default: {over: button-over, disabled: button, font: default-font, fontColor: white, disabledFontColor: grey, down: button-down, up: button, transition: 0 },
clear: {down: clear-down, up: clear, over: clear-over, font: default-font, fontColor: white, disabledFontColor: grey },
empty: {font: default-font},
toggle: {font: default-font, fontColor: white, checked: button-down, down: button-down, up: button, over: button-over, disabled: button, disabledFontColor: grey }
},
io.anuke.ucore.scene.ui.ImageButton$ImageButtonStyle: {
default: {down: button-down, up: button, over: button-over },
empty: {},
empty: { imageDownColor: accent, imageUpColor: white},
emptytoggle: {imageCheckedColor: white, imageDownColor: white, imageUpColor: lightgray},
static: {up: button },
static-down: {up: button-down },
toggle: {checked: button-down, down: button-down, up: button },
@ -51,14 +59,15 @@ io.anuke.ucore.scene.ui.ScrollPane$ScrollPaneStyle: {
default: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical},
horizontal: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical, hScroll: scroll-horizontal, hScrollKnob: scroll-knob-horizontal},
volume: {background: button-map, vScroll: scroll, vScrollKnob: scroll-knob-vertical},
clear: {vScroll: scroll, vScrollKnob: scroll-knob-vertical}
clear: {vScroll: scroll, vScrollKnob: scroll-knob-vertical},
clear-black: {vScroll: scroll, vScrollKnob: scroll-knob-vertical-black}
},
io.anuke.ucore.scene.ui.Window$WindowStyle: {
default: {titleFont: default-font, background: window, titleFontColor: orange },
default: {titleFont: default-font, background: window, titleFontColor: accent },
dialog: {stageBackground: dialogDim, titleFont: default-font, background: window-empty, titleFontColor: accent }
},
io.anuke.ucore.scene.ui.KeybindDialog$KeybindDialogStyle: {
default: {keyColor: red, keyNameColor: white, paneStyle: clear},
default: {keyColor: accent, keyNameColor: white, paneStyle: clear},
},
io.anuke.ucore.scene.ui.Slider$SliderStyle: {
default-horizontal: {background: slider, knob: slider-knob, knobOver: slider-knob-over, knobDown: slider-knob-down},
@ -74,7 +83,7 @@ io.anuke.ucore.scene.ui.TextField$TextFieldStyle: {
default: {font: default-font, fontColor: white, disabledFontColor: grey, selection: selection, background: button, cursor: cursor, messageFont: default-font, messageFontColor: grey }
}
io.anuke.ucore.scene.ui.CheckBox$CheckBoxStyle: {
default: {checkboxOn: check-on, checkboxOff: check-off, checkboxOver: check-over, font: default-font, fontColor: white, disabledFontColor: grey }
default: {checkboxOn: check-on, checkboxOff: check-off, checkboxOnOver: check-on-over, checkboxOver: check-over, font: default-font, fontColor: white, disabledFontColor: grey }
},
io.anuke.ucore.scene.ui.List$ListStyle: {
default: {fontColorUnselected: white, fontColorSelected: white, font: default-font }

View File

@ -58,7 +58,7 @@ public class Vars{
public static float baseControllerSpeed = 11f;
public static final int saveSlots = 10;
public static final int saveSlots = 16;
//amount of drops that are left when breaking a block
public static final float breakDropAmount = 0.5f;

View File

@ -23,6 +23,7 @@ import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.DesktopInput;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.io.Saves;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Weapon;
@ -64,7 +65,9 @@ public class Control extends Module{
Array<SpawnPoint> spawnpoints = new Array<>();
boolean shouldUpdateItems = false;
boolean wasPaused = false;
Saves saves;
float respawntime;
InputHandler input;
@ -76,6 +79,8 @@ public class Control extends Module{
if(Mindustry.args.contains("-debug", false))
Vars.debug = true;
saves = new Saves();
Inputs.useControllers(false);
log("Total blocks loaded: " + Block.getAllBlocks().size);
@ -177,7 +182,8 @@ public class Control extends Module{
);
for(int i = 0; i < Vars.saveSlots; i ++){
Settings.defaults("saveslot" + i, "empty");
Settings.defaults("save-" + i + "-autosave", true);
Settings.defaults("save-" + i + "-name", "untitled");
}
Settings.loadAll("io.anuke.moment");
@ -189,7 +195,12 @@ public class Control extends Module{
player = new Player();
spawns = WaveCreator.getSpawns();
//WaveCreator.testWaves(1, 30);
saves.load();
}
public Saves getSaves(){
return saves;
}
public boolean showCursor(){

View File

@ -49,12 +49,12 @@ public class Tutorial{
row();
prev = new button("< Prev", ()->{
prev = new button("$text.tutorial.back", ()->{
if(!prev.isDisabled())
move(false);
}).left().get();
next = new button("Next >", ()->{
next = new button("$text.tutorial.next", ()->{
if(!next.isDisabled())
move(true);
}).right().get();

View File

@ -30,12 +30,14 @@ import io.anuke.mindustry.world.blocks.types.Configurable;
import io.anuke.ucore.UCore;
import io.anuke.ucore.core.*;
import io.anuke.ucore.core.Inputs.DeviceType;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Listenable;
import io.anuke.ucore.function.VisibilityProvider;
import io.anuke.ucore.modules.SceneModule;
import io.anuke.ucore.scene.Element;
import io.anuke.ucore.scene.Skin;
import io.anuke.ucore.scene.builders.build;
import io.anuke.ucore.scene.builders.field;
import io.anuke.ucore.scene.builders.label;
import io.anuke.ucore.scene.builders.table;
import io.anuke.ucore.scene.event.Touchable;
@ -367,12 +369,28 @@ public class UI extends SceneModule{
public void hideConfig(){
configtable.setVisible(false);
}
public void showTextInput(String title, String text, String def, Consumer<String> confirmed){
new Dialog(title, "dialog"){{
content().margin(30);
content().add(text).padRight(6f);
TextField field = content().addField(def, t->{}).size(170f, 50f).get();
field.setTextFieldFilter((f, c) -> field.getText().length() < 12);
Mindustry.platforms.addDialog(field);
buttons().defaults().size(120, 54).pad(4);
buttons().addButton("$text.ok", () -> {
confirmed.accept(field.getText());
hide();
}).disabled(b -> field.getText().isEmpty());
buttons().addButton("$text.cancel", this::hide);
}}.show();
}
public void showError(String text){
new Dialog("$text.error.title", "dialog"){{
content().margin(15);
content().add(text);
getButtonTable().addButton("$text.ok", this::hide).size(90, 50).pad(4);
buttons().addButton("$text.ok", this::hide).size(90, 50).pad(4);
}}.show();
}
@ -380,7 +398,7 @@ public class UI extends SceneModule{
new Dialog("$text.error.title", "dialog"){{
content().margin(15);
content().add(text);
getButtonTable().addButton("$text.quit", Gdx.app::exit).size(90, 50).pad(4);
buttons().addButton("$text.quit", Gdx.app::exit).size(90, 50).pad(4);
}}.show();
}

View File

@ -115,7 +115,11 @@ public class SaveIO{
}
public static boolean isSaveValid(int slot){
try(DataInputStream stream = new DataInputStream(fileFor(slot).read())){
return isSaveValid(fileFor(slot));
}
public static boolean isSaveValid(FileHandle file){
try(DataInputStream stream = new DataInputStream(file.read())){
int version = stream.readInt(); //read version
stream.readLong(); //read last saved time
stream.readByte(); //read the gamemode
@ -340,6 +344,7 @@ public class SaveIO{
Vars.control.getWeapons().clear();
Vars.control.getWeapons().add(Weapon.blaster);
Vars.player.weapon = Weapon.blaster;
int weapons = stream.readByte();

View File

@ -1,10 +1,107 @@
package io.anuke.mindustry.io;
import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.GameMode;
import io.anuke.mindustry.world.Map;
import io.anuke.ucore.core.Settings;
import java.lang.reflect.Array;
import java.io.IOException;
public class Saves {
private int lastSlot;
private IntArray saves;
private int nextSlot;
private Array<SaveSlot> saves = new Array<>();
public void load(){
saves.clear();
for(int i = 0; i < Vars.saveSlots; i ++){
if(SaveIO.isSaveValid(i)){
saves.add(new SaveSlot(i));
nextSlot = i + 1;
}
}
}
public boolean canAddSave(){
return nextSlot <= Vars.saveSlots;
}
public void addSave(String name){
SaveSlot slot = new SaveSlot(nextSlot);
nextSlot ++;
slot.setName(name);
saves.add(slot);
SaveIO.saveToSlot(slot.index);
}
public Array<SaveSlot> getSaveSlots(){
return saves;
}
public class SaveSlot{
public final int index;
public SaveSlot(int index){
this.index = index;
}
public String getDate(){
return SaveIO.getTimeString(index);
}
public Map getMap(){
return SaveIO.getMap(index);
}
public String getName(){
return Settings.getString("save-"+index+"-name");
}
public void setName(String name){
Settings.putString("save-"+index+"-name", name);
Settings.save();
}
public int getWave(){
return SaveIO.getWave(index);
}
public GameMode getMode(){
return SaveIO.getMode(index);
}
public boolean isAutosave(){
return Settings.getBool("save-"+index+"-autosave");
}
public void setAutosave(boolean save){
Settings.putBool("save-"+index + "-autosave", save);
Settings.save();
}
public void importFile(FileHandle file) throws IOException{
try{
file.copyTo(SaveIO.fileFor(index));
}catch (Exception e){
throw new IOException(e);
}
}
public void exportFile(FileHandle file) throws IOException{
try{
if(!file.extension().equals("mins")){
file = file.parent().child(file.nameWithoutExtension() + ".mins");
}
SaveIO.fileFor(index).copyTo(file);
}catch (Exception e){
throw new IOException(e);
}
}
public void delete(){
SaveIO.fileFor(index).delete();
load();
}
}
}

View File

@ -233,7 +233,7 @@ public class MapEditorDialog extends Dialog{
ImageButton undo = tools.addIButton("icon-undo", 16*2f, () -> view.undo()).get();
ImageButton redo = tools.addIButton("icon-redo", 16*2f, () -> view.redo()).get();
tools.addIButton("toggle", "icon-grid", 16*2f, () -> view.setGrid(!view.isGrid())).get();
tools.addIButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get();
undo.setDisabled(() -> !view.getStack().canUndo());
redo.setDisabled(() -> !view.getStack().canRedo());

View File

@ -53,7 +53,7 @@ public enum Weapon{
Effects.effect(Fx.shoot2, p.x + vector.x, p.y+vector.y);
}
},
flamer(5, BulletType.flame, stack(Item.steel, 60), stack(Item.coal, 60)){
flamer(5, BulletType.flame, stack(Item.steel, 60), stack(Item.iron, 120)){
{
shootsound = "flame2";

View File

@ -59,7 +59,7 @@ public class FileChooser extends FloatingDialog{
if(!open) Mindustry.platforms.addDialog(filefield);
filefield.setDisabled(open);
ok = new TextButton(open ? "$text.save" : "$text.save");
ok = new TextButton(open ? "$text.load" : "$text.save");
ok.clicked(() -> {
if(ok.isDisabled()) return;

View File

@ -12,7 +12,7 @@ import io.anuke.ucore.scene.event.InputEvent;
import io.anuke.ucore.scene.ui.*;
import io.anuke.ucore.scene.ui.layout.Stack;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.utils.ClickListener;
import io.anuke.ucore.scene.event.ClickListener;
import io.anuke.ucore.scene.utils.Elements;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Tmp;

View File

@ -1,21 +1,28 @@
package io.anuke.mindustry.ui;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.io.SaveIO;
import io.anuke.mindustry.io.Saves.SaveSlot;
import io.anuke.ucore.UCore;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.ui.Label;
import io.anuke.ucore.scene.builders.button;
import io.anuke.ucore.scene.builders.dialog;
import io.anuke.ucore.scene.ui.Dialog;
import io.anuke.ucore.scene.ui.ScrollPane;
import io.anuke.ucore.scene.ui.TextButton;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Strings;
import java.io.IOException;
public class LoadDialog extends FloatingDialog{
ScrollPane pane;
Table slots;
public LoadDialog() {
this("$text.loadgame");
@ -33,37 +40,112 @@ public class LoadDialog extends FloatingDialog{
addCloseButton();
}
private void setup(){
protected void setup(){
content().clear();
content().add("$text.selectslot").padBottom(2);
content().row();
Table slots = new Table();
pane = new ScrollPane(slots);
slots = new Table();
pane = new ScrollPane(slots, "clear-black");
pane.setFadeScrollBars(false);
pane.setScrollingDisabled(true, false);
slots.marginRight(24);
for(int i = 0; i < Vars.saveSlots; i++){
Timers.runTask(2f, () -> Core.scene.setScrollFocus(pane));
TextButton button = new TextButton(Bundles.format("text.slot", (i + 1)));
button.margin(12);
Array<SaveSlot> array = Vars.control.getSaves().getSaveSlots();
for(SaveSlot slot : array){
TextButton button = new TextButton("[accent]" + slot.getName(), "clear");
button.getLabelCell().growX().left();
button.getLabelCell().padBottom(8f);
button.getLabelCell().top().left().growX();
button.row();
button.defaults().left();
Label info = new Label("[gray]" + (!SaveIO.isSaveValid(i) ? Bundles.get("text.empty") : SaveIO.getMode(i) + ", "
+ Bundles.get("map."+SaveIO.getMap(i).name+".name", SaveIO.getMap(i).name) + ", " + Bundles.format("text.save.wave", SaveIO.getWave(i)) + "\n"
+ Bundles.format("text.save.date", SaveIO.getTimeString(i))));
info.setAlignment(Align.center, Align.center);
button.table(t -> {
t.right();
button.add(info).padBottom(3).padTop(7);
button.row();
button.row();
modifyButton(button, i);
t.addIButton("icon-floppy", "emptytoggle", 14*3, () -> {
slot.setAutosave(!slot.isAutosave());
}).checked(slot.isAutosave()).right();
slots.add(button).size(404, 104).pad(4);
t.addIButton("icon-trash", "empty", 14*3, () -> {
Vars.ui.showConfirm("$text.confirm", "$text.save.delete.confirm", () -> {
slot.delete();
setup();
});
}).size(14*3).right();
t.addIButton("icon-dots", "empty", 14*3, () -> {
FloatingDialog dialog = new FloatingDialog("Save Options");
dialog.addCloseButton();
dialog.content().defaults().left().uniformX().size(230f, 60f);
dialog.content().addImageTextButton("$text.save.rename", "icon-rename", 14*3, () -> {
Vars.ui.showTextInput("$text.save.rename", "$text.save.rename.text", slot.getName(), text -> {
slot.setName(text);
dialog.hide();
setup();
});
});
dialog.content().row();
dialog.content().addImageTextButton("$text.save.import", "icon-save", 14*3, () -> {
new FileChooser("$text.save.import", f -> f.extension().equals("mins"), true, file -> {
if(SaveIO.isSaveValid(file)){
try{
slot.importFile(file);
setup();
}catch (IOException e){
Vars.ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false)));
}
}else{
Vars.ui.showError("$text.save.import.invalid");
}
dialog.hide();
}).show();
});
dialog.content().row();
dialog.content().addImageTextButton("$text.save.export", "icon-load", 14*3, () -> {
new FileChooser("$text.save.export", false, file -> {
try{
slot.exportFile(file);
setup();
}catch (IOException e){
Vars.ui.showError(Bundles.format("text.save.export.fail", Strings.parseException(e, false)));
}
dialog.hide();
}).show();
});
dialog.show();
}).size(14*3).right();
}).padRight(-10).growX();
String color = "[lightgray]";
button.defaults().padBottom(3);
button.row();
button.add(Bundles.format("text.save.map", color+slot.getMap().localized()));
button.row();
button.add(Bundles.get("text.level.mode") + " " +color+ slot.getMode());
button.row();
button.add(Bundles.format("text.save.wave", color+slot.getWave()));
button.row();
button.label(() -> Bundles.format("text.save.autosave", color + Bundles.get(slot.isAutosave() ? "text.on" : "text.off")));
button.row();
button.add();
button.add(Bundles.format("text.save.date", color+slot.getDate()));
button.row();
modifyButton(button, slot);
slots.add(button).uniformX().fillX().pad(4).padRight(-4).margin(10f).marginLeft(20f).marginRight(20f);
slots.row();
}
@ -71,17 +153,16 @@ public class LoadDialog extends FloatingDialog{
}
public void modifyButton(TextButton button, int slot){
button.setDisabled(!SaveIO.isSaveValid(slot));
public void modifyButton(TextButton button, SaveSlot slot){
button.clicked(() -> {
if(!button.isDisabled()){
if(!button.childrenPressed()){
Vars.ui.showLoading();
Timers.runTask(3f, () -> {
Vars.ui.hideLoading();
hide();
try{
SaveIO.loadFromSlot(slot);
SaveIO.loadFromSlot(slot.index);
GameState.set(State.playing);
Vars.ui.hideMenu();
}catch(Exception e){
@ -90,7 +171,6 @@ public class LoadDialog extends FloatingDialog{
GameState.set(State.menu);
Vars.control.reset();
Vars.ui.showError("$text.save.corrupted");
return;
}
});
}

View File

@ -4,8 +4,12 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.io.SaveIO;
import io.anuke.mindustry.io.Saves;
import io.anuke.mindustry.io.Saves.SaveSlot;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.builders.button;
import io.anuke.ucore.scene.ui.ConfirmDialog;
import io.anuke.ucore.scene.ui.Dialog;
import io.anuke.ucore.scene.ui.TextButton;
import io.anuke.ucore.scene.ui.layout.Cell;
import io.anuke.ucore.util.Bundles;
@ -17,21 +21,31 @@ public class SaveDialog extends LoadDialog{
}
@Override
public void modifyButton(TextButton button, int slot){
protected void setup(){
super.setup();
if(!Vars.control.getSaves().canAddSave()){
return;
}
slots.row();
slots.addImageTextButton("$text.save.new", "icon-add", "clear", 14*3, () -> {
Vars.ui.showTextInput("$text.save", "$text.save.newslot", "", text -> {
Vars.control.getSaves().addSave(text);
setup();
});
}).fillX().margin(10f).height(70f).pad(4f).padRight(-4);
}
@Override
public void modifyButton(TextButton button, SaveSlot slot){
button.clicked(() -> {
if(SaveIO.isSaveValid(slot)){
new ConfirmDialog("$text.overwrite", "$text.save.overwrite", () -> {
save(slot);
}){
{
content().margin(16);
for(Cell<?> cell : getButtonTable().getCells())
cell.size(110, 45).pad(4);
}
}.show();
}else{
save(slot);
}
if(button.childrenPressed()) return;
Vars.ui.showConfirm("$text.overwrite", "$text.save.overwrite", () -> {
save(slot.index);
});
});
}

View File

@ -220,7 +220,7 @@ public class Tile{
public void changed(){
if(entity != null){
if(entity.added) entity.remove();
entity.remove();
entity = null;
}

View File

@ -3,6 +3,7 @@ package io.anuke.mindustry.desktop;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@ -30,7 +31,7 @@ public class DesktopLauncher {
config.setWindowIcon("sprites/icon.png");
Mindustry.platforms = new PlatformFunction(){
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm");
DateFormat format = SimpleDateFormat.getDateTimeInstance();
@Override
public String format(Date date){