Blindfold removal fix
[slashemextended.git] / src / pline.c
blobe370bc66479df0af9a56485f66a9e745682b8ad0
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. */
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
12 #ifdef OVLB
14 static boolean no_repeat = FALSE;
16 static char *You_buf(int);
18 #if defined(DUMP_LOG)
19 char msgs[DUMPMSGS][BUFSZ];
20 int msgs_count[DUMPMSGS];
21 int lastmsg = -1;
22 #endif
24 void
25 msgpline_add(typ, pattern)
26 int typ;
27 char *pattern;
29 struct _plinemsg *tmp = (struct _plinemsg *) alloc(sizeof(struct _plinemsg));
30 if (!tmp) return;
31 tmp->msgtype = typ;
32 tmp->pattern = strdup(pattern);
33 tmp->next = pline_msg;
34 pline_msg = tmp;
37 void
38 msgpline_free()
40 struct _plinemsg *tmp = pline_msg;
41 struct _plinemsg *tmp2;
42 while (tmp) {
43 free(tmp->pattern);
44 tmp2 = tmp;
45 tmp = tmp->next;
46 free(tmp2);
48 pline_msg = NULL;
51 int
52 msgpline_type(msg)
53 char *msg;
55 struct _plinemsg *tmp = pline_msg;
56 while (tmp) {
57 if (pmatch(tmp->pattern, msg)) return tmp->msgtype;
58 tmp = tmp->next;
60 return MSGTYP_NORMAL;
63 /*VARARGS1*/
64 /* Note that these declarations rely on knowledge of the internals
65 * of the variable argument handling stuff in "tradstdc.h"
67 char * replace(const char *, const char *, const char *, BOOLEAN_P);
69 #if defined(USE_STDARG) || defined(USE_VARARGS)
70 static void vpline(const char *, va_list);
72 void
73 pline VA_DECL(const char *, line)
74 VA_START(line);
75 VA_INIT(line, char *);
76 vpline(line, VA_ARGS);
77 VA_END();
80 char prevmsg[BUFSZ];
82 # ifdef USE_STDARG
83 static void
84 vpline(const char *line, va_list the_args) {
85 # else
86 static void
87 vpline(line, the_args) const char *line; va_list the_args; {
88 # endif
90 #else /* USE_STDARG | USE_VARARG */
92 #define vpline pline
94 void
95 pline VA_DECL(const char *, line)
96 #endif /* USE_STDARG | USE_VARARG */
98 char pbuf[BUFSZ];
99 int typ;
100 /* Do NOT use VA_START and VA_END in here... see above */
102 if (!line || !*line) return;
104 if (program_state.done_hup)
105 return;
107 if (PlayerHearsMessages && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && rn2(3) && !u.captchahack
109 #if defined(WIN32)
110 && !program_state.exiting
111 #endif
113 ) line = fauxmessage();
115 if (SpellColorRed && !rn2(10) && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && !u.captchahack
117 #if defined(WIN32)
118 && !program_state.exiting
119 #endif
121 ) line = generate_garbage_string();
123 if (LLMMessages && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && !u.captchahack
125 /* buildfix by EternalEye: sinfo.exiting only exists on win32 */
126 #if defined(WIN32)
127 && !program_state.exiting
128 #endif
130 ) line = "Warning: Low Local Memory. Freeing description strings.";
132 if (MessagesSuppressed && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && !u.captchahack
133 #if defined(WIN32)
134 && !program_state.exiting
135 #endif
136 ) line = " ";
138 if (index(line, '%')) {
139 vsnprintf(pbuf,sizeof pbuf,line,VA_ARGS);
140 line = pbuf;
143 if (RotThirteenCipher && (strlen(line)<(BUFSZ-5)) &&(!program_state.in_impossible) ) {
145 line = replace(line,"a","N", FALSE);
146 line = replace(line,"b","O", FALSE);
147 line = replace(line,"c","P", FALSE);
148 line = replace(line,"d","Q", FALSE);
149 line = replace(line,"e","R", FALSE);
150 line = replace(line,"f","S", FALSE);
151 line = replace(line,"g","T", FALSE);
152 line = replace(line,"h","U", FALSE);
153 line = replace(line,"i","V", FALSE);
154 line = replace(line,"j","W", FALSE);
155 line = replace(line,"k","X", FALSE);
156 line = replace(line,"l","Y", FALSE);
157 line = replace(line,"m","Z", FALSE);
158 line = replace(line,"n","A", FALSE);
159 line = replace(line,"o","B", FALSE);
160 line = replace(line,"p","C", FALSE);
161 line = replace(line,"q","D", FALSE);
162 line = replace(line,"r","E", FALSE);
163 line = replace(line,"s","F", FALSE);
164 line = replace(line,"t","G", FALSE);
165 line = replace(line,"u","H", FALSE);
166 line = replace(line,"v","I", FALSE);
167 line = replace(line,"w","J", FALSE);
168 line = replace(line,"x","K", FALSE);
169 line = replace(line,"y","L", FALSE);
170 line = replace(line,"z","M", FALSE);
172 } else if (YouHaveBigscript && (strlen(line)<(BUFSZ-5)) &&(!program_state.in_impossible) ) {
174 line = replace(line,"a","A", FALSE);
175 line = replace(line,"b","B", FALSE);
176 line = replace(line,"c","C", FALSE);
177 line = replace(line,"d","D", FALSE);
178 line = replace(line,"e","E", FALSE);
179 line = replace(line,"f","F", FALSE);
180 line = replace(line,"g","G", FALSE);
181 line = replace(line,"h","H", FALSE);
182 line = replace(line,"i","I", FALSE);
183 line = replace(line,"j","J", FALSE);
184 line = replace(line,"k","K", FALSE);
185 line = replace(line,"l","L", FALSE);
186 line = replace(line,"m","M", FALSE);
187 line = replace(line,"n","N", FALSE);
188 line = replace(line,"o","O", FALSE);
189 line = replace(line,"p","P", FALSE);
190 line = replace(line,"q","Q", FALSE);
191 line = replace(line,"r","R", FALSE);
192 line = replace(line,"s","S", FALSE);
193 line = replace(line,"t","T", FALSE);
194 line = replace(line,"u","U", FALSE);
195 line = replace(line,"v","V", FALSE);
196 line = replace(line,"w","W", FALSE);
197 line = replace(line,"x","X", FALSE);
198 line = replace(line,"y","Y", FALSE);
199 line = replace(line,"z","Z", FALSE);
203 /*Intercept direct speach, inpossible() and very short or long Strings here*/
204 /* to cut down unnecesary calls to the now slower replace */
205 /* other checks like read must be done dynamically because */
206 /* they depent on position -CK */
207 /* right : Ye read "Here lies ..."
208 wrong : You read "Here lies ..."
209 wrong : Ye read "'er lies ..." */
210 if( (Role_if(PM_PIRATE) || Role_if(PM_KORSAIR) || PirateSpeakOn) &&(*line!='"')&&(strlen(line)<(BUFSZ-5))
211 &&(!program_state.in_impossible)
212 &&(strlen(line)>9)){
213 /* >9: "You die ..." but not "It hits." */
214 line = replace(line,"You","Ye", TRUE);
215 line = replace(line,"you","ye", TRUE);
216 line = replace(line,"His","'is", TRUE);
217 line = replace(line," his"," 'is", TRUE);
218 line = replace(line,"Her","'er", TRUE);
219 line = replace(line," her"," 'er", TRUE);
220 line = replace(line,"Are","Be", TRUE);
221 line = replace(line," are"," be", TRUE);
222 line = replace(line,"Is ","Be", TRUE);
223 line = replace(line," is "," be ", TRUE);
224 line = replace(line," is."," be.", TRUE);
225 line = replace(line," is,"," be,", TRUE);
226 if (Role_if(PM_KORSAIR) || (uwep && uwep->oartifact == ART_ARRRRRR_MATEY) ) { /* words beginning with a c will begin with a k for korsairs --Amy */
227 line = replace(line,"C","K", FALSE);
228 line = replace(line," c"," k", FALSE);
229 line = replace(line,"(c","(k", FALSE);
231 line = replace(line,"Is ","Be ", TRUE);
232 line = replace(line,"Of ","O' ", TRUE);
233 line = replace(line," of "," o' ", TRUE);
234 line = replace(line,"Of.","O'.", TRUE);
235 line = replace(line," of."," o'.", TRUE);
236 line = replace(line,"Of,","O',", TRUE);
237 line = replace(line," of,"," o',", TRUE);
238 line = replace(line," ear"," lug", TRUE);
239 line = replace(line,"Ear","Lug", TRUE);
240 line = replace(line,"eye","deadlight", TRUE);
241 line = replace(line,"Eye","Deadlight", TRUE);
242 /* If orkmid isn't contained, save some time -CK */
243 if(strstr(line,"orkmid") )
245 line = replace(line,"zorkmids ","doubloons ", TRUE);
246 line = replace(line,"Zorkmids ","Doubloons ", TRUE);
247 line = replace(line,"zorkmids.","doubloons.", TRUE);
248 line = replace(line,"Zorkmids.","Doubloons.", TRUE);
249 line = replace(line,"zorkmids,","doubloons,", TRUE);
250 line = replace(line,"Zorkmids,","Doubloons,", TRUE);
251 line = replace(line,"zorkmids)","doubloons)", TRUE);
252 line = replace(line,"Zorkmids)","Doubloons)", TRUE);
253 line = replace(line,"zorkmid ","doubloon ", TRUE);
254 line = replace(line,"Zorkmid ","Doubloon ", TRUE);
255 line = replace(line,"zorkmid.","doubloon.", TRUE);
256 line = replace(line,"Zorkmid.","Doubloon.", TRUE);
257 line = replace(line,"zorkmid,","doubloon,", TRUE);
258 line = replace(line,"Zorkmid,","Doubloon,", TRUE);
259 line = replace(line,"zorkmid)","doubloon)", TRUE);
260 line = replace(line,"Zorkmid)","Doubloon)", TRUE);
261 } /* endif orkmid */
262 /* If old coin isn't contained, save some time -CK */
263 if(strstr(line,"old coin") )
265 line = replace(line,"gold coins","pieces of eight", TRUE);
266 line = replace(line,"Gold coins","Pieces of eight", TRUE);
267 line = replace(line,"gold coin","piece of eight", TRUE);
268 line = replace(line,"Gold coin","Piece of eight", TRUE);
270 /* If old piece isn't contained, save some time -CK */
271 if(strstr(line,"old piece") )
273 line = replace(line,"gold pieces.","pieces of eight", TRUE);
274 line = replace(line,"Gold pieces.","Pieces of eight", TRUE);
275 line = replace(line,"gold pieces,","pieces of eight", TRUE);
276 line = replace(line,"Gold pieces,","Pieces of eight", TRUE);
277 line = replace(line,"gold pieces ","pieces of eight", TRUE);
278 line = replace(line,"Gold pieces ","Pieces of eight", TRUE);
279 line = replace(line,"gold piece.","piece of eight", TRUE);
280 line = replace(line,"Gold piece.","Piece of eight", TRUE);
281 line = replace(line,"gold piece,","piece of eight", TRUE);
282 line = replace(line,"Gold piece,","Piece of eight", TRUE);
283 line = replace(line,"gold piece ","piece of eight", TRUE);
284 line = replace(line,"Gold piece ","Piece of eight", TRUE);
285 } /* endif old piece */
286 } /* endif role_if(PM_PIRATE),etc. */
288 /* ZAPM has buckazoids; shopkeepers and stuff will also use that term, so no check for direct speech --Amy */
289 if (zapmrename() && (strlen(line)<(BUFSZ-5))
290 &&(!program_state.in_impossible)
291 &&(strlen(line)>9)) {
292 if(strstr(line,"orkmid") )
294 line = replace(line,"zorkmids ","buckazoids ", FALSE);
295 line = replace(line,"Zorkmids ","Buckazoids ", FALSE);
296 line = replace(line,"zorkmids.","buckazoids.", FALSE);
297 line = replace(line,"Zorkmids.","Buckazoids.", FALSE);
298 line = replace(line,"zorkmids,","buckazoids,", FALSE);
299 line = replace(line,"Zorkmids,","Buckazoids,", FALSE);
300 line = replace(line,"zorkmids)","buckazoids)", FALSE);
301 line = replace(line,"Zorkmids)","Buckazoids)", FALSE);
302 line = replace(line,"zorkmid ","buckazoid ", FALSE);
303 line = replace(line,"Zorkmid ","Buckazoid ", FALSE);
304 line = replace(line,"zorkmid.","buckazoid.", FALSE);
305 line = replace(line,"Zorkmid.","Buckazoid.", FALSE);
306 line = replace(line,"zorkmid,","buckazoid,", FALSE);
307 line = replace(line,"Zorkmid,","Buckazoid,", FALSE);
308 line = replace(line,"zorkmid)","buckazoid)", FALSE);
309 line = replace(line,"Zorkmid)","Buckazoid)", FALSE);
310 } /* endif orkmid */
311 /* If old coin isn't contained, save some time -CK */
312 if(strstr(line,"old coin") )
314 line = replace(line,"gold coins","buckazoids", FALSE);
315 line = replace(line,"Gold coins","Buckazoids", FALSE);
316 line = replace(line,"gold coin","buckazoids", FALSE);
317 line = replace(line,"Gold coin","Buckazoids", FALSE);
319 /* If old piece isn't contained, save some time -CK */
320 if(strstr(line,"old piece") )
322 line = replace(line,"gold pieces.","buckazoids.", FALSE);
323 line = replace(line,"Gold pieces.","Buckazoids.", FALSE);
324 line = replace(line,"gold pieces,","buckazoids,", FALSE);
325 line = replace(line,"Gold pieces,","Buckazoids,", FALSE);
326 line = replace(line,"gold pieces ","buckazoids ", FALSE);
327 line = replace(line,"Gold pieces ","Buckazoids ", FALSE);
328 line = replace(line,"gold pieces","buckazoids", FALSE);
329 line = replace(line,"Gold pieces","Buckazoids", FALSE);
330 line = replace(line,"gold piece.","buckazoid.", FALSE);
331 line = replace(line,"Gold piece.","Buckazoid.", FALSE);
332 line = replace(line,"gold piece,","buckazoid,", FALSE);
333 line = replace(line,"Gold piece,","Buckazoid,", FALSE);
334 line = replace(line,"gold piece ","buckazoid ", FALSE);
335 line = replace(line,"Gold piece ","Buckazoid ", FALSE);
336 line = replace(line,"gold piece","buckazoid", FALSE);
337 line = replace(line,"Gold piece","Buckazoid", FALSE);
338 } /* endif old piece */
339 } /* endif ZAPM etc. */
341 if (u.wollohhack && !program_state.in_impossible && (strlen(line)<(BUFSZ-20)) ) {
342 line = replace(line,".",", wolloh.", FALSE);
343 line = replace(line,"!",", wolloh!", FALSE);
344 line = replace(line,", ",", wolloh, ", FALSE);
348 if ( (UmengEffect || u.uprops[UMENG_EFFECT].extrinsic || have_umengstone() ) && !program_state.in_impossible && (strlen(line)<(BUFSZ-20)) ) {
349 if (UmengXtra) line = replace(line,",",", alter ich hab umeng geschrieben", FALSE);
350 else line = replace(line,",",", umeng", FALSE);
353 #if defined(DUMP_LOG)
354 if (DUMPMSGS > 0 && !program_state.gameover) {
355 /* count identical messages */
356 if (!strncmp(msgs[lastmsg], line, BUFSZ)) {
357 msgs_count[lastmsg] += 1;
358 } else if (strncmp(line, "Unknown command", 15) ) {
359 lastmsg = (lastmsg + 1) % DUMPMSGS;
360 strncpy(msgs[lastmsg], line, BUFSZ);
361 msgs_count[lastmsg] = 1;
364 #endif
366 typ = msgpline_type(line);
367 if (!iflags.window_inited) {
368 raw_print(line);
369 return;
371 #ifndef MAC
372 if (no_repeat && !strcmp(line, toplines))
373 return;
374 #endif /* MAC */
375 if (vision_full_recalc) vision_recalc(0);
376 if (u.ux) flush_screen(1); /* %% */
377 if (typ == MSGTYP_NOSHOW && !(MommaBugEffect || u.uprops[MOMMA_BUG].extrinsic || (uimplant && uimplant->oartifact == ART_DEINE_MUDDA) || have_mommystone()) && !autismweaponcheck(ART_BRAND_BRAND) && !(uarmf && uarmf->oartifact == ART_GRENEUVENIA_S_HUG)) return;
378 if (typ == MSGTYP_NOREP && !(MommaBugEffect || u.uprops[MOMMA_BUG].extrinsic || (uimplant && uimplant->oartifact == ART_DEINE_MUDDA) || have_mommystone()) && !autismweaponcheck(ART_BRAND_BRAND) && !(uarmf && uarmf->oartifact == ART_GRENEUVENIA_S_HUG) && !strcmp(line, prevmsg)) return;
379 putstr(WIN_MESSAGE, 0, line);
381 if (HeapEffectBug || u.uprops[HEAP_EFFECT].extrinsic || have_heapstone() || autismweaponcheck(ART_ESSCOOAHLIPBOOURRR) || (uarm && uarm->oartifact == ART_CANNOT_BE_HARMED_BLA_BLA) ) {
382 int heaping = rno(4);
383 if (!rn2(7)) heaping += rno(8);
384 while (heaping > 0) {
385 heaping--;
386 putstr(WIN_MESSAGE, 0, line);
390 strncpy(prevmsg, line, BUFSZ);
391 if (typ == MSGTYP_STOP && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */
394 /*VARARGS1*/
395 void
396 Norep VA_DECL(const char *, line)
397 VA_START(line);
398 VA_INIT(line, const char *);
399 no_repeat = TRUE;
400 vpline(line, VA_ARGS);
401 no_repeat = FALSE;
402 VA_END();
403 return;
406 /* work buffer for You(), &c and verbalize() */
407 static char *you_buf = 0;
408 static int you_buf_siz = 0;
410 static char *
411 You_buf(siz)
412 int siz;
414 if (siz > you_buf_siz) {
415 if (you_buf) free((void *) you_buf);
416 you_buf_siz = siz + 10;
417 you_buf = (char *) alloc((unsigned) you_buf_siz);
419 return you_buf;
422 void
423 free_youbuf()
425 if (you_buf) free((void *) you_buf), you_buf = (char *)0;
426 you_buf_siz = 0;
429 /* `prefix' must be a string literal, not a pointer */
430 #define YouPrefix(pointer,prefix,text) \
431 strcpy((pointer = You_buf((int)(strlen(text) + sizeof prefix))), prefix)
433 #define YouMessage(pointer,prefix,text) \
434 strcat((YouPrefix(pointer, prefix, text), pointer), text)
436 /*VARARGS1*/
437 void
438 You VA_DECL(const char *, line)
439 char *tmp;
440 VA_START(line);
441 VA_INIT(line, const char *);
442 if ((FilteringBug || u.uprops[FILTERING_BUG].extrinsic || have_filteringstone()) && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && rn2(5))
443 vpline(fauxmessage(), VA_ARGS);
444 else
445 vpline(YouMessage(tmp, "You ", line), VA_ARGS);
446 VA_END();
449 /*VARARGS1*/
450 void
451 Your VA_DECL(const char *,line)
452 char *tmp;
453 VA_START(line);
454 VA_INIT(line, const char *);
455 if ((FilteringBug || u.uprops[FILTERING_BUG].extrinsic || have_filteringstone()) && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && rn2(5))
456 vpline(fauxmessage(), VA_ARGS);
457 else
458 vpline(YouMessage(tmp, "Your ", line), VA_ARGS);
459 VA_END();
462 /*VARARGS1*/
463 void
464 You_feel VA_DECL(const char *,line)
465 char *tmp;
466 VA_START(line);
467 VA_INIT(line, const char *);
468 if ((FilteringBug || u.uprops[FILTERING_BUG].extrinsic || have_filteringstone()) && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && rn2(5))
469 vpline(fauxmessage(), VA_ARGS);
470 else
471 vpline(YouMessage(tmp, "You feel ", line), VA_ARGS);
472 VA_END();
476 /*VARARGS1*/
477 void
478 You_cant VA_DECL(const char *,line)
479 char *tmp;
480 VA_START(line);
481 VA_INIT(line, const char *);
482 if ((FilteringBug || u.uprops[FILTERING_BUG].extrinsic || have_filteringstone()) && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && rn2(5))
483 vpline(fauxmessage(), VA_ARGS);
484 else
485 vpline(YouMessage(tmp, "You can't ", line), VA_ARGS);
486 VA_END();
489 /*VARARGS1*/
490 void
491 pline_The VA_DECL(const char *,line)
492 char *tmp;
493 VA_START(line);
494 VA_INIT(line, const char *);
495 if ((FilteringBug || u.uprops[FILTERING_BUG].extrinsic || have_filteringstone()) && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && rn2(5))
496 vpline(fauxmessage(), VA_ARGS);
497 else
498 vpline(YouMessage(tmp, "The ", line), VA_ARGS);
499 VA_END();
502 /*VARARGS1*/
503 void
504 There VA_DECL(const char *,line)
505 char *tmp;
506 VA_START(line);
507 VA_INIT(line, const char *);
508 if ((FilteringBug || u.uprops[FILTERING_BUG].extrinsic || have_filteringstone()) && !program_state.in_impossible && !program_state.in_paniclog && !program_state.panicking && !program_state.gameover && rn2(5))
509 vpline(fauxmessage(), VA_ARGS);
510 else
511 vpline(YouMessage(tmp, "There ", line), VA_ARGS);
512 VA_END();
515 /*VARARGS1*/
516 void
517 You_hear VA_DECL(const char *,line)
518 char *tmp;
519 VA_START(line);
520 VA_INIT(line, const char *);
521 if (Underwater)
522 YouPrefix(tmp, "You barely hear ", line);
523 else if (u.usleep)
524 YouPrefix(tmp, "You dream that you hear ", line);
525 else
526 YouPrefix(tmp, "You hear ", line);
527 vpline(strcat(tmp, line), VA_ARGS);
528 VA_END();
531 /*VARARGS1*/
532 void
533 verbalize VA_DECL(const char *,line)
534 char *tmp;
535 if (!flags.soundok) return;
536 VA_START(line);
537 VA_INIT(line, const char *);
538 tmp = You_buf((int)strlen(line) + sizeof "\"\"");
539 strcpy(tmp, "\"");
540 strcat(tmp, line);
541 strcat(tmp, "\"");
542 vpline(tmp, VA_ARGS);
543 VA_END();
546 /*VARARGS1*/
547 /* Note that these declarations rely on knowledge of the internals
548 * of the variable argument handling stuff in "tradstdc.h"
551 #if defined(USE_STDARG) || defined(USE_VARARGS)
552 static void vraw_printf(const char *,va_list);
554 void
555 raw_printf VA_DECL(const char *, line)
556 VA_START(line);
557 VA_INIT(line, char *);
558 vraw_printf(line, VA_ARGS);
559 VA_END();
562 # ifdef USE_STDARG
563 static void
564 vraw_printf(const char *line, va_list the_args) {
565 # else
566 static void
567 vraw_printf(line, the_args) const char *line; va_list the_args; {
568 # endif
570 #else /* USE_STDARG | USE_VARARG */
572 void
573 raw_printf VA_DECL(const char *, line)
574 #endif
575 /* Do NOT use VA_START and VA_END in here... see above */
577 if(!index(line, '%'))
578 raw_print(line);
579 else {
580 char pbuf[BUFSZ];
581 vsnprintf(pbuf,sizeof pbuf,line,VA_ARGS);
582 raw_print(pbuf);
587 /*VARARGS1*/
588 void
589 impossible VA_DECL(const char *, s)
591 char pbuf[BUFSZ];
592 VA_START(s);
593 VA_INIT(s, const char *);
594 if (program_state.in_impossible)
595 panic("impossible called impossible");
596 program_state.in_impossible = 1;
597 vsnprintf(pbuf,sizeof pbuf,s,VA_ARGS);
598 pbuf[BUFSZ-1] = '\0'; /* sanity */
599 paniclog("impossible", pbuf);
600 pline("%s", pbuf); /*used to be vpline(s,VA_ARGS); but that was causing funky issues --Amy */
601 pline("Program in disorder. Please inform Amy about this bug.");
602 pline("The admins can be contacted on the #em.slashem.me IRC channel (Libera).");
603 program_state.in_impossible = 0;
604 VA_END();
608 const char *
609 align_str(alignment)
610 aligntyp alignment;
612 switch ((int)alignment) {
613 case A_CHAOTIC: return "chaotic";
614 case A_NEUTRAL: return "neutral";
615 case A_LAWFUL: return "lawful";
616 case A_NONE: return "unaligned";
618 return "unknown";
621 const char *
622 hybrid_str()
624 static char string[BUFSZ];
625 *string = '\0';
627 int hybridcount = 0;
629 if (flags.hybridangbander && (hybridcount++ < 20)) sprintf(eos(string), "angbander ");
630 if (flags.hybridaquarian && (hybridcount++ < 20)) sprintf(eos(string), "aquarian ");
631 if (flags.hybridcurser && (hybridcount++ < 20)) sprintf(eos(string), "curser ");
632 if (flags.hybridhaxor && (hybridcount++ < 20)) sprintf(eos(string), "haxor ");
633 if (flags.hybridhomicider && (hybridcount++ < 20)) sprintf(eos(string), "homicider ");
634 if (flags.hybridsuxxor && (hybridcount++ < 20)) sprintf(eos(string), "suxxor ");
635 if (flags.hybridwarper && (hybridcount++ < 20)) sprintf(eos(string), "warper ");
636 if (flags.hybridrandomizer && (hybridcount++ < 20)) sprintf(eos(string), "randomizer ");
637 if (flags.hybridnullrace && (hybridcount++ < 20)) sprintf(eos(string), "null ");
638 if (flags.hybridmazewalker && (hybridcount++ < 20)) sprintf(eos(string), "mazewalker ");
639 if (flags.hybridsoviet && (hybridcount++ < 20)) sprintf(eos(string), "soviet ");
640 if (flags.hybridxrace && (hybridcount++ < 20)) sprintf(eos(string), "x-race ");
641 if (flags.hybridheretic && (hybridcount++ < 20)) sprintf(eos(string), "heretic ");
642 if (flags.hybridsokosolver && (hybridcount++ < 20)) sprintf(eos(string), "sokosolver ");
643 if (flags.hybridspecialist && (hybridcount++ < 20)) sprintf(eos(string), "specialist ");
644 if (flags.hybridamerican && (hybridcount++ < 20)) sprintf(eos(string), "american ");
645 if (flags.hybridminimalist && (hybridcount++ < 20)) sprintf(eos(string), "minimalist ");
646 if (flags.hybridnastinator && (hybridcount++ < 20)) sprintf(eos(string), "nastinator ");
647 if (flags.hybridrougelike && (hybridcount++ < 20)) sprintf(eos(string), "rougelike ");
648 if (flags.hybridsegfaulter && (hybridcount++ < 20)) sprintf(eos(string), "segfaulter ");
649 if (flags.hybridironman && (hybridcount++ < 20)) sprintf(eos(string), "ironman ");
650 if (flags.hybridamnesiac && (hybridcount++ < 20)) sprintf(eos(string), "amnesiac ");
651 if (flags.hybridproblematic && (hybridcount++ < 20)) sprintf(eos(string), "problematic ");
652 if (flags.hybridwindinhabitant && (hybridcount++ < 20)) sprintf(eos(string), "windinhabitant ");
653 if (flags.hybridaggravator && (hybridcount++ < 20)) sprintf(eos(string), "aggravator ");
654 if (flags.hybridevilvariant && (hybridcount++ < 20)) sprintf(eos(string), "evilvariant ");
655 if (flags.hybridlevelscaler && (hybridcount++ < 20)) sprintf(eos(string), "levelscaler ");
656 if (flags.hybriderosator && (hybridcount++ < 20)) sprintf(eos(string), "erosator ");
657 if (flags.hybridroommate && (hybridcount++ < 20)) sprintf(eos(string), "roommate ");
658 if (flags.hybridextravator && (hybridcount++ < 20)) sprintf(eos(string), "extravator ");
659 if (flags.hybridhallucinator && (hybridcount++ < 20)) sprintf(eos(string), "hallucinator ");
660 if (flags.hybridbossrusher && (hybridcount++ < 20)) sprintf(eos(string), "bossrusher ");
661 if (flags.hybriddorian && (hybridcount++ < 20)) sprintf(eos(string), "dorian ");
662 if (flags.hybridtechless && (hybridcount++ < 20)) sprintf(eos(string), "techless ");
663 if (flags.hybridblait && (hybridcount++ < 20)) sprintf(eos(string), "blait ");
664 if (flags.hybridgrouper && (hybridcount++ < 20)) sprintf(eos(string), "grouper ");
665 if (flags.hybridscriptor && (hybridcount++ < 20)) sprintf(eos(string), "scriptor ");
666 if (flags.hybridunbalancor && (hybridcount++ < 20)) sprintf(eos(string), "unbalancor ");
667 if (flags.hybridbeacher && (hybridcount++ < 20)) sprintf(eos(string), "beacher ");
668 if (flags.hybridstairseeker && (hybridcount++ < 20)) sprintf(eos(string), "stairseeker ");
669 if (flags.hybridmatrayser && (hybridcount++ < 20)) sprintf(eos(string), "matrayser ");
670 if (flags.hybridfeminizer && (hybridcount++ < 20)) sprintf(eos(string), "feminizer ");
671 if (flags.hybridchallenger && (hybridcount++ < 20)) sprintf(eos(string), "challenger ");
672 if (flags.hybridhardmoder && (hybridcount++ < 20)) sprintf(eos(string), "hardmoder ");
673 if (flags.hybridstunfish && (hybridcount++ < 20)) sprintf(eos(string), "stunned-like-a-fish ");
674 if (flags.hybridkillfiller && (hybridcount++ < 20)) sprintf(eos(string), "killfiller ");
675 if (flags.hybridbadstatter && (hybridcount++ < 20)) sprintf(eos(string), "badstatter ");
676 if (flags.hybriddroughter && (hybridcount++ < 20)) sprintf(eos(string), "droughter ");
677 if (flags.hybridvanillaoid && (hybridcount++ < 20)) sprintf(eos(string), "vanillaoid ");
678 if (hybridcount >= 20) sprintf(eos(string), "(%d hybrids) ", hybridcount);
680 if (!(flags.hybridangbander) && !(flags.hybridaquarian) && !(flags.hybridcurser) && !(flags.hybridhaxor) && !(flags.hybridhomicider) && !(flags.hybridsuxxor) && !(flags.hybridwarper) && !(flags.hybridrandomizer) && !(flags.hybridnullrace) && !(flags.hybridmazewalker) && !(flags.hybridsoviet) && !(flags.hybridxrace) && !(flags.hybridheretic) && !(flags.hybridsokosolver) && !(flags.hybridspecialist) && !(flags.hybridamerican) && !(flags.hybridminimalist) && !(flags.hybridnastinator) && !(flags.hybridrougelike) && !(flags.hybridsegfaulter) && !(flags.hybridironman) && !(flags.hybridamnesiac) && !(flags.hybridproblematic) && !(flags.hybridwindinhabitant) && !(flags.hybridaggravator) && !(flags.hybridevilvariant) && !(flags.hybridlevelscaler) && !(flags.hybriderosator) && !(flags.hybridroommate) && !(flags.hybridextravator) && !(flags.hybridhallucinator) && !(flags.hybridbossrusher) && !(flags.hybriddorian) && !(flags.hybridtechless) && !(flags.hybridblait) && !(flags.hybridgrouper) && !(flags.hybridscriptor) && !(flags.hybridunbalancor) && !(flags.hybridbeacher) && !(flags.hybridstairseeker) && !(flags.hybridmatrayser) && !(flags.hybridbadstatter) && !(flags.hybridvanillaoid) && !(flags.hybridfeminizer) && !(flags.hybridchallenger) && !(flags.hybridhardmoder) && !(flags.hybridkillfiller) && !(flags.hybriddroughter) && !(flags.hybridstunfish)) sprintf(eos(string), "none ");
682 return (string);
685 const char *
686 hybrid_strcode()
688 static char string[BUFSZ];
689 *string = '\0';
690 if (flags.hybridangbander) sprintf(eos(string), "Agb");
691 if (flags.hybridaquarian) sprintf(eos(string), "Aqu");
692 if (flags.hybridcurser) sprintf(eos(string), "Cur");
693 if (flags.hybridhaxor) sprintf(eos(string), "Hax");
694 if (flags.hybridhomicider) sprintf(eos(string), "Hom");
695 if (flags.hybridsuxxor) sprintf(eos(string), "Sux");
696 if (flags.hybridwarper) sprintf(eos(string), "War");
697 if (flags.hybridrandomizer) sprintf(eos(string), "Ran");
698 if (flags.hybridnullrace) sprintf(eos(string), "Nul");
699 if (flags.hybridmazewalker) sprintf(eos(string), "Maz");
700 if (flags.hybridsoviet) sprintf(eos(string), "Sov");
701 if (flags.hybridxrace) sprintf(eos(string), "Xra");
702 if (flags.hybridheretic) sprintf(eos(string), "Her");
703 if (flags.hybridsokosolver) sprintf(eos(string), "Sok");
704 if (flags.hybridspecialist) sprintf(eos(string), "Spe");
705 if (flags.hybridamerican) sprintf(eos(string), "Ame");
706 if (flags.hybridminimalist) sprintf(eos(string), "Min");
707 if (flags.hybridnastinator) sprintf(eos(string), "Nas");
708 if (flags.hybridrougelike) sprintf(eos(string), "Rou");
709 if (flags.hybridsegfaulter) sprintf(eos(string), "Seg");
710 if (flags.hybridironman) sprintf(eos(string), "Iro");
711 if (flags.hybridamnesiac) sprintf(eos(string), "Amn");
712 if (flags.hybridproblematic) sprintf(eos(string), "Pro");
713 if (flags.hybridwindinhabitant) sprintf(eos(string), "Win");
714 if (flags.hybridaggravator) sprintf(eos(string), "Agg");
715 if (flags.hybridevilvariant) sprintf(eos(string), "Evi");
716 if (flags.hybridlevelscaler) sprintf(eos(string), "Lvl");
717 if (flags.hybriderosator) sprintf(eos(string), "Ero");
718 if (flags.hybridroommate) sprintf(eos(string), "Roo");
719 if (flags.hybridextravator) sprintf(eos(string), "Ext");
720 if (flags.hybridhallucinator) sprintf(eos(string), "Hal");
721 if (flags.hybridbossrusher) sprintf(eos(string), "Bos");
722 if (flags.hybriddorian) sprintf(eos(string), "Dor");
723 if (flags.hybridtechless) sprintf(eos(string), "Tec");
724 if (flags.hybridblait) sprintf(eos(string), "Bla");
725 if (flags.hybridgrouper) sprintf(eos(string), "Gro");
726 if (flags.hybridscriptor) sprintf(eos(string), "Scr");
727 if (flags.hybridunbalancor) sprintf(eos(string), "Unb");
728 if (flags.hybridbeacher) sprintf(eos(string), "Bea");
729 if (flags.hybridstairseeker) sprintf(eos(string), "Sta");
730 if (flags.hybridmatrayser) sprintf(eos(string), "Mat");
731 if (flags.hybridfeminizer) sprintf(eos(string), "Fem");
732 if (flags.hybridchallenger) sprintf(eos(string), "Cha");
733 if (flags.hybridhardmoder) sprintf(eos(string), "Har");
734 if (flags.hybridstunfish) sprintf(eos(string), "Stu");
735 if (flags.hybridkillfiller) sprintf(eos(string), "Kil");
736 if (flags.hybridbadstatter) sprintf(eos(string), "Bad");
737 if (flags.hybriddroughter) sprintf(eos(string), "Dgh");
738 if (flags.hybridvanillaoid) sprintf(eos(string), "Van");
740 if (!(flags.hybridangbander) && !(flags.hybridaquarian) && !(flags.hybridcurser) && !(flags.hybridhaxor) && !(flags.hybridhomicider) && !(flags.hybridsuxxor) && !(flags.hybridwarper) && !(flags.hybridrandomizer) && !(flags.hybridnullrace) && !(flags.hybridmazewalker) && !(flags.hybridsoviet) && !(flags.hybridxrace) && !(flags.hybridheretic) && !(flags.hybridsokosolver) && !(flags.hybridspecialist) && !(flags.hybridamerican) && !(flags.hybridminimalist) && !(flags.hybridnastinator) && !(flags.hybridrougelike) && !(flags.hybridsegfaulter) && !(flags.hybridironman) && !(flags.hybridamnesiac) && !(flags.hybridproblematic) && !(flags.hybridwindinhabitant) && !(flags.hybridaggravator) && !(flags.hybridevilvariant) && !(flags.hybridlevelscaler) && !(flags.hybriderosator) && !(flags.hybridroommate) && !(flags.hybridextravator) && !(flags.hybridhallucinator) && !(flags.hybridbossrusher) && !(flags.hybriddorian) && !(flags.hybridtechless) && !(flags.hybridblait) && !(flags.hybridgrouper) && !(flags.hybridscriptor) && !(flags.hybridunbalancor) && !(flags.hybridbeacher) && !(flags.hybridstairseeker) && !(flags.hybridmatrayser) && !(flags.hybridbadstatter) && !(flags.hybridfeminizer) && !(flags.hybridchallenger) && !(flags.hybridhardmoder) && !(flags.hybridkillfiller) && !(flags.hybridvanillaoid) && !(flags.hybriddroughter) && !(flags.hybridstunfish)) sprintf(eos(string), "none ");
742 return (string);
745 const char *
746 generate_garbage_string()
748 static char string[BUFSZ];
749 string[0] = '\0';
751 char tmpstr[2] = {0, 0};
753 int stringlength = rnd(25);
754 if (!rn2(10)) stringlength += rnd(25);
756 while (stringlength --> 0) {
757 #ifdef UNIX
758 /* Sadly, terminals can be screwed up if we use "unsafe" glyphs. Sure, this is SLEX, interface screws
759 * are meant to be a part of the game, but we don't want to fuck up the player's actual terminal session.
760 * After all, even SLEX has limits. Therefore we need to limit the strings to "safe" glyphs. --Amy */
761 tmpstr[0] = 32 + rnd(94);
762 #else
763 tmpstr[0] = rnd(255);
764 #endif
766 /* get rid of some control codes that mess everything up */
767 switch (tmpstr[0]) {
768 case 7: case 10: case 11: case 13: case '%':
769 tmpstr[0] = ' ';
772 sprintf(eos(string), "%s", tmpstr);
775 return string;
778 const char *
779 generate_garbage_char()
781 static char string[BUFSZ];
782 string[0] = '\0';
784 char tmpstr[2] = {0, 0};
786 #ifdef UNIX
787 tmpstr[0] = 32 + rnd(94);
788 #else
789 tmpstr[0] = rnd(255);
790 #endif
792 /* get rid of some control codes that mess everything up */
793 switch (tmpstr[0]) {
794 case 7: case 10: case 11: case 13: case '%':
795 tmpstr[0] = ' ';
797 tmpstr[1] = '\0';
799 sprintf(eos(string), "%s", tmpstr);
801 return string;
804 void
805 mstatuslinestats(mtmp)
806 register struct monst *mtmp;
808 char info[BUFSZ], monnambuf[BUFSZ];
809 info[0] = 0;
811 if (mtmp->meating) strcat(info, ", eating");
812 if (mtmp->mcan) strcat(info, ", cancelled");
813 if (mtmp->mconf) strcat(info, ", confused");
814 if (mtmp->healblock) strcat(info, ", healing blocked");
815 if (mtmp->inertia) strcat(info, ", slowed by inertia");
816 if (mtmp->bleedout) strcat(info, ", bleeding");
817 if (mtmp->mblinded || !mtmp->mcansee)
818 strcat(info, ", blind");
819 if (mtmp->mstun) strcat(info, ", stunned");
820 if (mtmp->msleeping) strcat(info, ", asleep");
821 #if 0 /* unfortunately mfrozen covers temporary sleep and being busy
822 (donning armor, for instance) as well as paralysis */
823 else if (mtmp->mfrozen) strcat(info, ", paralyzed");
824 #else
825 else if (mtmp->mfrozen || !mtmp->mcanmove) {
826 strcat(info, ", can't move");
827 if (mtmp->masleep) strcat(info, " (sleeping)");
829 #endif
830 /* [arbitrary reason why it isn't moving] */
831 else if (mtmp->mstrategy & STRAT_WAITMASK)
832 strcat(info, ", meditating");
833 else if (mtmp->mflee) strcat(info, ", scared");
835 if (mtmp->mtrapped) strcat(info, ", trapped");
836 if (mtmp->mspeed) strcat(info,
837 mtmp->mspeed == MFAST ? ", fast" :
838 mtmp->mspeed == MSLOW ? ", slow" :
839 ", ???? speed");
840 if (mtmp->mundetected) strcat(info, ", concealed");
841 if (mtmp->minvis) strcat(info, ", invisible");
842 if (mtmp == u.ustuck) strcat(info,
843 (sticks(youmonst.data)) ? ", held by you" :
844 u.uswallow ? (is_animal(u.ustuck->data) ?
845 ", swallowed you" :
846 ", engulfed you") :
847 ", holding you");
848 if (mtmp == u.usteed) strcat(info, ", carrying you");
849 if (mtmp->butthurt) sprintf(eos(info), ", butthurt (%d)", mtmp->butthurt);
851 /* avoid "Status of the invisible newt ..., invisible" */
852 /* and unlike a normal mon_nam, use "saddled" even if it has a name */
853 strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *)0,
854 (SUPPRESS_IT|SUPPRESS_INVISIBLE), FALSE));
855 sprintf(eos(monnambuf), " (%s)", Hallucination ? "sparkly dood" : sanityrandomname() ? rndmonnam() : mtmp->data->mname);
857 pline("%s%s.", monnambuf, info);
861 void
862 mstatusline(mtmp)
863 register struct monst *mtmp;
865 aligntyp alignment;
866 char info[BUFSZ], monnambuf[BUFSZ];
868 if (mtmp->ispriest || mtmp->data == &mons[PM_ALIGNED_PRIEST] || mtmp->data == &mons[PM_ELITE_PRIEST] || mtmp->data == &mons[PM_MASTER_PRIEST] || mtmp->data == &mons[PM_EXPERIENCED_PRIEST] || mtmp->data == &mons[PM_EXCEPTIONAL_PRIEST]
869 || mtmp->data == &mons[PM_ANGEL])
870 alignment = EPRI(mtmp)->shralign;
871 else
872 alignment = mtmp->data->maligntyp;
873 alignment = (alignment > 0) ? A_LAWFUL :
874 (alignment < 0) ? A_CHAOTIC :
875 A_NEUTRAL;
877 info[0] = 0;
878 if (mtmp->mtame) { strcat(info, ", tame");
879 #ifdef WIZARD
880 if (wizard) {
881 sprintf(eos(info), " (%d", mtmp->mtame);
882 if (!mtmp->isminion)
883 sprintf(eos(info), "; hungry %ld; apport %d; abuse %d",
884 EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport, EDOG(mtmp)->abuse);
885 strcat(info, ")");
887 #endif
889 else if (mtmp->mpeaceful) strcat(info, ", peaceful");
890 else if (mtmp->mtraitor) strcat(info, ", traitor");
891 if (mtmp->meating) strcat(info, ", eating");
892 if (mtmp->mcan) strcat(info, ", cancelled");
893 if (mtmp->mconf) strcat(info, ", confused");
894 if (mtmp->healblock) strcat(info, ", healing blocked");
895 if (mtmp->inertia) strcat(info, ", slowed by inertia");
896 if (mtmp->bleedout) strcat(info, ", bleeding");
897 if (mtmp->mblinded || !mtmp->mcansee)
898 strcat(info, ", blind");
899 if (mtmp->mstun) strcat(info, ", stunned");
900 if (mtmp->msleeping) strcat(info, ", asleep");
901 #if 0 /* unfortunately mfrozen covers temporary sleep and being busy
902 (donning armor, for instance) as well as paralysis */
903 else if (mtmp->mfrozen) strcat(info, ", paralyzed");
904 #else
905 else if (mtmp->mfrozen || !mtmp->mcanmove) {
906 strcat(info, ", can't move");
907 if (mtmp->masleep) strcat(info, " (sleeping)");
909 #endif
910 /* [arbitrary reason why it isn't moving] */
911 else if (mtmp->mstrategy & STRAT_WAITMASK)
912 strcat(info, ", meditating");
913 else if (mtmp->mflee) { strcat(info, ", scared");
914 #ifdef WIZARD
915 if (wizard) sprintf(eos(info), " (%d)", mtmp->mfleetim);
916 #endif
918 if (mtmp->mtrapped) strcat(info, ", trapped");
919 if (mtmp->mspeed) strcat(info,
920 mtmp->mspeed == MFAST ? ", fast" :
921 mtmp->mspeed == MSLOW ? ", slow" :
922 ", ???? speed");
923 if (mtmp->mundetected) strcat(info, ", concealed");
924 if (mtmp->minvis) strcat(info, ", invisible");
925 if (mtmp == u.ustuck) strcat(info,
926 (sticks(youmonst.data)) ? ", held by you" :
927 u.uswallow ? (is_animal(u.ustuck->data) ?
928 ", swallowed you" :
929 ", engulfed you") :
930 ", holding you");
931 if (mtmp == u.usteed) strcat(info, ", carrying you");
932 if (mtmp->butthurt) sprintf(eos(info), ", butthurt (%d)", mtmp->butthurt);
934 /* avoid "Status of the invisible newt ..., invisible" */
935 /* and unlike a normal mon_nam, use "saddled" even if it has a name */
936 strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *)0,
937 (SUPPRESS_IT|SUPPRESS_INVISIBLE), FALSE));
938 sprintf(eos(monnambuf), " (%s)", Hallucination ? "sparkly dood" : sanityrandomname() ? rndmonnam() : mtmp->data->mname);
940 pline("Status of %s (%s): Level %d HP %d(%d) Pw %d(%d) AC %d%s.",
941 monnambuf,
942 align_str(alignment),
943 mtmp->m_lev,
944 mtmp->mhp,
945 mtmp->mhpmax,
946 mtmp->m_en,
947 mtmp->m_enmax,
948 find_mac(mtmp),
949 info);
952 void
953 mstatuslinebl(mtmp) /*for blessed stethoscope --Amy*/
954 register struct monst *mtmp;
956 aligntyp alignment;
957 char info[BUFSZ], monnambuf[BUFSZ];
959 if (mtmp->ispriest || mtmp->data == &mons[PM_ALIGNED_PRIEST] || mtmp->data == &mons[PM_MASTER_PRIEST] || mtmp->data == &mons[PM_EXPERIENCED_PRIEST] || mtmp->data == &mons[PM_EXCEPTIONAL_PRIEST] || mtmp->data == &mons[PM_ELITE_PRIEST]
960 || mtmp->data == &mons[PM_ANGEL])
961 alignment = EPRI(mtmp)->shralign;
962 else
963 alignment = mtmp->data->maligntyp;
964 alignment = (alignment > 0) ? A_LAWFUL :
965 (alignment < 0) ? A_CHAOTIC :
966 A_NEUTRAL;
968 info[0] = 0;
969 if (mtmp->mtame) { strcat(info, ", tame");
970 sprintf(eos(info), " (%d", mtmp->mtame);
971 if (!mtmp->isminion)
972 sprintf(eos(info), "; hungry %ld; apport %d",
973 EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport);
974 strcat(info, ")");
976 else if (mtmp->mpeaceful) strcat(info, ", peaceful");
977 else if (mtmp->mtraitor) strcat(info, ", traitor");
978 if (mtmp->meating) strcat(info, ", eating");
979 if (mtmp->mcan) strcat(info, ", cancelled");
980 if (mtmp->mconf) strcat(info, ", confused");
981 if (mtmp->healblock) strcat(info, ", healing blocked");
982 if (mtmp->inertia) strcat(info, ", slowed by inertia");
983 if (mtmp->bleedout) strcat(info, ", bleeding");
984 if (mtmp->mblinded || !mtmp->mcansee)
985 strcat(info, ", blind");
986 if (mtmp->mstun) strcat(info, ", stunned");
987 if (mtmp->msleeping) strcat(info, ", asleep");
988 #if 0 /* unfortunately mfrozen covers temporary sleep and being busy
989 (donning armor, for instance) as well as paralysis */
990 else if (mtmp->mfrozen) strcat(info, ", paralyzed");
991 #else
992 else if (mtmp->mfrozen || !mtmp->mcanmove) {
993 strcat(info, ", can't move");
994 if (mtmp->masleep) strcat(info, " (sleeping)");
996 #endif
997 /* [arbitrary reason why it isn't moving] */
998 else if (mtmp->mstrategy & STRAT_WAITMASK)
999 strcat(info, ", meditating");
1000 else if (mtmp->mflee) { strcat(info, ", scared");
1001 sprintf(eos(info), " (%d)", mtmp->mfleetim);
1003 if (mtmp->mtrapped) strcat(info, ", trapped");
1004 if (mtmp->mspeed) strcat(info,
1005 mtmp->mspeed == MFAST ? ", fast" :
1006 mtmp->mspeed == MSLOW ? ", slow" :
1007 ", ???? speed");
1008 if (mtmp->mundetected) strcat(info, ", concealed");
1009 if (mtmp->minvis) strcat(info, ", invisible");
1010 if (mtmp == u.ustuck) strcat(info,
1011 (sticks(youmonst.data)) ? ", held by you" :
1012 u.uswallow ? (is_animal(u.ustuck->data) ?
1013 ", swallowed you" :
1014 ", engulfed you") :
1015 ", holding you");
1016 if (mtmp == u.usteed) strcat(info, ", carrying you");
1018 /* avoid "Status of the invisible newt ..., invisible" */
1019 /* and unlike a normal mon_nam, use "saddled" even if it has a name */
1020 strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *)0,
1021 (SUPPRESS_IT|SUPPRESS_INVISIBLE), FALSE));
1022 sprintf(eos(monnambuf), " (%s)", Hallucination ? "sparkly dood" : sanityrandomname() ? rndmonnam() : mtmp->data->mname);
1024 pline("Status of %s (%s): Level %d HP %d(%d) Pw %d(%d) AC %d%s.",
1025 monnambuf,
1026 align_str(alignment),
1027 mtmp->m_lev,
1028 mtmp->mhp,
1029 mtmp->mhpmax,
1030 mtmp->m_en,
1031 mtmp->m_enmax,
1032 find_mac(mtmp),
1033 info);
1036 void
1037 ustatusline()
1039 char info[BUFSZ];
1041 info[0] = '\0';
1042 if (Sick) {
1043 strcat(info, ", dying from");
1044 if (u.usick_type & SICK_VOMITABLE)
1045 strcat(info, " food poisoning");
1046 if (u.usick_type & SICK_NONVOMITABLE) {
1047 if (u.usick_type & SICK_VOMITABLE)
1048 strcat(info, " and");
1049 strcat(info, " illness");
1052 if (Stoned) strcat(info, ", solidifying");
1053 if (Slimed) strcat(info, ", becoming slimy");
1054 if (Strangled) strcat(info, ", being strangled");
1055 if (PlayerBleeds) strcat(info, ", bleeding");
1056 if (Vomiting) strcat(info, ", nauseated"); /* !"nauseous" */
1057 if (Confusion) strcat(info, ", confused");
1058 if (Blind) {
1059 strcat(info, ", blind");
1060 if (u.ucreamed) {
1061 if ((long)u.ucreamed < Blinded || Blindfolded
1062 || !haseyes(youmonst.data))
1063 strcat(info, ", cover");
1064 strcat(info, "ed by sticky goop");
1065 } /* note: "goop" == "glop"; variation is intentional */
1067 if (Stunned) strcat(info, ", stunned");
1068 if (Numbed) strcat(info, ", numbed");
1069 if (Feared) strcat(info, ", stricken with fear");
1070 if (Frozen) strcat(info, ", frozen solid");
1071 if (Burned) strcat(info, ", burned");
1072 if (Dimmed) strcat(info, ", dimmed");
1073 if (!u.usteed)
1074 if (Wounded_legs) {
1075 const char *what = body_part(LEG);
1076 if ((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
1077 what = makeplural(what);
1078 sprintf(eos(info), ", injured %s", what);
1080 if (IsGlib) sprintf(eos(info), ", slippery %s",
1081 makeplural(body_part(HAND)));
1082 if (u.utrap) strcat(info, ", trapped");
1083 if (Fast) strcat(info, Very_fast ?
1084 ", very fast" : ", fast");
1085 if (u.uundetected) strcat(info, ", concealed");
1086 if (Invis) strcat(info, ", invisible");
1087 if (u.ustuck) {
1088 if (sticks(youmonst.data))
1089 strcat(info, ", holding ");
1090 else
1091 strcat(info, ", held by ");
1092 strcat(info, mon_nam(u.ustuck));
1095 pline("Status of %s (%s%s): Level %d HP %d(%d) Pw %d(%d) AC %d%s.",
1096 playeraliasname,
1097 (u.ualign.record >= 20) ? "piously " :
1098 (u.ualign.record > 13) ? "devoutly " :
1099 (u.ualign.record > 8) ? "fervently " :
1100 (u.ualign.record > 3) ? "stridently " :
1101 (u.ualign.record == 3) ? "" :
1102 (u.ualign.record >= 1) ? "haltingly " :
1103 (u.ualign.record == 0) ? "nominally " :
1104 "insufficiently ",
1105 align_str(u.ualign.type),
1106 Upolyd ? mons[u.umonnum].mlevel : u.ulevel,
1107 Upolyd ? u.mh : u.uhp,
1108 Upolyd ? u.mhmax : u.uhpmax,
1109 u.uen,
1110 u.uenmax,
1111 u.uac,
1112 info);
1115 void
1116 self_invis_message()
1118 if(Role_if(PM_PIRATE) || Role_if(PM_KORSAIR) || PirateSpeakOn) {
1119 pline("%s %s.",
1120 FunnyHallu ? "Arr, Matey! Ye" : "Avast! All of a sudden, ye",
1121 See_invisible ? "can see right through yerself" :
1122 "can't see yerself");
1124 else{
1125 pline("%s %s.",
1126 FunnyHallu ? "Far out, man! You" : "Gee! All of a sudden, you",
1127 See_invisible ? "can see right through yourself" :
1128 "can't see yourself");
1132 /* replace() from CK */
1134 /*Consecutive calls to replace would result in strings copied onto itselves*/
1135 /*So we alternate between two buffers*/
1136 char replace_buffer[BUFSZ*2]; /* two buffers */
1137 unsigned int flipflop=0; /* which one ? */
1138 /* flipflop must be unsigned int (not int or boolean) to act as senitel */
1139 /* If it wrote beyond the end of buffer, flipflop is >1 ... */
1140 /* ... then you can panic */
1142 char *replace(st, orig, repl, extratest)
1143 const char *st, *orig, *repl;
1144 boolean extratest;
1146 char *buffer;
1147 char *ch;
1148 char *tmp;
1149 int i;
1151 /* Direct speach ? (cheapest test, and only once ) */
1152 /*"Thou art doomed, scapegrace!" */
1153 /*"Who do you think you are, War?" */
1154 /*"Hello Dudley. Welcome to Delphi."*/
1155 if(extratest && ((*st)== '"') ) return st;
1157 /* at most 20 times we replace the word to prevent infinite loops */
1158 i=100;
1159 REPEAT:
1160 /*Most calls won't match, so do the match first.*/
1161 if (!(ch = strstr(st, orig)))
1162 return st;
1164 if (u.wollohhack) {
1165 if( (tmp = strstr(st,"wolloh,")) ) return st;
1166 if( (tmp = strstr(st,"wolloh.")) ) return st;
1167 if( (tmp = strstr(st,"wolloh!")) ) return st;
1170 if ( (UmengEffect || u.uprops[UMENG_EFFECT].extrinsic || have_umengstone() ) ) {
1172 if( (tmp = strstr(st,"umeng")) ) return st;
1173 if( (tmp = strstr(st,"alter ich hab umeng geschrieben")) ) return st;
1177 /* You read "eyelbereth" */
1178 /*if( (tmp = strstr(st,"read")) && (tmp<ch) ) return st;*/
1179 /* note by Amy: already caught by the direct speech test above */
1181 /* A cursed rusty iron chain named Eye Pod */
1182 /* if( (tmp = strstr(st,"named")) && (tmp<ch) ) return st; */
1184 /* A raven called Hugin - Eye of Odin */
1185 /* if( (tmp = strstr(st,"called")) && (tmp<ch) ) return st; */
1187 /* A tiger eye ring (that is called tiger eye in inventory) */
1188 /* if( !strcmp(orig,"eye") && strstr(st,"tiger") ) return st; */
1190 /* The Eye of the Aethiopica, The Eyes of the Overworld */
1191 /* if( !strcmp(orig,"Eye") && (
1192 strstr(ch,"Aethiopica") ||
1193 strstr(ch,"Overworld")
1194 )) return st; */
1196 /* note by Amy - I think the Deadlight of the Aethiopica sounds funny... */
1197 /* tiger deadlight ring etc. too :D */
1199 /* Check if it will fit into the buffer */
1200 /* 2 is enough, but 5 is safer */
1201 /* Should be rare enough to come late */
1202 if( ( strlen(st)+strlen(repl)-strlen(orig)+5 )>BUFSZ ) return st;
1204 /*Quote beginning in the middle of the string */
1205 /*The voice of Moloch booms out "So, mortal! You dare desecrate my High Temple!"*/
1206 /* voice o' Moloch, but not Ye dare */
1207 /* rare enough, to come last */
1208 if( (tmp=strstr(st,"\"")) && (tmp<ch) && extratest ) return st;
1210 /* Don't convert disorder messages into pirate slang ! */
1211 /* Nested calls of impossible() call panic(). */
1212 if(program_state.in_impossible) return st;
1214 /* get a buffer */
1215 buffer = &replace_buffer[(flipflop^=1)?BUFSZ:0];
1217 /* If it is the same buffer, something went wrong. */
1218 /* This may happen if you work with two strings at the same time */
1219 /* and make intersecting calls to replace */
1220 if(buffer==st)
1222 /* Assert a disorder if in wizard mode */
1223 /* otherwise do it silently */
1224 if(wizard)
1225 impossible("Intersecting calls to replace() in pline.c !");
1226 return st;
1229 strncpy(buffer, st, ch-st);
1230 buffer[ch-st] = 0;
1231 sprintf(buffer+(ch-st), "%s%s", repl, ch+strlen(orig));
1233 /* we don't know how much data was destroyed, so assume the worst */
1234 if(flipflop>1)
1235 panic("Memory leak in replace() !");
1237 st=buffer;
1238 if(i--) goto REPEAT;
1239 return st;
1242 #endif /* OVLB */
1243 /*pline.c*/