1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.save.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.save.c,v 1.4 1999/11/16 10:26:37 marcel Exp $ */
7 extern char SAVEF
[], nul
[];
9 static bool dosave0(int);
15 settty("Be seeing you ...\n");
21 #ifndef NOSAVEONHANGUP
23 hangup(int n __unused
)
28 #endif /* NOSAVEONHANGUP */
30 /* returns 1 if save successful */
37 signal(SIGHUP
, SIG_IGN
);
38 signal(SIGINT
, SIG_IGN
);
39 if ((fd
= creat(SAVEF
, FMASK
)) < 0) {
41 pline("Cannot open save file. (Continue or Quit)");
42 unlink(SAVEF
); /* ab@unido */
45 if (flags
.moonphase
== FULL_MOON
) /* ut-sally!fletcher */
46 u
.uluck
--; /* and unido!ab */
48 saveobjchn(fd
, invent
);
49 saveobjchn(fd
, fcobj
);
50 savemonchn(fd
, fallen_down
);
52 bwrite(fd
, (char *)&tmp
, sizeof(tmp
));
53 bwrite(fd
, (char *)&flags
, sizeof(struct flag
));
54 bwrite(fd
, (char *)&dlevel
, sizeof(dlevel
));
55 bwrite(fd
, (char *)&maxdlevel
, sizeof(maxdlevel
));
56 bwrite(fd
, (char *)&moves
, sizeof(moves
));
57 bwrite(fd
, (char *)&u
, sizeof(struct you
));
59 bwrite(fd
, (char *)&(u
.ustuck
->m_id
), sizeof(u
.ustuck
->m_id
));
60 bwrite(fd
, (char *)pl_character
, sizeof(pl_character
));
61 bwrite(fd
, (char *)genocided
, sizeof(genocided
));
62 bwrite(fd
, (char *)fut_geno
, sizeof(fut_geno
));
64 for (tmp
= 1; tmp
<= maxdlevel
; tmp
++) {
65 if (tmp
== dlevel
|| !level_exists
[tmp
])
68 if ((ofd
= open(lock
, O_RDONLY
)) < 0) {
70 pline("Error while saving: cannot read %s.", lock
);
77 getlev(ofd
, hackpid
, tmp
);
79 bwrite(fd
, (char *)&tmp
, sizeof(tmp
)); /* level number */
80 savelev(fd
, tmp
); /* actual level */
85 unlink(lock
); /* get rid of current level --jgm */
95 int tmp
; /* not a ! */
96 unsigned mid
; /* idem */
101 invent
= restobjchn(fd
);
102 for (otmp
= invent
; otmp
; otmp
= otmp
->nobj
)
104 setworn(otmp
, otmp
->owornmask
);
105 fcobj
= restobjchn(fd
);
106 fallen_down
= restmonchn(fd
);
107 mread(fd
, (char *)&tmp
, sizeof(tmp
));
108 if (tmp
!= (int)getuid()) { /* strange ... */
111 puts("Saved game was not yours.");
115 mread(fd
, (char *)&flags
, sizeof(struct flag
));
116 mread(fd
, (char *)&dlevel
, sizeof(dlevel
));
117 mread(fd
, (char *)&maxdlevel
, sizeof(maxdlevel
));
118 mread(fd
, (char *)&moves
, sizeof(moves
));
119 mread(fd
, (char *)&u
, sizeof(struct you
));
121 mread(fd
, (char *)&mid
, sizeof(mid
));
122 mread(fd
, (char *)pl_character
, sizeof(pl_character
));
123 mread(fd
, (char *)genocided
, sizeof(genocided
));
124 mread(fd
, (char *)fut_geno
, sizeof(fut_geno
));
127 if (read(fd
, (char *)&tmp
, sizeof(tmp
)) != sizeof(tmp
))
131 if ((nfd
= creat(lock
, FMASK
)) < 0)
132 panic("Cannot open temp file %s!\n", lock
);
136 lseek(fd
, (off_t
)0, SEEK_SET
);
141 for (otmp
= fobj
; otmp
; otmp
= otmp
->nobj
)
142 if (otmp
->olet
== CHAIN_SYM
)
144 panic("Cannot find the iron chain?");
148 for (otmp
= fobj
; otmp
; otmp
= otmp
->nobj
)
149 if (otmp
->olet
== BALL_SYM
&& otmp
->spe
)
151 panic("Cannot find the iron ball?");
159 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
160 if (mtmp
->m_id
== mid
)
162 panic("Cannot find the monster ustuck.");
167 setsee(); /* only to recompute seelx etc. - these weren't saved */
177 struct obj
*otmp
, *otmp2
;
178 struct obj
*first
= NULL
;
181 /* suppress "used before set" warning from lint */
184 mread(fd
, (char *)&xl
, sizeof(xl
));
192 mread(fd
, (char *)otmp
, (unsigned)xl
+ sizeof(struct obj
));
193 if (!otmp
->o_id
) otmp
->o_id
= flags
.ident
++;
196 if (first
&& otmp2
->nobj
) {
197 impossible("Restobjchn: error reading objchn.");
206 struct monst
*mtmp
, *mtmp2
;
207 struct monst
*first
= NULL
;
209 struct permonst
*monbegin
;
212 mread(fd
, (char *)&monbegin
, sizeof(monbegin
));
213 differ
= (char *)(&mons
[0]) - (char *)(monbegin
);
215 /* suppress "used before set" warning from lint */
218 mread(fd
, (char *)&xl
, sizeof(xl
));
226 mread(fd
, (char *)mtmp
, (unsigned)xl
+ sizeof(struct monst
));
228 mtmp
->m_id
= flags
.ident
++;
229 mtmp
->data
= (struct permonst
*)
230 ((char *)mtmp
->data
+ differ
);
232 mtmp
->minvent
= restobjchn(fd
);
235 if (first
&& mtmp2
->nmon
) {
236 impossible("Restmonchn: error reading monchn.");