Add message and bailout on invalid save.
[open-adventure.git] / saveresume.c
index f4d986a36ddb5312d0cfc0d10ef842213c96ccb7..c9278a413bf448ba6ec096a1fcbc711ac887f1c2 100644 (file)
@@ -60,10 +60,11 @@ int suspend(void)
     /*  Suspend.  Offer to save things in a file, but charging
      *  some points (so can't win by using saved games to retry
      *  battles or to start over after learning zzword).
-     *  If ADVENT_NOSAVE is defined, do nothing instead. */
+     *  If ADVENT_NOSAVE is defined, gripe instead. */
 
-#ifdef ADVENT_NOSAVE
-    return GO_UNKNOWN;
+#if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE
+    rspeak(SAVERESUME_DISABLED)
+    return GO_TOP;
 #endif
     FILE *fp = NULL;
 
@@ -91,10 +92,11 @@ int suspend(void)
 int resume(void)
 {
     /*  Resume.  Read a suspended game back from a file.
-     *  If ADVENT_NOSAVE is defined, do nothing instead. */
+     *  If ADVENT_NOSAVE is defined, gripe instead. */
 
-#ifdef ADVENT_NOSAVE
-    return GO_UNKNOWN;
+#if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE
+    rspeak(SAVERESUME_DISABLED)
+    return GO_TOP;
 #endif
     FILE *fp = NULL;
 
@@ -107,9 +109,9 @@ int resume(void)
 
     while (fp == NULL) {
         char* name = myreadline("\nFile name: ");
-       // Autocomplete can leave the input with an extra trailing space.
-       if (name != NULL && strlen(name) > 0 && name[strlen(name) - 1] == ' ')
-           name[strlen(name) - 1] = '\0';
+        // Autocomplete can leave the input with an extra trailing space.
+        if (name != NULL && strlen(name) > 0 && name[strlen(name) - 1] == ' ')
+            name[strlen(name) - 1] = '\0';
         if (name == NULL)
             return GO_TOP;
         fp = fopen(name, READ_MODE);
@@ -125,16 +127,20 @@ int restore(FILE* fp)
 {
     /*  Read and restore game state from file, assuming
      *  sane initial state.
-     *  If ADVENT_NOSAVE is defined, do nothing instead. */
+     *  If ADVENT_NOSAVE is defined, gripe instead. */
 #ifdef ADVENT_NOSAVE
-    return GO_UNKNOWN;
+    rspeak(SAVERESUME_DISABLED)
+    return GO_TOP;
 #endif
 
     IGNORE(fread(&save, sizeof(struct save_t), 1, fp));
     fclose(fp);
     if (save.version != VRSION) {
         rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), VRSION / 10, MOD(VRSION, 10));
-    } else if (is_valid(save.game)) {
+    } else if (!is_valid(save.game)) {
+       rspeak(SAVE_TAMPERING);
+       exit(EXIT_SUCCESS);
+    } else {
         game = save.game;
     }
     return GO_TOP;
@@ -143,8 +149,8 @@ int restore(FILE* fp)
 bool is_valid(struct game_t valgame)
 {
     /*  Save files can be roughly grouped into three groups:
-     *  With valid, reaceable state, with valid, but unreachable
-     *  state and with invaild state. We check that state is
+     *  With valid, reacheable state, with valid, but unreachable
+     *  state and with invalid state. We check that state is
      *  valid: no states are outside minimal or maximal value
      */
 
@@ -227,7 +233,7 @@ bool is_valid(struct game_t valgame)
             case VASE:
             case CHAIN:
                 if (valgame.prop[obj] == 2) // There are multiple different states, but it's convenient to clump them together
-                    continue;
+                    continue;  // LCOV_EXCL_LINE
             /* FALLTHRU */
             case BEAR:
                 if (valgame.prop[BEAR] == CONTENTED_BEAR || valgame.prop[BEAR] == BEAR_DEAD)