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

@@ -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;
}