Source:NetHack 3.0.0/bones.c

From NetHackWiki
Revision as of 04:21, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/bones.c moved to Source:NetHack 3.0.0/bones.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to bones.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/bones.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, 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.0	88/04/13
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    
7.    #ifdef TOS
8.    #define OMASK	0x8000
9.    #else
10.   #define OMASK	0
11.   #endif
12.   
13.   #ifdef DGK
14.   char bones[FILENAME];
15.   #else
16.   char bones[] = "bones.xx";
17.   #endif
18.   
19.   #ifdef COMPRESS
20.   static char cmd[60], proxy[20];
21.   
22.   static void
23.   compress_bones()
24.   {
25.   	Strcpy(cmd, COMPRESS);
26.   	Strcat(cmd, " ");
27.   # ifdef COMPRESS_OPTIONS
28.   	Strcat(cmd, COMPRESS_OPTIONS);
29.   	Strcat(cmd, " ");
30.   # endif
31.   	Strcat(cmd, bones);
32.   	(void) system(cmd);
33.   }
34.   #endif /* COMPRESS */
35.   
36.   static boolean
37.   no_bones_level(lev)
38.   int lev;
39.   {
40.   	return (lev == medusa_level ||
41.   		lev == wiz_level
42.   #ifdef STRONGHOLD
43.   		|| lev == stronghold_level ||
44.   		(lev >= tower_level && lev <= tower_level+2)
45.   #endif
46.   #ifdef ENDGAME
47.   		|| lev == ENDLEVEL
48.   #endif
49.   		);
50.   }
51.   
52.   static void
53.   goodfruit(id)
54.   int id;
55.   {
56.   	register struct fruit *f;
57.   
58.   	for(f=ffruit; f; f=f->nextf) {
59.   		if(f->fid == -id) {
60.   			f->fid = id;
61.   			return;
62.   		}
63.   	}
64.   }
65.   
66.   /* save bones and possessions of a deceased adventurer */
67.   void
68.   savebones(){
69.   	register int fd, x, y;
70.   	register struct obj *otmp;
71.   	register struct trap *ttmp;
72.   	register struct monst *mtmp, *mtmp2;
73.   	struct fruit *f;
74.   
75.   	if(dlevel <= 0 || dlevel > MAXLEVEL) return;
76.   	if(no_bones_level(dlevel)) return; /* no bones for specific levels */
77.   	if(!rn2(1 + (dlevel>>2)) /* not so many ghosts on low levels */
78.   #ifdef WIZARD
79.   		&& !wizard
80.   #endif
81.   		) return;
82.   #ifdef EXPLORE_MODE
83.   	/* don't let multiple restarts generate multiple copies of objects
84.   	 * in bones files */
85.   	if(discover) return;
86.   #endif
87.   
88.   	name_file(bones, dlevel);
89.   #ifdef COMPRESS
90.   	Strcpy(proxy, bones);
91.   	Strcat(proxy, ".Z");
92.   
93.   	if((fd = open(proxy, OMASK)) >= 0) {
94.   #else
95.   	if((fd = open(bones, OMASK)) >= 0) {
96.   #endif
97.   		(void) close(fd);
98.   #ifdef WIZARD
99.   		if(wizard)
100.  			pline("Bones file already exists.");
101.  #endif
102.  		return;
103.  	}
104.  #ifdef WALKIES
105.  	unleash_all();
106.  #endif
107.  	/* in case these characters are not in their home bases */
108.  	mtmp2 = fmon;
109.  	while((mtmp = mtmp2)) {
110.  		mtmp2 = mtmp->nmon;
111.  		if(mtmp->iswiz) mongone(mtmp);
112.  #ifdef MEDUSA
113.  		if(mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp);
114.  #endif
115.  	}
116.  	/* mark all fruits as nonexistent; when we come to them we'll mark
117.  	 * them as existing (using goodfruit())
118.  	 */
119.  	for(f=ffruit; f; f=f->nextf) f->fid = -f->fid;
120.  
121.  	/* drop everything; the corpse's possessions are usually cursed */
122.  	otmp = invent;
123.  	while(otmp) {
124.  		otmp->ox = u.ux;
125.  		otmp->oy = u.uy;
126.  		otmp->owornmask = 0;
127.  		if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
128.  		if(rn2(5)) curse(otmp);
129.  		if(!otmp->nobj){
130.  			otmp->nobj = fobj;
131.  			fobj = invent;
132.  			invent = 0;	/* superfluous */
133.  			levl[u.ux][u.uy].omask = 1;
134.  			break;
135.  		}
136.  		otmp = otmp->nobj;
137.  	}
138.  	if (u.ugrave_arise == -1) {
139.  		if(!(mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy))) return;
140.  		Strcpy((char *) mtmp->mextra, plname);
141.  	} else {
142.  		in_mklev = TRUE;
143.  	/* tricks makemon() into allowing monster creation on your square */
144.  		mons[u.ugrave_arise].pxlth += strlen(plname);
145.  		mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy);
146.  		mons[u.ugrave_arise].pxlth -= strlen(plname);
147.  		in_mklev = FALSE;
148.  		if (!mtmp) return;
149.  		Strcpy(NAME(mtmp), plname);
150.  		mtmp->mnamelth = strlen(plname);
151.  		atl(u.ux, u.uy, mtmp->data->mlet);
152.  		Your("body rises from the dead as a%s %s...",
153.  			index(vowels, *(mons[u.ugrave_arise].mname)) ? "n" : "",
154.  			mons[u.ugrave_arise].mname);
155.  	}
156.  	mtmp->m_lev = (u.ulevel ? u.ulevel : 1);
157.  	mtmp->mhp = mtmp->mhpmax = u.uhpmax;
158.  	mtmp->msleep = 1;
159.  	if(u.ugold) mkgold(u.ugold, u.ux, u.uy);
160.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
161.  		for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj) {
162.  		    otmp->dknown = otmp->bknown = 0;
163.  		    if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
164.  		    if(uses_known(otmp)) otmp->known = 0;
165.  		    if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) {
166.  			otmp->spe = -1;  /* no longer the actual amulet */
167.  			curse(otmp);
168.  		    }
169.  		}
170.  		mtmp->m_id = 0;
171.  		mtmp->mlstmv = 0L;
172.  		if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0;
173.  		if(mtmp->mdispl) unpmon(mtmp);
174.  	}
175.  	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
176.  		ttmp->tseen = 0;
177.  
178.  	for(otmp = fobj; otmp; otmp = otmp->nobj)  {
179.  
180.  		otmp->o_id = 0;
181.  		if (((otmp->otyp != CORPSE && otmp->otyp != STATUE)
182.  				|| otmp->corpsenm < PM_ARCHEOLOGIST)
183.  #ifdef NAMED_ITEMS
184.  				&& !is_artifact(otmp)
185.  #endif
186.  		   )
187.  			otmp->onamelth = 0;
188.  		if(uses_known(otmp)) otmp->known = 0;
189.  		if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
190.  		otmp->dknown = otmp->bknown = 0;
191.  		otmp->invlet = 0;
192.  #ifdef MAIL
193.  		if (otmp->otyp == SCR_MAIL)
194.  			otmp->spe = 1;
195.  #endif
196.  #ifdef POLYSELF
197.  		if (otmp->otyp == EGG)
198.  			otmp->spe = 0;
199.  #endif
200.  		if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) {
201.  			otmp->spe = -1;      /* no longer the actual amulet */
202.  			curse(otmp);
203.  		}
204.  	}
205.  
206.  	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
207.  		levl[x][y].seen = levl[x][y].new = levl[x][y].scrsym = 0;
208.  
209.  #ifdef MSDOS
210.  	fd = open(bones, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK);
211.  #else
212.  	fd = creat(bones, FCMASK);
213.  #endif
214.  	if(fd < 0) {
215.  #ifdef WIZARD
216.  		if(wizard)
217.  			pline("Cannot create bones file - creat failed");
218.  #endif
219.  		return;
220.  	}
221.  	savefruitchn(fd);
222.  #ifdef DGK
223.  	savelev(fd,dlevel, COUNT | WRITE);
224.  #else
225.  	savelev(fd,dlevel);
226.  #endif
227.  #ifdef ZEROCOMP
228.  	bflush(fd);
229.  #endif
230.  	(void) close(fd);
231.  #ifdef COMPRESS
232.  	compress_bones();
233.  #endif
234.  }
235.  
236.  int
237.  getbones() {
238.  	register int fd;
239.  	register int ok;
240.  
241.  	/* wizard check added by GAN 02/05/87 */
242.  	if(rn2(3)	/* only once in three times do we find bones */
243.  #ifdef WIZARD
244.  		&& !wizard
245.  #endif
246.  		) return(0);
247.  	if(no_bones_level(dlevel)) return(0);
248.  	name_file(bones, dlevel);
249.  #ifdef COMPRESS
250.  	if((fd = open(bones, OMASK)) >= 0) goto gotbones;
251.  	Strcpy(proxy, bones);
252.  	Strcat(proxy, ".Z");
253.  	if((fd = open(proxy, OMASK)) < 0) return(0);
254.  	else {
255.  	    (void) close(fd);
256.  	    Strcpy(cmd, COMPRESS);
257.  	    Strcat(cmd, " -d ");	/* uncompress */
258.  # ifdef COMPRESS_OPTIONS
259.  	    Strcat(cmd, COMPRESS_OPTIONS);
260.  	    Strcat(cmd, " ");
261.  # endif
262.  	    Strcat(cmd,proxy);
263.  	    (void) system(cmd);
264.  	}
265.  #endif
266.  	if((fd = open(bones, OMASK)) < 0) return(0);
267.  #ifdef COMPRESS
268.  gotbones:
269.  #endif
270.  	if((ok = uptodate(fd)) != 0){
271.  #ifdef WIZARD
272.  		if(wizard)  {
273.  			pline("Get bones? ");
274.  			if(yn() == 'n') {
275.  				(void) close(fd);
276.  # ifdef COMPRESS
277.  				compress_bones();
278.  # endif
279.  				return(0);
280.  			}
281.  		}
282.  #endif
283.  #ifdef ZEROCOMP
284.  		minit();
285.  #endif
286.  		getlev(fd, 0, dlevel, TRUE);
287.  	}
288.  	(void) close(fd);
289.  #ifdef WIZARD
290.  	if(wizard) {
291.  		pline("Unlink bones? ");
292.  		if(yn() == 'n') {
293.  # ifdef COMPRESS
294.  			compress_bones();
295.  # endif
296.  			return(ok);
297.  		}
298.  	}
299.  #endif
300.  	if(unlink(bones) < 0){
301.  		pline("Cannot unlink %s.", bones);
302.  		return(0);
303.  	}
304.  	return(ok);
305.  }
306.  
307.  /* construct the string  file.level 
308.   * This assumes there is space on the end of 'file' to append
309.   * a two digit number.  This is true for 'bones' and 'level'
310.   * but be careful if you use it for other things -dgk
311.   */
312.  void
313.  name_file(file, level)
314.  char *file;
315.  int level;
316.  {
317.  	char *tf;
318.  
319.  	if (tf = rindex(file, '.'))
320.  	    Sprintf(tf+1, "%d", level);
321.  #ifdef MSDOS /* for glo() */
322.  	else if (tf = eos(file))
323.  	    Sprintf(tf, ".%d", level);
324.  #endif
325.  	return;
326.  }