Fandom

Wikihack

Source:SLASH'EM 0.0.7E7F2/questpgr.c

2,035pages on
this wiki
Add New Page
Talk0

Below is the full text to questpgr.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/questpgr.c#line123]], for example.

The latest source code for vanilla NetHack is at Source code.


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

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.