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