1 /* NetHack 3.6 pline.c $NHDT-Date: 1432512770 2015/05/25 00:12:50 $ $NHDT-Branch: master $:$NHDT-Revision: 1.42 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
10 #define NEED_VARARGS /* Uses ... */ /* comment line for pre-compiled headers \
14 static boolean no_repeat = FALSE;
15 static char prevmsg[BUFSZ];
17 static char *FDECL(You_buf, (int));
20 /* Note that these declarations rely on knowledge of the internals
21 * of the variable argument handling stuff in "tradstdc.h"
24 #if defined(USE_STDARG) || defined(USE_VARARGS)
25 static void FDECL(vpline, (const char *, va_list));
28 VA_DECL(const char *, line)
31 VA_INIT(line, char *);
32 vpline(line, VA_ARGS);
38 vpline(const char *line, va_list the_args)
41 vpline(line, the_args)
46 #else /* USE_STDARG | USE_VARARG */
51 VA_DECL(const char *, line)
52 #endif /* USE_STDARG | USE_VARARG */
53 { /* start of vpline() or of nested block in USE_OLDARG's pline() */
57 /* Do NOT use VA_START and VA_END in here... see above */
62 if (program_state.done_hup)
65 if (program_state.wizkit_wishing)
68 if (index(line, '%')) {
69 Vsprintf(pbuf, line, VA_ARGS);
72 if ((ln = (int) strlen(line)) > BUFSZ - 1) {
73 if (line != pbuf) /* no '%' was present */
74 (void) strncpy(pbuf, line, BUFSZ - 1); /* caveat: unterminated */
75 /* truncate, preserving the final 3 characters:
76 "___ extremely long text" -> "___ extremely l...ext"
77 (this may be suboptimal if overflow is less than 3) */
78 (void) strncpy(pbuf + BUFSZ - 1 - 6, "...", 3);
79 /* avoid strncpy; buffers could overlap if excess is small */
80 pbuf[BUFSZ - 1 - 3] = line[ln - 3];
81 pbuf[BUFSZ - 1 - 2] = line[ln - 2];
82 pbuf[BUFSZ - 1 - 1] = line[ln - 1];
83 pbuf[BUFSZ - 1] = '\0';
86 if (!iflags.window_inited) {
88 iflags.last_msg = PLNMSG_UNKNOWN;
92 if (no_repeat && !strcmp(line, toplines))
95 if (vision_full_recalc)
98 flush_screen(1); /* %% */
99 msgtyp = msgtype_type(line);
100 if (msgtyp == MSGTYP_NOSHOW) return;
101 if (msgtyp == MSGTYP_NOREP && !strcmp(line, prevmsg)) return;
102 putstr(WIN_MESSAGE, 0, line);
103 /* this gets cleared after every pline message */
104 iflags.last_msg = PLNMSG_UNKNOWN;
105 strncpy(prevmsg, line, BUFSZ);
106 if (msgtyp == MSGTYP_STOP) display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */
108 #if !(defined(USE_STDARG) || defined(USE_VARARGS))
109 /* provide closing brace for the nested block
110 which immediately follows USE_OLDARGS's VA_DECL() */
117 VA_DECL(const char *, line)
120 VA_INIT(line, const char *);
122 vpline(line, VA_ARGS);
128 /* work buffer for You(), &c and verbalize() */
129 static char *you_buf = 0;
130 static int you_buf_siz = 0;
136 if (siz > you_buf_siz) {
138 free((genericptr_t) you_buf);
139 you_buf_siz = siz + 10;
140 you_buf = (char *) alloc((unsigned) you_buf_siz);
149 free((genericptr_t) you_buf), you_buf = (char *) 0;
153 /* `prefix' must be a string literal, not a pointer */
154 #define YouPrefix(pointer, prefix, text) \
155 Strcpy((pointer = You_buf((int) (strlen(text) + sizeof prefix))), prefix)
157 #define YouMessage(pointer, prefix, text) \
158 strcat((YouPrefix(pointer, prefix, text), pointer), text)
162 VA_DECL(const char *, line)
166 VA_INIT(line, const char *);
168 vpline(YouMessage(tmp, "You ", line), VA_ARGS);
170 vpline(YouMessage(tmp, "
\82 \82È
\82½
\82Í", line), VA_ARGS);
176 VA_DECL(const char *, line)
180 VA_INIT(line, const char *);
182 vpline(YouMessage(tmp, "Your ", line), VA_ARGS);
184 vpline(YouMessage(tmp, "
\82 \82È
\82½
\82Ì", line), VA_ARGS);
190 VA_DECL(const char *, line)
194 VA_INIT(line, const char *);
197 YouPrefix(tmp, "You dream that you feel ", line);
199 YouPrefix(tmp, "
\82 \82È
\82½
\82Í
\96²
\82Ì
\92\86\82Å", line);
202 YouPrefix(tmp, "You feel ", line);
204 YouPrefix(tmp, "
\82 \82È
\82½
\82Í", line);
205 vpline(strcat(tmp, line), VA_ARGS);
211 VA_DECL(const char *, line)
215 VA_INIT(line, const char *);
217 vpline(YouMessage(tmp, "You can't ", line), VA_ARGS);
219 vpline(YouMessage(tmp, "
\82 \82È
\82½
\82Í", line), VA_ARGS);
225 VA_DECL(const char *, line)
229 VA_INIT(line, const char *);
231 vpline(YouMessage(tmp, "The ", line), VA_ARGS);
233 vpline(YouMessage(tmp, "", line), VA_ARGS);
239 VA_DECL(const char *, line)
243 VA_INIT(line, const char *);
245 vpline(YouMessage(tmp, "There ", line), VA_ARGS);
247 vpline(YouMessage(tmp, "", line), VA_ARGS);
253 VA_DECL(const char *, line)
261 if (Deaf || !flags.acoustics)
264 VA_INIT(line, const char *);
267 YouPrefix(tmp, "You barely hear ", line);
269 YouPrefix(tmp, "You dream that you hear ", line);
271 YouPrefix(tmp, "You hear ", line);
272 vpline(strcat(tmp, line), VA_ARGS);
275 adj = "
\82©
\82·
\82©
\82É";
277 adj = "
\96²
\82Ì
\92\86\82Å";
280 tmp = You_buf(strlen(adj) + strlen(line) + sizeof("
\82 \82È
\82½
\82Í "));
282 p = (char *)strstr(line, "
\95·
\82±") ;
284 Strcpy(tmp, "
\82 \82È
\82½
\82Í");
287 if (p != NULL || (p = (char *)strstr(line, "
\95·
\82¢")) != NULL){
288 strncat(tmp, line, (p - line));
294 vpline(tmp, VA_ARGS);
301 VA_DECL(const char *, line)
306 VA_INIT(line, const char *);
309 YouPrefix(tmp, "You dream that you see ", line);
311 YouPrefix(tmp, "
\82 \82È
\82½
\82Í
\96²
\82Ì
\92\86\82Å", line);
312 #if 0 /*JP*//*
\82±
\82±
\82Í
\8cÄ
\82Ñ
\8fo
\82µ
\8c³
\82Å
\8f\88\97\9d\82·
\82é?*/
313 else if (Blind) /* caller should have caught this... */
314 YouPrefix(tmp, "You sense ", line);
318 YouPrefix(tmp, "You see ", line);
320 YouPrefix(tmp, "
\82 \82È
\82½
\82Í", line);
321 vpline(strcat(tmp, line), VA_ARGS);
325 /* Print a message inside double-quotes.
326 * The caller is responsible for checking deafness.
327 * Gods can speak directly to you in spite of deafness.
331 VA_DECL(const char *, line)
336 VA_INIT(line, const char *);
338 tmp = You_buf((int) strlen(line) + sizeof "\"\"");
343 tmp = You_buf((int) strlen(line) + sizeof "
\81u
\81v");
348 vpline(tmp, VA_ARGS);
353 /* Note that these declarations rely on knowledge of the internals
354 * of the variable argument handling stuff in "tradstdc.h"
357 #if defined(USE_STDARG) || defined(USE_VARARGS)
358 static void FDECL(vraw_printf, (const char *, va_list));
361 VA_DECL(const char *, line)
364 VA_INIT(line, char *);
365 vraw_printf(line, VA_ARGS);
371 vraw_printf(const char *line, va_list the_args)
374 vraw_printf(line, the_args)
379 #else /* USE_STDARG | USE_VARARG */
382 VA_DECL(const char *, line)
385 char pbuf[3 * BUFSZ];
387 /* Do NOT use VA_START and VA_END in here... see above */
389 if (index(line, '%')) {
390 Vsprintf(pbuf, line, VA_ARGS);
393 if ((ln = (int) strlen(line)) > BUFSZ - 1) {
395 line = strncpy(pbuf, line, BUFSZ - 1);
396 /* unlike pline, we don't futz around to keep last few chars */
397 pbuf[BUFSZ - 1] = '\0'; /* terminate strncpy or truncate vsprintf */
400 #if !(defined(USE_STDARG) || defined(USE_VARARGS))
401 VA_END(); /* (see vpline) */
407 VA_DECL(const char *, s)
409 char pbuf[2 * BUFSZ];
411 VA_INIT(s, const char *);
412 if (program_state.in_impossible)
413 panic("impossible called impossible");
415 program_state.in_impossible = 1;
416 Vsprintf(pbuf, s, VA_ARGS);
417 pbuf[BUFSZ - 1] = '\0'; /* sanity */
418 paniclog("impossible", pbuf);
421 pline("Program in disorder - perhaps you'd better #quit.");
423 pline("
\83v
\83\8d\83O
\83\89\83\80\82É
\8fá
\8aQ
\94
\90¶ - #quit
\82µ
\82½
\82Ù
\82¤
\82ª
\82æ
\82³
\82»
\82¤
\82¾
\81D");
424 program_state.in_impossible = 0;
432 switch ((int) alignment) {
447 return "
\92\81\8f\98";
462 register struct monst *mtmp;
464 aligntyp alignment = mon_aligntyp(mtmp);
465 char info[BUFSZ], monnambuf[BUFSZ];
470 Strcat(info, ", tame");
472 Strcat(info, ",
\8e\94\82¢
\82È
\82ç
\82³
\82ê
\82Ä
\82¢
\82é");
474 Sprintf(eos(info), " (%d", mtmp->mtame);
476 Sprintf(eos(info), "; hungry %ld; apport %d",
477 EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport);
480 } else if (mtmp->mpeaceful)
482 Strcat(info, ", peaceful");
484 Strcat(info, ",
\97F
\8dD
\93I");
485 if (mtmp->cham >= LOW_PM && mtmp->data != &mons[mtmp->cham])
486 /* don't reveal the innate form (chameleon, vampire, &c),
487 just expose the fact that this current form isn't it */
489 Strcat(info, ", shapechanger");
491 Strcat(info, ",
\95Ï
\89»");
493 /* pets eating mimic corpses mimic while eating, so this comes first */
496 Strcat(info, ", eating");
498 Strcat(info, ",
\90H
\8e\96\92\86");
499 /* a stethoscope exposes mimic before getting here so this
500 won't be relevant for it, but wand of probing doesn't */
503 Sprintf(eos(info), ", mimicking %s",
504 (mtmp->m_ap_type == M_AP_FURNITURE)
505 ? an(defsyms[mtmp->mappearance].explanation)
506 : (mtmp->m_ap_type == M_AP_OBJECT)
507 ? ((mtmp->mappearance == GOLD_PIECE)
509 : an(simple_typename(mtmp->mappearance)))
510 : (mtmp->m_ap_type == M_AP_MONSTER)
511 ? an(mons[mtmp->mappearance].mname)
512 : something); /* impossible... */
514 Sprintf(eos(info), ", %s
\82Ì
\82Ü
\82Ë
\82ð
\82µ
\82Ä
\82¢
\82é",
515 (mtmp->m_ap_type == M_AP_FURNITURE)
516 ? an(defsyms[mtmp->mappearance].explanation)
517 : (mtmp->m_ap_type == M_AP_OBJECT)
518 ? ((mtmp->mappearance == GOLD_PIECE)
520 : an(simple_typename(mtmp->mappearance)))
521 : (mtmp->m_ap_type == M_AP_MONSTER)
522 ? an(mons[mtmp->mappearance].mname)
523 : something); /* impossible... */
527 Strcat(info, ", cancelled");
529 Strcat(info, ",
\96³
\97Í");
532 Strcat(info, ", confused");
534 Strcat(info, ",
\8d¬
\97\90\8fó
\91Ô");
535 if (mtmp->mblinded || !mtmp->mcansee)
537 Strcat(info, ", blind");
539 Strcat(info, ",
\96Ó
\96Ú");
542 Strcat(info, ", stunned");
544 Strcat(info, ",
\82
\82ç
\82
\82ç
\8fó
\91Ô");
547 Strcat(info, ", asleep");
549 Strcat(info, ",
\90\87\96°
\8fó
\91Ô");
550 #if 0 /* unfortunately mfrozen covers temporary sleep and being busy \
551 (donning armor, for instance) as well as paralysis */
552 else if (mtmp->mfrozen) Strcat(info, ", paralyzed");
554 else if (mtmp->mfrozen || !mtmp->mcanmove)
556 Strcat(info, ", can't move");
558 Strcat(info, ",
\93®
\82¯
\82È
\82¢");
560 /* [arbitrary reason why it isn't moving] */
561 else if (mtmp->mstrategy & STRAT_WAITMASK)
563 Strcat(info, ", meditating");
565 Strcat(info, ",
\96»
\91z
\92\86");
568 Strcat(info, ", scared");
570 Strcat(info, ",
\8b¯
\82¦
\82Ä
\82¢
\82é");
573 Strcat(info, ", trapped");
575 Strcat(info, ", ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é");
578 Strcat(info, mtmp->mspeed == MFAST ? ", fast" : mtmp->mspeed == MSLOW
582 Strcat(info, mtmp->mspeed == MFAST ? ",
\91f
\91\81\82¢" : mtmp->mspeed == MSLOW
584 : ",
\91¬
\93x
\95s
\96¾");
586 if (mtmp->mundetected)
588 Strcat(info, ", concealed");
590 Strcat(info, ",
\89B
\82ê
\82Ä
\82¢
\82é");
593 Strcat(info, ", invisible");
595 Strcat(info, ",
\95s
\89Â
\8e\8b");
596 if (mtmp == u.ustuck)
598 Strcat(info, sticks(youmonst.data)
600 : !u.uswallow ? ", holding you"
601 : attacktype_fordmg(u.ustuck->data,
604 : is_animal(u.ustuck->data)
606 : ", engulfing you");
608 Strcat(info, sticks(youmonst.data)
609 ? ",
\82 \82È
\82½
\82ª
\92Í
\82Ü
\82¦
\82Ä
\82¢
\82é"
610 : !u.uswallow ? ",
\92Í
\82Ü
\82¦
\82Ä
\82¢
\82é"
611 : attacktype_fordmg(u.ustuck->data,
613 ? ",
\8fÁ
\89»
\82µ
\82Ä
\82¢
\82é"
614 : is_animal(u.ustuck->data)
615 ? ",
\88ù
\82Ý
\8d\9e\82ñ
\82Å
\82¢
\82é"
616 : ",
\8aª
\82«
\8d\9e\82ñ
\82Å
\82¢
\82é");
618 if (mtmp == u.usteed)
620 Strcat(info, ", carrying you");
622 Strcat(info, ",
\82 \82È
\82½
\82ð
\8fæ
\82¹
\82Ä
\82¢
\82é");
624 /* avoid "Status of the invisible newt ..., invisible" */
625 /* and unlike a normal mon_nam, use "saddled" even if it has a name */
626 Strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
627 (SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE));
630 pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", monnambuf,
632 pline("%s
\82Ì
\8fó
\91Ô (%s)
\81F Level %d HP %d(%d) AC %d%s", monnambuf,
633 align_str(alignment), mtmp->m_lev, mtmp->mhp, mtmp->mhpmax,
634 find_mac(mtmp), info);
645 Strcat(info, ", dying from");
646 if (u.usick_type & SICK_VOMITABLE)
647 Strcat(info, " food poisoning");
648 if (u.usick_type & SICK_NONVOMITABLE) {
649 if (u.usick_type & SICK_VOMITABLE)
650 Strcat(info, " and");
651 Strcat(info, " illness");
655 if (u.usick_type & SICK_VOMITABLE)
656 Strcat(info, "
\90H
\92\86\93Å");
657 if (u.usick_type & SICK_NONVOMITABLE) {
658 if (u.usick_type & SICK_VOMITABLE)
659 Strcat(info, "
\82Æ");
660 Strcat(info, "
\95a
\8bC");
662 Strcat(info, "
\82Å
\8e\80\82É
\82Â
\82Â
\82 \82é");
667 Strcat(info, ", solidifying");
669 Strcat(info, ",
\90Î
\89»
\82µ
\82Â
\82Â
\82 \82é");
672 Strcat(info, ", becoming slimy");
674 Strcat(info, ",
\83X
\83\89\83C
\83\80\82É
\82È
\82è
\82Â
\82Â
\82 \82é");
677 Strcat(info, ", being strangled");
679 Strcat(info, ",
\8eñ
\82ð
\8di
\82ß
\82ç
\82ê
\82Ä
\82¢
\82é");
682 Strcat(info, ", nauseated"); /* !"nauseous" */
684 Strcat(info, ",
\93f
\82«
\8bC
\82ª
\82·
\82é");
688 Strcat(info, ", confused");
690 Strcat(info, ",
\8d¬
\97\90\8fó
\91Ô");
693 Strcat(info, ", blind");
695 if ((long) u.ucreamed < Blinded || Blindfolded
696 || !haseyes(youmonst.data))
697 Strcat(info, ", cover");
698 Strcat(info, "ed by sticky goop");
699 } /* note: "goop" == "glop"; variation is intentional */
703 Strcat(info, "
\82Ë
\82Î
\82Ë
\82Î
\82×
\82Æ
\82Â
\82
\82à
\82Ì
\82Å");
704 if ((long)u.ucreamed < Blinded || Blindfolded
705 || !haseyes(youmonst.data))
706 Strcat(info, "
\95¢
\82í
\82ê
\82Ä");
708 Strcat(info, "
\96Ó
\96Ú
\8fó
\91Ô");
713 Strcat(info, ", stunned");
715 Strcat(info, ",
\82
\82ç
\82
\82ç
\8fó
\91Ô");
716 if (!u.usteed && Wounded_legs) {
717 const char *what = body_part(LEG);
718 if ((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
719 what = makeplural(what);
721 Sprintf(eos(info), ", injured %s", what);
723 Sprintf(eos(info), ", %s
\82É
\82¯
\82ª
\82ð
\82µ
\82Ä
\82¢
\82é", what);
727 Sprintf(eos(info), ", slippery %s", makeplural(body_part(HAND)));
729 Sprintf(eos(info), ", %s
\82ª
\82Ê
\82é
\82Ê
\82é", makeplural(body_part(HAND)));
732 Strcat(info, ", trapped");
734 Strcat(info, ", ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é");
737 Strcat(info, Very_fast ? ", very fast" : ", fast");
739 Strcat(info, Very_fast ? ",
\82Æ
\82Ä
\82à
\91f
\91\81\82¢" : ",
\91f
\91\81\82¢");
742 Strcat(info, ", concealed");
744 Strcat(info, ",
\89B
\82ê
\82Ä
\82¢
\82é");
747 Strcat(info, ", invisible");
749 Strcat(info, ",
\95s
\89Â
\8e\8b");
752 if (sticks(youmonst.data))
753 Strcat(info, ", holding ");
755 Strcat(info, ", held by ");
756 Strcat(info, mon_nam(u.ustuck));
759 Strcat(info, mon_nam(u.ustuck));
760 if (sticks(youmonst.data))
761 Strcat(info, "
\82ð
\92Í
\82Ü
\82¦
\82Ä
\82¢
\82é");
763 Strcat(info, "
\82É
\92Í
\82Ü
\82¦
\82ç
\82ê
\82Ä
\82¢
\82é");
768 pline("Status of %s (%s%s): Level %d HP %d(%d) AC %d%s.", plname,
770 pline("%s
\82Ì
\8fó
\91Ô (%s %s)
\81F Level %d HP %d(%d) AC %d%s", plname,
771 (u.ualign.record >= 20)
776 : (u.ualign.record > 13)
781 : (u.ualign.record > 8)
786 : (u.ualign.record > 3)
790 ? "
\90º
\82Ì
\82©
\82ñ
\8d\82\82¢"
791 : (u.ualign.record == 3)
793 : (u.ualign.record >= 1)
798 : (u.ualign.record == 0)
807 align_str(u.ualign.type),
808 Upolyd ? mons[u.umonnum].mlevel : u.ulevel, Upolyd ? u.mh : u.uhp,
809 Upolyd ? u.mhmax : u.uhpmax, u.uac, info);
817 Hallucination ? "Far out, man! You" : "Gee! All of a sudden, you",
818 See_invisible ? "can see right through yourself"
819 : "can't see yourself");
821 pline("%s
\82 \82È
\82½
\82Í%s
\81D",
822 Hallucination ? "
\83\8f\81[
\83I
\81I" : "
\82°
\81I
\93Ë
\91R",
823 See_invisible ? "
\8e©
\95ª
\8e©
\90g
\82ª
\82¿
\82á
\82ñ
\82Æ
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½"
824 : "
\8e©
\95ª
\8e©
\90g
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½");
829 pudding_merge_message(otmp, otmp2)
834 cansee(otmp->ox, otmp->oy) || cansee(otmp2->ox, otmp2->oy);
835 boolean onfloor = otmp->where == OBJ_FLOOR || otmp2->where == OBJ_FLOOR;
836 boolean inpack = carried(otmp) || carried(otmp2);
838 /* the player will know something happened inside his own inventory */
839 if ((!Blind && visible) || inpack) {
843 You_see("parts of the floor melting!");
845 You_see("
\8f°
\82Ì
\88ê
\95\94\82ª
\97n
\82¯
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81I");
848 Your("pack reaches out and grabs something!");
850 Your("
\82©
\82Î
\82ñ
\82ª
\8eè
\82ð
\90L
\82Î
\82µ
\82Ä
\89½
\82©
\82ð
\82Â
\82©
\82ñ
\82¾
\81I");
852 /* even though we can see where they should be,
853 * they'll be out of our view (minvent or container)
854 * so don't actually show anything */
855 } else if (onfloor || inpack) {
857 pline("The %s coalesce%s.", makeplural(obj_typename(otmp->otyp)),
858 inpack ? " inside your pack" : "");
860 pline("%s
\82ª%s
\8d\87\91Ì
\82µ
\82½
\81D", obj_typename(otmp->otyp),
861 inpack ? "
\82 \82È
\82½
\82Ì
\82©
\82Î
\82ñ
\82Ì
\92\86\82Å" : "");
866 You_hear("a faint sloshing sound.");
868 You_hear("
\82©
\82·
\82©
\82È
\83o
\83V
\83\83\83o
\83V
\83\83\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");