Wikia

Wikihack

Source:Questpgr.c

2,032pages on
this wiki
Talk0

Below is the full text to src/questpgr.c from NetHack 3.4.3. To link to a particular line, write [[questpgr.c#line123]], for example.

Top of file Edit

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.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
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.   

dump_qtlist Edit

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.   

Fread Edit

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! Expected %d bytes, got %d",
64.   		    (size * nitems), (size * cnt));
65.   	}
66.   }
67.   

construct_qtlist Edit

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.   

load_qtlist Edit

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("CANNOT 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.  

unload_qtlist Edit

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.  

quest_info Edit

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.  

ldrname Edit

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.  

intermed Edit

174.  STATIC_OVL const char *
175.  intermed()	/* return your intermediate target string */
176.  {
177.  	return (urole.intermed);
178.  }
179.  

is_quest_artifact Edit

180.  boolean
181.  is_quest_artifact(otmp)
182.  struct obj *otmp;
183.  {
184.  	return((boolean)(otmp->oartifact == urole.questarti));
185.  }
186.  

neminame Edit

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.  

guardname Edit

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.  

homebase Edit

206.  STATIC_OVL const char *
207.  homebase()	/* return your role leader's location */
208.  {
209.  	return(urole.homebase);
210.  }
211.  

msg_in Edit

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.  

convert_arg Edit

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.  

convert_line Edit

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.  

deliver_by_pline Edit

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.  

deliver_by_window Edit

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.  

com_pager Edit

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.  

qt_pager Edit

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.  

qt_montype Edit

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*/

Around Wikia's network

Random Wiki