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 $ */
4 /* $DragonFly: src/games/hack/hack.save.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $ */
8 extern char SAVEF
[], nul
[];
10 static bool dosave0(int);
16 settty("Be seeing you ...\n");
22 #ifndef NOSAVEONHANGUP
24 hangup(__unused
int unused
)
29 #endif /* NOSAVEONHANGUP */
31 /* returns 1 if save successful */
38 signal(SIGHUP
, SIG_IGN
);
39 signal(SIGINT
, SIG_IGN
);
40 if((fd
= creat(SAVEF
, FMASK
)) < 0) {
41 if(!hu
) 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
]) continue;
67 if((ofd
= open(lock
, 0)) < 0) {
68 if(!hu
) pline("Error while saving: cannot read %s.", lock
);
71 if(!hu
) done("tricked");
74 getlev(ofd
, hackpid
, tmp
);
76 bwrite(fd
, (char *) &tmp
, sizeof tmp
); /* level number */
77 savelev(fd
,tmp
); /* actual level */
82 unlink(lock
); /* get rid of current level --jgm */
92 int tmp
; /* not a ! */
93 unsigned mid
; /* idem */
98 invent
= restobjchn(fd
);
99 for(otmp
= invent
; otmp
; otmp
= otmp
->nobj
)
101 setworn(otmp
, otmp
->owornmask
);
102 fcobj
= restobjchn(fd
);
103 fallen_down
= restmonchn(fd
);
104 mread(fd
, (char *) &tmp
, sizeof tmp
);
105 if(tmp
!= (int)getuid()) { /* strange ... */
108 puts("Saved game was not yours.");
112 mread(fd
, (char *) &flags
, sizeof(struct flag
));
113 mread(fd
, (char *) &dlevel
, sizeof dlevel
);
114 mread(fd
, (char *) &maxdlevel
, sizeof maxdlevel
);
115 mread(fd
, (char *) &moves
, sizeof moves
);
116 mread(fd
, (char *) &u
, sizeof(struct you
));
118 mread(fd
, (char *) &mid
, sizeof mid
);
119 mread(fd
, (char *) pl_character
, sizeof pl_character
);
120 mread(fd
, (char *) genocided
, sizeof genocided
);
121 mread(fd
, (char *) fut_geno
, sizeof fut_geno
);
124 if(read(fd
, (char *) &tmp
, sizeof tmp
) != sizeof tmp
)
128 if((nfd
= creat(lock
, FMASK
)) < 0)
129 panic("Cannot open temp file %s!\n", lock
);
133 lseek(fd
, (off_t
)0, 0);
138 for(otmp
= fobj
; otmp
; otmp
= otmp
->nobj
)
139 if(otmp
->olet
== CHAIN_SYM
) goto chainfnd
;
140 panic("Cannot find the iron chain?");
144 for(otmp
= fobj
; otmp
; otmp
= otmp
->nobj
)
145 if(otmp
->olet
== BALL_SYM
&& otmp
->spe
)
147 panic("Cannot find the iron ball?");
155 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
156 if(mtmp
->m_id
== mid
) goto monfnd
;
157 panic("Cannot find the monster ustuck.");
162 setsee(); /* only to recompute seelx etc. - these weren't saved */
172 struct obj
*otmp
, *otmp2
;
173 struct obj
*first
= 0;
175 /* suppress "used before set" warning from lint */
178 mread(fd
, (char *) &xl
, sizeof(xl
));
181 if(!first
) first
= otmp
;
182 else otmp2
->nobj
= otmp
;
183 mread(fd
, (char *) otmp
, (unsigned) xl
+ sizeof(struct obj
));
184 if(!otmp
->o_id
) otmp
->o_id
= flags
.ident
++;
187 if(first
&& otmp2
->nobj
){
188 impossible("Restobjchn: error reading objchn.");
197 struct monst
*mtmp
, *mtmp2
;
198 struct monst
*first
= 0;
201 struct permonst
*monbegin
;
204 mread(fd
, (char *)&monbegin
, sizeof(monbegin
));
205 differ
= (char *)(&mons
[0]) - (char *)(monbegin
);
207 /* suppress "used before set" warning from lint */
210 mread(fd
, (char *) &xl
, sizeof(xl
));
213 if(!first
) first
= mtmp
;
214 else mtmp2
->nmon
= mtmp
;
215 mread(fd
, (char *) mtmp
, (unsigned) xl
+ sizeof(struct monst
));
217 mtmp
->m_id
= flags
.ident
++;
218 mtmp
->data
= (struct permonst
*)
219 ((char *) mtmp
->data
+ differ
);
221 mtmp
->minvent
= restobjchn(fd
);
224 if(first
&& mtmp2
->nmon
){
225 impossible("Restmonchn: error reading monchn.");