Difference between revisions of "Source:NetHack 3.4.0/questpgr.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 3.4.0/questpgr.c moved to Source:NetHack 3.4.0/questpgr.c: Robot: moved page) |
(No difference)
|
Latest revision as of 13:49, 4 March 2008
Below is the full text to questpgr.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/questpgr.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: @(#)questpgr.c 3.4 2000/05/05 */ 2. /* Copyright 1991, M. Stephenson */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "dlb.h" 7. 8. /* quest-specific pager routines. */ 9. 10. #include "qtext.h" 11. 12. #define QTEXT_FILE "quest.dat" 13. 14. /* #define DEBUG */ /* uncomment for debugging */ 15. 16. static void FDECL(Fread, (genericptr_t,int,int,dlb *)); 17. STATIC_DCL struct qtmsg * FDECL(construct_qtlist, (long)); 18. STATIC_DCL const char * NDECL(intermed); 19. STATIC_DCL const char * NDECL(neminame); 20. STATIC_DCL const char * NDECL(guardname); 21. STATIC_DCL const char * NDECL(homebase); 22. STATIC_DCL struct qtmsg * FDECL(msg_in, (struct qtmsg *,int)); 23. STATIC_DCL void FDECL(convert_arg, (CHAR_P)); 24. STATIC_DCL void NDECL(convert_line); 25. STATIC_DCL void FDECL(deliver_by_pline, (struct qtmsg *)); 26. STATIC_DCL void FDECL(deliver_by_window, (struct qtmsg *,int)); 27. 28. static char in_line[80], cvt_buf[64], out_line[128]; 29. static struct qtlists qt_list; 30. static dlb *msg_file; 31. /* used by ldrname() and neminame(), then copied into cvt_buf */ 32. static char nambuf[sizeof cvt_buf]; 33. 34. #ifdef DEBUG 35. static void NDECL(dump_qtlist); 36. 37. static void 38. dump_qtlist() /* dump the character msg list to check appearance */ 39. { 40. struct qtmsg *msg; 41. long size; 42. 43. for (msg = qt_list.chrole; msg->msgnum > 0; msg++) { 44. pline("msgnum %d: delivery %c", 45. msg->msgnum, msg->delivery); 46. more(); 47. (void) dlb_fseek(msg_file, msg->offset, SEEK_SET); 48. deliver_by_window(msg, NHW_TEXT); 49. } 50. } 51. #endif /* DEBUG */ 52. 53. static void 54. Fread(ptr, size, nitems, stream) 55. genericptr_t ptr; 56. int size, nitems; 57. dlb *stream; 58. { 59. int cnt; 60. 61. if ((cnt = dlb_fread(ptr, size, nitems, stream)) != nitems) { 62. 63. panic("PREMATURE EOF ON QUEST TEXT FILE!\nExpected %d bytes - got %d\n", 64. (size * nitems), (size * cnt)); 65. } 66. } 67. 68. STATIC_OVL struct qtmsg * 69. construct_qtlist(hdr_offset) 70. long hdr_offset; 71. { 72. struct qtmsg *msg_list; 73. int n_msgs; 74. 75. (void) dlb_fseek(msg_file, hdr_offset, SEEK_SET); 76. Fread(&n_msgs, sizeof(int), 1, msg_file); 77. msg_list = (struct qtmsg *) 78. alloc((unsigned)(n_msgs+1)*sizeof(struct qtmsg)); 79. 80. /* 81. * Load up the list. 82. */ 83. Fread((genericptr_t)msg_list, n_msgs*sizeof(struct qtmsg), 1, msg_file); 84. 85. msg_list[n_msgs].msgnum = -1; 86. return(msg_list); 87. } 88. 89. void 90. load_qtlist() 91. { 92. 93. int n_classes, i; 94. char qt_classes[N_HDR][LEN_HDR]; 95. long qt_offsets[N_HDR]; 96. 97. msg_file = dlb_fopen(QTEXT_FILE, RDBMODE); 98. if (!msg_file) 99. panic("\rCANNOT OPEN QUEST TEXT FILE %s.", QTEXT_FILE); 100. 101. /* 102. * Read in the number of classes, then the ID's & offsets for 103. * each header. 104. */ 105. 106. Fread(&n_classes, sizeof(int), 1, msg_file); 107. Fread(&qt_classes[0][0], sizeof(char)*LEN_HDR, n_classes, msg_file); 108. Fread(qt_offsets, sizeof(long), n_classes, msg_file); 109. 110. /* 111. * Now construct the message lists for quick reference later 112. * on when we are actually paging the messages out. 113. */ 114. 115. qt_list.common = qt_list.chrole = (struct qtmsg *)0; 116. 117. for (i = 0; i < n_classes; i++) { 118. if (!strncmp(COMMON_ID, qt_classes[i], LEN_HDR)) 119. qt_list.common = construct_qtlist(qt_offsets[i]); 120. else if (!strncmp(urole.filecode, qt_classes[i], LEN_HDR)) 121. qt_list.chrole = construct_qtlist(qt_offsets[i]); 122. #if 0 /* UNUSED but available */ 123. else if (!strncmp(urace.filecode, qt_classes[i], LEN_HDR)) 124. qt_list.chrace = construct_qtlist(qt_offsets[i]); 125. #endif 126. } 127. 128. if (!qt_list.common || !qt_list.chrole) 129. impossible("load_qtlist: cannot load quest text."); 130. #ifdef DEBUG 131. dump_qtlist(); 132. #endif 133. return; /* no ***DON'T*** close the msg_file */ 134. } 135. 136. /* called at program exit */ 137. void 138. unload_qtlist() 139. { 140. if (msg_file) 141. (void) dlb_fclose(msg_file), msg_file = 0; 142. if (qt_list.common) 143. free((genericptr_t) qt_list.common), qt_list.common = 0; 144. if (qt_list.chrole) 145. free((genericptr_t) qt_list.chrole), qt_list.chrole = 0; 146. return; 147. } 148. 149. short 150. quest_info(typ) 151. int typ; 152. { 153. switch (typ) { 154. case 0: return (urole.questarti); 155. case MS_LEADER: return (urole.ldrnum); 156. case MS_NEMESIS: return (urole.neminum); 157. case MS_GUARDIAN: return (urole.guardnum); 158. default: impossible("quest_info(%d)", typ); 159. } 160. return 0; 161. } 162. 163. const char * 164. ldrname() /* return your role leader's name */ 165. { 166. int i = urole.ldrnum; 167. 168. Sprintf(nambuf, "%s%s", 169. type_is_pname(&mons[i]) ? "" : "the ", 170. mons[i].mname); 171. return nambuf; 172. } 173. 174. STATIC_OVL const char * 175. intermed() /* return your intermediate target string */ 176. { 177. return (urole.intermed); 178. } 179. 180. boolean 181. is_quest_artifact(otmp) 182. struct obj *otmp; 183. { 184. return((boolean)(otmp->oartifact == urole.questarti)); 185. } 186. 187. STATIC_OVL const char * 188. neminame() /* return your role nemesis' name */ 189. { 190. int i = urole.neminum; 191. 192. Sprintf(nambuf, "%s%s", 193. type_is_pname(&mons[i]) ? "" : "the ", 194. mons[i].mname); 195. return nambuf; 196. } 197. 198. STATIC_OVL const char * 199. guardname() /* return your role leader's guard monster name */ 200. { 201. int i = urole.guardnum; 202. 203. return(mons[i].mname); 204. } 205. 206. STATIC_OVL const char * 207. homebase() /* return your role leader's location */ 208. { 209. return(urole.homebase); 210. } 211. 212. STATIC_OVL struct qtmsg * 213. msg_in(qtm_list, msgnum) 214. struct qtmsg *qtm_list; 215. int msgnum; 216. { 217. struct qtmsg *qt_msg; 218. 219. for (qt_msg = qtm_list; qt_msg->msgnum > 0; qt_msg++) 220. if (qt_msg->msgnum == msgnum) return(qt_msg); 221. 222. return((struct qtmsg *)0); 223. } 224. 225. STATIC_OVL void 226. convert_arg(c) 227. char c; 228. { 229. register const char *str; 230. 231. switch (c) { 232. 233. case 'p': str = plname; 234. break; 235. case 'c': str = (flags.female && urole.name.f) ? 236. urole.name.f : urole.name.m; 237. break; 238. case 'r': str = rank_of(u.ulevel, Role_switch, flags.female); 239. break; 240. case 'R': str = rank_of(MIN_QUEST_LEVEL, Role_switch, 241. flags.female); 242. break; 243. case 's': str = (flags.female) ? "sister" : "brother"; 244. break; 245. case 'S': str = (flags.female) ? "daughter" : "son"; 246. break; 247. case 'l': str = ldrname(); 248. break; 249. case 'i': str = intermed(); 250. break; 251. case 'o': str = the(artiname(urole.questarti)); 252. break; 253. case 'n': str = neminame(); 254. break; 255. case 'g': str = guardname(); 256. break; 257. case 'G': str = align_gtitle(u.ualignbase[A_ORIGINAL]); 258. break; 259. case 'H': str = homebase(); 260. break; 261. case 'a': str = align_str(u.ualignbase[A_ORIGINAL]); 262. break; 263. case 'A': str = align_str(u.ualign.type); 264. break; 265. case 'd': str = align_gname(u.ualignbase[A_ORIGINAL]); 266. break; 267. case 'D': str = align_gname(A_LAWFUL); 268. break; 269. case 'C': str = "chaotic"; 270. break; 271. case 'N': str = "neutral"; 272. break; 273. case 'L': str = "lawful"; 274. break; 275. case 'x': str = Blind ? "sense" : "see"; 276. break; 277. case 'Z': str = dungeons[0].dname; 278. break; 279. case '%': str = "%"; 280. break; 281. default: str = ""; 282. break; 283. } 284. Strcpy(cvt_buf, str); 285. } 286. 287. STATIC_OVL void 288. convert_line() 289. { 290. char *c, *cc; 291. char xbuf[BUFSZ]; 292. 293. cc = out_line; 294. for (c = xcrypt(in_line, xbuf); *c; c++) { 295. 296. *cc = 0; 297. switch(*c) { 298. 299. case '\r': 300. case '\n': 301. *(++cc) = 0; 302. return; 303. 304. case '%': 305. if (*(c+1)) { 306. convert_arg(*(++c)); 307. switch (*(++c)) { 308. 309. /* insert "a"/"an" prefix */ 310. case 'A': Strcat(cc, An(cvt_buf)); 311. cc += strlen(cc); 312. continue; /* for */ 313. case 'a': Strcat(cc, an(cvt_buf)); 314. cc += strlen(cc); 315. continue; /* for */ 316. 317. /* capitalize */ 318. case 'C': cvt_buf[0] = highc(cvt_buf[0]); 319. break; 320. 321. /* pluralize */ 322. case 'P': cvt_buf[0] = highc(cvt_buf[0]); 323. case 'p': Strcpy(cvt_buf, makeplural(cvt_buf)); 324. break; 325. 326. /* append possessive suffix */ 327. case 'S': cvt_buf[0] = highc(cvt_buf[0]); 328. case 's': Strcpy(cvt_buf, s_suffix(cvt_buf)); 329. break; 330. 331. /* strip any "the" prefix */ 332. case 't': if (!strncmpi(cvt_buf, "the ", 4)) { 333. Strcat(cc, &cvt_buf[4]); 334. cc += strlen(cc); 335. continue; /* for */ 336. } 337. break; 338. 339. default: --c; /* undo switch increment */ 340. break; 341. } 342. Strcat(cc, cvt_buf); 343. cc += strlen(cvt_buf); 344. break; 345. } /* else fall through */ 346. 347. default: 348. *cc++ = *c; 349. break; 350. } 351. } 352. if (cc >= out_line + sizeof out_line) 353. panic("convert_line: overflow"); 354. *cc = 0; 355. return; 356. } 357. 358. STATIC_OVL void 359. deliver_by_pline(qt_msg) 360. struct qtmsg *qt_msg; 361. { 362. long size; 363. 364. for (size = 0; size < qt_msg->size; size += (long)strlen(in_line)) { 365. (void) dlb_fgets(in_line, 80, msg_file); 366. convert_line(); 367. pline(out_line); 368. } 369. 370. } 371. 372. STATIC_OVL void 373. deliver_by_window(qt_msg, how) 374. struct qtmsg *qt_msg; 375. int how; 376. { 377. long size; 378. winid datawin = create_nhwindow(how); 379. 380. for (size = 0; size < qt_msg->size; size += (long)strlen(in_line)) { 381. (void) dlb_fgets(in_line, 80, msg_file); 382. convert_line(); 383. putstr(datawin, 0, out_line); 384. } 385. display_nhwindow(datawin, TRUE); 386. destroy_nhwindow(datawin); 387. } 388. 389. void 390. com_pager(msgnum) 391. int msgnum; 392. { 393. struct qtmsg *qt_msg; 394. 395. if (!(qt_msg = msg_in(qt_list.common, msgnum))) { 396. impossible("com_pager: message %d not found.", msgnum); 397. return; 398. } 399. 400. (void) dlb_fseek(msg_file, qt_msg->offset, SEEK_SET); 401. if (qt_msg->delivery == 'p') deliver_by_pline(qt_msg); 402. else if (msgnum == 1) deliver_by_window(qt_msg, NHW_MENU); 403. else deliver_by_window(qt_msg, NHW_TEXT); 404. return; 405. } 406. 407. void 408. qt_pager(msgnum) 409. int msgnum; 410. { 411. struct qtmsg *qt_msg; 412. 413. if (!(qt_msg = msg_in(qt_list.chrole, msgnum))) { 414. impossible("qt_pager: message %d not found.", msgnum); 415. return; 416. } 417. 418. (void) dlb_fseek(msg_file, qt_msg->offset, SEEK_SET); 419. if (qt_msg->delivery == 'p' && strcmp(windowprocs.name, "X11")) 420. deliver_by_pline(qt_msg); 421. else deliver_by_window(qt_msg, NHW_TEXT); 422. return; 423. } 424. 425. struct permonst * 426. qt_montype() 427. { 428. int qpm; 429. 430. if (rn2(5)) { 431. qpm = urole.enemy1num; 432. if (qpm != NON_PM && rn2(5) && !(mvitals[qpm].mvflags & G_GENOD)) 433. return (&mons[qpm]); 434. return (mkclass(urole.enemy1sym, 0)); 435. } 436. qpm = urole.enemy2num; 437. if (qpm != NON_PM && rn2(5) && !(mvitals[qpm].mvflags & G_GENOD)) 438. return (&mons[qpm]); 439. return (mkclass(urole.enemy2sym, 0)); 440. } 441. 442. /*questpgr.c*/