mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-01-13 08:15:04 +07:00
Merged save previews
This commit is contained in:
commit
b39464a7d1
BIN
core/assets-raw/sprites/ui/nomap.png
Normal file
BIN
core/assets-raw/sprites/ui/nomap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 586 KiB After Width: | Height: | Size: 579 KiB |
@ -18,7 +18,7 @@ import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.input.*;
|
||||
import io.anuke.mindustry.maps.*;
|
||||
import io.anuke.mindustry.maps.Map;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.ui.dialogs.*;
|
||||
@ -26,8 +26,8 @@ import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.blocks.storage.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.time.*;
|
||||
import java.time.format.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
import static io.anuke.arc.Core.*;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
@ -233,7 +233,7 @@ public class Control implements ApplicationListener, Loadable{
|
||||
state.rules = rules;
|
||||
logic.play();
|
||||
if(settings.getBool("savecreate")){
|
||||
control.saves.addSave(map.name() + "-" + DateTimeFormatter.ofPattern("MMM dd h:mm").format(LocalDateTime.now()));
|
||||
control.saves.addSave(map.name() + " " + new SimpleDateFormat("MMM dd h:mm", Locale.getDefault()).format(new Date()));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -387,6 +387,8 @@ public class Control implements ApplicationListener, Loadable{
|
||||
@Override
|
||||
public void update(){
|
||||
saves.update();
|
||||
//update and load any requested assets
|
||||
assets.update();
|
||||
|
||||
input.updateController();
|
||||
|
||||
|
@ -87,6 +87,7 @@ public class UI implements ApplicationListener, Loadable{
|
||||
skin.addRegions(Core.atlas);
|
||||
loadExtraStyle(skin);
|
||||
skin.add("outline", Core.assets.get("outline"));
|
||||
skin.getFont("outline").getData().markupEnabled = true;
|
||||
skin.getFont("default").getData().markupEnabled = true;
|
||||
skin.getFont("default").setOwnsTexture(false);
|
||||
skin.load(Core.files.internal("sprites/uiskin.json"));
|
||||
|
@ -1,30 +1,31 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.assets.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.files.FileHandle;
|
||||
import io.anuke.arc.files.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.EventType.StateChangeEvent;
|
||||
import io.anuke.mindustry.io.SaveIO;
|
||||
import io.anuke.mindustry.io.SaveIO.SaveException;
|
||||
import io.anuke.mindustry.io.SaveMeta;
|
||||
import io.anuke.arc.util.async.*;
|
||||
import io.anuke.mindustry.core.GameState.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.io.*;
|
||||
import io.anuke.mindustry.io.SaveIO.*;
|
||||
import io.anuke.mindustry.maps.Map;
|
||||
import io.anuke.mindustry.type.Zone;
|
||||
import io.anuke.mindustry.type.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.saveExtension;
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Saves{
|
||||
private int nextSlot;
|
||||
private Array<SaveSlot> saves = new Array<>();
|
||||
private IntMap<SaveSlot> saveMap = new IntMap<>();
|
||||
private SaveSlot current;
|
||||
private AsyncExecutor previewExecutor = new AsyncExecutor(2);
|
||||
private boolean saving;
|
||||
private float time;
|
||||
|
||||
@ -32,6 +33,8 @@ public class Saves{
|
||||
private long lastTimestamp;
|
||||
|
||||
public Saves(){
|
||||
Core.assets.setLoader(Texture.class, ".spreview", new SavePreviewLoader());
|
||||
|
||||
Events.on(StateChangeEvent.class, event -> {
|
||||
if(event.to == State.menu){
|
||||
totalPlaytime = 0;
|
||||
@ -162,6 +165,7 @@ public class Saves{
|
||||
|
||||
public class SaveSlot{
|
||||
public final int index;
|
||||
boolean requestedPreview;
|
||||
SaveMeta meta;
|
||||
|
||||
public SaveSlot(int index){
|
||||
@ -174,6 +178,7 @@ public class Saves{
|
||||
meta = SaveIO.getMeta(index);
|
||||
current = this;
|
||||
totalPlaytime = meta.timePlayed;
|
||||
savePreview();
|
||||
}catch(Exception e){
|
||||
throw new SaveException(e);
|
||||
}
|
||||
@ -191,6 +196,41 @@ public class Saves{
|
||||
}
|
||||
|
||||
totalPlaytime = prev;
|
||||
savePreview();
|
||||
}
|
||||
|
||||
private void savePreview(){
|
||||
if(Core.assets.isLoaded(loadPreviewFile().path())){
|
||||
Core.assets.unload(loadPreviewFile().path());
|
||||
}
|
||||
previewExecutor.submit(() -> {
|
||||
try{
|
||||
previewFile().writePNG(renderer.minimap.getPixmap());
|
||||
requestedPreview = false;
|
||||
}catch(Throwable t){
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Texture previewTexture(){
|
||||
if(!previewFile().exists()){
|
||||
return null;
|
||||
}else if(Core.assets.isLoaded(loadPreviewFile().path())){
|
||||
return Core.assets.get(loadPreviewFile().path());
|
||||
}else if(!requestedPreview){
|
||||
Core.assets.load(new AssetDescriptor<>(loadPreviewFile(), Texture.class));
|
||||
requestedPreview = true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private FileHandle previewFile(){
|
||||
return mapPreviewDirectory.child("save_slot_" + index + ".png");
|
||||
}
|
||||
|
||||
private FileHandle loadPreviewFile(){
|
||||
return previewFile().sibling(previewFile().name() + ".spreview");
|
||||
}
|
||||
|
||||
public boolean isHidden(){
|
||||
@ -214,7 +254,7 @@ public class Saves{
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return Core.settings.getString("save-" + index + "-name", "untittled");
|
||||
return Core.settings.getString("save-" + index + "-name", "untitled");
|
||||
}
|
||||
|
||||
public void setName(String name){
|
||||
@ -270,6 +310,10 @@ public class Saves{
|
||||
current = null;
|
||||
}
|
||||
|
||||
if(Core.assets.isLoaded(loadPreviewFile().path())){
|
||||
Core.assets.unload(loadPreviewFile().path());
|
||||
}
|
||||
|
||||
saveSlots();
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,10 @@ public class MinimapRenderer implements Disposable{
|
||||
Events.on(TileChangeEvent.class, event -> Core.app.post(() -> update(event.tile)));
|
||||
}
|
||||
|
||||
public Pixmap getPixmap(){
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
public Texture getTexture(){
|
||||
return texture;
|
||||
}
|
||||
|
23
core/src/io/anuke/mindustry/io/SavePreviewLoader.java
Normal file
23
core/src/io/anuke/mindustry/io/SavePreviewLoader.java
Normal file
@ -0,0 +1,23 @@
|
||||
package io.anuke.mindustry.io;
|
||||
|
||||
import io.anuke.arc.assets.*;
|
||||
import io.anuke.arc.assets.loaders.*;
|
||||
import io.anuke.arc.assets.loaders.resolvers.*;
|
||||
import io.anuke.arc.files.*;
|
||||
|
||||
public class SavePreviewLoader extends TextureLoader{
|
||||
|
||||
public SavePreviewLoader(){
|
||||
super(new AbsoluteFileHandleResolver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadAsync(AssetManager manager, String fileName, FileHandle file, TextureParameter parameter){
|
||||
try{
|
||||
super.loadAsync(manager, fileName, file.sibling(file.nameWithoutExtension()), parameter);
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
file.sibling(file.nameWithoutExtension()).delete();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
package io.anuke.mindustry.ui;
|
||||
|
||||
import io.anuke.arc.graphics.Texture;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.scene.ui.Image;
|
||||
import io.anuke.arc.scene.ui.layout.UnitScl;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
|
||||
public class BorderImage extends Image{
|
||||
private float thickness = 4f;
|
||||
public float thickness = 4f;
|
||||
public Color borderColor = Pal.gray;
|
||||
|
||||
public BorderImage(){
|
||||
|
||||
@ -27,6 +28,11 @@ public class BorderImage extends Image{
|
||||
thickness = thick;
|
||||
}
|
||||
|
||||
public BorderImage border(Color color){
|
||||
this.borderColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
super.draw();
|
||||
@ -34,7 +40,7 @@ public class BorderImage extends Image{
|
||||
float scaleX = getScaleX();
|
||||
float scaleY = getScaleY();
|
||||
|
||||
Draw.color(Pal.gray);
|
||||
Draw.color(borderColor);
|
||||
Draw.alpha(parentAlpha);
|
||||
Lines.stroke(UnitScl.dp.scl(thickness));
|
||||
Lines.rect(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY);
|
||||
|
@ -9,6 +9,7 @@ import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.arc.scene.*;
|
||||
import io.anuke.arc.scene.style.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.scene.utils.*;
|
||||
@ -77,20 +78,30 @@ public class DeployDialog extends FloatingDialog{
|
||||
}}.setScaling(Scaling.fit));
|
||||
|
||||
if(control.saves.getZoneSlot() != null){
|
||||
float size = 230f;
|
||||
float size = 250f;
|
||||
|
||||
stack.add(new Table(t -> {
|
||||
SaveSlot slot = control.saves.getZoneSlot();
|
||||
|
||||
Stack sub = new Stack();
|
||||
|
||||
if(control.saves.getZoneSlot().getZone() != null){
|
||||
if(slot.getZone() != null){
|
||||
sub.add(new Table(f -> f.margin(4f).add(new Image("whiteui")).color(Color.fromGray(0.1f)).grow()));
|
||||
sub.add(new Table(f -> f.margin(4f).add(new Image(control.saves.getZoneSlot().getZone().preview).setScaling(Scaling.fit)).color(Color.DARK_GRAY).grow()));
|
||||
|
||||
sub.add(new Table(f -> f.margin(4f).add(new Image(slot.getZone().preview).setScaling(Scaling.fit)).update(img -> {
|
||||
TextureRegionDrawable draw = (TextureRegionDrawable)img.getDrawable();
|
||||
if(draw.getRegion().getTexture().isDisposed()){
|
||||
draw.setRegion(slot.getZone().preview);
|
||||
}
|
||||
|
||||
Texture text = slot.previewTexture();
|
||||
if(draw.getRegion() == slot.getZone().preview && text != null){
|
||||
draw.setRegion(new TextureRegion(text));
|
||||
}
|
||||
}).color(Color.DARK_GRAY).grow()));
|
||||
}
|
||||
|
||||
TextButton button = Elements.newButton(Core.bundle.format("resume", slot.getZone().localizedName()), "square", () -> {
|
||||
|
||||
hide();
|
||||
ui.loadAnd(() -> {
|
||||
logic.reset();
|
||||
@ -127,7 +138,7 @@ public class DeployDialog extends FloatingDialog{
|
||||
slot.delete();
|
||||
setup();
|
||||
});
|
||||
}).width(230f).height(50f).padTop(3);
|
||||
}).width(size).height(50f).padTop(3);
|
||||
}));
|
||||
}else{
|
||||
stack.add(new View());
|
||||
|
@ -3,6 +3,9 @@ package io.anuke.mindustry.ui.dialogs;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.files.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.scene.style.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
@ -12,6 +15,7 @@ import io.anuke.mindustry.game.Saves.*;
|
||||
import io.anuke.mindustry.io.*;
|
||||
import io.anuke.mindustry.io.SaveIO.*;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
@ -55,33 +59,35 @@ public class LoadDialog extends FloatingDialog{
|
||||
for(SaveSlot slot : array){
|
||||
if(slot.isHidden()) continue;
|
||||
|
||||
TextButton button = new TextButton("[accent]" + slot.getName(), "clear");
|
||||
button.getLabelCell().growX().left();
|
||||
button.getLabelCell().padBottom(8f);
|
||||
button.getLabelCell().top().left().growX();
|
||||
TextButton button = new TextButton("", "clear");
|
||||
button.getLabel().remove();
|
||||
button.clearChildren();
|
||||
|
||||
button.defaults().left();
|
||||
|
||||
button.table(t -> {
|
||||
t.right();
|
||||
button.table(title -> {
|
||||
title.add("[accent]" + slot.getName()).left().growX().width(230f).wrap();
|
||||
|
||||
t.addImageButton("icon-floppy", "emptytoggle", iconsize, () -> {
|
||||
slot.setAutosave(!slot.isAutosave());
|
||||
}).checked(slot.isAutosave()).right();
|
||||
title.table(t -> {
|
||||
t.right();
|
||||
|
||||
t.addImageButton("icon-trash", "empty", iconsize, () -> {
|
||||
ui.showConfirm("$confirm", "$save.delete.confirm", () -> {
|
||||
slot.delete();
|
||||
setup();
|
||||
});
|
||||
}).size(iconsize).right();
|
||||
t.addImageButton("icon-floppy", "emptytoggle", iconsize, () -> {
|
||||
slot.setAutosave(!slot.isAutosave());
|
||||
}).checked(slot.isAutosave()).right();
|
||||
|
||||
t.addImageButton("icon-pencil", "empty", iconsize, () -> {
|
||||
ui.showTextInput("$save.rename", "$save.rename.text", slot.getName(), text -> {
|
||||
slot.setName(text);
|
||||
setup();
|
||||
});
|
||||
}).size(iconsize).right();
|
||||
t.addImageButton("icon-trash", "empty", iconsize, () -> {
|
||||
ui.showConfirm("$confirm", "$save.delete.confirm", () -> {
|
||||
slot.delete();
|
||||
setup();
|
||||
});
|
||||
}).size(iconsize).right();
|
||||
|
||||
t.addImageButton("icon-pencil", "empty", iconsize, () -> {
|
||||
ui.showTextInput("$save.rename", "$save.rename.text", slot.getName(), text -> {
|
||||
slot.setName(text);
|
||||
setup();
|
||||
});
|
||||
}).size(iconsize).right();
|
||||
|
||||
t.addImageButton("icon-save", "empty", iconsize, () -> {
|
||||
if(!ios){
|
||||
@ -105,26 +111,44 @@ public class LoadDialog extends FloatingDialog{
|
||||
}).size(iconsize).right();
|
||||
|
||||
|
||||
}).padRight(-10).growX();
|
||||
}).padRight(-10).growX();
|
||||
}).growX().colspan(2);
|
||||
button.row();
|
||||
|
||||
String color = "[lightgray]";
|
||||
TextureRegion def = Core.atlas.find("nomap");
|
||||
|
||||
button.left().add(new BorderImage(def, 4f)).update(i -> {
|
||||
TextureRegionDrawable draw = (TextureRegionDrawable)i.getDrawable();
|
||||
if(draw.getRegion().getTexture().isDisposed()){
|
||||
draw.setRegion(def);
|
||||
}
|
||||
|
||||
Texture text = slot.previewTexture();
|
||||
if(draw.getRegion() == def && text != null){
|
||||
draw.setRegion(new TextureRegion(text));
|
||||
}
|
||||
}).left().size(160f).padRight(5);
|
||||
|
||||
button.table(meta -> {
|
||||
meta.left().top();
|
||||
meta.defaults().padBottom(-2).left().width(250f);
|
||||
meta.row();
|
||||
meta.labelWrap(Core.bundle.format("save.map", color + (slot.getMap() == null ? Core.bundle.get("unknown") : slot.getMap().name())));
|
||||
meta.row();
|
||||
meta.labelWrap(Core.bundle.format("save.wave", color + slot.getWave()));
|
||||
meta.row();
|
||||
meta.labelWrap(() -> Core.bundle.format("save.autosave", color + Core.bundle.get(slot.isAutosave() ? "on" : "off")));
|
||||
meta.row();
|
||||
meta.labelWrap(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime()));
|
||||
meta.row();
|
||||
meta.labelWrap(Core.bundle.format("save.date", color + slot.getDate()));
|
||||
meta.row();
|
||||
}).left().growX().width(250f);
|
||||
|
||||
button.defaults().padBottom(3);
|
||||
button.row();
|
||||
button.add(Core.bundle.format("save.map", color + (slot.getMap() == null ? Core.bundle.get("unknown") : slot.getMap().name())));
|
||||
button.row();
|
||||
button.add(Core.bundle.format("save.wave", color + slot.getWave()));
|
||||
button.row();
|
||||
button.label(() -> Core.bundle.format("save.autosave", color + Core.bundle.get(slot.isAutosave() ? "on" : "off")));
|
||||
button.row();
|
||||
button.label(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime()));
|
||||
button.row();
|
||||
button.add(Core.bundle.format("save.date", color + slot.getDate())).colspan(2).padTop(5).right();
|
||||
button.row();
|
||||
modifyButton(button, slot);
|
||||
|
||||
slots.add(button).uniformX().fillX().pad(4).padRight(-4).margin(10f).marginLeft(20f).marginRight(20f);
|
||||
slots.row();
|
||||
slots.add(button).uniformX().fillX().pad(4).padRight(-4).margin(10f).row();
|
||||
}
|
||||
|
||||
cont.add(pane);
|
||||
|
Loading…
Reference in New Issue
Block a user