Wikia

Wikihack

Source:SLASH'EM 0.0.7E7F2/bones.c

2,032pages on
this wiki
Talk0

Below is the full text to bones.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/bones.c#line123]], for example.

The latest source code for vanilla NetHack is at Source code.


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

Around Wikia's network

Random Wiki