X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=core%2Fsrc%2Fru%2Fdeadsoftware%2Fcavedroid%2Fgame%2FGameSaver.java;h=39d227844ac1badb1d7898e28490d37019535e70;hb=cb0605053ce3de493b0d1f43cd7ec1e4a9cf0ac5;hp=1ff2bad9783788a68d6ff1858dc9185f2a9a6fbe;hpb=97fa700baa58d95bd4b655366a35bcdac4bcaac9;p=cavedroid.git diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java index 1ff2bad..39d2278 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java @@ -4,25 +4,39 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.model.block.Block; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; +import ru.deadsoftware.cavedroid.game.objects.container.ContainerController; +import ru.deadsoftware.cavedroid.game.world.GameWorld; import javax.annotation.CheckForNull; import java.io.*; import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; public class GameSaver { + private static final String TAG = "GameSaver"; + public static class Data { @CheckForNull private MobsController mMobsController; @CheckForNull private DropController mDropController; @CheckForNull - private int[][] mForeMap, mBackMap; + private ContainerController mContainerController; + @CheckForNull + private Block[][] mForeMap, mBackMap; - public Data(MobsController mobsController, DropController dropController, int[][] foreMap, int[][] backMap) { + public Data(MobsController mobsController, + DropController dropController, + ContainerController containerController, + Block[][] foreMap, + Block[][] backMap) { mMobsController = mobsController; mDropController = dropController; + mContainerController = containerController; mForeMap = foreMap; mBackMap = backMap; } @@ -41,22 +55,33 @@ public class GameSaver { return dropController; } - public int[][] retrieveForeMap() { + public ContainerController retrieveFurnaceController() { + assert mContainerController != null; + ContainerController containerController = mContainerController; + mContainerController = null; + return containerController; + } + + public Block[][] retrieveForeMap() { assert mForeMap != null; - int[][] foreMap = mForeMap; + Block[][] foreMap = mForeMap; mForeMap = null; return foreMap; } - public int[][] retrieveBackMap() { + public Block[][] retrieveBackMap() { assert mBackMap != null; - int[][] backMap = mBackMap; + Block[][] backMap = mBackMap; mBackMap = null; return backMap; } public boolean isEmpty() { - return mMobsController == null && mDropController == null && mForeMap == null && mBackMap == null; + return mMobsController == null && + mDropController == null && + mContainerController == null && + mForeMap == null && + mBackMap == null; } } @@ -66,56 +91,96 @@ public class GameSaver { return ByteBuffer.allocate(4).putInt(i).array(); } - private static void saveMap(FileHandle file, int[][] map) throws IOException { + private static Map buildBlocksDictionary(Block[][] foreMap, Block[][] backMap) { + final HashMap dict = new HashMap<>(); + + int id = 0; + for (int i = 0; i < foreMap.length; i++) { + for (int j = 0; j < foreMap[i].length; j++) { + for (int k = 0; k < 2; k++) { + final Block block = k == 0 ? foreMap[i][j] : backMap[i][j]; + final String key = block.getParams().getKey(); + if (!dict.containsKey(key)) { + dict.put(key, id++); + } + } + } + } + + return dict; + } + + private static void saveDict(FileHandle file, Map dict) { + final String[] arr = new String[dict.size()]; + + for (Map.Entry entry : dict.entrySet()) { + arr[entry.getValue()] = entry.getKey(); + } + + final StringBuilder builder = new StringBuilder(); + for (String key : arr) { + builder.append(key); + builder.append('\n'); + } + + file.writeString(builder.toString(), false); + } + + private static String[] loadDict(FileHandle file) { + return file.readString().split("\n"); + } + + private static void saveMap(FileHandle file, Block[][] map, Map dict) throws IOException { int run, block; int width = map.length; int height = map[0].length; BufferedOutputStream out = new BufferedOutputStream(file.write(false)); - out.write(intToBytes(SAVE_VERSION)); + out.write(SAVE_VERSION); out.write(intToBytes(width)); out.write(intToBytes(height)); for (int y = 0; y < height; y++) { - block = map[0][y]; + block = dict.get(map[0][y].getParams().getKey()); run = 0; - for (int[] ints : map) { - if (ints[y] != block) { - out.write(intToBytes(run)); - out.write(intToBytes(block)); + for (Block[] blocks : map) { + int newValue = dict.get(blocks[y].getParams().getKey()); + if (run >= 0xFF || newValue != block) { + out.write(run); + out.write(block); run = 0; - block = ints[y]; + block = dict.get(blocks[y].getParams().getKey()); } run++; } - out.write(intToBytes(run)); - out.write(intToBytes(block)); + out.write(run); + out.write(block); } out.flush(); out.close(); } - private static int[][] loadMap(FileHandle file) throws Exception { - int[][] map; + private static Block[][] loadMap(GameItemsHolder gameItemsHolder, FileHandle file, String[] dict) throws Exception { + Block[][] map; int version, width, height; int run, block; DataInputStream in = new DataInputStream(file.read()); - version = in.readInt(); + version = in.readByte(); if (SAVE_VERSION == version) { width = in.readInt(); height = in.readInt(); - map = new int[width][height]; + map = new Block[width][height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x += run) { - run = in.readInt(); - block = in.readInt(); + run = in.readUnsignedByte(); + block = in.readUnsignedByte(); for (int i = x; i < x + run; i++) { - map[i][y] = block; + map[i][y] = gameItemsHolder.getBlock(dict[block]); } } } @@ -128,7 +193,7 @@ public class GameSaver { } @CheckForNull - public static Data load(MainConfig mainConfig) { + public static Data load(MainConfig mainConfig, GameItemsHolder gameItemsHolder) { String folder = mainConfig.getGameFolder(); FileHandle file = Gdx.files.absolute(folder + "/saves/game.sav"); @@ -137,24 +202,27 @@ public class GameSaver { int version = in.readInt(); DropController dropController; MobsController mobsController; + ContainerController containerController; if (SAVE_VERSION == version) { dropController = (DropController) in.readObject(); mobsController = (MobsController) in.readObject(); + containerController = (ContainerController) in.readObject(); } else { throw new Exception("version mismatch"); } in.close(); - int[][] foreMap = loadMap(Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/foremap.sav")); - int[][] backMap = loadMap(Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/backmap.sav")); + final String[] dict = loadDict(Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/dict")); + Block[][] foreMap = loadMap(gameItemsHolder, Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/foremap.sav"), dict); + Block[][] backMap = loadMap(gameItemsHolder, Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/backmap.sav"), dict); if (dropController == null || mobsController == null) { throw new Exception("couldn't load"); } - return new Data(mobsController, dropController, foreMap, backMap); + return new Data(mobsController, dropController, containerController, foreMap, backMap); } catch (Exception e) { Gdx.app.error("GameSaver", e.getMessage()); } @@ -165,21 +233,30 @@ public class GameSaver { public static void save(MainConfig mainConfig, DropController dropController, MobsController mobsController, + ContainerController containerController, GameWorld gameWorld) { - String folder = mainConfig.getGameFolder(); FileHandle file = Gdx.files.absolute(folder + "/saves/"); file.mkdirs(); file = Gdx.files.absolute(folder + "/saves/game.sav"); + final Block[][] foreMap, backMap; + foreMap = gameWorld.getFullForeMap(); + backMap = gameWorld.getFullBackMap(); + + final Map dict = buildBlocksDictionary(foreMap, backMap); + try { ObjectOutputStream out = new ObjectOutputStream(file.write(false)); out.writeInt(SAVE_VERSION); out.writeObject(dropController); out.writeObject(mobsController); + out.writeObject(containerController); out.close(); - saveMap(Gdx.files.absolute(folder + "/saves/foremap.sav"), gameWorld.getFullForeMap()); - saveMap(Gdx.files.absolute(folder + "/saves/backmap.sav"), gameWorld.getFullBackMap()); + + saveDict(Gdx.files.absolute(folder + "/saves/dict"), dict); + saveMap(Gdx.files.absolute(folder + "/saves/foremap.sav"), gameWorld.getFullForeMap(), dict); + saveMap(Gdx.files.absolute(folder + "/saves/backmap.sav"), gameWorld.getFullBackMap(), dict); } catch (Exception e) { e.printStackTrace(); }