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 14static boolean no_repeat = FALSE; 15 16static 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) 24static void FDECL(vpline, (const char *, va_list)); 25 26void 27pline 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 35static void 36vpline(const char *line, va_list the_args) { 37# else 38static void 39vpline(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 46void 47pline 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*/ 72void 73Norep 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() */ 84static char *you_buf = 0; 85static int you_buf_siz = 0; 86 87static char * 88You_buf(siz) 89int 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 99void 100free_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*/ 114void 115You 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*/ 124void 125Your 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*/ 134void 135You_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*/ 145void 146You_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*/ 155void 156pline_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*/ 165void 166There 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*/ 175void 176You_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*/ 191void 192verbalize 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) 211static void FDECL(vraw_printf,(const char *,va_list)); 212 213void 214raw_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 222static void 223vraw_printf(const char *line, va_list the_args) { 224# else 225static void 226vraw_printf(line, the_args) const char *line; va_list the_args; { 227# endif 228 229#else /* USE_STDARG | USE_VARARG */ 230 231void 232raw_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*/ 247void 248impossible 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 265const char * 266align_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 278void 279mstatusline(mtmp) 280register 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 357void 358ustatusline() 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 430void 431self_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*/ 441