Finished most of new save system, added new localized strings
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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(){
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ public class Tile{
|
||||
|
||||
public void changed(){
|
||||
if(entity != null){
|
||||
if(entity.added) entity.remove();
|
||||
entity.remove();
|
||||
entity = null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user