diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index 06fe509cf..8832a3751 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -28,7 +28,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Awareness; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Light; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MindVision; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; -import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Ghost; @@ -74,7 +73,6 @@ import com.watabou.utils.PathFinder; import com.watabou.utils.Random; import com.watabou.utils.SparseArray; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; @@ -231,7 +229,7 @@ public class Dungeon { Badges.reset(); - StartScene.curClass.initHero( hero ); + StartScene.selectedClass.initHero( hero ); } public static boolean isChallenged( int mask ) { @@ -431,10 +429,6 @@ public class Dungeon { return Random.Int(5 - floorThisSet) < asLeftThisSet; } - private static final String GAME_FOLDER = "game%d"; - private static final String GAME_FILE = "game.dat"; - private static final String DEPTH_FILE = "depth%d.dat"; - private static final String VERSION = "version"; private static final String SEED = "seed"; private static final String CHALLENGES = "challenges"; @@ -448,62 +442,7 @@ public class Dungeon { private static final String QUESTS = "quests"; private static final String BADGES = "badges"; - //TODO remove class-based loading - - public static File gameFolder( HeroClass cl ) { - switch (cl) { - case WARRIOR: - return gameFolder(1); - case MAGE: - return gameFolder(2); - case ROGUE: default: - return gameFolder(3); - case HUNTRESS: - return gameFolder(4); - } - } - - - - public static File gameFile( HeroClass cl ) { - switch (cl) { - case WARRIOR: - return gameFile(1); - case MAGE: - return gameFile(2); - case ROGUE: default: - return gameFile(3); - case HUNTRESS: - return gameFile(4); - } - } - - public static File depthFile( HeroClass cl, int depth ) { - switch (cl) { - case WARRIOR: - return depthFile(1, depth); - case MAGE: - return depthFile(2, depth); - case ROGUE: default: - return depthFile(3, depth); - case HUNTRESS: - return depthFile(4, depth); - } - } - - public static File gameFolder( int save ){ - return FileUtils.getDir(Messages.format(GAME_FOLDER, save)); - } - - public static File gameFile( int save ){ - return FileUtils.getFile(gameFolder( save ), GAME_FILE); - } - - public static File depthFile( int save, int depth ) { - return FileUtils.getFile( gameFolder(save), Messages.format(DEPTH_FILE, depth)); - } - - public static void saveGame( HeroClass cl ) throws IOException { + public static void saveGame( int save ) throws IOException { try { Bundle bundle = new Bundle(); @@ -556,29 +495,30 @@ public class Dungeon { Badges.saveLocal( badges ); bundle.put( BADGES, badges ); - FileUtils.bundleToFile( gameFile(cl), bundle); + FileUtils.bundleToFile( GamesInProgress.gameFile(save), bundle); } catch (IOException e) { - GamesInProgress.setUnknown( hero.heroClass ); + GamesInProgress.setUnknown( save ); ShatteredPixelDungeon.reportException(e); } } - public static void saveLevel() throws IOException { + public static void saveLevel( int save ) throws IOException { Bundle bundle = new Bundle(); bundle.put( LEVEL, level ); - FileUtils.bundleToFile(depthFile( hero.heroClass, depth), bundle); + FileUtils.bundleToFile(GamesInProgress.depthFile( save, depth), bundle); } public static void saveAll() throws IOException { if (hero != null && hero.isAlive()) { Actor.fixTime(); - saveGame( hero.heroClass ); - saveLevel(); + saveGame( GamesInProgress.curSlot ); + saveLevel( GamesInProgress.curSlot ); - GamesInProgress.set( hero.heroClass, depth, hero.lvl, challenges != 0 ); + GamesInProgress.set( GamesInProgress.curSlot, depth, challenges, + hero.lvl, hero.heroClass, hero.subClass ); } else if (WndResurrect.instance != null) { @@ -588,13 +528,13 @@ public class Dungeon { } } - public static void loadGame( HeroClass cl ) throws IOException { - loadGame( cl, true ); + public static void loadGame( int save ) throws IOException { + loadGame( save, true ); } - public static void loadGame( HeroClass cl, boolean fullLoad ) throws IOException { + public static void loadGame( int save, boolean fullLoad ) throws IOException { - Bundle bundle = FileUtils.bundleFromFile( gameFile( cl ) ); + Bundle bundle = FileUtils.bundleFromFile( GamesInProgress.gameFile( save ) ); version = bundle.getInt( VERSION ); @@ -681,12 +621,12 @@ public class Dungeon { } } - public static Level loadLevel( HeroClass cl ) throws IOException { + public static Level loadLevel( int save ) throws IOException { Dungeon.level = null; Actor.clear(); - Bundle bundle = FileUtils.bundleFromFile( depthFile( cl, depth)) ; + Bundle bundle = FileUtils.bundleFromFile( GamesInProgress.depthFile( save, depth)) ; Level level = (Level)bundle.get( LEVEL ); @@ -697,21 +637,21 @@ public class Dungeon { } } - public static void deleteGame( HeroClass cl, boolean deleteLevels ) { + public static void deleteGame( int save, boolean deleteLevels ) { - FileUtils.deleteFile(gameFile(cl)); + FileUtils.deleteFile(GamesInProgress.gameFile(save)); if (deleteLevels) { - FileUtils.deleteDir(gameFolder(cl)); + FileUtils.deleteDir(GamesInProgress.gameFolder(save)); } - GamesInProgress.delete( cl ); + GamesInProgress.delete( save ); } public static void preview( GamesInProgress.Info info, Bundle bundle ) { info.depth = bundle.getInt( DEPTH ); info.version = bundle.getInt( VERSION ); - info.challenges = (bundle.getInt( CHALLENGES ) != 0); + info.challenges = bundle.getInt( CHALLENGES ); Hero.preview( info, bundle.getBundle( HERO ) ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/GamesInProgress.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/GamesInProgress.java index d1ca60f90..49eb00ffb 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/GamesInProgress.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/GamesInProgress.java @@ -22,29 +22,58 @@ package com.shatteredpixel.shatteredpixeldungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.watabou.utils.Bundle; import com.watabou.utils.FileUtils; +import java.io.File; import java.io.IOException; import java.util.HashMap; public class GamesInProgress { - - private static HashMap state = new HashMap(); - //TODO this should check if a game directly exists - public static Info check( HeroClass cl ) { + //null means we have loaded info and it is empty, no entry means unknown. + private static HashMap slotStates = new HashMap<>(); + public static int curSlot; + + private static final String GAME_FOLDER = "game%d"; + private static final String GAME_FILE = "game.dat"; + private static final String DEPTH_FILE = "depth%d.dat"; + + public static boolean gameExists( int slot ){ + return FileUtils.dirExists(Messages.format(GAME_FOLDER, slot)); + } + + public static File gameFolder( int slot ){ + return FileUtils.getDir(Messages.format(GAME_FOLDER, slot)); + } + + public static File gameFile( int slot ){ + return FileUtils.getFile(gameFolder( slot ), GAME_FILE); + } + + public static File depthFile( int slot, int depth ) { + return FileUtils.getFile( gameFolder(slot), Messages.format(DEPTH_FILE, depth)); + } + + public static Info check( int slot ) { - if (state.containsKey( cl )) { + if (slotStates.containsKey( slot )) { - return state.get( cl ); + return slotStates.get( slot ); + + } else if (!gameExists( slot )) { + + slotStates.put(slot, null); + return null; } else { Info info; try { - Bundle bundle = FileUtils.bundleFromFile(Dungeon.gameFile(cl)); + Bundle bundle = FileUtils.bundleFromFile(gameFile(slot)); info = new Info(); Dungeon.preview(info, bundle); @@ -58,32 +87,40 @@ public class GamesInProgress { info = null; } - state.put( cl, info ); + slotStates.put( slot, info ); return info; } } - public static void set( HeroClass cl, int depth, int level, boolean challenges ) { + public static void set( int slot, int depth, int challenges, + int level, HeroClass heroClass, HeroSubClass subClass) { Info info = new Info(); info.depth = depth; - info.level = level; info.challenges = challenges; - state.put( cl, info ); + + info.level = level; + info.heroClass = heroClass; + info.subClass = subClass; + + slotStates.put( slot, info ); } - public static void setUnknown( HeroClass cl ) { - state.remove( cl ); + public static void setUnknown( int slot ) { + slotStates.remove( slot ); } - public static void delete( HeroClass cl ) { - state.put( cl, null ); + public static void delete( int slot ) { + slotStates.put( slot, null ); } public static class Info { public int depth; - public int level; public int version; - public boolean challenges; + public int challenges; + + public int level; + public HeroClass heroClass; + public HeroSubClass subClass; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java index 71e3b4d84..b640ed863 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java @@ -260,6 +260,8 @@ public class Hero extends Char { public static void preview( GamesInProgress.Info info, Bundle bundle ) { info.level = bundle.getInt( LEVEL ); + info.heroClass = HeroClass.restoreInBundle( bundle ); + info.subClass = HeroSubClass.restoreInBundle( bundle ); } public String className() { @@ -851,7 +853,7 @@ public class Hero extends Char { ready(); } else { Dungeon.win( Amulet.class ); - Dungeon.deleteGame( Dungeon.hero.heroClass, true ); + Dungeon.deleteGame( GamesInProgress.curSlot, true ); Game.switchScene( SurfaceScene.class ); } @@ -1342,7 +1344,7 @@ public class Hero extends Char { } else { - Dungeon.deleteGame( Dungeon.hero.heroClass, false ); + Dungeon.deleteGame( GamesInProgress.curSlot, false ); GameScene.show( new WndResurrect( ankh, cause ) ); } @@ -1403,7 +1405,7 @@ public class Hero extends Char { ((Hero.Doom)cause).onDeath(); } - Dungeon.deleteGame( Dungeon.hero.heroClass, true ); + Dungeon.deleteGame( GamesInProgress.curSlot, true ); } //effectively cache this buff to prevent having to call buff(Berserk.class) a bunch. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/secret/SecretRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/secret/SecretRoom.java index f6f26bc14..c48f7e9c1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/secret/SecretRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/secret/SecretRoom.java @@ -52,7 +52,7 @@ public abstract class SecretRoom extends SpecialRoom { float[] regionChances = baseRegionSecrets.clone(); - if (StartScene.curClass == HeroClass.ROGUE){ + if (StartScene.selectedClass == HeroClass.ROGUE){ for (int i = 0; i < regionChances.length; i++){ regionChances[i] += 0.6f; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/AmuletScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/AmuletScene.java index e43bea537..f57457f9b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/AmuletScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/AmuletScene.java @@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.scenes; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.GamesInProgress; import com.shatteredpixel.shatteredpixeldungeon.effects.Flare; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.items.Amulet; @@ -63,7 +64,7 @@ public class AmuletScene extends PixelScene { @Override protected void onClick() { Dungeon.win( Amulet.class ); - Dungeon.deleteGame( Dungeon.hero.heroClass, true ); + Dungeon.deleteGame( GamesInProgress.curSlot, true ); Game.switchScene( RankingsScene.class ); } }; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java index c5afb19b2..2861727b6 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java @@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.scenes; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.GamesInProgress; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; @@ -213,7 +214,7 @@ public class InterlevelScene extends PixelScene { level = Dungeon.newLevel(); } else { Dungeon.depth++; - level = Dungeon.loadLevel( Dungeon.hero.heroClass ); + level = Dungeon.loadLevel( GamesInProgress.curSlot ); } Dungeon.switchLevel( level, level.entrance ); } @@ -230,7 +231,7 @@ public class InterlevelScene extends PixelScene { level = Dungeon.newLevel(); } else { Dungeon.depth++; - level = Dungeon.loadLevel( Dungeon.hero.heroClass ); + level = Dungeon.loadLevel( GamesInProgress.curSlot ); } Dungeon.switchLevel( level, level.fallCell( fallIntoPit )); } @@ -242,7 +243,7 @@ public class InterlevelScene extends PixelScene { Dungeon.saveAll(); Dungeon.depth--; - Level level = Dungeon.loadLevel( Dungeon.hero.heroClass ); + Level level = Dungeon.loadLevel( GamesInProgress.curSlot ); Dungeon.switchLevel( level, level.exit ); } @@ -253,7 +254,7 @@ public class InterlevelScene extends PixelScene { Dungeon.saveAll(); Dungeon.depth = returnDepth; - Level level = Dungeon.loadLevel( Dungeon.hero.heroClass ); + Level level = Dungeon.loadLevel( GamesInProgress.curSlot ); Dungeon.switchLevel( level, returnPos ); } @@ -264,12 +265,12 @@ public class InterlevelScene extends PixelScene { GameLog.wipe(); - Dungeon.loadGame( StartScene.curClass ); + Dungeon.loadGame( GamesInProgress.curSlot ); if (Dungeon.depth == -1) { Dungeon.depth = Statistics.deepestFloor; - Dungeon.switchLevel( Dungeon.loadLevel( StartScene.curClass ), -1 ); + Dungeon.switchLevel( Dungeon.loadLevel( GamesInProgress.curSlot ), -1 ); } else { - Level level = Dungeon.loadLevel( StartScene.curClass ); + Level level = Dungeon.loadLevel( GamesInProgress.curSlot ); Dungeon.switchLevel( level, Dungeon.hero.pos ); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/StartScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/StartScene.java index abbd701bf..9f3a5667d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/StartScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/StartScene.java @@ -77,7 +77,7 @@ public class StartScene extends PixelScene { private boolean huntressUnlocked; private Group unlock; - public static HeroClass curClass; + public static HeroClass selectedClass; @Override public void create() { @@ -121,7 +121,7 @@ public class StartScene extends PixelScene { btnNewGame = new GameButton( Messages.get(this, "new") ) { @Override protected void onClick() { - if (GamesInProgress.check( curClass ) != null) { + if (GamesInProgress.check( GamesInProgress.curSlot ) != null) { StartScene.this.add( new WndOptions( Messages.get(StartScene.class, "really"), Messages.get(StartScene.class, "warning"), @@ -217,7 +217,7 @@ public class StartScene extends PixelScene { btnExit.setPos( Camera.main.width - btnExit.width(), 0 ); add( btnExit ); - curClass = null; + GamesInProgress.curSlot = 0; ActionIndicator.action = null; updateClass( HeroClass.values()[ShatteredPixelDungeon.lastClass()] ); @@ -245,25 +245,29 @@ public class StartScene extends PixelScene { private void updateClass( HeroClass cl ) { - if (curClass == cl) { + int slot = cl.ordinal()+1; + + if (GamesInProgress.curSlot == slot) { add( new WndClass( cl ) ); return; + } else { + GamesInProgress.curSlot = slot; } - if (curClass != null) { - shields.get( curClass ).highlight( false ); + if (selectedClass != null) { + shields.get( selectedClass ).highlight( false ); } - shields.get( curClass = cl ).highlight( true ); + shields.get( selectedClass = cl ).highlight( true ); if (cl != HeroClass.HUNTRESS || huntressUnlocked) { unlock.visible = false; - GamesInProgress.Info info = GamesInProgress.check( curClass ); + GamesInProgress.Info info = GamesInProgress.check( GamesInProgress.curSlot ); if (info != null) { btnLoad.visible = true; - btnLoad.secondary( Messages.format( Messages.get(this, "depth_level"), info.depth, info.level ), info.challenges ); + btnLoad.secondary( Messages.format( Messages.get(this, "depth_level"), info.depth, info.level ), info.challenges != 0 ); btnNewGame.visible = true; btnNewGame.secondary( Messages.get(this, "erase"), false ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/WelcomeScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/WelcomeScene.java index d41a52017..7d75042c2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/WelcomeScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/WelcomeScene.java @@ -23,7 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.scenes; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Badges; -import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.GamesInProgress; import com.shatteredpixel.shatteredpixeldungeon.Rankings; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.effects.BannerSprites; @@ -171,7 +171,7 @@ public class WelcomeScene extends PixelScene { if (FileUtils.fileExists(name + ".dat")){ try { Bundle gamedata = FileUtils.bundleFromFile(name + ".dat"); - FileUtils.bundleToFile(Dungeon.gameFile(i), gamedata); + FileUtils.bundleToFile(GamesInProgress.gameFile(i), gamedata); FileUtils.deleteFile(name + ".dat"); //rogue's safe files have a different name @@ -180,7 +180,7 @@ public class WelcomeScene extends PixelScene { int depth = 1; while (FileUtils.fileExists(name + depth + ".dat")) { gamedata = FileUtils.bundleFromFile(name + depth + ".dat"); - FileUtils.bundleToFile(Dungeon.depthFile(i, depth), gamedata); + FileUtils.bundleToFile(GamesInProgress.depthFile(i, depth), gamedata); FileUtils.deleteFile(name + depth + ".dat"); depth++; }