Fandom

Wikihack

Source:NetHack 3.0.0/mail.c

2,034pages on
this wiki
Add New Page
Talk0

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Below is the full text to mail.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/mail.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.
1.    /*	SCCS Id: @(#)mail.c	3.0	89/07/07
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    /* block some unused #defines to avoid overloading some cpp's */
6.    #define MONATTK_H
7.    #include "hack.h"	/* mainly for index() which depends on BSD */
8.    
9.    #ifdef MAIL
10.   
11.   # ifdef UNIX
12.   #include <sys/stat.h>
13.   # endif
14.   
15.   /*
16.    * Notify user when new mail has arrived. [Idea from Merlyn Leroy, but
17.    * I don't know the details of his implementation.]
18.    * { Later note: he disliked my calling a general mailreader and felt that
19.    *   hack should do the paging itself. But when I get mail, I want to put it
20.    *   in some folder, reply, etc. - it would be unreasonable to put all these
21.    *   functions in hack. }
22.    * The motion of the mail daemon is less restrained than usual:
23.    * diagonal moves from a DOOR are possible. He might also use SDOOR's. Also,
24.    * the mail daemon is visible in a ROOM, even when you are Blind.
25.    * Its path should be longer when you are Telepat-hic and Blind.
26.    *
27.    * Possible extensions:
28.    *	- Open the file MAIL and do fstat instead of stat for efficiency.
29.    *	  (But sh uses stat, so this cannot be too bad.)
30.    *	- Examine the mail and produce a scroll of mail named "From somebody".
31.    *	- Invoke MAILREADER in such a way that only this single letter is read.
32.    *	- Do something to the text when the scroll is enchanted or cancelled.
33.    */
34.   
35.   /*
36.    * { Note by Olaf Seibert: On the Amiga, we usually don't get mail.
37.    *   So we go through most of the effects at 'random' moments. }
38.    */
39.   
40.   /*
41.    * I found many bugs in this code, some dating back to Hack.
42.    * Here are some minor problems i didn't fix:  -3.
43.    *
44.    *	- The code sometimes pops up the mail daemon next to you on
45.    *	  the corridor side of doorways when there are open spaces in
46.    *	  the room.
47.    *	- It may also do this with adjoining castle rooms.
48.    */
49.   
50.   # ifdef AMIGA
51.   int mustgetmail = -1;
52.   # endif
53.   
54.   # ifdef UNIX
55.   static struct stat omstat,nmstat;
56.   static char *mailbox;
57.   static long laststattime;
58.   
59.   void
60.   getmailstatus() {
61.   	if(!(mailbox = getenv("MAIL")))
62.   		return;
63.   	if(stat(mailbox, &omstat)){
64.   #  ifdef PERMANENT_MAILBOX
65.   		pline("Cannot get status of MAIL=%s .", mailbox);
66.   		mailbox = 0;
67.   #  else
68.   		omstat.st_mtime = 0;
69.   #  endif
70.   	}
71.   }
72.   # endif /* UNIX */
73.   
74.   /* make md run through the cave */
75.   static void
76.   mdrush(md,away)
77.   register struct monst *md;
78.   boolean away;
79.   {
80.   	register int uroom = inroom(u.ux, u.uy);
81.   	if(uroom >= 0 && inroom(md->mx,md->my) == uroom) {
82.   		register int tmp = rooms[uroom].fdoor;
83.   		register int cnt = rooms[uroom].doorct;
84.   		register int fx = u.ux, fy = u.uy;
85.   		while(cnt--) {
86.   			if(dist(fx,fy) < dist(doors[tmp].x, doors[tmp].y)){
87.   				fx = doors[tmp].x;
88.   				fy = doors[tmp].y;
89.   			}
90.   			tmp++;
91.   		}
92.   		if (has_dnstairs(&rooms[uroom]))
93.   			if(dist(fx,fy) < dist(xdnstair, ydnstair)){
94.   				fx = xdnstair;
95.   				fy = ydnstair;
96.   			}
97.   		if (has_upstairs(&rooms[uroom]))
98.   			if(dist(fx,fy) < dist(xupstair, yupstair)){
99.   				fx = xupstair;
100.  				fy = yupstair;
101.  			}
102.  		tmp_at(-1, md->data->mlet);	/* open call */
103.  		tmp_at(-3, (int)AT_MON);
104.  		if(away) {	/* interchange origin and destination */
105.  			unpmon(md);
106.  			levl[md->mx][md->my].mmask = 0;
107.  			levl[fx][fy].mmask = 1;
108.  			tmp = fx; fx = md->mx; md->mx = tmp;
109.  			tmp = fy; fy = md->my; md->my = tmp;
110.  		}
111.  		while(fx != md->mx || fy != md->my) {
112.  			register int dx,dy,nfx = fx,nfy = fy,d1,d2;
113.  
114.  			tmp_at(fx,fy);
115.  			d1 = dist2(fx,fy,md->mx,md->my);
116.  			for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
117.  			    if((dx || dy) && 
118.  			       !IS_STWALL(levl[fx+dx][fy+dy].typ)) {
119.  				d2 = dist2(fx+dx,fy+dy,md->mx,md->my);
120.  				if(d2 < d1) {
121.  				    d1 = d2;
122.  				    nfx = fx+dx;
123.  				    nfy = fy+dy;
124.  				}
125.  			    }
126.  			if(nfx != fx || nfy != fy) {
127.  			    fx = nfx;
128.  			    fy = nfy;
129.  			} else {
130.  			    if(!away) {
131.  				levl[md->mx][md->my].mmask = 0;
132.  				levl[fx][fy].mmask = 1;
133.  				md->mx = fx;
134.  				md->my = fy;
135.  			    }
136.  			    break;
137.  			} 
138.  		}
139.  		tmp_at(-1,-1);			/* close call */
140.  	}
141.  	if(!away)
142.  		pmon(md);
143.  }
144.  
145.  static void
146.  newmail() {
147.  	/* deliver a scroll of mail */
148.  	register boolean invload =
149.  	((inv_weight() + (int)objects[SCR_MAIL].oc_weight) > 0 ||
150.  	 inv_cnt() >= 52 || Fumbling);
151.  	register struct monst *md = 
152.  	makemon(&mons[PM_MAIL_DAEMON], u.ux, u.uy);
153.  
154.  	if(!md)	return;
155.  
156.  	mdrush(md,0);
157.  
158.  	pline("\"Hello, %s!  I have some mail for you.\"", plname);
159.  
160.  	if(dist(md->mx,md->my) > 2)
161.  		verbalize("Catch!");
162.  	more();
163.  	if(invload) {
164.  		struct obj *obj = mksobj_at(SCR_MAIL,u.ux,u.uy);
165.  		obj->known = obj->dknown = TRUE;
166.  		makeknown(SCR_MAIL);
167.  		stackobj(fobj);		
168.  		verbalize("Oops!");
169.  		more();
170.  	} else {
171.  		/* set known and do prinv() */
172.  		(void) identify(addinv(mksobj(SCR_MAIL,FALSE)));
173.  	}
174.  
175.  	/* disappear again */
176.  	mdrush(md,1);
177.  	mongone(md);
178.  
179.  	/* force the graphics character set off */
180.  	nscr();
181.  }
182.  
183.  # ifdef AMIGA
184.  void
185.  ckmailstatus() {
186.  	if (mustgetmail < 0)
187.  	    return;
188.  	if (--mustgetmail <= 0) {
189.  		newmail();
190.  		mustgetmail = -1;
191.  	}
192.  }
193.  
194.  void
195.  readmail()
196.  {
197.  	pline("It says: \"How nice to get a letter down here!\"");
198.  }
199.  # endif /* AMIGA */
200.  
201.  # ifdef UNIX
202.  void
203.  ckmailstatus() {
204.  	if(!mailbox
205.  #  ifdef MAILCKFREQ
206.  		    || moves < laststattime + MAILCKFREQ
207.  #  endif
208.  							)
209.  		return;
210.  
211.  	laststattime = moves;
212.  	if(stat(mailbox, &nmstat)){
213.  #  ifdef PERMANENT_MAILBOX
214.  		pline("Cannot get status of MAIL=%s anymore.", mailbox);
215.  		mailbox = 0;
216.  #  else
217.  		nmstat.st_mtime = 0;
218.  #  endif
219.  	} else if(nmstat.st_mtime > omstat.st_mtime) {
220.  		if(nmstat.st_size)
221.  			newmail();
222.  		getmailstatus();	/* might be too late ... */
223.  	}
224.  }
225.  
226.  void
227.  readmail() {
228.  #  ifdef DEF_MAILREADER			/* This implies that UNIX is defined */
229.  	register char *mr = 0;
230.  	more();
231.  	if(!(mr = getenv("MAILREADER")))
232.  		mr = DEF_MAILREADER;
233.  	if(child(1)){
234.  		(void) execl(mr, mr, NULL);
235.  		exit(1);
236.  	}
237.  #  else
238.  	(void) page_file(mailbox, FALSE);
239.  #  endif
240.  	/* get new stat; not entirely correct: there is a small time
241.  	   window where we do not see new mail */
242.  	getmailstatus();
243.  }
244.  # endif /* UNIX */
245.  
246.  #endif /* MAIL */

Also on Fandom

Random Wiki