savegame.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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 <stdio.h>
  22. #include <fcntl.h>
  23. #include "header.h"
  24. #include "savegame.h"
  25. #include "saveutils.h"
  26. #include "ularn_game.h"
  27. #include "ularn_win.h"
  28. #include "monster.h"
  29. #include "player.h"
  30. #include "spell.h"
  31. #include "dungeon.h"
  32. #include "sphere.h"
  33. #include "store.h"
  34. #include "scores.h"
  35. #include "itm.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. {
  56. if (wizard)
  57. return;
  58. Print("\n\nI am so sorry but your character is a little TOO good! Since this\n");
  59. Print("cannot normally happen from an honest game, I must assume that you cheated.\n");
  60. Print("Since you are GREEDY as well as a CHEATER, I cannot allow this game\n");
  61. Print("to continue.\n");
  62. nap(5000);
  63. cheat = 1;
  64. c[GOLD] = c[BANKACCOUNT] = 0;
  65. died(DIED_GREEDY_CHEATER, 0);
  66. return;
  67. }
  68. /* =============================================================================
  69. * FUNCTION: fsorry
  70. *
  71. * DESCRIPTION:
  72. * Subroutine to not allow altered save files and terminate the attempted
  73. * restart.
  74. * Sets the cheat flag to disallow scoring for this game.
  75. *
  76. * PARAMETERS:
  77. *
  78. * None.
  79. *
  80. * RETURN VALUE:
  81. *
  82. * None.
  83. */
  84. static void fsorry(void)
  85. {
  86. if (cheat)
  87. return;
  88. Print("\nSorry but your savefile has been altered.\n");
  89. Print("However, since I am a good sport, I will let you play.\n");
  90. Print("Be advised, though, that you won't be placed on the scoreboard.");
  91. cheat = 1;
  92. nap(4000);
  93. }
  94. /* =============================================================================
  95. * FUNCTION: fcheat
  96. *
  97. * DESCRIPTION:
  98. * Subroutine to not allow game if save file can't be deleted.
  99. * Displays a message and quits the game.
  100. *
  101. * PARAMETERS:
  102. *
  103. * None
  104. *
  105. * RETURN VALUE:
  106. *
  107. * None.
  108. */
  109. static void fcheat(void)
  110. {
  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. {
  132. FILE *fp;
  133. nosignal = 1;
  134. /* Save the current level to storage */
  135. savelevel();
  136. /* make sure the interest on bank deposits is up to date */
  137. ointerest();
  138. /*
  139. * try and create the save file
  140. */
  141. fp = fopen(fname, "wb");
  142. if (fp == NULL)
  143. {
  144. Printf("Can't open file <%s> to save game\n", fname);
  145. nosignal = 0;
  146. return(-1);
  147. }
  148. FileSum = 0;
  149. write_player(fp);
  150. write_levels(fp);
  151. write_store(fp);
  152. write_monster_data(fp);
  153. write_spheres(fp);
  154. /* file sum */
  155. bwrite(fp, (char *) &FileSum, sizeof(FileSum));
  156. fclose(fp);
  157. nosignal = 0;
  158. return(0);
  159. }
  160. /* =============================================================================
  161. * FUNCTION: restoregame
  162. */
  163. void restoregame(char *fname)
  164. {
  165. int i;
  166. unsigned int thesum;
  167. unsigned int asum;
  168. int TotalAttr;
  169. FILE *fp;
  170. fp = fopen(fname, "rb");
  171. if (fp == NULL)
  172. {
  173. Printf("Can't open file <%s> to restore game\n", fname);
  174. nap(4000);
  175. c[GOLD] = c[BANKACCOUNT] = 0;
  176. died(DIED_MISSING_SAVE_FILE, 0);
  177. return;
  178. }
  179. Printf(" Reading data...");
  180. init_cells();
  181. FileSum = 0;
  182. read_player(fp);
  183. read_levels(fp);
  184. read_store(fp);
  185. read_monster_data(fp);
  186. read_spheres(fp);
  187. /* sum of everything so far */
  188. thesum = FileSum;
  189. bread(fp, (char *)&asum, sizeof(asum));
  190. if (asum != thesum)
  191. {
  192. fsorry();
  193. }
  194. fclose(fp);
  195. lastpx = 0;
  196. lastpy = 0;
  197. if (strcmp(fname, ckpfile) == 0)
  198. {
  199. fp = fopen(fname, "ab+");
  200. if (fp == NULL)
  201. {
  202. /*
  203. * Hmmm. We should be able to write to this file, something fishy
  204. * is going on.
  205. */
  206. fcheat();
  207. }
  208. else
  209. {
  210. fclose(fp);
  211. }
  212. }
  213. else if (unlink(fname) == -1)
  214. {
  215. /* can't unlink save file */
  216. fcheat();
  217. }
  218. /* for the greedy cheater checker */
  219. TotalAttr = 0;
  220. for (i = ABILITY_FIRST ; i < ABILITY_LAST ; i++)
  221. {
  222. TotalAttr += c[i];
  223. if (c[i] > 300)
  224. {
  225. greedy();
  226. }
  227. }
  228. if (TotalAttr > 600)
  229. {
  230. greedy();
  231. }
  232. if ((c[HPMAX] > 999) || (c[SPELLMAX] > 125))
  233. {
  234. greedy();
  235. }
  236. /* XP has been boosted in the save file, so fix character level */
  237. if ((c[LEVEL] == 25) && (c[EXPERIENCE] > skill[24]))
  238. {
  239. long tmp_xp = c[EXPERIENCE]-skill[24]; /* amount to go up */
  240. c[EXPERIENCE] = skill[24];
  241. raiseexperience((long) tmp_xp);
  242. }
  243. /* Get the current dungeon level from storage */
  244. getlevel();
  245. }