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