pc-hack

PC HACK 3.61 source code (archival)
git clone http://frotz.net/git/pc-hack.git
Log | Files | Refs

pri.c (14903B)


      1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
      2 /* pri.c - version 1.0.3 */
      3 
      4 #include <stdio.h>
      5 #include "hack.h"
      6 xchar scrlx, scrhx, scrly, scrhy;	/* corners of new area on screen */
      7 
      8 extern char *hu_stat[];	/* in eat.c */
      9 extern char *CD;
     10 
     11 swallowed()
     12 {
     13 	char *ulook = "|@|";
     14 	ulook[1] = u.usym;
     15 
     16 	cls();
     17 	curs(u.ux-1, u.uy+1);
     18 	fputs("/-\\", stdout);
     19 	curx = u.ux+2;
     20 	curs(u.ux-1, u.uy+2);
     21 	fputs(ulook, stdout);
     22 	curx = u.ux+2;
     23 	curs(u.ux-1, u.uy+3);
     24 	fputs("\\-/", stdout);
     25 	curx = u.ux+2;
     26 	u.udispl = 1;
     27 	u.udisx = u.ux;
     28 	u.udisy = u.uy;
     29 }
     30 
     31 
     32 /*VARARGS1*/
     33 boolean panicking;
     34 
     35 panic(str,a1,a2,a3,a4,a5,a6)
     36 char *str;
     37 {
     38 	if(panicking++) exit(1);    /* avoid loops - this should never happen*/
     39 	cls();
     40 	home();
     41 	puts(" Suddenly, the dungeon collapses.");
     42 	fputs(" ERROR:  ", stdout);
     43 	printf(str,a1,a2,a3,a4,a5,a6);
     44 #ifdef DEBUG
     45 #ifdef UNIX
     46 	if(!fork())
     47 		abort();	/* generate core dump */
     48 #endif /* UNIX /**/
     49 #endif /* DEBUG /**/
     50 	more();			/* contains a fflush() */
     51 	done("panicked");
     52 }
     53 
     54 atl(x,y,ch)
     55 register x,y;
     56 {
     57 	register struct rm *crm = &levl[x][y];
     58 
     59 	if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1){
     60 		impossible("atl(%d,%d,%c)",x,y,ch);
     61 		return;
     62 	}
     63 	if(crm->seen && crm->scrsym == ch) return;
     64 	crm->scrsym = ch;
     65 	crm->new = 1;
     66 	on_scr(x,y);
     67 }
     68 
     69 on_scr(x,y)
     70 register x,y;
     71 {
     72 	if(x < scrlx) scrlx = x;
     73 	if(x > scrhx) scrhx = x;
     74 	if(y < scrly) scrly = y;
     75 	if(y > scrhy) scrhy = y;
     76 }
     77 
     78 /* call: (x,y) - display
     79 	(-1,0) - close (leave last symbol)
     80 	(-1,-1)- close (undo last symbol)
     81 	(-1,let)-open: initialize symbol
     82 	(-2,let)-change let
     83 */
     84 
     85 tmp_at(x,y) schar x,y; {
     86 static schar prevx, prevy;
     87 static char let;
     88 	if((int)x == -2){	/* change let call */
     89 		let = y;
     90 		return;
     91 	}
     92 	if((int)x == -1 && (int)y >= 0){	/* open or close call */
     93 		let = y;
     94 		prevx = -1;
     95 		return;
     96 	}
     97 	if(prevx >= 0 && cansee(prevx,prevy)) {
     98 		delay_output();
     99 		prl(prevx, prevy);	/* in case there was a monster */
    100 		at(prevx, prevy, levl[prevx][prevy].scrsym);
    101 	}
    102 	if(x >= 0){	/* normal call */
    103 		if(cansee(x,y)) at(x,y,let);
    104 		prevx = x;
    105 		prevy = y;
    106 	} else {	/* close call */
    107 		let = 0;
    108 		prevx = -1;
    109 	}
    110 }
    111 
    112 /* like the previous, but the symbols are first erased on completion */
    113 Tmp_at(x,y) schar x,y; {
    114 static char let;
    115 static xchar cnt;
    116 static coord tc[COLNO];		/* but watch reflecting beams! */
    117 register xx,yy;
    118 	if((int)x == -1) {
    119 		if(y > 0) {	/* open call */
    120 			let = y;
    121 			cnt = 0;
    122 			return;
    123 		}
    124 		/* close call (do not distinguish y==0 and y==-1) */
    125 		while(cnt--) {
    126 			xx = tc[cnt].x;
    127 			yy = tc[cnt].y;
    128 			prl(xx, yy);
    129 			at(xx, yy, levl[xx][yy].scrsym);
    130 		}
    131 		cnt = let = 0;	/* superfluous */
    132 		return;
    133 	}
    134 	if((int)x == -2) {	/* change let call */
    135 		let = y;
    136 		return;
    137 	}
    138 	/* normal call */
    139 	if(cansee(x,y)) {
    140 		if(cnt) delay_output();
    141 		at(x,y,let);
    142 		tc[cnt].x = x;
    143 		tc[cnt].y = y;
    144 		if(++cnt >= COLNO) panic("Tmp_at overflow?");
    145 		levl[x][y].new = 0;	/* prevent pline-nscr erasing --- */
    146 	}
    147 }
    148 
    149 setclipped(){
    150 	error("Hack needs a screen of size at least %d by %d.\n",
    151 		ROWNO+2, COLNO);
    152 }
    153 
    154 #ifdef DGK
    155 static int multipleAts;		/* TRUE if we have many at()'s to do */
    156 static int DECgraphics;		/* The graphics mode toggle */
    157 #define DECgraphicsON() if (!DECgraphics) (void) putchar('\16'), DECgraphics = 1
    158 #define DECgraphicsOFF() if (DECgraphics) (void) putchar('\17'), DECgraphics = 0
    159 #endif
    160 
    161 at(x,y,ch)
    162 register xchar x,y;
    163 char ch;
    164 {
    165 #ifndef lint
    166 	/* if xchar is unsigned, lint will complain about  if(x < 0)  */
    167 	if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) {
    168 		impossible("At gets 0%o at %d %d.", ch, x, y);
    169 		return;
    170 	}
    171 #endif /* lint /**/
    172 	if(!ch) {
    173 		impossible("At gets null at %d %d.", x, y);
    174 		return;
    175 	}
    176 	y += 2;
    177 	curs(x,y);
    178 #ifdef DGK
    179 	if (flags.DECRainbow) {
    180 		/* If there are going to be many at()s in a row without
    181 		 * intervention, only change the graphics mode when the
    182 		 * character changes between graphic and regular.
    183 		 */
    184 		if (multipleAts) {
    185 			if (ch & 0x80) {
    186 				DECgraphicsON();
    187 				putchar(ch ^ 0x80); /* Strip 8th bit */
    188 			} else {
    189 				DECgraphicsOFF();
    190 				putchar(ch);
    191 			}
    192 		/* Otherwise, we don't know how many at()s will be happening
    193 		 * before printing of normal strings, so change to graphics
    194 		 * mode when necessary, then change right back.
    195 		 */
    196 		} else {
    197 			if (ch & 0x80) {
    198 				DECgraphicsON();
    199 				putchar(ch ^ 0x80); /* Strip 8th bit */
    200 				DECgraphicsOFF();
    201 			} else
    202 				putchar(ch);
    203 		}
    204 	} else
    205 # endif
    206 		(void) putchar(ch);
    207 	curx++;
    208 }
    209 
    210 prme(){
    211 	if(!Invisible) at(u.ux,u.uy,u.usym);
    212 }
    213 
    214 doredraw()
    215 {
    216 	docrt();
    217 	return(0);
    218 }
    219 
    220 docrt()
    221 {
    222 	register x,y;
    223 	register struct rm *room;
    224 	register struct monst *mtmp;
    225 
    226 	if(u.uswallow) {
    227 		swallowed();
    228 		return;
    229 	}
    230 	cls();
    231 
    232 /* Some ridiculous code to get display of @ and monsters (almost) right */
    233 	if(!Invisible) {
    234 		levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
    235 		levl[u.udisx][u.udisy].seen = 1;
    236 		u.udispl = 1;
    237 	} else	u.udispl = 0;
    238 
    239 	seemons();	/* reset old positions */
    240 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
    241 		mtmp->mdispl = 0;
    242 	seemons();	/* force new positions to be shown */
    243 /* This nonsense should disappear soon --------------------------------- */
    244 
    245 # ifdef DGK
    246 	/* For DEC Rainbows, we must translate each character.
    247 	 */
    248 	if (flags.DECRainbow) {
    249 		multipleAts = TRUE;
    250 		DECgraphicsOFF();
    251 	}
    252 # endif
    253 	for(y = 0; y < ROWNO; y++)
    254 		for(x = 0; x < COLNO; x++)
    255 			if((room = &levl[x][y])->new) {
    256 				room->new = 0;
    257 				at(x,y,room->scrsym);
    258 			} else if(room->seen)
    259 				at(x,y,room->scrsym);
    260 # ifdef DGK
    261 	if (flags.DECRainbow) {
    262 		multipleAts = FALSE;
    263 		DECgraphicsOFF();
    264 	}
    265 #endif
    266 	scrlx = COLNO;
    267 	scrly = ROWNO;
    268 	scrhx = scrhy = 0;
    269 	flags.botlx = 1;
    270 	bot();
    271 }
    272 
    273 docorner(xmin,ymax) register xmin,ymax; {
    274 	register x,y;
    275 	register struct rm *room;
    276 	register struct monst *mtmp;
    277 
    278 	if(u.uswallow) {	/* Can be done more efficiently */
    279 		swallowed();
    280 		return;
    281 	}
    282 
    283 	seemons();	/* reset old positions */
    284 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
    285 	    if(mtmp->mx >= xmin && mtmp->my < ymax)
    286 		mtmp->mdispl = 0;
    287 	seemons();	/* force new positions to be shown */
    288 
    289 #ifdef DGK
    290 	if (flags.DECRainbow) {
    291 		multipleAts = TRUE;
    292 		DECgraphicsOFF();
    293 	}
    294 #endif
    295 	for(y = 0; y < ymax; y++) {
    296 		if(y > ROWNO && CD) break;
    297 		curs(xmin,y+2);
    298 		cl_end();
    299 		if(y < ROWNO) {
    300 		    for(x = xmin; x < COLNO; x++) {
    301 			if((room = &levl[x][y])->new) {
    302 				room->new = 0;
    303 				at(x,y,room->scrsym);
    304 			} else
    305 				if(room->seen)
    306 					at(x,y,room->scrsym);
    307 		    }
    308 		}
    309 	}
    310 #ifdef DGK
    311 	if (flags.DECRainbow) {
    312 		multipleAts = FALSE;
    313 		DECgraphicsOFF();
    314 	}
    315 #endif
    316 	if(ymax > ROWNO) {
    317 		cornbot(xmin-1);
    318 		if(ymax > ROWNO+1 && CD) {
    319 			curs(1,ROWNO+3);
    320 			cl_eos();
    321 		}
    322 	}
    323 }
    324 
    325 curs_on_u(){
    326 	curs(u.ux, u.uy+2);
    327 }
    328 
    329 pru()
    330 {
    331 	if(u.udispl && (Invisible || u.udisx != u.ux || u.udisy != u.uy))
    332 		/* if(! levl[u.udisx][u.udisy].new) */
    333 			if(!vism_at(u.udisx, u.udisy))
    334 				newsym(u.udisx, u.udisy);
    335 	if(Invisible) {
    336 		u.udispl = 0;
    337 		prl(u.ux,u.uy);
    338 	} else
    339 	if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
    340 		atl(u.ux, u.uy, u.usym);
    341 		u.udispl = 1;
    342 		u.udisx = u.ux;
    343 		u.udisy = u.uy;
    344 	}
    345 	levl[u.ux][u.uy].seen = 1;
    346 }
    347 
    348 #ifndef NOWORM
    349 #include	"wseg.h"
    350 extern struct wseg *m_atseg;
    351 #endif /* NOWORM /**/
    352 
    353 /* print a position that is visible for @ */
    354 prl(x,y)
    355 {
    356 	register struct rm *room;
    357 	register struct monst *mtmp;
    358 	register struct obj *otmp;
    359 
    360 	if(x == u.ux && y == u.uy && (!Invisible)) {
    361 		pru();
    362 		return;
    363 	}
    364 	if(!isok(x,y)) return;
    365 	room = &levl[x][y];
    366 	if((!room->typ) ||
    367 	   (IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR))
    368 		return;
    369 	if((mtmp = m_at(x,y)) && !mtmp->mhide &&
    370 		(!mtmp->minvis || See_invisible)) {
    371 #ifndef NOWORM
    372 		if(m_atseg)
    373 			pwseg(m_atseg);
    374 		else
    375 #endif /* NOWORM /**/
    376 		pmon(mtmp);
    377 	}
    378 	else if((otmp = o_at(x,y)) && room->typ != POOL)
    379 		atl(x,y,otmp->olet);
    380 	else if(mtmp && (!mtmp->minvis || See_invisible)) {
    381 		/* must be a hiding monster, but not hiding right now */
    382 		/* assume for the moment that long worms do not hide */
    383 		pmon(mtmp);
    384 	}
    385 	else if(g_at(x,y) && room->typ != POOL)
    386 		atl(x,y,'$');
    387 	else if(!room->seen || room->scrsym == ' ') {
    388 		room->new = room->seen = 1;
    389 		newsym(x,y);
    390 		on_scr(x,y);
    391 	}
    392 	room->seen = 1;
    393 }
    394 
    395 char
    396 news0(x,y)
    397 register xchar x,y;
    398 {
    399 	register struct obj *otmp;
    400 	register struct trap *ttmp;
    401 	struct rm *room;
    402 	register char tmp;
    403 
    404 	room = &levl[x][y];
    405 	if(!room->seen) tmp = ' ';
    406 	else if(room->typ == POOL) tmp = POOL_SYM;
    407 	else if(!Blind && (otmp = o_at(x,y))) tmp = otmp->olet;
    408 	else if(!Blind && g_at(x,y)) tmp = '$';
    409 	else if(x == xupstair && y == yupstair) tmp = '<';
    410 	else if(x == xdnstair && y == ydnstair) tmp = '>';
    411 	else if((ttmp = t_at(x,y)) && ttmp->tseen) tmp = '^';
    412 	else switch(room->typ) {
    413 	case SCORR:
    414 	case SDOOR:
    415 		tmp = room->scrsym;	/* %% wrong after killing mimic ! */
    416 		break;
    417 #ifdef DGK
    418 	case HWALL:
    419 		tmp = room->scrsym;	/* OK for corners only */
    420 		if (!IS_CORNER(tmp))
    421 			tmp = symbol.hwall;
    422 		break;
    423 	case VWALL:
    424 		tmp = symbol.vwall;
    425 		break;
    426 	case LDOOR:
    427 	case DOOR:
    428 		tmp = symbol.door;
    429 		break;
    430 	case CORR:
    431 		tmp = symbol.corr;
    432 		break;
    433 	case ROOM:
    434 		if(room->lit || cansee(x,y) || Blind) tmp = symbol.room;
    435 		else tmp = ' ';
    436 		break;
    437 #else
    438 	case HWALL:
    439 		tmp = '-';
    440 		break;
    441 	case VWALL:
    442 		tmp = '|';
    443 		break;
    444 	case LDOOR:
    445 	case DOOR:
    446 		tmp = '+';
    447 		break;
    448 	case CORR:
    449 		tmp = CORR_SYM;
    450 		break;
    451 	case ROOM:
    452 		if(room->lit || cansee(x,y) || Blind) tmp = '.';
    453 		else tmp = ' ';
    454 		break;
    455 #endif
    456 /*
    457 	case POOL:
    458 		tmp = POOL_SYM;
    459 		break;
    460 */
    461 	default:
    462 		tmp = ERRCHAR;
    463 	}
    464 	return(tmp);
    465 }
    466 
    467 newsym(x,y)
    468 register x,y;
    469 {
    470 	atl(x,y,news0(x,y));
    471 }
    472 
    473 /* used with wand of digging (or pick-axe): fill scrsym and force display */
    474 /* also when a POOL evaporates */
    475 mnewsym(x,y)
    476 register x,y;
    477 {
    478 	register struct rm *room;
    479 	char newscrsym;
    480 
    481 	if(!vism_at(x,y)) {
    482 		room = &levl[x][y];
    483 		newscrsym = news0(x,y);
    484 		if(room->scrsym != newscrsym) {
    485 			room->scrsym = newscrsym;
    486 			room->seen = 0;
    487 		}
    488 	}
    489 }
    490 
    491 nosee(x,y)
    492 register x,y;
    493 {
    494 	register struct rm *room;
    495 
    496 	if(!isok(x,y)) return;
    497 	room = &levl[x][y];
    498 #ifdef DGK
    499 	if(room->scrsym == symbol.room && !room->lit && !Blind) {
    500 #else
    501 	if(room->scrsym == '.' && !room->lit && !Blind) {
    502 #endif
    503 		room->scrsym = ' ';
    504 		room->new = 1;
    505 		on_scr(x,y);
    506 	}
    507 }
    508 
    509 prl1(x,y)
    510 register x,y;
    511 {
    512 	if(u.dx) {
    513 		if(u.dy) {
    514 			prl(x-(2*u.dx),y);
    515 			prl(x-u.dx,y);
    516 			prl(x,y);
    517 			prl(x,y-u.dy);
    518 			prl(x,y-(2*u.dy));
    519 		} else {
    520 			prl(x,y-1);
    521 			prl(x,y);
    522 			prl(x,y+1);
    523 		}
    524 	} else {
    525 		prl(x-1,y);
    526 		prl(x,y);
    527 		prl(x+1,y);
    528 	}
    529 }
    530 
    531 nose1(x,y)
    532 register x,y;
    533 {
    534 	if(u.dx) {
    535 		if(u.dy) {
    536 			nosee(x,u.uy);
    537 			nosee(x,u.uy-u.dy);
    538 			nosee(x,y);
    539 			nosee(u.ux-u.dx,y);
    540 			nosee(u.ux,y);
    541 		} else {
    542 			nosee(x,y-1);
    543 			nosee(x,y);
    544 			nosee(x,y+1);
    545 		}
    546 	} else {
    547 		nosee(x-1,y);
    548 		nosee(x,y);
    549 		nosee(x+1,y);
    550 	}
    551 }
    552 
    553 vism_at(x,y)
    554 register x,y;
    555 {
    556 	register struct monst *mtmp;
    557 
    558 	return((x == u.ux && y == u.uy && !Invisible)
    559 			? 1 :
    560 	       (mtmp = m_at(x,y))
    561 			? ((Blind && Telepat) || canseemon(mtmp)) :
    562 		0);
    563 }
    564 
    565 #ifdef NEWSCR
    566 pobj(obj) register struct obj *obj; {
    567 register int show = (!obj->oinvis || See_invisible) &&
    568 		cansee(obj->ox,obj->oy);
    569 	if(obj->odispl){
    570 		if(obj->odx != obj->ox || obj->ody != obj->oy || !show)
    571 		if(!vism_at(obj->odx,obj->ody)){
    572 			newsym(obj->odx, obj->ody);
    573 			obj->odispl = 0;
    574 		}
    575 	}
    576 	if(show && !vism_at(obj->ox,obj->oy)){
    577 		atl(obj->ox,obj->oy,obj->olet);
    578 		obj->odispl = 1;
    579 		obj->odx = obj->ox;
    580 		obj->ody = obj->oy;
    581 	}
    582 }
    583 #endif /* NEWSCR /**/
    584 
    585 unpobj(obj) register struct obj *obj; {
    586 /* 	if(obj->odispl){
    587 		if(!vism_at(obj->odx, obj->ody))
    588 			newsym(obj->odx, obj->ody);
    589 		obj->odispl = 0;
    590 	}
    591 */
    592 	if(!vism_at(obj->ox,obj->oy))
    593 		newsym(obj->ox,obj->oy);
    594 }
    595 
    596 seeobjs(){
    597 register struct obj *obj, *obj2;
    598 	for(obj = fobj; obj; obj = obj2) {
    599 		obj2 = obj->nobj;
    600 		if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
    601 			&& obj->age + 250 < moves)
    602 				delobj(obj);
    603 	}
    604 	for(obj = invent; obj; obj = obj2) {
    605 		obj2 = obj->nobj;
    606 		if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
    607 			&& obj->age + 250 < moves)
    608 				useup(obj);
    609 	}
    610 }
    611 
    612 seemons(){
    613 register struct monst *mtmp;
    614 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
    615 		if(mtmp->data->mlet == ';')
    616 			mtmp->minvis = (u.ustuck != mtmp &&
    617 					levl[mtmp->mx][mtmp->my].typ == POOL);
    618 		pmon(mtmp);
    619 #ifndef NOWORM
    620 		if(mtmp->wormno) wormsee(mtmp->wormno);
    621 #endif /* NOWORM /**/
    622 	}
    623 }
    624 
    625 pmon(mon) register struct monst *mon; {
    626 register int show = (Blind && Telepat) || canseemon(mon);
    627 	if(mon->mdispl){
    628 		if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
    629 			unpmon(mon);
    630 	}
    631 	if(show && !mon->mdispl){
    632 		atl(mon->mx,mon->my,
    633 		 	(!mon->mappearance || Protection_from_shape_changers)
    634 		 		? mon->data->mlet : mon->mappearance);
    635 		mon->mdispl = 1;
    636 		mon->mdx = mon->mx;
    637 		mon->mdy = mon->my;
    638 	}
    639 }
    640 
    641 unpmon(mon) register struct monst *mon; {
    642 	if(mon->mdispl){
    643 		newsym(mon->mdx, mon->mdy);
    644 		mon->mdispl = 0;
    645 	}
    646 }
    647 
    648 nscr()
    649 {
    650 	register x,y;
    651 	register struct rm *room;
    652 
    653 	if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
    654 	pru();
    655 	for(y = scrly; y <= scrhy; y++)
    656 		for(x = scrlx; x <= scrhx; x++)
    657 			if((room = &levl[x][y])->new) {
    658 				room->new = 0;
    659 				at(x,y,room->scrsym);
    660 			}
    661 	scrhx = scrhy = 0;
    662 	scrlx = COLNO;
    663 	scrly = ROWNO;
    664 }
    665 
    666 /* 100 suffices for bot(); no relation with COLNO */
    667 char oldbot[100], newbot[100];
    668 cornbot(lth)
    669 register int lth;
    670 {
    671 	if(lth < sizeof(oldbot)) {
    672 		oldbot[lth] = 0;
    673 		flags.botl = 1;
    674 	}
    675 }
    676 
    677 bot()
    678 {
    679 register char *ob = oldbot, *nb = newbot;
    680 register int i;
    681 extern char *eos();
    682 	if(flags.botlx) *ob = 0;
    683 	flags.botl = flags.botlx = 0;
    684 #define GOLD_ON_BOTL
    685 #ifdef GOLD_ON_BOTL
    686 	(void) sprintf(newbot,
    687 		"Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  Str ",
    688 		dlevel, u.ugold, u.uhp, u.uhpmax, u.uac);
    689 #else
    690 	(void) sprintf(newbot,
    691 		"Level %-2d   Hp %3d(%d)   Ac %-2d   Str ",
    692 		dlevel,  u.uhp, u.uhpmax, u.uac);
    693 #endif /* GOLD_ON_BOTL /**/
    694 	if(u.ustr>18) {
    695 	    if(u.ustr>117)
    696 		(void) strcat(newbot,"18/**");
    697 	    else
    698 		(void) sprintf(eos(newbot), "18/%02d",u.ustr-18);
    699 	} else
    700 	    (void) sprintf(eos(newbot), "%-2d   ",u.ustr);
    701 #ifdef EXP_ON_BOTL
    702 	(void) sprintf(eos(newbot), "  Exp %2d/%-5lu ", u.ulevel,u.uexp);
    703 #else
    704 	(void) sprintf(eos(newbot), "   Exp %2u  ", u.ulevel);
    705 #endif /* EXP_ON_BOTL /**/
    706 	(void) strcat(newbot, hu_stat[u.uhs]);
    707 	if(flags.time)
    708 	    (void) sprintf(eos(newbot), "  %ld", moves);
    709 	if(strlen(newbot) >= COLNO) {
    710 		register char *bp0, *bp1;
    711 		bp0 = bp1 = newbot;
    712 		do {
    713 			if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
    714 				*bp1++ = *bp0;
    715 		} while(*bp0++);
    716 	}
    717 	for(i = 1; i<COLNO; i++) {
    718 		if(*ob != *nb){
    719 			curs(i,ROWNO+2);
    720 			(void) putchar(*nb ? *nb : ' ');
    721 			curx++;
    722 		}
    723 		if(*ob) ob++;
    724 		if(*nb) nb++;
    725 	}
    726 	(void) strcpy(oldbot, newbot);
    727 }
    728 
    729 #ifdef WAN_PROBING
    730 mstatusline(mtmp) register struct monst *mtmp; {
    731 	pline("Status of %s: ", monnam(mtmp));
    732 	pline("Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  Dam %d",
    733 	    mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax,
    734 	    mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1));
    735 }
    736 #endif /* WAN_PROBING /**/
    737 
    738 cls(){
    739 	if(flags.toplin == 1)
    740 		more();
    741 	flags.toplin = 0;
    742 
    743 	clear_screen();
    744 
    745 	flags.botlx = 1;
    746 }