OSDN Git Service

no bone
[nethackexpress/trunk.git] / src / bones.c
1 /*      SCCS Id: @(#)bones.c    3.4     2003/09/06      */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #include "hack.h"
6 #include "lev.h"
7
8 extern char bones[];    /* from files.c */
9 #ifdef MFLOPPY
10 extern long bytes_counted;
11 #endif
12
13 STATIC_DCL boolean FDECL(no_bones_level, (d_level *));
14 STATIC_DCL void FDECL(goodfruit, (int));
15 STATIC_DCL void FDECL(resetobjs,(struct obj *,BOOLEAN_P));
16 STATIC_DCL void FDECL(drop_upon_death, (struct monst *, struct obj *));
17
18 STATIC_OVL boolean
19 no_bones_level(lev)
20 d_level *lev;
21 {
22         extern d_level save_dlevel;             /* in do.c */
23         s_level *sptr;
24
25         if (ledger_no(&save_dlevel)) assign_level(lev, &save_dlevel);
26
27         return (boolean)(((sptr = Is_special(lev)) != 0 && !sptr->boneid)
28                 || !dungeons[lev->dnum].boneid
29                    /* no bones on the last or multiway branch levels */
30                    /* in any dungeon (level 1 isn't multiway).       */
31                 || Is_botlevel(lev) || (Is_branchlev(lev) && lev->dlevel > 1)
32                    /* no bones in the invocation level               */
33                 || (In_hell(lev) && lev->dlevel == dunlevs_in_dungeon(lev) - 1)
34                 );
35 }
36
37 /* Call this function for each fruit object saved in the bones level: it marks
38  * that particular type of fruit as existing (the marker is that that type's
39  * ID is positive instead of negative).  This way, when we later save the
40  * chain of fruit types, we know to only save the types that exist.
41  */
42 STATIC_OVL void
43 goodfruit(id)
44 int id;
45 {
46         register struct fruit *f;
47
48         for(f=ffruit; f; f=f->nextf) {
49                 if(f->fid == -id) {
50                         f->fid = id;
51                         return;
52                 }
53         }
54 }
55
56 STATIC_OVL void
57 resetobjs(ochain,restore)
58 struct obj *ochain;
59 boolean restore;
60 {
61         struct obj *otmp;
62
63         for (otmp = ochain; otmp; otmp = otmp->nobj) {
64                 if (otmp->cobj)
65                     resetobjs(otmp->cobj,restore);
66
67                 if (((otmp->otyp != CORPSE || otmp->corpsenm < SPECIAL_PM)
68                         && otmp->otyp != STATUE)
69                         && (!otmp->oartifact ||
70                            (restore && (exist_artifact(otmp->otyp, ONAME(otmp))
71                                         || is_quest_artifact(otmp))))) {
72                         otmp->oartifact = 0;
73                         otmp->onamelth = 0;
74                         *ONAME(otmp) = '\0';
75                 } else if (otmp->oartifact && restore)
76                         artifact_exists(otmp,ONAME(otmp),TRUE);
77                 if (!restore) {
78                         /* do not zero out o_ids for ghost levels anymore */
79
80                         if(objects[otmp->otyp].oc_uses_known) otmp->known = 0;
81                         otmp->dknown = otmp->bknown = 0;
82                         otmp->rknown = 0;
83                         otmp->invlet = 0;
84                         otmp->no_charge = 0;
85
86                         if (otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
87 #ifdef MAIL
88                         else if (otmp->otyp == SCR_MAIL) otmp->spe = 1;
89 #endif
90                         else if (otmp->otyp == EGG) otmp->spe = 0;
91                         else if (otmp->otyp == TIN) {
92                             /* make tins of unique monster's meat be empty */
93                             if (otmp->corpsenm >= LOW_PM &&
94                                     (mons[otmp->corpsenm].geno & G_UNIQ))
95                                 otmp->corpsenm = NON_PM;
96                         } else if (otmp->otyp == AMULET_OF_YENDOR) {
97                             /* no longer the real Amulet */
98                             otmp->otyp = FAKE_AMULET_OF_YENDOR;
99                             curse(otmp);
100                         } else if (otmp->otyp == CANDELABRUM_OF_INVOCATION) {
101                             if (otmp->lamplit)
102                                 end_burn(otmp, TRUE);
103                             otmp->otyp = WAX_CANDLE;
104                             otmp->age = 50L;  /* assume used */
105                             if (otmp->spe > 0)
106                                 otmp->quan = (long)otmp->spe;
107                             otmp->spe = 0;
108                             otmp->owt = weight(otmp);
109                             curse(otmp);
110                         } else if (otmp->otyp == BELL_OF_OPENING) {
111                             otmp->otyp = BELL;
112                             curse(otmp);
113                         } else if (otmp->otyp == SPE_BOOK_OF_THE_DEAD) {
114                             otmp->otyp = SPE_BLANK_PAPER;
115                             curse(otmp);
116                         }
117                 }
118         }
119 }
120
121 STATIC_OVL void
122 drop_upon_death(mtmp, cont)
123 struct monst *mtmp;
124 struct obj *cont;
125 {
126         struct obj *otmp;
127
128         uswapwep = 0; /* ensure curse() won't cause swapwep to drop twice */
129         while ((otmp = invent) != 0) {
130                 obj_extract_self(otmp);
131                 obj_no_longer_held(otmp);
132
133                 otmp->owornmask = 0;
134                 /* lamps don't go out when dropped */
135                 if ((cont || artifact_light(otmp)) && obj_is_burning(otmp))
136                     end_burn(otmp, TRUE);       /* smother in statue */
137
138                 if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
139
140                 if(rn2(5)) curse(otmp);
141                 if (mtmp)
142                         (void) add_to_minv(mtmp, otmp);
143                 else if (cont)
144                         (void) add_to_container(cont, otmp);
145                 else
146                         place_object(otmp, u.ux, u.uy);
147         }
148 #ifndef GOLDOBJ
149         if(u.ugold) {
150                 long ugold = u.ugold;
151                 if (mtmp) mtmp->mgold = ugold;
152                 else if (cont) (void) add_to_container(cont, mkgoldobj(ugold));
153                 else (void)mkgold(ugold, u.ux, u.uy);
154                 u.ugold = ugold;        /* undo mkgoldobj()'s removal */
155         }
156 #endif
157         if (cont) cont->owt = weight(cont);
158 }
159
160 /* check whether bones are feasible */
161 boolean
162 can_make_bones()
163 {
164         register struct trap *ttmp;
165
166 #ifdef NO_BONES
167         return FALSE;
168 #else
169         if (ledger_no(&u.uz) <= 0 || ledger_no(&u.uz) > maxledgerno())
170             return FALSE;
171         if (no_bones_level(&u.uz))
172             return FALSE;               /* no bones for specific levels */
173         if (u.uswallow) {
174             return FALSE;               /* no bones when swallowed */
175         }
176         if (!Is_branchlev(&u.uz)) {
177             /* no bones on non-branches with portals */
178             for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
179                 if (ttmp->ttyp == MAGIC_PORTAL) return FALSE;
180         }
181
182         if(depth(&u.uz) <= 0 ||         /* bulletproofing for endgame */
183            (!rn2(1 + (depth(&u.uz)>>2)) /* fewer ghosts on low levels */
184 #ifdef WIZARD
185                 && !wizard
186 #endif
187                 )) return FALSE;
188         /* don't let multiple restarts generate multiple copies of objects
189          * in bones files */
190         if (discover) return FALSE;
191         return TRUE;
192 #endif
193 }
194
195 /* save bones and possessions of a deceased adventurer */
196 void
197 savebones(corpse)
198 struct obj *corpse;
199 {
200         int fd, x, y;
201         struct trap *ttmp;
202         struct monst *mtmp;
203         struct permonst *mptr;
204         struct fruit *f;
205         char c, *bonesid;
206         char whynot[BUFSZ];
207
208         /* caller has already checked `can_make_bones()' */
209
210         clear_bypasses();
211         fd = open_bonesfile(&u.uz, &bonesid);
212         if (fd >= 0) {
213                 (void) close(fd);
214                 compress_bonesfile();
215 #ifdef WIZARD
216                 if (wizard) {
217                     if (yn("Bones file already exists.  Replace it?") == 'y') {
218                         if (delete_bonesfile(&u.uz)) goto make_bones;
219                         else pline("Cannot unlink old bones.");
220                     }
221                 }
222 #endif
223                 return;
224         }
225
226 #ifdef WIZARD
227  make_bones:
228 #endif
229         unleash_all();
230         /* in case these characters are not in their home bases */
231         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
232             if (DEADMONSTER(mtmp)) continue;
233             mptr = mtmp->data;
234             if (mtmp->iswiz || mptr == &mons[PM_MEDUSA] ||
235                     mptr->msound == MS_NEMESIS || mptr->msound == MS_LEADER ||
236                     mptr == &mons[PM_VLAD_THE_IMPALER])
237                 mongone(mtmp);
238         }
239 #ifdef STEED
240         if (u.usteed) dismount_steed(DISMOUNT_BONES);
241 #endif
242         dmonsfree();            /* discard dead or gone monsters */
243
244         /* mark all fruits as nonexistent; when we come to them we'll mark
245          * them as existing (using goodfruit())
246          */
247         for(f=ffruit; f; f=f->nextf) f->fid = -f->fid;
248
249         /* check iron balls separately--maybe they're not carrying it */
250         if (uball) uball->owornmask = uchain->owornmask = 0;
251
252         /* dispose of your possessions, usually cursed */
253         if (u.ugrave_arise == (NON_PM - 1)) {
254                 struct obj *otmp;
255
256                 /* embed your possessions in your statue */
257                 otmp = mk_named_object(STATUE, &mons[u.umonnum],
258                                        u.ux, u.uy, plname);
259
260                 drop_upon_death((struct monst *)0, otmp);
261                 if (!otmp) return;      /* couldn't make statue */
262                 mtmp = (struct monst *)0;
263         } else if (u.ugrave_arise < LOW_PM) {
264                 /* drop everything */
265                 drop_upon_death((struct monst *)0, (struct obj *)0);
266                 /* trick makemon() into allowing monster creation
267                  * on your location
268                  */
269                 in_mklev = TRUE;
270                 mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, MM_NONAME);
271                 in_mklev = FALSE;
272                 if (!mtmp) return;
273                 mtmp = christen_monst(mtmp, plname);
274                 if (corpse)
275                         (void) obj_attach_mid(corpse, mtmp->m_id); 
276         } else {
277                 /* give your possessions to the monster you become */
278                 in_mklev = TRUE;
279                 mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy, NO_MM_FLAGS);
280                 in_mklev = FALSE;
281                 if (!mtmp) {
282                         drop_upon_death((struct monst *)0, (struct obj *)0);
283                         return;
284                 }
285                 mtmp = christen_monst(mtmp, plname);
286                 newsym(u.ux, u.uy);
287                 Your("body rises from the dead as %s...",
288                         an(mons[u.ugrave_arise].mname));
289                 display_nhwindow(WIN_MESSAGE, FALSE);
290                 drop_upon_death(mtmp, (struct obj *)0);
291                 m_dowear(mtmp, TRUE);
292         }
293         if (mtmp) {
294                 mtmp->m_lev = (u.ulevel ? u.ulevel : 1);
295                 mtmp->mhp = mtmp->mhpmax = u.uhpmax;
296                 mtmp->female = flags.female;
297                 mtmp->msleeping = 1;
298         }
299         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
300                 resetobjs(mtmp->minvent,FALSE);
301                 /* do not zero out m_ids for bones levels any more */
302                 mtmp->mlstmv = 0L;
303                 if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0;
304         }
305         for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
306                 ttmp->madeby_u = 0;
307                 ttmp->tseen = (ttmp->ttyp == HOLE);
308         }
309         resetobjs(fobj,FALSE);
310         resetobjs(level.buriedobjlist, FALSE);
311
312         /* Hero is no longer on the map. */
313         u.ux = u.uy = 0;
314
315         /* Clear all memory from the level. */
316         for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) {
317             levl[x][y].seenv = 0;
318             levl[x][y].waslit = 0;
319             levl[x][y].glyph = cmap_to_glyph(S_stone);
320         }
321
322         fd = create_bonesfile(&u.uz, &bonesid, whynot);
323         if(fd < 0) {
324 #ifdef WIZARD
325                 if(wizard)
326                         pline("%s", whynot);
327 #endif
328                 /* bones file creation problems are silent to the player.
329                  * Keep it that way, but place a clue into the paniclog.
330                  */
331                 paniclog("savebones", whynot);
332                 return;
333         }
334         c = (char) (strlen(bonesid) + 1);
335
336 #ifdef MFLOPPY  /* check whether there is room */
337         if (iflags.checkspace) {
338             savelev(fd, ledger_no(&u.uz), COUNT_SAVE);
339             /* savelev() initializes bytes_counted to 0, so it must come
340              * first here even though it does not in the real save.  the
341              * resulting extra bflush() at the end of savelev() may increase
342              * bytes_counted by a couple over what the real usage will be.
343              *
344              * note it is safe to call store_version() here only because
345              * bufon() is null for ZEROCOMP, which MFLOPPY uses -- otherwise
346              * this code would have to know the size of the version
347              * information itself.
348              */
349             store_version(fd);
350             bwrite(fd, (genericptr_t) &c, sizeof c);
351             bwrite(fd, (genericptr_t) bonesid, (unsigned) c);   /* DD.nnn */
352             savefruitchn(fd, COUNT_SAVE);
353             bflush(fd);
354             if (bytes_counted > freediskspace(bones)) { /* not enough room */
355 # ifdef WIZARD
356                 if (wizard)
357                         pline("Insufficient space to create bones file.");
358 # endif
359                 (void) close(fd);
360                 cancel_bonesfile();
361                 return;
362             }
363             co_false(); /* make sure stuff before savelev() gets written */
364         }
365 #endif /* MFLOPPY */
366
367         store_version(fd);
368         bwrite(fd, (genericptr_t) &c, sizeof c);
369         bwrite(fd, (genericptr_t) bonesid, (unsigned) c);       /* DD.nnn */
370         savefruitchn(fd, WRITE_SAVE | FREE_SAVE);
371         update_mlstmv();        /* update monsters for eventual restoration */
372         savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE);
373         bclose(fd);
374         commit_bonesfile(&u.uz);
375         compress_bonesfile();
376 }
377
378 int
379 getbones()
380 {
381         register int fd;
382         register int ok;
383         char c, *bonesid, oldbonesid[10];
384
385 #ifdef NO_BONES
386         return(0);
387 #else
388         if(discover)            /* save bones files for real games */
389                 return(0);
390
391         /* wizard check added by GAN 02/05/87 */
392         if(rn2(3)       /* only once in three times do we find bones */
393 #ifdef WIZARD
394                 && !wizard
395 #endif
396                 ) return(0);
397         if(no_bones_level(&u.uz)) return(0);
398         fd = open_bonesfile(&u.uz, &bonesid);
399         if (fd < 0) return(0);
400
401         if ((ok = uptodate(fd, bones)) == 0) {
402 #ifdef WIZARD
403             if (!wizard)
404 #endif
405                 pline("Discarding unuseable bones; no need to panic...");
406         } else {
407 #ifdef WIZARD
408                 if(wizard)  {
409                         if(yn("Get bones?") == 'n') {
410                                 (void) close(fd);
411                                 compress_bonesfile();
412                                 return(0);
413                         }
414                 }
415 #endif
416                 mread(fd, (genericptr_t) &c, sizeof c); /* length incl. '\0' */
417                 mread(fd, (genericptr_t) oldbonesid, (unsigned) c); /* DD.nnn */
418                 if (strcmp(bonesid, oldbonesid) != 0) {
419                         char errbuf[BUFSZ];
420
421                         Sprintf(errbuf, "This is bones level '%s', not '%s'!",
422                                 oldbonesid, bonesid);
423 #ifdef WIZARD
424                         if (wizard) {
425                                 pline("%s", errbuf);
426                                 ok = FALSE;     /* won't die of trickery */
427                         }
428 #endif
429                         trickery(errbuf);
430                 } else {
431                         register struct monst *mtmp;
432
433                         getlev(fd, 0, 0, TRUE);
434
435                         /* Note that getlev() now keeps tabs on unique
436                          * monsters such as demon lords, and tracks the
437                          * birth counts of all species just as makemon()
438                          * does.  If a bones monster is extinct or has been
439                          * subject to genocide, their mhpmax will be
440                          * set to the magic DEFUNCT_MONSTER cookie value.
441                          */
442                         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
443                             if (mtmp->mhpmax == DEFUNCT_MONSTER) {
444 #if defined(DEBUG) && defined(WIZARD)
445                                 if (wizard)
446                                     pline("Removing defunct monster %s from bones.",
447                                         mtmp->data->mname);
448 #endif
449                                 mongone(mtmp);
450                             } else
451                                 /* to correctly reset named artifacts on the level */
452                                 resetobjs(mtmp->minvent,TRUE);
453                         }
454                         resetobjs(fobj,TRUE);
455                         resetobjs(level.buriedobjlist,TRUE);
456                 }
457         }
458         (void) close(fd);
459
460 #ifdef WIZARD
461         if(wizard) {
462                 if(yn("Unlink bones?") == 'n') {
463                         compress_bonesfile();
464                         return(ok);
465                 }
466         }
467 #endif
468         if (!delete_bonesfile(&u.uz)) {
469                 /* When N games try to simultaneously restore the same
470                  * bones file, N-1 of them will fail to delete it
471                  * (the first N-1 under AmigaDOS, the last N-1 under UNIX).
472                  * So no point in a mysterious message for a normal event
473                  * -- just generate a new level for those N-1 games.
474                  */
475                 /* pline("Cannot unlink bones."); */
476                 return(0);
477         }
478         return(ok);
479 #endif
480 }
481
482 /*bones.c*/