savegame.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /* =============================================================================
  2. * PROGRAM: ularn
  3. * FILENAME: savegame.c
  4. *
  5. * DESCRIPTION:
  6. * This module contains functions for saving and loading the game.
  7. *
  8. * =============================================================================
  9. * EXPORTED VARIABLES
  10. *
  11. * None
  12. *
  13. * =============================================================================
  14. * EXPORTED FUNCTIONS
  15. *
  16. * savegame : Function to save the game
  17. * restoregame : Function to load the game
  18. *
  19. * =============================================================================
  20. */
  21. #include <fcntl.h>
  22. #include <stdio.h>
  23. #include "dungeon.h"
  24. #include "header.h"
  25. #include "itm.h"
  26. #include "monster.h"
  27. #include "player.h"
  28. #include "savegame.h"
  29. #include "saveutils.h"
  30. #include "scores.h"
  31. #include "spell.h"
  32. #include "sphere.h"
  33. #include "store.h"
  34. #include "ularn_game.h"
  35. #include "ularn_win.h"
  36. /* =============================================================================
  37. * Local functions
  38. */
  39. /* =============================================================================
  40. * FUNCTION: greedy
  41. *
  42. * DESCRIPTION:
  43. * Subroutine to not allow greedy cheaters.
  44. * Displays a cheater message and quits the game.
  45. *
  46. * PARAMETERS:
  47. *
  48. * None
  49. *
  50. * RETURN VALUE:
  51. *
  52. * None.
  53. */
  54. static void greedy(void) {
  55. if (wizard)
  56. return;
  57. Print("\n\nI am so sorry but your character is a little TOO good! Since "
  58. "this\n");
  59. Print("cannot normally happen from an honest game, I must assume that you "
  60. "cheated.\n");
  61. Print(
  62. "Since you are GREEDY as well as a CHEATER, I cannot allow this game\n");
  63. Print("to continue.\n");
  64. nap(5000);
  65. cheat = 1;
  66. c[GOLD] = c[BANKACCOUNT] = 0;
  67. died(DIED_GREEDY_CHEATER, 0);
  68. return;
  69. }
  70. /* =============================================================================
  71. * FUNCTION: fsorry
  72. *
  73. * DESCRIPTION:
  74. * Subroutine to not allow altered save files and terminate the attempted
  75. * restart.
  76. * Sets the cheat flag to disallow scoring for this game.
  77. *
  78. * PARAMETERS:
  79. *
  80. * None.
  81. *
  82. * RETURN VALUE:
  83. *
  84. * None.
  85. */
  86. static void fsorry(void) {
  87. if (cheat)
  88. return;
  89. Print("\nSorry but your savefile has been altered.\n");
  90. Print("However, since I am a good sport, I will let you play.\n");
  91. Print("Be advised, though, that you won't be placed on the scoreboard.");
  92. cheat = 1;
  93. nap(4000);
  94. }
  95. /* =============================================================================
  96. * FUNCTION: fcheat
  97. *
  98. * DESCRIPTION:
  99. * Subroutine to not allow game if save file can't be deleted.
  100. * Displays a message and quits the game.
  101. *
  102. * PARAMETERS:
  103. *
  104. * None
  105. *
  106. * RETURN VALUE:
  107. *
  108. * None.
  109. */
  110. static void fcheat(void) {
  111. if (wizard)
  112. return;
  113. if (cheat)
  114. return;
  115. Print("\nSorry but your savefile can't be deleted. This can only mean\n");
  116. Print("that you tried to CHEAT by protecting the directory the savefile\n");
  117. Print("is in. Since this is unfair to the rest of the VLarn community, I\n");
  118. Print("cannot let you play this game.\n");
  119. nap(5000);
  120. c[GOLD] = c[BANKACCOUNT] = 0;
  121. died(DIED_PROTECTED_SAVE_FILE, 0);
  122. return;
  123. }
  124. /* =============================================================================
  125. * Exported functions
  126. */
  127. /* =============================================================================
  128. * FUNCTION: savegame
  129. */
  130. int savegame(char *fname) {
  131. FILE *fp;
  132. nosignal = 1;
  133. /* Save the current level to storage */
  134. savelevel();
  135. /* make sure the interest on bank deposits is up to date */
  136. ointerest();
  137. /*
  138. * try and create the save file
  139. */
  140. fp = fopen(fname, "wb");
  141. if (fp == NULL) {
  142. Printf("Can't open file <%s> to save game\n", fname);
  143. nosignal = 0;
  144. return -1;
  145. }
  146. FileSum = 0;
  147. write_player(fp);
  148. write_levels(fp);
  149. write_store(fp);
  150. write_monster_data(fp);
  151. write_spheres(fp);
  152. /* file sum */
  153. bwrite(fp, (char *)&FileSum, sizeof(FileSum));
  154. fclose(fp);
  155. nosignal = 0;
  156. return 0;
  157. }
  158. /* =============================================================================
  159. * FUNCTION: restoregame
  160. */
  161. void restoregame(char *fname) {
  162. int i;
  163. unsigned int thesum;
  164. unsigned int asum;
  165. int TotalAttr;
  166. FILE *fp;
  167. fp = fopen(fname, "rb");
  168. if (fp == NULL) {
  169. Printf("Can't open file <%s> to restore game\n", fname);
  170. nap(4000);
  171. c[GOLD] = c[BANKACCOUNT] = 0;
  172. died(DIED_MISSING_SAVE_FILE, 0);
  173. return;
  174. }
  175. Printf(" Reading data...");
  176. init_cells();
  177. FileSum = 0;
  178. read_player(fp);
  179. read_levels(fp);
  180. read_store(fp);
  181. read_monster_data(fp);
  182. read_spheres(fp);
  183. /* sum of everything so far */
  184. thesum = FileSum;
  185. bread(fp, (char *)&asum, sizeof(asum));
  186. if (asum != thesum)
  187. fsorry();
  188. fclose(fp);
  189. lastpx = 0;
  190. lastpy = 0;
  191. if (strcmp(fname, ckpfile) == 0) {
  192. fp = fopen(fname, "ab+");
  193. if (fp == NULL)
  194. /*
  195. * Hmmm. We should be able to write to this file, something fishy
  196. * is going on.
  197. */
  198. fcheat();
  199. else
  200. fclose(fp);
  201. } else if (unlink(fname) == -1)
  202. /* can't unlink save file */
  203. fcheat();
  204. /* for the greedy cheater checker */
  205. TotalAttr = 0;
  206. for (i = ABILITY_FIRST; i < ABILITY_LAST; i++) {
  207. TotalAttr += c[i];
  208. if (c[i] > 300)
  209. greedy();
  210. }
  211. if (TotalAttr > 600)
  212. greedy();
  213. if ((c[HPMAX] > 999) || (c[SPELLMAX] > 125))
  214. greedy();
  215. /* XP has been boosted in the save file, so fix character level */
  216. if ((c[LEVEL] == 25) && (c[EXPERIENCE] > skill[24])) {
  217. long tmp_xp = c[EXPERIENCE] - skill[24]; /* amount to go up */
  218. c[EXPERIENCE] = skill[24];
  219. raiseexperience((long)tmp_xp);
  220. }
  221. /* Get the current dungeon level from storage */
  222. getlevel();
  223. }