mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-13 09:17:28 +07:00
Bugfixes / Rework of save discovery system
This commit is contained in:
@ -230,7 +230,7 @@ data.export = Export Data
|
|||||||
data.import = Import Data
|
data.import = Import Data
|
||||||
data.exported = Data exported.
|
data.exported = Data exported.
|
||||||
data.invalid = This isn't valid game data.
|
data.invalid = This isn't valid game data.
|
||||||
data.import.confirm = Importing external data will erase[scarlet] all[] your current game data.\n[accent]This cannot be undone![]\n\nOnce the data is imported, your game will exit immediately.
|
data.import.confirm = Importing external data will overwrite[scarlet] all[] your current game data.\n[accent]This cannot be undone![]\n\nOnce the data is imported, your game will exit immediately.
|
||||||
classic.export = Export Classic Data
|
classic.export = Export Classic Data
|
||||||
classic.export.text = [accent]Mindustry[] has just had a major update.\nClassic (v3.5 build 40) save or map data has been detected. Would you like to export these saves to your phone's home folder, for use in the Mindustry Classic app?
|
classic.export.text = [accent]Mindustry[] has just had a major update.\nClassic (v3.5 build 40) save or map data has been detected. Would you like to export these saves to your phone's home folder, for use in the Mindustry Classic app?
|
||||||
quit.confirm = Are you sure you want to quit?
|
quit.confirm = Are you sure you want to quit?
|
||||||
|
@ -185,6 +185,10 @@ public class World{
|
|||||||
Events.fire(new WorldLoadEvent());
|
Events.fire(new WorldLoadEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setGenerating(boolean gen){
|
||||||
|
this.generating = gen;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isGenerating(){
|
public boolean isGenerating(){
|
||||||
return generating;
|
return generating;
|
||||||
}
|
}
|
||||||
|
@ -357,8 +357,8 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
public void drawOver(){
|
public void drawOver(){
|
||||||
if(dead) return;
|
if(dead) return;
|
||||||
|
|
||||||
if(isBuilding()){
|
if(isBuilding() && isBuilding){
|
||||||
if(!state.isPaused() && isBuilding){
|
if(!state.isPaused()){
|
||||||
drawBuilding();
|
drawBuilding();
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@ -458,7 +458,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//mine only when not building
|
//mine only when not building
|
||||||
if(buildRequest() == null){
|
if(buildRequest() == null || !isBuilding){
|
||||||
updateMining();
|
updateMining();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,14 +66,8 @@ public class GlobalData{
|
|||||||
throw new IllegalArgumentException("Not valid save data.");
|
throw new IllegalArgumentException("Not valid save data.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//purge existing data
|
//purge existing tmp data, keep everything else
|
||||||
for(FileHandle f : base.list()){
|
tmpDirectory.deleteDirectory();
|
||||||
if(f.isDirectory()){
|
|
||||||
f.deleteDirectory();
|
|
||||||
}else if(!f.name().equals("zipdata.zip")){
|
|
||||||
f.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
zipped.walk(f -> f.copyTo(base.child(f.path())));
|
zipped.walk(f -> f.copyTo(base.child(f.path())));
|
||||||
dest.delete();
|
dest.delete();
|
||||||
|
@ -22,13 +22,12 @@ import java.util.*;
|
|||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class Saves{
|
public class Saves{
|
||||||
private int nextSlot;
|
|
||||||
private Array<SaveSlot> saves = new Array<>();
|
private Array<SaveSlot> saves = new Array<>();
|
||||||
private IntMap<SaveSlot> saveMap = new IntMap<>();
|
|
||||||
private SaveSlot current;
|
private SaveSlot current;
|
||||||
private AsyncExecutor previewExecutor = new AsyncExecutor(1);
|
private AsyncExecutor previewExecutor = new AsyncExecutor(1);
|
||||||
private boolean saving;
|
private boolean saving;
|
||||||
private float time;
|
private float time;
|
||||||
|
private FileHandle zoneFile;
|
||||||
|
|
||||||
private long totalPlaytime;
|
private long totalPlaytime;
|
||||||
private long lastTimestamp;
|
private long lastTimestamp;
|
||||||
@ -47,16 +46,13 @@ public class Saves{
|
|||||||
|
|
||||||
public void load(){
|
public void load(){
|
||||||
saves.clear();
|
saves.clear();
|
||||||
IntArray slots = Core.settings.getObject("save-slots", IntArray.class, IntArray::new);
|
zoneFile = saveDirectory.child("-1.msav");
|
||||||
|
|
||||||
for(int i = 0; i < slots.size; i++){
|
for(FileHandle file : saveDirectory.list()){
|
||||||
int index = slots.get(i);
|
if(!file.name().contains("backup") && SaveIO.isSaveValid(file)){
|
||||||
if(SaveIO.isSaveValid(index)){
|
SaveSlot slot = new SaveSlot(file);
|
||||||
SaveSlot slot = new SaveSlot(index);
|
|
||||||
saves.add(slot);
|
saves.add(slot);
|
||||||
saveMap.put(slot.index, slot);
|
slot.meta = SaveIO.getMeta(file);
|
||||||
slot.meta = SaveIO.getMeta(index);
|
|
||||||
nextSlot = Math.max(index + 1, nextSlot);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,73 +106,63 @@ public class Saves{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void zoneSave(){
|
public void zoneSave(){
|
||||||
SaveSlot slot = new SaveSlot(-1);
|
SaveSlot slot = new SaveSlot(zoneFile);
|
||||||
slot.setName("zone");
|
slot.setName("zone");
|
||||||
saves.remove(s -> s.index == -1);
|
saves.remove(s -> s.file.equals(zoneFile));
|
||||||
saves.add(slot);
|
saves.add(slot);
|
||||||
saveMap.put(slot.index, slot);
|
|
||||||
slot.save();
|
slot.save();
|
||||||
saveSlots();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SaveSlot addSave(String name){
|
public SaveSlot addSave(String name){
|
||||||
SaveSlot slot = new SaveSlot(nextSlot);
|
SaveSlot slot = new SaveSlot(getNextSlotFile());
|
||||||
nextSlot++;
|
|
||||||
slot.setName(name);
|
slot.setName(name);
|
||||||
saves.add(slot);
|
saves.add(slot);
|
||||||
saveMap.put(slot.index, slot);
|
|
||||||
slot.save();
|
slot.save();
|
||||||
saveSlots();
|
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SaveSlot importSave(FileHandle file) throws IOException{
|
public SaveSlot importSave(FileHandle file) throws IOException{
|
||||||
SaveSlot slot = new SaveSlot(nextSlot);
|
SaveSlot slot = new SaveSlot(getNextSlotFile());
|
||||||
slot.importFile(file);
|
slot.importFile(file);
|
||||||
nextSlot++;
|
|
||||||
slot.setName(file.nameWithoutExtension());
|
slot.setName(file.nameWithoutExtension());
|
||||||
saves.add(slot);
|
saves.add(slot);
|
||||||
saveMap.put(slot.index, slot);
|
slot.meta = SaveIO.getMeta(slot.file);
|
||||||
slot.meta = SaveIO.getMeta(slot.index);
|
|
||||||
current = slot;
|
current = slot;
|
||||||
saveSlots();
|
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SaveSlot getZoneSlot(){
|
public SaveSlot getZoneSlot(){
|
||||||
SaveSlot slot = getByID(-1);
|
SaveSlot slot = getSaveSlots().find(s -> s.file.equals(zoneFile));
|
||||||
return slot == null || slot.getZone() == null ? null : slot;
|
return slot == null || slot.getZone() == null ? null : slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SaveSlot getByID(int id){
|
public FileHandle getNextSlotFile(){
|
||||||
return saveMap.get(id);
|
int i = 0;
|
||||||
|
FileHandle file;
|
||||||
|
while((file = saveDirectory.child(i + "." + saveExtension)).exists()){
|
||||||
|
i ++;
|
||||||
|
}
|
||||||
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Array<SaveSlot> getSaveSlots(){
|
public Array<SaveSlot> getSaveSlots(){
|
||||||
return saves;
|
return saves;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveSlots(){
|
|
||||||
IntArray result = new IntArray(saves.size);
|
|
||||||
for(int i = 0; i < saves.size; i++) result.add(saves.get(i).index);
|
|
||||||
|
|
||||||
Core.settings.putObject("save-slots", result);
|
|
||||||
Core.settings.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SaveSlot{
|
public class SaveSlot{
|
||||||
public final int index;
|
//public final int index;
|
||||||
|
public final FileHandle file;
|
||||||
boolean requestedPreview;
|
boolean requestedPreview;
|
||||||
SaveMeta meta;
|
SaveMeta meta;
|
||||||
|
|
||||||
public SaveSlot(int index){
|
public SaveSlot(FileHandle file){
|
||||||
this.index = index;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load() throws SaveException{
|
public void load() throws SaveException{
|
||||||
try{
|
try{
|
||||||
SaveIO.loadFromSlot(index);
|
SaveIO.load(file);
|
||||||
meta = SaveIO.getMeta(index);
|
meta = SaveIO.getMeta(file);
|
||||||
current = this;
|
current = this;
|
||||||
totalPlaytime = meta.timePlayed;
|
totalPlaytime = meta.timePlayed;
|
||||||
savePreview();
|
savePreview();
|
||||||
@ -190,8 +176,8 @@ public class Saves{
|
|||||||
long prev = totalPlaytime;
|
long prev = totalPlaytime;
|
||||||
totalPlaytime = time;
|
totalPlaytime = time;
|
||||||
|
|
||||||
SaveIO.saveToSlot(index);
|
SaveIO.save(file);
|
||||||
meta = SaveIO.getMeta(index);
|
meta = SaveIO.getMeta(file);
|
||||||
if(!state.is(State.menu)){
|
if(!state.is(State.menu)){
|
||||||
current = this;
|
current = this;
|
||||||
}
|
}
|
||||||
@ -226,8 +212,12 @@ public class Saves{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String index(){
|
||||||
|
return file.nameWithoutExtension();
|
||||||
|
}
|
||||||
|
|
||||||
private FileHandle previewFile(){
|
private FileHandle previewFile(){
|
||||||
return mapPreviewDirectory.child("save_slot_" + index + ".png");
|
return mapPreviewDirectory.child("save_slot_" + index() + ".png");
|
||||||
}
|
}
|
||||||
|
|
||||||
private FileHandle loadPreviewFile(){
|
private FileHandle loadPreviewFile(){
|
||||||
@ -266,11 +256,11 @@ public class Saves{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getName(){
|
public String getName(){
|
||||||
return Core.settings.getString("save-" + index + "-name", "untitled");
|
return Core.settings.getString("save-" + index() + "-name", "untitled");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name){
|
public void setName(String name){
|
||||||
Core.settings.put("save-" + index + "-name", name);
|
Core.settings.put("save-" + index() + "-name", name);
|
||||||
Core.settings.save();
|
Core.settings.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,34 +285,33 @@ public class Saves{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAutosave(){
|
public boolean isAutosave(){
|
||||||
return Core.settings.getBool("save-" + index + "-autosave", true);
|
return Core.settings.getBool("save-" + index() + "-autosave", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAutosave(boolean save){
|
public void setAutosave(boolean save){
|
||||||
Core.settings.put("save-" + index + "-autosave", save);
|
Core.settings.put("save-" + index() + "-autosave", save);
|
||||||
Core.settings.save();
|
Core.settings.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importFile(FileHandle file) throws IOException{
|
public void importFile(FileHandle from) throws IOException{
|
||||||
try{
|
try{
|
||||||
file.copyTo(SaveIO.fileFor(index));
|
from.copyTo(file);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exportFile(FileHandle file) throws IOException{
|
public void exportFile(FileHandle to) throws IOException{
|
||||||
try{
|
try{
|
||||||
SaveIO.fileFor(index).copyTo(file);
|
file.copyTo(to);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(){
|
public void delete(){
|
||||||
SaveIO.fileFor(index).delete();
|
file.delete();
|
||||||
saves.removeValue(this, true);
|
saves.removeValue(this, true);
|
||||||
saveMap.remove(index);
|
|
||||||
if(this == current){
|
if(this == current){
|
||||||
current = null;
|
current = null;
|
||||||
}
|
}
|
||||||
@ -330,8 +319,6 @@ public class Saves{
|
|||||||
if(Core.assets.isLoaded(loadPreviewFile().path())){
|
if(Core.assets.isLoaded(loadPreviewFile().path())){
|
||||||
Core.assets.unload(loadPreviewFile().path());
|
Core.assets.unload(loadPreviewFile().path());
|
||||||
}
|
}
|
||||||
|
|
||||||
saveSlots();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import io.anuke.mindustry.input.*;
|
|||||||
import io.anuke.mindustry.input.PlaceUtils.*;
|
import io.anuke.mindustry.input.PlaceUtils.*;
|
||||||
import io.anuke.mindustry.type.*;
|
import io.anuke.mindustry.type.*;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
|
import io.anuke.mindustry.world.blocks.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.zip.*;
|
import java.util.zip.*;
|
||||||
@ -205,7 +206,7 @@ public class Schematics implements Loadable{
|
|||||||
|
|
||||||
/** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */
|
/** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */
|
||||||
public Array<BuildRequest> toRequests(Schematic schem, int x, int y){
|
public Array<BuildRequest> toRequests(Schematic schem, int x, int y){
|
||||||
return schem.tiles.map(t -> new BuildRequest(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block).original(t.x, t.y, schem.width, schem.height).configure(t.config)).removeAll(s -> !s.block.isVisible());
|
return schem.tiles.map(t -> new BuildRequest(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block).original(t.x, t.y, schem.width, schem.height).configure(t.config)).removeAll(s -> !s.block.isVisible() || !s.block.unlocked());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a schematic to the list, also copying it into the files.*/
|
/** Adds a schematic to the list, also copying it into the files.*/
|
||||||
@ -251,7 +252,7 @@ public class Schematics implements Loadable{
|
|||||||
for(int cy = y; cy <= y2; cy++){
|
for(int cy = y; cy <= y2; cy++){
|
||||||
Tile linked = world.ltile(cx, cy);
|
Tile linked = world.ltile(cx, cy);
|
||||||
|
|
||||||
if(linked != null && linked.entity != null && linked.entity.block.isVisible()){
|
if(linked != null && linked.entity != null && linked.entity.block.isVisible() && !(linked.block() instanceof BuildBlock)){
|
||||||
int top = linked.block().size/2;
|
int top = linked.block().size/2;
|
||||||
int bot = linked.block().size % 2 == 1 ? -linked.block().size/2 : -(linked.block().size - 1)/2;
|
int bot = linked.block().size % 2 == 1 ? -linked.block().size/2 : -(linked.block().size - 1)/2;
|
||||||
minx = Math.min(linked.x + bot, minx);
|
minx = Math.min(linked.x + bot, minx);
|
||||||
@ -279,7 +280,7 @@ public class Schematics implements Loadable{
|
|||||||
for(int cy = oy; cy <= oy2; cy++){
|
for(int cy = oy; cy <= oy2; cy++){
|
||||||
Tile tile = world.ltile(cx, cy);
|
Tile tile = world.ltile(cx, cy);
|
||||||
|
|
||||||
if(tile != null && tile.entity != null && !counted.contains(tile.pos())){
|
if(tile != null && tile.entity != null && !counted.contains(tile.pos()) && !(tile.block() instanceof BuildBlock) && tile.entity.block.isVisible()){
|
||||||
int config = tile.entity.config();
|
int config = tile.entity.config();
|
||||||
if(tile.block().posConfig){
|
if(tile.block().posConfig){
|
||||||
config = Pos.get(Pos.x(config) + offsetX, Pos.y(config) + offsetY);
|
config = Pos.get(Pos.x(config) + offsetX, Pos.y(config) + offsetY);
|
||||||
|
@ -182,7 +182,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
mode = none;
|
mode = none;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mode != none || isPlacing()){
|
if(mode == placing || isPlacing()){
|
||||||
selectRequests.clear();
|
selectRequests.clear();
|
||||||
lastSchematic = null;
|
lastSchematic = null;
|
||||||
}
|
}
|
||||||
@ -379,7 +379,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
deleting = true;
|
deleting = true;
|
||||||
}else if(selected != null){
|
}else if(selected != null){
|
||||||
//only begin shooting if there's no cursor event
|
//only begin shooting if there's no cursor event
|
||||||
if(!tileTapped(selected) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && player.buildQueue().size == 0 && !droppingItem &&
|
if(!tileTapped(selected) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.buildQueue().size == 0 || !player.isBuilding) && !droppingItem &&
|
||||||
!tryBeginMine(selected) && player.getMineTile() == null && !ui.chatfrag.chatOpen()){
|
!tryBeginMine(selected) && player.getMineTile() == null && !ui.chatfrag.chatOpen()){
|
||||||
player.isShooting = true;
|
player.isShooting = true;
|
||||||
}
|
}
|
||||||
|
@ -34,37 +34,23 @@ public class SaveIO{
|
|||||||
return versions.get(version);
|
return versions.get(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveToSlot(int slot){
|
public static void save(FileHandle file){
|
||||||
FileHandle file = fileFor(slot);
|
|
||||||
boolean exists = file.exists();
|
boolean exists = file.exists();
|
||||||
if(exists) file.moveTo(backupFileFor(file));
|
if(exists) file.moveTo(backupFileFor(file));
|
||||||
try{
|
try{
|
||||||
write(fileFor(slot));
|
write(file);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
if(exists) backupFileFor(file).moveTo(file);
|
if(exists) backupFileFor(file).moveTo(file);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadFromSlot(int slot) throws SaveException{
|
public static DataInputStream getStream(FileHandle file){
|
||||||
load(fileFor(slot));
|
return new DataInputStream(new InflaterInputStream(file.read(bufferSize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DataInputStream getSlotStream(int slot){
|
public static DataInputStream getBackupStream(FileHandle file){
|
||||||
return new DataInputStream(new InflaterInputStream(fileFor(slot).read(bufferSize)));
|
return new DataInputStream(new InflaterInputStream(backupFileFor(file).read(bufferSize)));
|
||||||
}
|
|
||||||
|
|
||||||
public static DataInputStream getBackupSlotStream(int slot){
|
|
||||||
return new DataInputStream(new InflaterInputStream(backupFileFor(fileFor(slot)).read(bufferSize)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSaveValid(int slot){
|
|
||||||
try{
|
|
||||||
getMeta(slot);
|
|
||||||
return true;
|
|
||||||
}catch(Exception e){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSaveValid(FileHandle file){
|
public static boolean isSaveValid(FileHandle file){
|
||||||
@ -85,11 +71,11 @@ public class SaveIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SaveMeta getMeta(int slot){
|
public static SaveMeta getMeta(FileHandle file){
|
||||||
try{
|
try{
|
||||||
return getMeta(getSlotStream(slot));
|
return getMeta(getStream(file));
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
return getMeta(getBackupSlotStream(slot));
|
return getMeta(getBackupStream(file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +153,7 @@ public class SaveIO{
|
|||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
throw new SaveException(e);
|
throw new SaveException(e);
|
||||||
}finally{
|
}finally{
|
||||||
|
world.setGenerating(false);
|
||||||
content.setTemporaryMapper(null);
|
content.setTemporaryMapper(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package io.anuke.mindustry.io;
|
|||||||
import io.anuke.arc.collection.*;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.util.*;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.arc.util.io.*;
|
import io.anuke.arc.util.io.*;
|
||||||
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.core.*;
|
import io.anuke.mindustry.core.*;
|
||||||
import io.anuke.mindustry.ctype.*;
|
import io.anuke.mindustry.ctype.*;
|
||||||
import io.anuke.mindustry.entities.*;
|
import io.anuke.mindustry.entities.*;
|
||||||
@ -166,6 +167,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
short floorid = stream.readShort();
|
short floorid = stream.readShort();
|
||||||
short oreid = stream.readShort();
|
short oreid = stream.readShort();
|
||||||
int consecutives = stream.readUnsignedByte();
|
int consecutives = stream.readUnsignedByte();
|
||||||
|
if(content.block(floorid) == Blocks.air) floorid = Blocks.stone.id;
|
||||||
|
|
||||||
context.create(x, y, floorid, oreid, (short)0);
|
context.create(x, y, floorid, oreid, (short)0);
|
||||||
|
|
||||||
@ -182,6 +184,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
int x = i % width, y = i / width;
|
int x = i % width, y = i / width;
|
||||||
Block block = content.block(stream.readShort());
|
Block block = content.block(stream.readShort());
|
||||||
Tile tile = context.tile(x, y);
|
Tile tile = context.tile(x, y);
|
||||||
|
if(block == null) block = Blocks.air;
|
||||||
tile.setBlock(block);
|
tile.setBlock(block);
|
||||||
|
|
||||||
if(tile.entity != null){
|
if(tile.entity != null){
|
||||||
|
@ -4,6 +4,7 @@ import io.anuke.arc.collection.*;
|
|||||||
import io.anuke.arc.function.*;
|
import io.anuke.arc.function.*;
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.arc.math.geom.*;
|
import io.anuke.arc.math.geom.*;
|
||||||
|
import io.anuke.arc.util.ArcAnnotate.*;
|
||||||
import io.anuke.mindustry.content.*;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.entities.traits.*;
|
import io.anuke.mindustry.entities.traits.*;
|
||||||
import io.anuke.mindustry.entities.type.*;
|
import io.anuke.mindustry.entities.type.*;
|
||||||
@ -152,7 +153,7 @@ public class Tile implements Position, TargetTrait{
|
|||||||
return team;
|
return team;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlock(Block type, Team team, int rotation){
|
public void setBlock(@NonNull Block type, Team team, int rotation){
|
||||||
preChanged();
|
preChanged();
|
||||||
this.block = type;
|
this.block = type;
|
||||||
this.team = (byte)team.ordinal();
|
this.team = (byte)team.ordinal();
|
||||||
@ -160,11 +161,12 @@ public class Tile implements Position, TargetTrait{
|
|||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlock(Block type, Team team){
|
public void setBlock(@NonNull Block type, Team team){
|
||||||
setBlock(type, team, 0);
|
setBlock(type, team, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlock(Block type){
|
public void setBlock(@NonNull Block type){
|
||||||
|
if(type == null) throw new IllegalArgumentException("Block cannot be null.");
|
||||||
preChanged();
|
preChanged();
|
||||||
this.block = type;
|
this.block = type;
|
||||||
this.rotation = 0;
|
this.rotation = 0;
|
||||||
@ -172,13 +174,13 @@ public class Tile implements Position, TargetTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**This resets the overlay!*/
|
/**This resets the overlay!*/
|
||||||
public void setFloor(Floor type){
|
public void setFloor(@NonNull Floor type){
|
||||||
this.floor = type;
|
this.floor = type;
|
||||||
this.overlay = (Floor)Blocks.air;
|
this.overlay = (Floor)Blocks.air;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the floor, preserving overlay.*/
|
/** Sets the floor, preserving overlay.*/
|
||||||
public void setFloorUnder(Floor floor){
|
public void setFloorUnder(@NonNull Floor floor){
|
||||||
Block overlay = this.overlay;
|
Block overlay = this.overlay;
|
||||||
setFloor(floor);
|
setFloor(floor);
|
||||||
setOverlay(overlay);
|
setOverlay(overlay);
|
||||||
|
@ -670,28 +670,25 @@ public class ServerControl implements ApplicationListener{
|
|||||||
if(state.is(State.playing)){
|
if(state.is(State.playing)){
|
||||||
err("Already hosting. Type 'stop' to stop hosting first.");
|
err("Already hosting. Type 'stop' to stop hosting first.");
|
||||||
return;
|
return;
|
||||||
}else if(!Strings.canParseInt(arg[0])){
|
|
||||||
err("Invalid save slot '{0}'.", arg[0]);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int slot = Strings.parseInt(arg[0]);
|
FileHandle file = saveDirectory.child(arg[0] + "." + saveExtension);
|
||||||
|
|
||||||
if(!SaveIO.isSaveValid(slot)){
|
if(!SaveIO.isSaveValid(file)){
|
||||||
err("No (valid) save data found for slot.");
|
err("No (valid) save data found for slot.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.app.post(() -> {
|
Core.app.post(() -> {
|
||||||
try{
|
try{
|
||||||
SaveIO.loadFromSlot(slot);
|
SaveIO.load(file);
|
||||||
state.rules.zone = null;
|
state.rules.zone = null;
|
||||||
|
info("Save loaded.");
|
||||||
|
host();
|
||||||
|
state.set(State.playing);
|
||||||
}catch(Throwable t){
|
}catch(Throwable t){
|
||||||
err("Failed to load save. Outdated or corrupt file.");
|
err("Failed to load save. Outdated or corrupt file.");
|
||||||
}
|
}
|
||||||
info("Save loaded.");
|
|
||||||
host();
|
|
||||||
state.set(State.playing);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -699,18 +696,25 @@ public class ServerControl implements ApplicationListener{
|
|||||||
if(!state.is(State.playing)){
|
if(!state.is(State.playing)){
|
||||||
err("Not hosting. Host a game first.");
|
err("Not hosting. Host a game first.");
|
||||||
return;
|
return;
|
||||||
}else if(!Strings.canParseInt(arg[0])){
|
|
||||||
err("Invalid save slot '{0}'.", arg[0]);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileHandle file = saveDirectory.child(arg[0] + "." + saveExtension);
|
||||||
|
|
||||||
Core.app.post(() -> {
|
Core.app.post(() -> {
|
||||||
int slot = Strings.parseInt(arg[0]);
|
SaveIO.save(file);
|
||||||
SaveIO.saveToSlot(slot);
|
info("Saved to {0}.", file);
|
||||||
info("Saved to slot {0}.", slot);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
handler.register("saves", "List all saves in the save directory.", arg -> {
|
||||||
|
info("Save files: ");
|
||||||
|
for(FileHandle file : saveDirectory.list()){
|
||||||
|
if(file.extension().equals(saveExtension)){
|
||||||
|
info("| &ly{0}", file.nameWithoutExtension());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
handler.register("gameover", "Force a game over.", arg -> {
|
handler.register("gameover", "Force a game over.", arg -> {
|
||||||
if(state.is(State.menu)){
|
if(state.is(State.menu)){
|
||||||
info("Not playing a map.");
|
info("Not playing a map.");
|
||||||
|
@ -198,7 +198,7 @@ public class ApplicationTests{
|
|||||||
void save(){
|
void save(){
|
||||||
world.loadMap(testMap);
|
world.loadMap(testMap);
|
||||||
assertTrue(state.teams.get(defaultTeam).cores.size > 0);
|
assertTrue(state.teams.get(defaultTeam).cores.size > 0);
|
||||||
SaveIO.saveToSlot(0);
|
SaveIO.save(saveDirectory.child("0.msav"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -206,9 +206,9 @@ public class ApplicationTests{
|
|||||||
world.loadMap(testMap);
|
world.loadMap(testMap);
|
||||||
Map map = world.getMap();
|
Map map = world.getMap();
|
||||||
|
|
||||||
SaveIO.saveToSlot(0);
|
SaveIO.save(saveDirectory.child("0.msav"));
|
||||||
resetWorld();
|
resetWorld();
|
||||||
SaveIO.loadFromSlot(0);
|
SaveIO.load(saveDirectory.child("0.msav"));
|
||||||
|
|
||||||
assertEquals(world.width(), map.width);
|
assertEquals(world.width(), map.width);
|
||||||
assertEquals(world.height(), map.height);
|
assertEquals(world.height(), map.height);
|
||||||
|
Reference in New Issue
Block a user