OSDN Git Service

Initial Import
[nethackexpress/trunk.git] / src / pline.c
1 /*      SCCS Id: @(#)pline.c    3.4     1999/11/28      */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #define NEED_VARARGS /* Uses ... */     /* comment line for pre-compiled headers */
6 #include "hack.h"
7 #include "epri.h"
8 #ifdef WIZARD
9 #include "edog.h"
10 #endif
11
12 #ifdef OVLB
13
14 static boolean no_repeat = FALSE;
15
16 static char *FDECL(You_buf, (int));
17
18 /*VARARGS1*/
19 /* Note that these declarations rely on knowledge of the internals
20  * of the variable argument handling stuff in "tradstdc.h"
21  */
22
23 #if defined(USE_STDARG) || defined(USE_VARARGS)
24 static void FDECL(vpline, (const char *, va_list));
25
26 void
27 pline VA_DECL(const char *, line)
28         VA_START(line);
29         VA_INIT(line, char *);
30         vpline(line, VA_ARGS);
31         VA_END();
32 }
33
34 # ifdef USE_STDARG
35 static void
36 vpline(const char *line, va_list the_args) {
37 # else
38 static void
39 vpline(line, the_args) const char *line; va_list the_args; {
40 # endif
41
42 #else   /* USE_STDARG | USE_VARARG */
43
44 #define vpline pline
45
46 void
47 pline VA_DECL(const char *, line)
48 #endif  /* USE_STDARG | USE_VARARG */
49
50         char pbuf[BUFSZ];
51 /* Do NOT use VA_START and VA_END in here... see above */
52
53         if (!line || !*line) return;
54         if (index(line, '%')) {
55             Vsprintf(pbuf,line,VA_ARGS);
56             line = pbuf;
57         }
58         if (!iflags.window_inited) {
59             raw_print(line);
60             return;
61         }
62 #ifndef MAC
63         if (no_repeat && !strcmp(line, toplines))
64             return;
65 #endif /* MAC */
66         if (vision_full_recalc) vision_recalc(0);
67         if (u.ux) flush_screen(1);              /* %% */
68         putstr(WIN_MESSAGE, 0, line);
69 }
70
71 /*VARARGS1*/
72 void
73 Norep VA_DECL(const char *, line)
74         VA_START(line);
75         VA_INIT(line, const char *);
76         no_repeat = TRUE;
77         vpline(line, VA_ARGS);
78         no_repeat = FALSE;
79         VA_END();
80         return;
81 }
82
83 /* work buffer for You(), &c and verbalize() */
84 static char *you_buf = 0;
85 static int you_buf_siz = 0;
86
87 static char *
88 You_buf(siz)
89 int siz;
90 {
91         if (siz > you_buf_siz) {
92                 if (you_buf) free((genericptr_t) you_buf);
93                 you_buf_siz = siz + 10;
94                 you_buf = (char *) alloc((unsigned) you_buf_siz);
95         }
96         return you_buf;
97 }
98
99 void
100 free_youbuf()
101 {
102         if (you_buf) free((genericptr_t) you_buf),  you_buf = (char *)0;
103         you_buf_siz = 0;
104 }
105
106 /* `prefix' must be a string literal, not a pointer */
107 #define YouPrefix(pointer,prefix,text) \
108  Strcpy((pointer = You_buf((int)(strlen(text) + sizeof prefix))), prefix)
109
110 #define YouMessage(pointer,prefix,text) \
111  strcat((YouPrefix(pointer, prefix, text), pointer), text)
112
113 /*VARARGS1*/
114 void
115 You VA_DECL(const char *, line)
116         char *tmp;
117         VA_START(line);
118         VA_INIT(line, const char *);
119         vpline(YouMessage(tmp, "You ", line), VA_ARGS);
120         VA_END();
121 }
122
123 /*VARARGS1*/
124 void
125 Your VA_DECL(const char *,line)
126         char *tmp;
127         VA_START(line);
128         VA_INIT(line, const char *);
129         vpline(YouMessage(tmp, "Your ", line), VA_ARGS);
130         VA_END();
131 }
132
133 /*VARARGS1*/
134 void
135 You_feel VA_DECL(const char *,line)
136         char *tmp;
137         VA_START(line);
138         VA_INIT(line, const char *);
139         vpline(YouMessage(tmp, "You feel ", line), VA_ARGS);
140         VA_END();
141 }
142
143
144 /*VARARGS1*/
145 void
146 You_cant VA_DECL(const char *,line)
147         char *tmp;
148         VA_START(line);
149         VA_INIT(line, const char *);
150         vpline(YouMessage(tmp, "You can't ", line), VA_ARGS);
151         VA_END();
152 }
153
154 /*VARARGS1*/
155 void
156 pline_The VA_DECL(const char *,line)
157         char *tmp;
158         VA_START(line);
159         VA_INIT(line, const char *);
160         vpline(YouMessage(tmp, "The ", line), VA_ARGS);
161         VA_END();
162 }
163
164 /*VARARGS1*/
165 void
166 There VA_DECL(const char *,line)
167         char *tmp;
168         VA_START(line);
169         VA_INIT(line, const char *);
170         vpline(YouMessage(tmp, "There ", line), VA_ARGS);
171         VA_END();
172 }
173
174 /*VARARGS1*/
175 void
176 You_hear VA_DECL(const char *,line)
177         char *tmp;
178         VA_START(line);
179         VA_INIT(line, const char *);
180         if (Underwater)
181                 YouPrefix(tmp, "You barely hear ", line);
182         else if (u.usleep)
183                 YouPrefix(tmp, "You dream that you hear ", line);
184         else
185                 YouPrefix(tmp, "You hear ", line);
186         vpline(strcat(tmp, line), VA_ARGS);
187         VA_END();
188 }
189
190 /*VARARGS1*/
191 void
192 verbalize VA_DECL(const char *,line)
193         char *tmp;
194         if (!flags.soundok) return;
195         VA_START(line);
196         VA_INIT(line, const char *);
197         tmp = You_buf((int)strlen(line) + sizeof "\"\"");
198         Strcpy(tmp, "\"");
199         Strcat(tmp, line);
200         Strcat(tmp, "\"");
201         vpline(tmp, VA_ARGS);
202         VA_END();
203 }
204
205 /*VARARGS1*/
206 /* Note that these declarations rely on knowledge of the internals
207  * of the variable argument handling stuff in "tradstdc.h"
208  */
209
210 #if defined(USE_STDARG) || defined(USE_VARARGS)
211 static void FDECL(vraw_printf,(const char *,va_list));
212
213 void
214 raw_printf VA_DECL(const char *, line)
215         VA_START(line);
216         VA_INIT(line, char *);
217         vraw_printf(line, VA_ARGS);
218         VA_END();
219 }
220
221 # ifdef USE_STDARG
222 static void
223 vraw_printf(const char *line, va_list the_args) {
224 # else
225 static void
226 vraw_printf(line, the_args) const char *line; va_list the_args; {
227 # endif
228
229 #else  /* USE_STDARG | USE_VARARG */
230
231 void
232 raw_printf VA_DECL(const char *, line)
233 #endif
234 /* Do NOT use VA_START and VA_END in here... see above */
235
236         if(!index(line, '%'))
237             raw_print(line);
238         else {
239             char pbuf[BUFSZ];
240             Vsprintf(pbuf,line,VA_ARGS);
241             raw_print(pbuf);
242         }
243 }
244
245
246 /*VARARGS1*/
247 void
248 impossible VA_DECL(const char *, s)
249         VA_START(s);
250         VA_INIT(s, const char *);
251         if (program_state.in_impossible)
252                 panic("impossible called impossible");
253         program_state.in_impossible = 1;
254         {
255             char pbuf[BUFSZ];
256             Vsprintf(pbuf,s,VA_ARGS);
257             paniclog("impossible", pbuf);
258         }
259         vpline(s,VA_ARGS);
260         pline("Program in disorder - perhaps you'd better #quit.");
261         program_state.in_impossible = 0;
262         VA_END();
263 }
264
265 const char *
266 align_str(alignment)
267     aligntyp alignment;
268 {
269     switch ((int)alignment) {
270         case A_CHAOTIC: return "chaotic";
271         case A_NEUTRAL: return "neutral";
272         case A_LAWFUL:  return "lawful";
273         case A_NONE:    return "unaligned";
274     }
275     return "unknown";
276 }
277
278 void
279 mstatusline(mtmp)
280 register struct monst *mtmp;
281 {
282         aligntyp alignment;
283         char info[BUFSZ], monnambuf[BUFSZ];
284
285         if (mtmp->ispriest || mtmp->data == &mons[PM_ALIGNED_PRIEST]
286                                 || mtmp->data == &mons[PM_ANGEL])
287                 alignment = EPRI(mtmp)->shralign;
288         else
289                 alignment = mtmp->data->maligntyp;
290         alignment = (alignment > 0) ? A_LAWFUL :
291                 (alignment < 0) ? A_CHAOTIC :
292                 A_NEUTRAL;
293
294         info[0] = 0;
295         if (mtmp->mtame) {        Strcat(info, ", tame");
296 #ifdef WIZARD
297             if (wizard) {
298                 Sprintf(eos(info), " (%d", mtmp->mtame);
299                 if (!mtmp->isminion)
300                     Sprintf(eos(info), "; hungry %ld; apport %d",
301                         EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport);
302                 Strcat(info, ")");
303             }
304 #endif
305         }
306         else if (mtmp->mpeaceful) Strcat(info, ", peaceful");
307         if (mtmp->meating)        Strcat(info, ", eating");
308         if (mtmp->mcan)           Strcat(info, ", cancelled");
309         if (mtmp->mconf)          Strcat(info, ", confused");
310         if (mtmp->mblinded || !mtmp->mcansee)
311                                   Strcat(info, ", blind");
312         if (mtmp->mstun)          Strcat(info, ", stunned");
313         if (mtmp->msleeping)      Strcat(info, ", asleep");
314 #if 0   /* unfortunately mfrozen covers temporary sleep and being busy
315            (donning armor, for instance) as well as paralysis */
316         else if (mtmp->mfrozen)   Strcat(info, ", paralyzed");
317 #else
318         else if (mtmp->mfrozen || !mtmp->mcanmove)
319                                   Strcat(info, ", can't move");
320 #endif
321                                   /* [arbitrary reason why it isn't moving] */
322         else if (mtmp->mstrategy & STRAT_WAITMASK)
323                                   Strcat(info, ", meditating");
324         else if (mtmp->mflee)     Strcat(info, ", scared");
325         if (mtmp->mtrapped)       Strcat(info, ", trapped");
326         if (mtmp->mspeed)         Strcat(info,
327                                         mtmp->mspeed == MFAST ? ", fast" :
328                                         mtmp->mspeed == MSLOW ? ", slow" :
329                                         ", ???? speed");
330         if (mtmp->mundetected)    Strcat(info, ", concealed");
331         if (mtmp->minvis)         Strcat(info, ", invisible");
332         if (mtmp == u.ustuck)     Strcat(info,
333                         (sticks(youmonst.data)) ? ", held by you" :
334                                 u.uswallow ? (is_animal(u.ustuck->data) ?
335                                 ", swallowed you" :
336                                 ", engulfed you") :
337                                 ", holding you");
338 #ifdef STEED
339         if (mtmp == u.usteed)     Strcat(info, ", carrying you");
340 #endif
341
342         /* avoid "Status of the invisible newt ..., invisible" */
343         /* and unlike a normal mon_nam, use "saddled" even if it has a name */
344         Strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *)0,
345             (SUPPRESS_IT|SUPPRESS_INVISIBLE), FALSE));
346
347         pline("Status of %s (%s):  Level %d  HP %d(%d)  AC %d%s.",
348                 monnambuf,
349                 align_str(alignment),
350                 mtmp->m_lev,
351                 mtmp->mhp,
352                 mtmp->mhpmax,
353                 find_mac(mtmp),
354                 info);
355 }
356
357 void
358 ustatusline()
359 {
360         char info[BUFSZ];
361
362         info[0] = '\0';
363         if (Sick) {
364                 Strcat(info, ", dying from");
365                 if (u.usick_type & SICK_VOMITABLE)
366                         Strcat(info, " food poisoning");
367                 if (u.usick_type & SICK_NONVOMITABLE) {
368                         if (u.usick_type & SICK_VOMITABLE)
369                                 Strcat(info, " and");
370                         Strcat(info, " illness");
371                 }
372         }
373         if (Stoned)             Strcat(info, ", solidifying");
374         if (Slimed)             Strcat(info, ", becoming slimy");
375         if (Strangled)          Strcat(info, ", being strangled");
376         if (Vomiting)           Strcat(info, ", nauseated"); /* !"nauseous" */
377         if (Confusion)          Strcat(info, ", confused");
378         if (Blind) {
379             Strcat(info, ", blind");
380             if (u.ucreamed) {
381                 if ((long)u.ucreamed < Blinded || Blindfolded
382                                                 || !haseyes(youmonst.data))
383                     Strcat(info, ", cover");
384                 Strcat(info, "ed by sticky goop");
385             }   /* note: "goop" == "glop"; variation is intentional */
386         }
387         if (Stunned)            Strcat(info, ", stunned");
388 #ifdef STEED
389         if (!u.usteed)
390 #endif
391         if (Wounded_legs) {
392             const char *what = body_part(LEG);
393             if ((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
394                 what = makeplural(what);
395                                 Sprintf(eos(info), ", injured %s", what);
396         }
397         if (Glib)               Sprintf(eos(info), ", slippery %s",
398                                         makeplural(body_part(HAND)));
399         if (u.utrap)            Strcat(info, ", trapped");
400         if (Fast)               Strcat(info, Very_fast ?
401                                                 ", very fast" : ", fast");
402         if (u.uundetected)      Strcat(info, ", concealed");
403         if (Invis)              Strcat(info, ", invisible");
404         if (u.ustuck) {
405             if (sticks(youmonst.data))
406                 Strcat(info, ", holding ");
407             else
408                 Strcat(info, ", held by ");
409             Strcat(info, mon_nam(u.ustuck));
410         }
411
412         pline("Status of %s (%s%s):  Level %d  HP %d(%d)  AC %d%s.",
413                 plname,
414                     (u.ualign.record >= 20) ? "piously " :
415                     (u.ualign.record > 13) ? "devoutly " :
416                     (u.ualign.record > 8) ? "fervently " :
417                     (u.ualign.record > 3) ? "stridently " :
418                     (u.ualign.record == 3) ? "" :
419                     (u.ualign.record >= 1) ? "haltingly " :
420                     (u.ualign.record == 0) ? "nominally " :
421                                             "insufficiently ",
422                 align_str(u.ualign.type),
423                 Upolyd ? mons[u.umonnum].mlevel : u.ulevel,
424                 Upolyd ? u.mh : u.uhp,
425                 Upolyd ? u.mhmax : u.uhpmax,
426                 u.uac,
427                 info);
428 }
429
430 void
431 self_invis_message()
432 {
433         pline("%s %s.",
434             Hallucination ? "Far out, man!  You" : "Gee!  All of a sudden, you",
435             See_invisible ? "can see right through yourself" :
436                 "can't see yourself");
437 }
438
439 #endif /* OVLB */
440 /*pline.c*/