Fandom

Wikihack

Source:NetHack 3.3.0/questpgr.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 questpgr.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.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.
1.    /*	SCCS Id: @(#)questpgr.c	3.3	1999/11/26	*/
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.  boolean
213.  leaderless()	/* return true iff leader is dead */
214.  {
215.  	int i = urole.ldrnum;
216.  	/* BUG: This doesn't take the possibility of resurrection
217.  		via wand or spell of undead turning into account. */
218.  	return (boolean)(mvitals[i].died > 0);
219.  }
220.  
221.  STATIC_OVL struct qtmsg *
222.  msg_in(qtm_list, msgnum)
223.  struct qtmsg *qtm_list;
224.  int	msgnum;
225.  {
226.  	struct qtmsg *qt_msg;
227.  
228.  	for (qt_msg = qtm_list; qt_msg->msgnum > 0; qt_msg++)
229.  	    if (qt_msg->msgnum == msgnum) return(qt_msg);
230.  
231.  	return((struct qtmsg *)0);
232.  }
233.  
234.  STATIC_OVL void
235.  convert_arg(c)
236.  char c;
237.  {
238.  	register const char *str;
239.  
240.  	switch (c) {
241.  
242.  	    case 'p':	str = plname;
243.  			break;
244.  	    case 'c':	str = (flags.female && urole.name.f) ?
245.  	    			urole.name.f : urole.name.m;
246.  			break;
247.  	    case 'r':	str = rank_of(u.ulevel, Role_switch, flags.female);
248.  			break;
249.  	    case 'R':	str = rank_of(MIN_QUEST_LEVEL, Role_switch,
250.  	    			flags.female);
251.  			break;
252.  	    case 's':	str = (flags.female) ? "sister" : "brother";
253.  			break;
254.  	    case 'S':	str = (flags.female) ? "daughter" : "son";
255.  			break;
256.  	    case 'l':	str = ldrname();
257.  			break;
258.  	    case 'i':	str = intermed();
259.  			break;
260.  	    case 'o':	str = the(artiname(urole.questarti));
261.  			break;
262.  	    case 'n':	str = neminame();
263.  			break;
264.  	    case 'g':	str = guardname();
265.  			break;
266.  	    case 'G':	str = align_gtitle(u.ualignbase[1]);
267.  			break;
268.  	    case 'H':	str = homebase();
269.  			break;
270.  	    case 'a':	str = align_str(u.ualignbase[1]);
271.  			break;
272.  	    case 'A':	str = align_str(u.ualign.type);
273.  			break;
274.  	    case 'd':	str = align_gname(u.ualignbase[1]);
275.  			break;
276.  	    case 'D':	str = align_gname(A_LAWFUL);
277.  			break;
278.  	    case 'C':	str = "chaotic";
279.  			break;
280.  	    case 'N':	str = "neutral";
281.  			break;
282.  	    case 'L':	str = "lawful";
283.  			break;
284.  	    case 'x':	str = Blind ? "sense" : "see";
285.  			break;
286.  	    case 'Z':	str = dungeons[0].dname;
287.  			break;
288.  	    case '%':	str = "%";
289.  			break;
290.  	     default:	str = "";
291.  			break;
292.  	}
293.  	Strcpy(cvt_buf, str);
294.  }
295.  
296.  STATIC_OVL void
297.  convert_line()
298.  {
299.  	char *c, *cc;
300.  	char xbuf[BUFSZ];
301.  
302.  	cc = out_line;
303.  	for (c = xcrypt(in_line, xbuf); *c; c++) {
304.  
305.  	    *cc = 0;
306.  	    switch(*c) {
307.  
308.  		case '\r':
309.  		case '\n':
310.  			*(++cc) = 0;
311.  			return;
312.  
313.  		case '%':
314.  			if (*(c+1)) {
315.  			    convert_arg(*(++c));
316.  			    switch (*(++c)) {
317.  
318.  					/* insert "a"/"an" prefix */
319.  				case 'A': Strcat(cc, An(cvt_buf));
320.  				    cc += strlen(cc);
321.  				    continue; /* for */
322.  				case 'a': Strcat(cc, an(cvt_buf));
323.  				    cc += strlen(cc);
324.  				    continue; /* for */
325.  
326.  					/* capitalize */
327.  				case 'C': cvt_buf[0] = highc(cvt_buf[0]);
328.  				    break;
329.  
330.  					/* pluralize */
331.  				case 'P': cvt_buf[0] = highc(cvt_buf[0]);
332.  				case 'p': Strcpy(cvt_buf, makeplural(cvt_buf));
333.  				    break;
334.  
335.  					/* append possessive suffix */
336.  				case 'S': cvt_buf[0] = highc(cvt_buf[0]);
337.  				case 's': Strcpy(cvt_buf, s_suffix(cvt_buf));
338.  				    break;
339.  
340.  					/* strip any "the" prefix */
341.  				case 't': if (!strncmpi(cvt_buf, "the ", 4)) {
342.  					Strcat(cc, &cvt_buf[4]);
343.  					cc += strlen(cc);
344.  					continue; /* for */
345.  				    }
346.  				    break;
347.  
348.  				default: --c;	/* undo switch increment */
349.  				    break;
350.  			    }
351.  			    Strcat(cc, cvt_buf);
352.  			    cc += strlen(cvt_buf);
353.  			    break;
354.  			}	/* else fall through */
355.  
356.  		default:
357.  			*cc++ = *c;
358.  			break;
359.  	    }
360.  	}
361.  	if (cc >= out_line + sizeof out_line)
362.  	    panic("convert_line: overflow");
363.  	*cc = 0;
364.  	return;
365.  }
366.  
367.  STATIC_OVL void
368.  deliver_by_pline(qt_msg)
369.  struct qtmsg *qt_msg;
370.  {
371.  	long	size;
372.  
373.  	for (size = 0; size < qt_msg->size; size += (long)strlen(in_line)) {
374.  	    (void) dlb_fgets(in_line, 80, msg_file);
375.  	    convert_line();
376.  	    pline(out_line);
377.  	}
378.  
379.  }
380.  
381.  STATIC_OVL void
382.  deliver_by_window(qt_msg, how)
383.  struct qtmsg *qt_msg;
384.  int how;
385.  {
386.  	long	size;
387.  	winid datawin = create_nhwindow(how);
388.  
389.  	for (size = 0; size < qt_msg->size; size += (long)strlen(in_line)) {
390.  	    (void) dlb_fgets(in_line, 80, msg_file);
391.  	    convert_line();
392.  	    putstr(datawin, 0, out_line);
393.  	}
394.  	display_nhwindow(datawin, TRUE);
395.  	destroy_nhwindow(datawin);
396.  }
397.  
398.  void
399.  com_pager(msgnum)
400.  int	msgnum;
401.  {
402.  	struct qtmsg *qt_msg;
403.  
404.  	if (!(qt_msg = msg_in(qt_list.common, msgnum))) {
405.  		impossible("com_pager: message %d not found.", msgnum);
406.  		return;
407.  	}
408.  
409.  	(void) dlb_fseek(msg_file, qt_msg->offset, SEEK_SET);
410.  	if (qt_msg->delivery == 'p') deliver_by_pline(qt_msg);
411.  	else if (msgnum == 1) deliver_by_window(qt_msg, NHW_MENU);
412.  	else		     deliver_by_window(qt_msg, NHW_TEXT);
413.  	return;
414.  }
415.  
416.  void
417.  qt_pager(msgnum)
418.  int	msgnum;
419.  {
420.  	struct qtmsg *qt_msg;
421.  
422.  	if (!(qt_msg = msg_in(qt_list.chrole, msgnum))) {
423.  		impossible("qt_pager: message %d not found.", msgnum);
424.  		return;
425.  	}
426.  
427.  	(void) dlb_fseek(msg_file, qt_msg->offset, SEEK_SET);
428.  	if (qt_msg->delivery == 'p' && strcmp(windowprocs.name, "X11"))
429.  		deliver_by_pline(qt_msg);
430.  	else	deliver_by_window(qt_msg, NHW_TEXT);
431.  	return;
432.  }
433.  
434.  struct permonst *
435.  qt_montype()
436.  {
437.  	int qpm;
438.  
439.  	if (rn2(5)) {
440.  	    qpm = urole.enemy1num;
441.  	    if (qpm != NON_PM && rn2(5) && !(mvitals[qpm].mvflags & G_GENOD))
442.  	    	return (&mons[qpm]);
443.  	    return (mkclass(urole.enemy1sym, 0));
444.  	}
445.  	qpm = urole.enemy2num;
446.  	if (qpm != NON_PM && rn2(5) && !(mvitals[qpm].mvflags & G_GENOD))
447.  	    return (&mons[qpm]);
448.  	return (mkclass(urole.enemy2sym, 0));
449.  }
450.  
451.  /*questpgr.c*/

Also on Fandom

Random Wiki