X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;ds=sidebyside;f=core%2Fsrc%2Fru%2Fdeadsoftware%2Fcavedroid%2Fgame%2FGameSaver.java;h=cb52b3c76b126812e355c43d9ce076c7d5749140;hb=fd73b6dd24b9fe55c0bc8f52f8aa1104a5fe3cb0;hp=49822863f876b074fe28f25e10aab9a376951aab;hpb=562b0e19a771974bb596db6815dce1a01a761ce5;p=cavedroid.git diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java index 4982286..cb52b3c 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java @@ -2,113 +2,247 @@ package ru.deadsoftware.cavedroid.game; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; -import org.jetbrains.annotations.NotNull; -import ru.deadsoftware.cavedroid.CaveGame; +import ru.deadsoftware.cavedroid.MainConfig; +import ru.deadsoftware.cavedroid.game.mobs.MobsController; +import ru.deadsoftware.cavedroid.game.model.block.Block; +import ru.deadsoftware.cavedroid.game.objects.DropController; +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 int VERSION = 0; + private static final String TAG = "GameSaver"; + + public static class Data { + @CheckForNull + private MobsController mMobsController; + @CheckForNull + private DropController mDropController; + @CheckForNull + private Block[][] mForeMap, mBackMap; + + public Data(MobsController mobsController, DropController dropController, Block[][] foreMap, Block[][] backMap) { + mMobsController = mobsController; + mDropController = dropController; + mForeMap = foreMap; + mBackMap = backMap; + } + + public MobsController retrieveMobsController() { + assert mMobsController != null; + MobsController mobsController = mMobsController; + mMobsController = null; + return mobsController; + } + + public DropController retrieveDropController() { + assert mDropController != null; + DropController dropController = mDropController; + mDropController = null; + return dropController; + } + + public Block[][] retrieveForeMap() { + assert mForeMap != null; + Block[][] foreMap = mForeMap; + mForeMap = null; + return foreMap; + } + + public Block[][] retrieveBackMap() { + assert mBackMap != null; + Block[][] backMap = mBackMap; + mBackMap = null; + return backMap; + } + + public boolean isEmpty() { + return mMobsController == null && mDropController == null && mForeMap == null && mBackMap == null; + } + } + + private static final int SAVE_VERSION = 1; - @NotNull private static byte[] intToBytes(int i) { return ByteBuffer.allocate(4).putInt(i).array(); } - private static void saveMap(@NotNull FileHandle file, @NotNull int[][] map) throws IOException { - int rl, bl; + 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(VERSION)); + + out.write(SAVE_VERSION); out.write(intToBytes(width)); out.write(intToBytes(height)); + for (int y = 0; y < height; y++) { - bl = map[0][y]; - rl = 0; - for (int[] ints : map) { - if (ints[y] != bl) { - out.write(intToBytes(rl)); - out.write(intToBytes(bl)); - rl = 0; - bl = ints[y]; + block = dict.get(map[0][y].getParams().getKey()); + run = 0; + 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 = dict.get(blocks[y].getParams().getKey()); } - rl++; + run++; } - out.write(intToBytes(rl)); - out.write(intToBytes(bl)); + out.write(run); + out.write(block); } + out.flush(); out.close(); } - @NotNull - private static int[][] loadMap(@NotNull FileHandle file) throws Exception { - int[][] map; - int ver, width, height; - int rl, bl; + 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()); - ver = in.readInt(); - if (VERSION == ver) { + + 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 += rl) { - rl = in.readInt(); - bl = in.readInt(); - for (int i = x; i < x + rl; i++) map[i][y] = bl; + for (int x = 0; x < width; x += run) { + run = in.readUnsignedByte(); + block = in.readUnsignedByte(); + for (int i = x; i < x + run; i++) { + map[i][y] = gameItemsHolder.getBlock(dict[block]); + } } } - in.close(); - } else throw new Exception("version mismatch"); + } else { + throw new Exception("version mismatch"); + } + + in.close(); return map; } - public static GameProc load() { - FileHandle file = Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/game.sav"); - GameProc gameProc = null; + @CheckForNull + public static Data load(MainConfig mainConfig, GameItemsHolder gameItemsHolder) { + String folder = mainConfig.getGameFolder(); + FileHandle file = Gdx.files.absolute(folder + "/saves/game.sav"); + try { ObjectInputStream in = new ObjectInputStream(file.read()); - int ver = in.readInt(); - if (VERSION == ver) gameProc = (GameProc) in.readObject(); - else throw new Exception("version mismatch"); + int version = in.readInt(); + DropController dropController; + MobsController mobsController; + + if (SAVE_VERSION == version) { + dropController = (DropController) in.readObject(); + mobsController = (MobsController) in.readObject(); + } else { + throw new Exception("version mismatch"); + } + in.close(); - gameProc.world = new GameWorld( - loadMap(Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/foremap.sav")), - loadMap(Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/backmap.sav")) - ); - gameProc.physics = new GamePhysics(); - gameProc.input = new GameInput(); + + 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); } catch (Exception e) { - Gdx.app.error("GameSaver", e.getMessage(), e); - Gdx.app.exit(); + Gdx.app.error("GameSaver", e.getMessage()); } - return gameProc; + + return null; } - public static void save(GameProc gp) { - FileHandle file = Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/"); + public static void save(MainConfig mainConfig, + DropController dropController, + MobsController mobsController, + GameWorld gameWorld) { + String folder = mainConfig.getGameFolder(); + FileHandle file = Gdx.files.absolute(folder + "/saves/"); file.mkdirs(); - file = Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/game.sav"); + 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(VERSION); - out.writeObject(gp); + out.writeInt(SAVE_VERSION); + out.writeObject(dropController); + out.writeObject(mobsController); out.close(); - saveMap(Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/foremap.sav"), gp.world.getFullForeMap()); - saveMap(Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/backmap.sav"), gp.world.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(); } } - public static boolean exists() { - return (Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/game.sav").exists() && - Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/foremap.sav").exists() && - Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/backmap.sav").exists()); + public static boolean exists(MainConfig mainConfig) { + String folder = mainConfig.getGameFolder(); + return (Gdx.files.absolute(folder + "/saves/game.sav").exists() && + Gdx.files.absolute(folder + "/saves/foremap.sav").exists() && + Gdx.files.absolute(folder + "/saves/backmap.sav").exists()); } - }