OSDN Git Service

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