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