OSDN Git Service

upgrade to 3.6.1
[jnethack/source.git] / src / rumors.c
1 /* NetHack 3.6  rumors.c        $NHDT-Date: 1446713640 2015/11/05 08:54:00 $  $NHDT-Branch: master $:$NHDT-Revision: 1.27 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12 #include "lev.h"
13 #include "dlb.h"
14
15 /*      [note: this comment is fairly old, but still accurate for 3.1]
16  * Rumors have been entirely rewritten to speed up the access.  This is
17  * essential when working from floppies.  Using fseek() the way that's done
18  * here means rumors following longer rumors are output more often than those
19  * following shorter rumors.  Also, you may see the same rumor more than once
20  * in a particular game (although the odds are highly against it), but
21  * this also happens with real fortune cookies.  -dgk
22  */
23
24 /*      3.6
25  * The rumors file consists of a "do not edit" line, then a line containing
26  * three sets of three counts (first two in decimal, third in hexadecimal).
27  * The first set has the number of true rumors, the count in bytes for all
28  * true rumors, and the file offset to the first one.  The second set has
29  * the same group of numbers for the false rumors.  The third set has 0 for
30  * count, 0 for size, and the file offset for end-of-file.  The offset of
31  * the first true rumor plus the size of the true rumors matches the offset
32  * of the first false rumor.  Likewise, the offset of the first false rumor
33  * plus the size of the false rumors matches the offset for end-of-file.
34  */
35
36 /*      3.1     [now obsolete for rumors but still accurate for oracles]
37  * The rumors file consists of a "do not edit" line, a hexadecimal number
38  * giving the number of bytes of useful/true rumors, followed by those
39  * true rumors (one per line), followed by the useless/false/misleading/cute
40  * rumors (also one per line).  Number of bytes of untrue rumors is derived
41  * via fseek(EOF)+ftell().
42  *
43  * The oracles file consists of a "do not edit" comment, a decimal count N
44  * and set of N+1 hexadecimal fseek offsets, followed by N multiple-line
45  * records, separated by "---" lines.  The first oracle is a special case,
46  * and placed there by 'makedefs'.
47  */
48
49 STATIC_DCL void FDECL(init_rumors, (dlb *));
50 STATIC_DCL void FDECL(init_oracles, (dlb *));
51
52 /* rumor size variables are signed so that value -1 can be used as a flag */
53 static long true_rumor_size = 0L, false_rumor_size;
54 /* rumor start offsets are unsigned because they're handled via %lx format */
55 static unsigned long true_rumor_start, false_rumor_start;
56 /* rumor end offsets are signed because they're compared with [dlb_]ftell() */
57 static long true_rumor_end, false_rumor_end;
58 /* oracles are handled differently from rumors... */
59 static int oracle_flg = 0; /* -1=>don't use, 0=>need init, 1=>init done */
60 static unsigned oracle_cnt = 0;
61 static unsigned long *oracle_loc = 0;
62
63 STATIC_OVL void
64 init_rumors(fp)
65 dlb *fp;
66 {
67     static const char rumors_header[] = "%d,%ld,%lx;%d,%ld,%lx;0,0,%lx\n";
68     int true_count, false_count; /* in file but not used here */
69     unsigned long eof_offset;
70     char line[BUFSZ];
71
72     (void) dlb_fgets(line, sizeof line, fp); /* skip "don't edit" comment */
73     (void) dlb_fgets(line, sizeof line, fp);
74     if (sscanf(line, rumors_header, &true_count, &true_rumor_size,
75                &true_rumor_start, &false_count, &false_rumor_size,
76                &false_rumor_start, &eof_offset) == 7
77         && true_rumor_size > 0L
78         && false_rumor_size > 0L) {
79         true_rumor_end = (long) true_rumor_start + true_rumor_size;
80         /* assert( true_rumor_end == false_rumor_start ); */
81         false_rumor_end = (long) false_rumor_start + false_rumor_size;
82         /* assert( false_rumor_end == eof_offset ); */
83     } else {
84         true_rumor_size = -1L; /* init failed */
85         (void) dlb_fclose(fp);
86     }
87 }
88
89 /* exclude_cookie is a hack used because we sometimes want to get rumors in a
90  * context where messages such as "You swallowed the fortune!" that refer to
91  * cookies should not appear.  This has no effect for true rumors since none
92  * of them contain such references anyway.
93  */
94 char *
95 getrumor(truth, rumor_buf, exclude_cookie)
96 int truth; /* 1=true, -1=false, 0=either */
97 char *rumor_buf;
98 boolean exclude_cookie;
99 {
100     dlb *rumors;
101     long tidbit, beginning;
102     char *endp, line[BUFSZ], xbuf[BUFSZ];
103
104     rumor_buf[0] = '\0';
105     if (true_rumor_size < 0L) /* we couldn't open RUMORFILE */
106         return rumor_buf;
107
108     rumors = dlb_fopen(RUMORFILE, "r");
109
110     if (rumors) {
111         int count = 0;
112         int adjtruth;
113
114         do {
115             rumor_buf[0] = '\0';
116             if (true_rumor_size == 0L) { /* if this is 1st outrumor() */
117                 init_rumors(rumors);
118                 if (true_rumor_size < 0L) { /* init failed */
119                     Sprintf(rumor_buf, "Error reading \"%.80s\".", RUMORFILE);
120                     return rumor_buf;
121                 }
122             }
123             /*
124              *  input:      1    0   -1
125              *   rn2 \ +1  2=T  1=T  0=F
126              *   adj./ +0  1=T  0=F -1=F
127              */
128             switch (adjtruth = truth + rn2(2)) {
129             case 2: /*(might let a bogus input arg sneak thru)*/
130             case 1:
131                 beginning = (long) true_rumor_start;
132                 tidbit = Rand() % true_rumor_size;
133                 break;
134             case 0: /* once here, 0 => false rather than "either"*/
135             case -1:
136                 beginning = (long) false_rumor_start;
137                 tidbit = Rand() % false_rumor_size;
138                 break;
139             default:
140                 impossible("strange truth value for rumor");
141                 return strcpy(rumor_buf, "Oops...");
142             }
143             (void) dlb_fseek(rumors, beginning + tidbit, SEEK_SET);
144             (void) dlb_fgets(line, sizeof line, rumors);
145             if (!dlb_fgets(line, sizeof line, rumors)
146                 || (adjtruth > 0 && dlb_ftell(rumors) > true_rumor_end)) {
147                 /* reached end of rumors -- go back to beginning */
148                 (void) dlb_fseek(rumors, beginning, SEEK_SET);
149                 (void) dlb_fgets(line, sizeof line, rumors);
150             }
151             if ((endp = index(line, '\n')) != 0)
152                 *endp = 0;
153             Strcat(rumor_buf, xcrypt(line, xbuf));
154         } while (
155             count++ < 50 && exclude_cookie
156 #if 0 /*JP*/
157             && (strstri(rumor_buf, "fortune") || strstri(rumor_buf, "pity")));
158 #else
159             && (strstri(rumor_buf, "\90è") || strstri(rumor_buf, "\82È\82ñ\82Ä\82±\82Æ\82¾")));
160 #endif
161         (void) dlb_fclose(rumors);
162         if (count >= 50)
163             impossible("Can't find non-cookie rumor?");
164         else if (!in_mklev) /* avoid exercizing wisdom for graffiti */
165             exercise(A_WIS, (adjtruth > 0));
166     } else {
167 /*JP
168         pline("Can't open rumors file!");
169 */
170         pline("rumors\83t\83@\83C\83\8b\82ª\8aJ\82¯\82È\82¢\81I");
171         true_rumor_size = -1; /* don't try to open it again */
172     }
173 /* this is safe either way, so do it always since we can't get the definition
174  * out of makedefs.c
175  */
176 #define PAD_RUMORS_TO
177 #ifdef PAD_RUMORS_TO
178     /* remove padding */
179     {
180         char *x = eos(rumor_buf) - 1;
181
182         while (x > rumor_buf && *x == '_')
183             x--;
184         *++x = '\n';
185         *x = '\0';
186     }
187 #endif
188     return rumor_buf;
189 }
190
191 /*
192  * test that the true/false rumor boundaries are valid.
193  */
194 void
195 rumor_check()
196 {
197     dlb *rumors;
198     winid tmpwin;
199     char *endp, line[BUFSZ], xbuf[BUFSZ], rumor_buf[BUFSZ];
200
201     if (true_rumor_size < 0L) { /* we couldn't open RUMORFILE */
202     no_rumors:
203         pline("rumors not accessible.");
204         return;
205     }
206
207     rumors = dlb_fopen(RUMORFILE, "r");
208
209     if (rumors) {
210         long ftell_rumor_start = 0L;
211
212         rumor_buf[0] = '\0';
213         if (true_rumor_size == 0L) { /* if this is 1st outrumor() */
214             init_rumors(rumors);
215             if (true_rumor_size < 0L)
216                 goto no_rumors; /* init failed */
217         }
218         tmpwin = create_nhwindow(NHW_TEXT);
219
220         /*
221          * reveal the values.
222          */
223
224         Sprintf(
225             rumor_buf,
226             "T start=%06ld (%06lx), end=%06ld (%06lx), size=%06ld (%06lx)",
227             (long) true_rumor_start, true_rumor_start, true_rumor_end,
228             (unsigned long) true_rumor_end, true_rumor_size,
229             (unsigned long) true_rumor_size);
230         putstr(tmpwin, 0, rumor_buf);
231
232         Sprintf(
233             rumor_buf,
234             "F start=%06ld (%06lx), end=%06ld (%06lx), size=%06ld (%06lx)",
235             (long) false_rumor_start, false_rumor_start, false_rumor_end,
236             (unsigned long) false_rumor_end, false_rumor_size,
237             (unsigned long) false_rumor_size);
238         putstr(tmpwin, 0, rumor_buf);
239
240         /*
241          * check the first rumor (start of true rumors) by
242          * skipping the first two lines.
243          *
244          * Then seek to the start of the false rumors (based on
245          * the value read in rumors, and display it.
246          */
247         rumor_buf[0] = '\0';
248         (void) dlb_fseek(rumors, (long) true_rumor_start, SEEK_SET);
249         ftell_rumor_start = dlb_ftell(rumors);
250         (void) dlb_fgets(line, sizeof line, rumors);
251         if ((endp = index(line, '\n')) != 0)
252             *endp = 0;
253         Sprintf(rumor_buf, "T %06ld %s", ftell_rumor_start,
254                 xcrypt(line, xbuf));
255         putstr(tmpwin, 0, rumor_buf);
256         /* find last true rumor */
257         while (dlb_fgets(line, sizeof line, rumors)
258                && dlb_ftell(rumors) < true_rumor_end)
259             continue;
260         if ((endp = index(line, '\n')) != 0)
261             *endp = 0;
262         Sprintf(rumor_buf, "  %6s %s", "", xcrypt(line, xbuf));
263         putstr(tmpwin, 0, rumor_buf);
264
265         rumor_buf[0] = '\0';
266         (void) dlb_fseek(rumors, (long) false_rumor_start, SEEK_SET);
267         ftell_rumor_start = dlb_ftell(rumors);
268         (void) dlb_fgets(line, sizeof line, rumors);
269         if ((endp = index(line, '\n')) != 0)
270             *endp = 0;
271         Sprintf(rumor_buf, "F %06ld %s", ftell_rumor_start,
272                 xcrypt(line, xbuf));
273         putstr(tmpwin, 0, rumor_buf);
274         /* find last false rumor */
275         while (dlb_fgets(line, sizeof line, rumors)
276                && dlb_ftell(rumors) < false_rumor_end)
277             continue;
278         if ((endp = index(line, '\n')) != 0)
279             *endp = 0;
280         Sprintf(rumor_buf, "  %6s %s", "", xcrypt(line, xbuf));
281         putstr(tmpwin, 0, rumor_buf);
282
283         (void) dlb_fclose(rumors);
284         display_nhwindow(tmpwin, TRUE);
285         destroy_nhwindow(tmpwin);
286     } else {
287         impossible("Can't open rumors file!");
288         true_rumor_size = -1; /* don't try to open it again */
289     }
290 }
291
292 /* Gets a random line of text from file 'fname', and returns it. */
293 char *
294 get_rnd_text(fname, buf)
295 const char *fname;
296 char *buf;
297 {
298     dlb *fh;
299
300     buf[0] = '\0';
301
302     fh = dlb_fopen(fname, "r");
303
304     if (fh) {
305         /* TODO: cache sizetxt, starttxt, endtxt. maybe cache file contents?
306          */
307         long sizetxt = 0, starttxt = 0, endtxt = 0, tidbit = 0;
308         char *endp, line[BUFSZ], xbuf[BUFSZ];
309         (void) dlb_fgets(line, sizeof line,
310                          fh); /* skip "don't edit" comment */
311
312         (void) dlb_fseek(fh, 0L, SEEK_CUR);
313         starttxt = dlb_ftell(fh);
314         (void) dlb_fseek(fh, 0L, SEEK_END);
315         endtxt = dlb_ftell(fh);
316         sizetxt = endtxt - starttxt;
317         tidbit = Rand() % sizetxt;
318
319         (void) dlb_fseek(fh, starttxt + tidbit, SEEK_SET);
320         (void) dlb_fgets(line, sizeof line, fh);
321         if (!dlb_fgets(line, sizeof line, fh)) {
322             (void) dlb_fseek(fh, starttxt, SEEK_SET);
323             (void) dlb_fgets(line, sizeof line, fh);
324         }
325         if ((endp = index(line, '\n')) != 0)
326             *endp = 0;
327         Strcat(buf, xcrypt(line, xbuf));
328         (void) dlb_fclose(fh);
329     } else
330         impossible("Can't open file %s!", fname);
331     return buf;
332 }
333
334 void
335 outrumor(truth, mechanism)
336 int truth; /* 1=true, -1=false, 0=either */
337 int mechanism;
338 {
339     static const char fortune_msg[] =
340 /*JP
341         "This cookie has a scrap of paper inside.";
342 */
343         "\82±\82Ì\83N\83b\83L\81[\82É\82Í\8e\86\90Ø\82ª\93ü\82Á\82Ä\82¢\82é\81D";
344     const char *line;
345     char buf[BUFSZ];
346     boolean reading = (mechanism == BY_COOKIE || mechanism == BY_PAPER);
347
348     if (reading) {
349         /* deal with various things that prevent reading */
350         if (is_fainted() && mechanism == BY_COOKIE)
351             return;
352         else if (Blind) {
353             if (mechanism == BY_COOKIE)
354                 pline(fortune_msg);
355 /*JP
356             pline("What a pity that you cannot read it!");
357 */
358             pline("\82»\82ê\82ð\93Ç\82ß\82È\82¢\82È\82ñ\82Ä\8bC\82Ì\93Å\82È\81I");
359             return;
360         }
361     }
362     line = getrumor(truth, buf, reading ? FALSE : TRUE);
363     if (!*line)
364 /*JP
365         line = "NetHack rumors file closed for renovation.";
366 */
367         line = "\89\\82Ì\90^\91\8a\82Í\8dü\90V\82Ì\82½\82ß\8bx\8a§\82µ\82Ä\82¢\82é\81D";
368     switch (mechanism) {
369     case BY_ORACLE:
370         /* Oracle delivers the rumor */
371 #if 0 /*JP*/
372         pline("True to her word, the Oracle %ssays: ",
373               (!rn2(4) ? "offhandedly "
374                        : (!rn2(3) ? "casually "
375                                   : (rn2(2) ? "nonchalantly " : ""))));
376 #else
377         pline("\96ñ\91©\82Ç\82¨\82è\82É\81C\8c«\8eÒ\82Í%s\8fq\82×\82½:",
378               (!rn2(4) ? "\96³\91¢\8dì\82É"
379                        : (!rn2(3) ? "\89½\8bC\82È\82­"
380                                   : (rn2(2) ? "\96³\93Ú\92\85\82É" : ""))));
381 #endif
382         verbalize1(line);
383         /* [WIS exercized by getrumor()] */
384         return;
385     case BY_COOKIE:
386         pline(fortune_msg);
387     /* FALLTHRU */
388     case BY_PAPER:
389 /*JP
390         pline("It reads:");
391 */
392         pline("\82»\82ê\82ð\93Ç\82ñ\82¾:");
393         break;
394     }
395     pline1(line);
396 }
397
398 STATIC_OVL void
399 init_oracles(fp)
400 dlb *fp;
401 {
402     register int i;
403     char line[BUFSZ];
404     int cnt = 0;
405
406     /* this assumes we're only called once */
407     (void) dlb_fgets(line, sizeof line, fp); /* skip "don't edit" comment*/
408     (void) dlb_fgets(line, sizeof line, fp);
409     if (sscanf(line, "%5d\n", &cnt) == 1 && cnt > 0) {
410         oracle_cnt = (unsigned) cnt;
411         oracle_loc = (unsigned long *) alloc((unsigned) cnt * sizeof(long));
412         for (i = 0; i < cnt; i++) {
413             (void) dlb_fgets(line, sizeof line, fp);
414             (void) sscanf(line, "%5lx\n", &oracle_loc[i]);
415         }
416     }
417     return;
418 }
419
420 void
421 save_oracles(fd, mode)
422 int fd, mode;
423 {
424     if (perform_bwrite(mode)) {
425         bwrite(fd, (genericptr_t) &oracle_cnt, sizeof oracle_cnt);
426         if (oracle_cnt)
427             bwrite(fd, (genericptr_t) oracle_loc, oracle_cnt * sizeof(long));
428     }
429     if (release_data(mode)) {
430         if (oracle_cnt) {
431             free((genericptr_t) oracle_loc);
432             oracle_loc = 0, oracle_cnt = 0, oracle_flg = 0;
433         }
434     }
435 }
436
437 void
438 restore_oracles(fd)
439 int fd;
440 {
441     mread(fd, (genericptr_t) &oracle_cnt, sizeof oracle_cnt);
442     if (oracle_cnt) {
443         oracle_loc = (unsigned long *) alloc(oracle_cnt * sizeof(long));
444         mread(fd, (genericptr_t) oracle_loc, oracle_cnt * sizeof(long));
445         oracle_flg = 1; /* no need to call init_oracles() */
446     }
447 }
448
449 void
450 outoracle(special, delphi)
451 boolean special;
452 boolean delphi;
453 {
454     char line[COLNO];
455     char *endp;
456     dlb *oracles;
457     int oracle_idx;
458     char xbuf[BUFSZ];
459
460     /* early return if we couldn't open ORACLEFILE on previous attempt,
461        or if all the oracularities are already exhausted */
462     if (oracle_flg < 0 || (oracle_flg > 0 && oracle_cnt == 0))
463         return;
464
465     oracles = dlb_fopen(ORACLEFILE, "r");
466
467     if (oracles) {
468         winid tmpwin;
469         if (oracle_flg == 0) { /* if this is the first outoracle() */
470             init_oracles(oracles);
471             oracle_flg = 1;
472             if (oracle_cnt == 0)
473                 return;
474         }
475         /* oracle_loc[0] is the special oracle;
476            oracle_loc[1..oracle_cnt-1] are normal ones */
477         if (oracle_cnt <= 1 && !special)
478             return; /*(shouldn't happen)*/
479         oracle_idx = special ? 0 : rnd((int) oracle_cnt - 1);
480         (void) dlb_fseek(oracles, (long) oracle_loc[oracle_idx], SEEK_SET);
481         if (!special) /* move offset of very last one into this slot */
482             oracle_loc[oracle_idx] = oracle_loc[--oracle_cnt];
483
484         tmpwin = create_nhwindow(NHW_TEXT);
485         if (delphi)
486             putstr(tmpwin, 0,
487                    special
488 /*JP
489                      ? "The Oracle scornfully takes all your money and says:"
490 */
491                      ? "\8c«\8eÒ\82Í\8cy\95Ì\82µ\82½\82æ\82¤\82É\82 \82È\82½\82Ì\91S\82Ä\82Ì\82¨\8bà\82ð\8eó\82¯\82Æ\82è\81C\8fq\82×\82½\81F"
492 /*JP
493                      : "The Oracle meditates for a moment and then intones:");
494 */
495                      : "\8c«\8eÒ\82Í\82µ\82Î\82ç\82­\96»\91z\82µ\81C\89Ì\82¤\82æ\82¤\82É\98b\82µ\82½\81F");
496         else
497 /*JP
498             putstr(tmpwin, 0, "The message reads:");
499 */
500             putstr(tmpwin, 0, "\83\81\83b\83Z\81[\83W:");
501         putstr(tmpwin, 0, "");
502
503         while (dlb_fgets(line, COLNO, oracles) && strcmp(line, "---\n")) {
504             if ((endp = index(line, '\n')) != 0)
505                 *endp = 0;
506             putstr(tmpwin, 0, xcrypt(line, xbuf));
507         }
508         display_nhwindow(tmpwin, TRUE);
509         destroy_nhwindow(tmpwin);
510         (void) dlb_fclose(oracles);
511     } else {
512 /*JP
513         pline("Can't open oracles file!");
514 */
515         pline("oracles\83t\83@\83C\83\8b\82ð\8aJ\82¯\82È\82¢\81I");
516         oracle_flg = -1; /* don't try to open it again */
517     }
518 }
519
520 int
521 doconsult(oracl)
522 struct monst *oracl;
523 {
524     long umoney;
525     int u_pay, minor_cost = 50, major_cost = 500 + 50 * u.ulevel;
526     int add_xpts;
527     char qbuf[QBUFSZ];
528
529     multi = 0;
530     umoney = money_cnt(invent);
531
532     if (!oracl) {
533 /*JP
534         There("is no one here to consult.");
535 */
536         pline("\82±\82±\82É\82Í\90_\91õ\82ð\8fq\82×\82é\90l\82Í\82¢\82È\82¢\81D");
537         return 0;
538     } else if (!oracl->mpeaceful) {
539 /*JP
540         pline("%s is in no mood for consultations.", Monnam(oracl));
541 */
542         pline("\8c«\8eÒ\82Í\90_\91õ\82ð\8d\90\82°\82Ä\82­\82ê\82é\95µ\88Í\8bC\82Å\82Í\82È\82¢\81D");
543         return 0;
544     } else if (!umoney) {
545 /*JP
546         You("have no money.");
547 */
548         You("\82¨\8bà\82ª\82È\82¢\81D");
549         return 0;
550     }
551
552 /*JP
553     Sprintf(qbuf, "\"Wilt thou settle for a minor consultation?\" (%d %s)",
554 */
555     Sprintf(qbuf, "\81u\93ð\81C\92á\88Ê\82Ì\90_\91õ\82ð\8eó\82¯\82é\82©\81H\81v(%d%s)",
556             minor_cost, currency((long) minor_cost));
557     switch (ynq(qbuf)) {
558     default:
559     case 'q':
560         return 0;
561     case 'y':
562         if (umoney < (long) minor_cost) {
563 /*JP
564             You("don't even have enough money for that!");
565 */
566             You("\82±\82ê\82É\95¥\82¦\82é\82¾\82¯\82Ì\82¨\8bà\82·\82ç\8e\9d\82Á\82Ä\82¢\82È\82¢\81I");
567             return 0;
568         }
569         u_pay = minor_cost;
570         break;
571     case 'n':
572         if (umoney <= (long) minor_cost /* don't even ask */
573             || (oracle_cnt == 1 || oracle_flg < 0))
574             return 0;
575 /*JP
576         Sprintf(qbuf, "\"Then dost thou desire a major one?\" (%d %s)",
577 */
578         Sprintf(qbuf, "\81u\82È\82ç\82Î\93ð\81C\8d\82\88Ê\82Ì\90_\91õ\82ð\8eó\82¯\82é\82©\81H\81v(%d%s)",
579                 major_cost, currency((long) major_cost));
580         if (yn(qbuf) != 'y')
581             return 0;
582         u_pay = (umoney < (long) major_cost) ? (int) umoney : major_cost;
583         break;
584     }
585     money2mon(oracl, (long) u_pay);
586     context.botl = 1;
587     add_xpts = 0; /* first oracle of each type gives experience points */
588     if (u_pay == minor_cost) {
589         outrumor(1, BY_ORACLE);
590         if (!u.uevent.minor_oracle)
591             add_xpts = u_pay / (u.uevent.major_oracle ? 25 : 10);
592         /* 5 pts if very 1st, or 2 pts if major already done */
593         u.uevent.minor_oracle = TRUE;
594     } else {
595         boolean cheapskate = u_pay < major_cost;
596
597         outoracle(cheapskate, TRUE);
598         if (!cheapskate && !u.uevent.major_oracle)
599             add_xpts = u_pay / (u.uevent.minor_oracle ? 25 : 10);
600         /* ~100 pts if very 1st, ~40 pts if minor already done */
601         u.uevent.major_oracle = TRUE;
602         exercise(A_WIS, !cheapskate);
603     }
604     if (add_xpts) {
605         more_experienced(add_xpts, u_pay / 50);
606         newexplevel();
607     }
608     return 1;
609 }
610
611 /*rumors.c*/