Skip to content
Browse files

backup savegames in case of computer hardware malfunction

The backups are removed at game over, so permadeath still enforced.
  • Loading branch information...
1 parent f46dafe commit 1f874187dac7f4a1862696cd497de6db5b36262d @Mikolaj Mikolaj committed
Showing with 32 additions and 12 deletions.
  1. +2 −1 src/Action.hs
  2. +5 −2 src/Actions.hs
  3. +1 −1 src/Config.hs
  4. +24 −8 src/Save.hs
View
3 src/Action.hs
@@ -11,6 +11,7 @@ import Display2 hiding (display)
import Message
import State
import Level
+import qualified Save
newtype Action a = Action
{ runAction ::
@@ -53,7 +54,7 @@ handlerToIO :: Session -> State -> Message -> Action () -> IO ()
handlerToIO session state msg h =
runAction h
session
- (shutdown session) -- get out of the game
+ (Save.rmBkp (sconfig state) >> shutdown session) -- get out of the game
(perception_ state) -- cached perception
(\ _ _ x -> return x) -- final continuation returns result
(ioError $ userError "unhandled abort")
View
7 src/Actions.hs
@@ -25,9 +25,9 @@ import Message
import Monster
import Perception
import Random
-import qualified Save as S
import State
import qualified Config
+import qualified Save
displayHistory :: Action ()
displayHistory =
@@ -52,7 +52,7 @@ saveGame =
then do
-- Save the game state
st <- get
- liftIO $ S.saveGame st
+ liftIO $ Save.saveGame st
ln <- gets (lname . slevel)
let total = calculateTotal st
status = H.Camping ln
@@ -400,6 +400,9 @@ lvlchange vdir =
updatePlayerBody (\ p -> p { mloc = nloc })
-- Change the level of the player recorded in cursor.
modify (updateCursor (\ c -> c { creturnLn = nln }))
+ -- Create a backup of the savegame.
+ state <- get
+ liftIO $ Save.saveGame state >> Save.mvBkp (sconfig state)
_ -> -- no stairs
if targeting
then do
View
2 src/Config.hs
@@ -44,7 +44,7 @@ defaultCP :: CP
defaultCP = toCP defCF
-- | Path to the user configuration file.
-file :: IO String
+file :: IO FilePath
file =
do
appData <- getAppUserDataDirectory "LambdaHack"
View
32 src/Save.hs
@@ -9,7 +9,7 @@ import State
import qualified Config
-- | Name of the save game.
-file :: Config.CP -> IO String
+file :: Config.CP -> IO FilePath
file config = Config.getFile config "files" "saveGame"
-- | We save a simple serialized version of the current level and
@@ -18,7 +18,7 @@ saveGame :: State -> IO ()
saveGame state =
do
f <- file (sconfig state)
- encodeCompressedFile f (state,False)
+ encodeCompressedFile f (state, False)
-- | Restore a saved game. Returns either the current level and
-- game state, or a string containing an error message if restoring
@@ -27,10 +27,26 @@ restoreGame :: Config.CP -> IO (Either State String)
restoreGame config =
E.catch (do
f <- file config
- r <- strictDecodeCompressedFile f
- removeFile f
- case r of
- (x,z) -> (z :: Bool) `seq` return $ Left x)
+ (x, z) <- strictDecodeCompressedFile f
+ mvBkp config
+ (z :: Bool) `seq` return $ Left x)
(\ e -> case e :: IOException of
- _ -> return (Right $ "Restore failed: " ++
- (unwords . lines) (show e)))
+ _ -> return (Right $
+ "Restore failed: "
+ ++ (unwords . lines) (show e)))
+
+-- | Move the savegame file to a backup slot.
+mvBkp :: Config.CP -> IO ()
+mvBkp config =
+ do
+ f <- file config
+ renameFile f (f ++ ".bkp")
+
+-- | Remove the backup of the savegame. Should be called before any
+-- non-error exit from the game.
+rmBkp :: Config.CP -> IO ()
+rmBkp config =
+ do
+ f <- file config
+ E.catch (removeFile (f ++ ".bkp"))
+ (\ e -> case e :: IOException of _ -> return ())

0 comments on commit 1f87418

Please sign in to comment.
Something went wrong with that request. Please try again.