Source:NetHack 3.0.0/mail.c
Revision as of 04:49, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/mail.c moved to Source:NetHack 3.0.0/mail.c: Robot: moved page)
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.
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: @(#)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 */