Difference between revisions of "Source:NetHack 3.4.3/src/questpgr.c"

From NetHackWiki
Jump to navigation Jump to search
(add headers)
m (Questpgr.c moved to Source:Questpgr.c: Robot: moved page)
(No difference)

Revision as of 14:58, 4 March 2008

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

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.

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.

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

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

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

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

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

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

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

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

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

is_quest_artifact

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

neminame

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

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

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

msg_in

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

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

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

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

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

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

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

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