Source:NetHack 3.1.0/bones.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to bones.c from the source code of NetHack 3.1.0.

Warning! This is the source code from an old release. For newer releases, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)bones.c	3.1	93/01/07	*/
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.    #ifdef MFLOPPY
9.    extern char bones[];	/* from files.c */
10.   extern long bytes_counted;
11.   #endif
12.   
13.   static boolean FDECL(no_bones_level, (d_level *));
14.   #ifdef TUTTI_FRUTTI
15.   static void FDECL(goodfruit, (int));
16.   #endif
17.   static void FDECL(resetobjs,(struct obj *,BOOLEAN_P));
18.   static void FDECL(drop_upon_death, (struct monst *, struct obj *));
19.   
20.   static boolean
21.   no_bones_level(lev)
22.   d_level *lev;
23.   {
24.   	extern d_level save_dlevel;		/* in do.c */
25.   	s_level *sptr;
26.   
27.   	if (ledger_no(&save_dlevel)) assign_level(lev, &save_dlevel);
28.   
29.   	return (((sptr = Is_special(lev)) && !sptr->boneid)
30.   		|| !dungeons[lev->dnum].boneid
31.   		   /* no bones on the last or multiway branch levels */
32.   		   /* in any dungeon (level 1 isn't multiway).       */
33.   		|| Is_botlevel(lev) || (Is_branchlev(lev) && lev->dlevel > 1)
34.   		   /* no bones in the invocation level               */
35.   		|| (In_hell(lev) && lev->dlevel == dunlevs_in_dungeon(lev) - 1)
36.   		);
37.   }
38.   
39.   #ifdef TUTTI_FRUTTI
40.   static void
41.   goodfruit(id)
42.   int id;
43.   {
44.   	register struct fruit *f;
45.   
46.   	for(f=ffruit; f; f=f->nextf) {
47.   		if(f->fid == -id) {
48.   			f->fid = id;
49.   			return;
50.   		}
51.   	}
52.   }
53.   #endif
54.   
55.   static void
56.   resetobjs(ochain,restore)
57.   struct obj *ochain;
58.   boolean restore;
59.   {
60.   	struct obj *otmp;
61.   
62.   	for (otmp = ochain; otmp; otmp = otmp->nobj) {
63.   		if (otmp->cobj)
64.   		    resetobjs(otmp->cobj,restore);
65.   
66.   		if (((otmp->otyp != CORPSE || otmp->corpsenm < PM_ARCHEOLOGIST)
67.   			&& otmp->otyp != STATUE)
68.   			&& (!otmp->oartifact ||
69.   			    (exist_artifact(otmp->otyp,ONAME(otmp)) && restore))) {
70.   			otmp->oartifact = 0;
71.   			otmp->onamelth = 0;
72.   			*ONAME(otmp) = '\0';
73.   		} else if (otmp->oartifact && restore)
74.   			artifact_exists(otmp,ONAME(otmp),TRUE);
75.   		if (!restore) {
76.   			/* resetting the o_id's after getlev has carefully
77.   			 * created proper new ones via restobjchn is a Bad
78.   			 * Idea */
79.   			otmp->o_id = 0;
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.   #ifdef TUTTI_FRUTTI
85.   			if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
86.   #endif
87.   #ifdef MAIL
88.   			if (otmp->otyp == SCR_MAIL) otmp->spe = 1;
89.   #endif
90.   #ifdef POLYSELF
91.   			if (otmp->otyp == EGG) otmp->spe = 0;
92.   #endif
93.   			if(otmp->otyp == AMULET_OF_YENDOR) {
94.   				/* no longer the actual amulet */
95.   				otmp->otyp = FAKE_AMULET_OF_YENDOR;
96.   				curse(otmp);
97.   			}
98.   			if(otmp->otyp == CANDELABRUM_OF_INVOCATION) {
99.   			    if(otmp->spe > 0) { /* leave candles, if any */
100.  			        otmp->otyp = WAX_CANDLE;
101.  				otmp->age = 50L;  /* assume used */
102.  				otmp->quan = (long)otmp->spe;
103.  				otmp->lamplit = 0;
104.  				otmp->spe = 0;
105.  			    } else obfree(otmp, (struct obj *)0);
106.  			}
107.  			if(otmp->otyp == BELL_OF_OPENING) otmp->otyp = BELL;
108.  			if(otmp->otyp == SPE_BOOK_OF_THE_DEAD) {
109.  			    otmp->otyp = SPE_MAGIC_MISSILE +
110.  			                    rn2(SPE_BLANK_PAPER -
111.  						  SPE_MAGIC_MISSILE + 1);
112.  			    curse(otmp);
113.  			}
114.  		}
115.  	}			
116.  }
117.  
118.  static void
119.  drop_upon_death(mtmp, cont)
120.  struct monst *mtmp;
121.  struct obj *cont;
122.  {
123.  	struct obj *otmp = invent;
124.  	while(otmp) {
125.  		otmp->owornmask = 0;
126.  		otmp->lamplit = 0;
127.  #ifdef TUTTI_FRUTTI
128.  		if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
129.  #endif
130.  		if(rn2(5)) curse(otmp);
131.  		if(!mtmp && !cont) place_object(otmp, u.ux, u.uy);
132.  		if(!otmp->nobj) {
133.  			if (mtmp) {
134.  				otmp->nobj = mtmp->minvent;
135.  				mtmp->minvent = invent;
136.  			} else if (cont) {
137.  				otmp->nobj = cont->cobj;
138.  				cont->cobj = invent;
139.  			} else {
140.  				otmp->nobj = fobj;
141.  				fobj = invent;
142.  			}
143.  			invent = 0;	/* superfluous */
144.  			break;
145.  		}
146.  		otmp = otmp->nobj;
147.  	}
148.  	if(u.ugold) {
149.  		if (mtmp) mtmp->mgold = u.ugold;
150.  		else mkgold(u.ugold, u.ux, u.uy);
151.  	}
152.  }
153.  
154.  /* save bones and possessions of a deceased adventurer */
155.  void
156.  savebones()
157.  {
158.  	register int fd, x, y;
159.  	register struct trap *ttmp;
160.  	register struct monst *mtmp, *mtmp2;
161.  #ifdef TUTTI_FRUTTI
162.  	struct fruit *f;
163.  #endif
164.  	char *bonesid;
165.  
166.  	if(ledger_no(&u.uz) <= 0 || ledger_no(&u.uz) > maxledgerno()) return;
167.  	if(no_bones_level(&u.uz)) return; /* no bones for specific levels */
168.  	if(!rn2(1 + (depth(&u.uz)>>2)) /* fewer ghosts on low levels */
169.  #ifdef WIZARD
170.  		&& !wizard
171.  #endif
172.  		) return;
173.  #ifdef EXPLORE_MODE
174.  	/* don't let multiple restarts generate multiple copies of objects
175.  	 * in bones files */
176.  	if(discover) return;
177.  #endif
178.  
179.  	fd = open_bonesfile(&u.uz, &bonesid);
180.  	if (fd >= 0) {
181.  		(void) close(fd);
182.  		compress_bonesfile();
183.  #ifdef WIZARD
184.  		if(wizard)
185.  			pline("Bones file already exists.");
186.  #endif
187.  		return;
188.  	}
189.  
190.  #ifdef WALKIES
191.  	unleash_all();
192.  #endif
193.  	/* in case these characters are not in their home bases */
194.  	mtmp2 = fmon;
195.  	while((mtmp = mtmp2)) {
196.  		mtmp2 = mtmp->nmon;
197.  		if(mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp);
198.  	}
199.  #ifdef TUTTI_FRUTTI
200.  	/* mark all fruits as nonexistent; when we come to them we'll mark
201.  	 * them as existing (using goodfruit())
202.  	 */
203.  	for(f=ffruit; f; f=f->nextf) f->fid = -f->fid;
204.  #endif
205.  
206.  	/* check iron balls separately--maybe they're not carrying it */
207.  	if (uball) uball->owornmask = uchain->owornmask = 0;
208.  
209.  	/* dispose of your possessions, usually cursed */
210.  	if (u.ugrave_arise == -2) {
211.  		struct obj *otmp;
212.  
213.  		/* embed your possessions in your statue */
214.  		otmp = mk_named_object(STATUE,
215.  #ifdef POLYSELF
216.  					u.mtimedone ? uasmon :
217.  #endif
218.  					player_mon(), 
219.  					u.ux, u.uy, plname,
220.  					(int)strlen(plname));
221.  		if (!otmp) return;
222.  		drop_upon_death(mtmp = (struct monst *)0, otmp);
223.  	} else if (u.ugrave_arise == -1) {
224.  		/* drop everything */
225.  		drop_upon_death((struct monst *)0, (struct obj *)0);
226.  		/* trick makemon() into allowing monster creation
227.  		 * on your location
228.  		 */
229.  		in_mklev = TRUE;
230.  		mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy);
231.  		in_mklev = FALSE;
232.  		if (!mtmp) return;
233.  		Strcpy((char *) mtmp->mextra, plname);
234.  	} else {
235.  		/* give your possessions to the monster you become */
236.  		in_mklev = TRUE;
237.  		mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy);
238.  		in_mklev = FALSE;
239.  		if (!mtmp) return;
240.  		mtmp = christen_monst(mtmp, plname);
241.  		newsym(u.ux, u.uy);
242.  		Your("body rises from the dead as %s...",
243.  			an(mons[u.ugrave_arise].mname));
244.  		display_nhwindow(WIN_MESSAGE, FALSE);
245.  		drop_upon_death(mtmp, (struct obj *)0);
246.  #ifdef MUSE
247.  		m_dowear(mtmp, TRUE);
248.  #endif
249.  	}
250.  	if (mtmp) {
251.  		mtmp->m_lev = (u.ulevel ? u.ulevel : 1);
252.  		mtmp->mhp = mtmp->mhpmax = u.uhpmax;
253.  		mtmp->msleep = 1;
254.  	}
255.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
256.  		resetobjs(mtmp->minvent,FALSE);
257.  		mtmp->m_id = 0;
258.  		mtmp->mlstmv = 0L;
259.  		if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0;
260.  	}
261.  	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
262.  	        if(ttmp->ttyp == MAGIC_PORTAL) deltrap(ttmp);
263.  		ttmp->tseen = 0;
264.  	}
265.  	resetobjs(fobj,FALSE);
266.  
267.  	/* Clear all memory from the level. */
268.  	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) {
269.  	    levl[x][y].seen = levl[x][y].waslit = 0;
270.  	    levl[x][y].glyph = cmap_to_glyph(S_stone);
271.  	}
272.  
273.  	fd = create_bonesfile(&u.uz, &bonesid);
274.  	if(fd < 0) {
275.  #ifdef WIZARD
276.  		if(wizard)
277.  			pline("Cannot create bones file - create failed");
278.  #endif
279.  		return;
280.  	}
281.  
282.  	bufon(fd);
283.  #ifdef MFLOPPY  /* check whether there is room */
284.  	savelev(fd, ledger_no(&u.uz), COUNT_SAVE);
285.  # ifdef TUTTI_FRUTTI
286.  	/* this is in the opposite order from the real save, but savelev()
287.  	 * initializes bytes_counted to 0, so doing savefruitchn() first is
288.  	 * useless; the extra bflush() at the end of savelev() may increase
289.  	 * bytes_counted by a couple over what the real usage will be
290.  	 */
291.  	savefruitchn(fd, COUNT_SAVE);
292.  	bflush(fd);
293.  # endif
294.  	if (bytes_counted > freediskspace(bones)) {	/* not enough room */
295.  # ifdef WIZARD
296.  		if (wizard)
297.  			pline("Insufficient space to create bones file.");
298.  # endif
299.  		(void) close(fd);
300.  		delete_bonesfile(&u.uz);
301.  		return;
302.  	}
303.  	co_false();	/* make sure bonesid and savefruitchn get written */
304.  #endif /* MFLOPPY */
305.  
306.  	bwrite(fd, (genericptr_t) bonesid, 7);	/* DD.nnn */
307.  #ifdef TUTTI_FRUTTI
308.  	savefruitchn(fd, WRITE_SAVE | FREE_SAVE);
309.  #endif
310.  	savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE);
311.  	bclose(fd);
312.  	compress_bonesfile();
313.  }
314.  
315.  int
316.  getbones()
317.  {
318.  	register int fd;
319.  	register int ok;
320.  	char *bonesid, oldbonesid[7];
321.  
322.  #ifdef EXPLORE_MODE
323.  	if(discover)		/* save bones files for real games */
324.  		return(0);
325.  #endif
326.  	/* wizard check added by GAN 02/05/87 */
327.  	if(rn2(3)	/* only once in three times do we find bones */
328.  #ifdef WIZARD
329.  		&& !wizard
330.  #endif
331.  		) return(0);
332.  	if(no_bones_level(&u.uz)) return(0);
333.  	fd = open_bonesfile(&u.uz, &bonesid);
334.  	if (fd < 0) return(0);
335.  
336.  	if((ok = uptodate(fd)) != 0){
337.  #ifdef WIZARD
338.  		if(wizard)  {
339.  			if(yn("Get bones?") == 'n') {
340.  				(void) close(fd);
341.  				compress_bonesfile();
342.  				return(0);
343.  			}
344.  		}
345.  #endif
346.  		minit();	/* ZEROCOMP */
347.  		mread(fd, (genericptr_t) oldbonesid, 7);	/* DD.nnn */
348.  		if (strcmp(bonesid, oldbonesid)) {
349.  #ifdef WIZARD
350.  			if (wizard) {
351.  				pline("This is bones level '%s', not '%s'!",
352.  					oldbonesid, bonesid);
353.  				ok = FALSE;	/* won't die of trickery */
354.  			}
355.  #endif
356.  			trickery();
357.  		} else {
358.  			register struct monst *mtmp;
359.  
360.  			getlev(fd, 0, 0, TRUE);
361.  
362.  			/* to correctly reset named artifacts on the level */
363.  			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
364.  				resetobjs(mtmp->minvent,TRUE);
365.  			resetobjs(fobj,TRUE);
366.  		}
367.  	}
368.  	(void) close(fd);
369.  
370.  #ifdef WIZARD
371.  	if(wizard) {
372.  		if(yn("Unlink bones?") == 'n') {
373.  			compress_bonesfile();
374.  			return(ok);
375.  		}
376.  	}
377.  #endif
378.  	if (!delete_bonesfile(&u.uz)) {
379.  		pline("Cannot unlink bones.");
380.  		return(0);
381.  	}
382.  	return(ok);
383.  }
384.  
385.  /*bones.c*/