Finished most of new save system, added new localized strings
2
TODO.md
@ -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
|
||||
|
@ -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){
|
||||
|
@ -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;
|
||||
|
BIN
core/assets-raw/sprites/ui/check-on-over.png
Normal file
After Width: | Height: | Size: 210 B |
Before Width: | Height: | Size: 210 B After Width: | Height: | Size: 211 B |
Before Width: | Height: | Size: 197 B After Width: | Height: | Size: 197 B |
BIN
core/assets-raw/sprites/ui/icons/icon-add.png
Normal file
After Width: | Height: | Size: 234 B |
BIN
core/assets-raw/sprites/ui/icons/icon-dots.png
Normal file
After Width: | Height: | Size: 210 B |
BIN
core/assets-raw/sprites/ui/icons/icon-floppy.png
Normal file
After Width: | Height: | Size: 229 B |
BIN
core/assets-raw/sprites/ui/icons/icon-rename.png
Normal file
After Width: | Height: | Size: 208 B |
BIN
core/assets-raw/sprites/ui/icons/icon-trash.png
Normal file
After Width: | Height: | Size: 237 B |
BIN
core/assets-raw/sprites/ui/scroll-knob-vertical-black.9.png
Normal file
After Width: | Height: | Size: 186 B |
Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 209 B |
@ -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
|
||||
|
BIN
core/assets/mindustry-saves/3.mins
Normal file
BIN
core/assets/mindustry-saves/4.mins
Normal file
BIN
core/assets/mindustry-saves/5.mins
Normal file
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@ -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 }
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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){
|
||||
|