hack.c (19007B)
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2 /* hack.c - version 1.0.3 */ 3 4 #include <stdio.h> 5 #include "hack.h" 6 7 extern char news0(); 8 extern char *nomovemsg; 9 extern char *exclam(); 10 extern struct obj *addinv(); 11 extern boolean hmon(); 12 13 /* called on movement: 14 1. when throwing ball+chain far away 15 2. when teleporting 16 3. when walking out of a lit room 17 */ 18 unsee() { 19 register x,y; 20 register struct rm *lev; 21 22 /* 23 if(u.udispl){ 24 u.udispl = 0; 25 newsym(u.udisx, u.udisy); 26 } 27 */ 28 if(seehx){ 29 seehx = 0; 30 } else 31 for(x = u.ux-1; x < u.ux+2; x++) 32 for(y = u.uy-1; y < u.uy+2; y++) { 33 if(!isok(x, y)) continue; 34 lev = &levl[x][y]; 35 #ifdef DGK 36 if(!lev->lit && lev->scrsym == symbol.room) { 37 #else 38 if(!lev->lit && lev->scrsym == '.') { 39 #endif 40 lev->scrsym =' '; 41 lev->new = 1; 42 on_scr(x,y); 43 } 44 } 45 } 46 47 /* called: 48 in eat.c: seeoff(0) - blind after eating rotten food 49 in mon.c: seeoff(0) - blinded by a yellow light 50 in mon.c: seeoff(1) - swallowed 51 in do.c: seeoff(0) - blind after drinking potion 52 in do.c: seeoff(1) - go up or down the stairs 53 in trap.c:seeoff(1) - fall through trapdoor 54 */ 55 seeoff(mode) /* 1 to redo @, 0 to leave them */ 56 { /* 1 means misc movement, 0 means blindness */ 57 register x,y; 58 register struct rm *lev; 59 60 if(u.udispl && mode){ 61 u.udispl = 0; 62 levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy); 63 } 64 if(seehx) { 65 seehx = 0; 66 } else 67 if(!mode) { 68 for(x = u.ux-1; x < u.ux+2; x++) 69 for(y = u.uy-1; y < u.uy+2; y++) { 70 if(!isok(x, y)) continue; 71 lev = &levl[x][y]; 72 #ifdef DGK 73 if(!lev->lit && lev->scrsym == symbol.room) 74 #else 75 if(!lev->lit && lev->scrsym == '.') 76 #endif 77 lev->seen = 0; 78 } 79 } 80 } 81 82 static 83 moverock() { 84 register xchar rx, ry; 85 register struct obj *otmp; 86 register struct trap *ttmp; 87 88 while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) { 89 rx = u.ux+2*u.dx; 90 ry = u.uy+2*u.dy; 91 nomul(0); 92 if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) && 93 (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) && 94 !sobj_at(ENORMOUS_ROCK, rx, ry)) { 95 if(m_at(rx,ry)) { 96 pline("You hear a monster behind the rock."); 97 pline("Perhaps that's why you cannot move it."); 98 goto cannot_push; 99 } 100 if(ttmp = t_at(rx,ry)) 101 switch(ttmp->ttyp) { 102 case PIT: 103 pline("You push the rock into a pit!"); 104 deltrap(ttmp); 105 delobj(otmp); 106 pline("It completely fills the pit!"); 107 continue; 108 case TELEP_TRAP: 109 pline("You push the rock and suddenly it disappears!"); 110 delobj(otmp); 111 continue; 112 } 113 if(levl[rx][ry].typ == POOL) { 114 levl[rx][ry].typ = ROOM; 115 mnewsym(rx,ry); 116 prl(rx,ry); 117 pline("You push the rock into the water."); 118 pline("Now you can cross the water!"); 119 delobj(otmp); 120 continue; 121 } 122 otmp->ox = rx; 123 otmp->oy = ry; 124 /* pobj(otmp); */ 125 if(cansee(rx,ry)) atl(rx,ry,otmp->olet); 126 if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy); 127 128 { static long lastmovetime; 129 /* note: this var contains garbage initially and 130 after a restore */ 131 if(moves > lastmovetime+2 || moves < lastmovetime) 132 pline("With great effort you move the enormous rock."); 133 lastmovetime = moves; 134 } 135 } else { 136 pline("You try to move the enormous rock, but in vain."); 137 cannot_push: 138 if((!invent || inv_weight()+90 <= 0) && 139 (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ) 140 && IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))){ 141 pline("However, you can squeeze yourself into a small opening."); 142 break; 143 } else 144 return (-1); 145 } 146 } 147 return (0); 148 } 149 150 domove() 151 { 152 register struct monst *mtmp; 153 register struct rm *tmpr,*ust; 154 struct trap *trap; 155 register struct obj *otmp; 156 157 u_wipe_engr(rnd(5)); 158 159 if(inv_weight() > 0){ 160 pline("You collapse under your load."); 161 nomul(0); 162 return; 163 } 164 if(u.uswallow) { 165 u.dx = u.dy = 0; 166 u.ux = u.ustuck->mx; 167 u.uy = u.ustuck->my; 168 } else { 169 if(Confusion) { 170 do { 171 confdir(); 172 } while(!isok(u.ux+u.dx, u.uy+u.dy) || 173 IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ)); 174 } 175 if(!isok(u.ux+u.dx, u.uy+u.dy)){ 176 nomul(0); 177 return; 178 } 179 } 180 181 ust = &levl[u.ux][u.uy]; 182 u.ux0 = u.ux; 183 u.uy0 = u.uy; 184 if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen) 185 nomul(0); 186 if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx || 187 u.uy+u.dy != u.ustuck->my)) { 188 if(dist(u.ustuck->mx, u.ustuck->my) > 2){ 189 /* perhaps it fled (or was teleported or ... ) */ 190 u.ustuck = 0; 191 } else { 192 if(Blind) pline("You cannot escape from it!"); 193 else pline("You cannot escape from %s!", 194 monnam(u.ustuck)); 195 nomul(0); 196 return; 197 } 198 } 199 if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) { 200 /* attack monster */ 201 202 #ifdef DGK 203 /* Don't attack if you're running */ 204 if (flags.run && !mtmp->mimic 205 && (Blind ? Telepat : (!mtmp->minvis || See_invisible))) { 206 nomul(0); 207 flags.move = 0; 208 return; 209 } 210 #endif 211 nomul(0); 212 gethungry(); 213 if(multi < 0) return; /* we just fainted */ 214 215 /* try to attack; note that it might evade */ 216 if(attack(u.uswallow ? u.ustuck : mtmp)) 217 return; 218 } 219 /* not attacking an animal, so we try to move */ 220 if(u.utrap) { 221 if(u.utraptype == TT_PIT) { 222 pline("You are still in a pit."); 223 u.utrap--; 224 } else { 225 pline("You are caught in a beartrap."); 226 if((u.dx && u.dy) || !rn2(5)) u.utrap--; 227 } 228 return; 229 } 230 tmpr = &levl[u.ux+u.dx][u.uy+u.dy]; 231 if(IS_ROCK(tmpr->typ) || 232 (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){ 233 flags.move = 0; 234 nomul(0); 235 return; 236 } 237 if (moverock() < 0) return; 238 if(u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy+u.dy].typ) && 239 IS_ROCK(levl[u.ux+u.dx][u.uy].typ) && 240 invent && inv_weight()+40 > 0) { 241 pline("You are carrying too much to get through."); 242 nomul(0); 243 return; 244 } 245 if(Punished && 246 DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){ 247 if(carried(uball)) { 248 movobj(uchain, u.ux, u.uy); 249 goto nodrag; 250 } 251 252 if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){ 253 /* leave ball, move chain under/over ball */ 254 movobj(uchain, uball->ox, uball->oy); 255 goto nodrag; 256 } 257 258 if(inv_weight() + (int) uball->owt/2 > 0) { 259 pline("You cannot %sdrag the heavy iron ball.", 260 invent ? "carry all that and also " : ""); 261 nomul(0); 262 return; 263 } 264 265 movobj(uball, uchain->ox, uchain->oy); 266 unpobj(uball); /* BAH %% */ 267 uchain->ox = u.ux; 268 uchain->oy = u.uy; 269 nomul(-2); 270 nomovemsg = ""; 271 nodrag: ; 272 } 273 u.ux += u.dx; 274 u.uy += u.dy; 275 if(flags.run) { 276 if(tmpr->typ == DOOR || 277 (xupstair == u.ux && yupstair == u.uy) || 278 (xdnstair == u.ux && ydnstair == u.uy)) 279 nomul(0); 280 } 281 282 if(tmpr->typ == POOL && !Levitation) 283 drown(); /* not necessarily fatal */ 284 285 /* 286 if(u.udispl) { 287 u.udispl = 0; 288 newsym(u.ux0,u.uy0); 289 } 290 */ 291 if(!Blind) { 292 if(ust->lit) { 293 if(tmpr->lit) { 294 if(tmpr->typ == DOOR) 295 prl1(u.ux+u.dx,u.uy+u.dy); 296 else if(ust->typ == DOOR) 297 nose1(u.ux0-u.dx,u.uy0-u.dy); 298 } else { 299 unsee(); 300 prl1(u.ux+u.dx,u.uy+u.dy); 301 } 302 } else { 303 if(tmpr->lit) setsee(); 304 else { 305 prl1(u.ux+u.dx,u.uy+u.dy); 306 if(tmpr->typ == DOOR) { 307 if(u.dy) { 308 prl(u.ux-1,u.uy); 309 prl(u.ux+1,u.uy); 310 } else { 311 prl(u.ux,u.uy-1); 312 prl(u.ux,u.uy+1); 313 } 314 } 315 } 316 nose1(u.ux0-u.dx,u.uy0-u.dy); 317 } 318 } else { 319 pru(); 320 } 321 if(!flags.nopick) pickup(1); 322 if(trap) dotrap(trap); /* fall into pit, arrow trap, etc. */ 323 (void) inshop(); 324 if(!Blind) read_engr_at(u.ux,u.uy); 325 } 326 327 movobj(obj, ox, oy) 328 register struct obj *obj; 329 register int ox, oy; 330 { 331 /* Some dirty programming to get display right */ 332 freeobj(obj); 333 unpobj(obj); 334 obj->nobj = fobj; 335 fobj = obj; 336 obj->ox = ox; 337 obj->oy = oy; 338 } 339 340 dopickup(){ 341 if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) { 342 pline("There is nothing here to pick up."); 343 return(0); 344 } 345 if(Levitation) { 346 pline("You cannot reach the floor."); 347 return(1); 348 } 349 pickup(0); 350 return(1); 351 } 352 353 pickup(all) 354 { 355 register struct gold *gold; 356 register struct obj *obj, *obj2; 357 register int wt; 358 359 if(Levitation) return; 360 #ifdef DGK 361 if (all && !flags.pickup) { 362 int ct = 0; 363 364 for (obj = fobj; obj; obj = obj->nobj) 365 if (obj->ox == u.ux && obj->oy == u.uy) 366 if (!Punished || obj != uchain) 367 ct++; 368 /* If gold is the only thing here, pick it up. 369 */ 370 if (!ct && g_at(u.ux, u.uy)) { 371 if (flags.run) nomul(0); 372 while (gold = g_at(u.ux,u.uy)) { 373 pline("%ld gold piece%s.", gold->amount, 374 plur(gold->amount)); 375 u.ugold += gold->amount; 376 flags.botl = 1; 377 freegold(gold); 378 } 379 if (Invisible) newsym(u.ux,u.uy); 380 } 381 382 /* If there are objects here, take a look. 383 */ 384 if (ct) { 385 if (flags.run) 386 nomul(0); 387 nscr(); 388 if (ct < 5) 389 dolook(); 390 else 391 pline("There are several objects here."); 392 } 393 return; 394 } 395 #endif 396 while(gold = g_at(u.ux,u.uy)) { 397 pline("%ld gold piece%s.", gold->amount, plur(gold->amount)); 398 u.ugold += gold->amount; 399 flags.botl = 1; 400 freegold(gold); 401 if(flags.run) nomul(0); 402 if(Invisible) newsym(u.ux,u.uy); 403 } 404 /* check for more than one object */ 405 if(!all) { 406 register int ct = 0; 407 408 for(obj = fobj; obj; obj = obj->nobj) 409 if(obj->ox == u.ux && obj->oy == u.uy) 410 if(!Punished || obj != uchain) 411 ct++; 412 if(ct < 2) 413 all++; 414 else 415 pline("There are several objects here."); 416 } 417 418 for(obj = fobj; obj; obj = obj2) { 419 obj2 = obj->nobj; /* perhaps obj will be picked up */ 420 if(obj->ox == u.ux && obj->oy == u.uy) { 421 if(flags.run) nomul(0); 422 423 /* do not pick up uchain */ 424 if(Punished && obj == uchain) 425 continue; 426 427 if(!all) { 428 char c; 429 430 pline("Pick up %s ? [ynaq]", doname(obj)); 431 while(!index("ynaq ", (c = readchar()))) 432 bell(); 433 if(c == 'q') return; 434 if(c == 'n') continue; 435 if(c == 'a') all = 1; 436 } 437 438 if(obj->otyp == DEAD_COCKATRICE && !uarmg){ 439 pline("Touching the dead cockatrice is a fatal mistake."); 440 pline("You turn to stone."); 441 killer = "cockatrice cadaver"; 442 done("died"); 443 } 444 445 if(obj->otyp == SCR_SCARE_MONSTER){ 446 if(!obj->spe) obj->spe = 1; 447 else { 448 /* Note: perhaps the 1st pickup failed: you cannot 449 carry anymore, and so we never dropped it - 450 let's assume that treading on it twice also 451 destroys the scroll */ 452 pline("The scroll turns to dust as you pick it up."); 453 delobj(obj); 454 continue; 455 } 456 } 457 458 wt = inv_weight() + obj->owt; 459 if(wt > 0) { 460 if(obj->quan > 1) { 461 /* see how many we can lift */ 462 extern struct obj *splitobj(); 463 int savequan = obj->quan; 464 int iw = inv_weight(); 465 int qq; 466 for(qq = 1; qq < savequan; qq++){ 467 obj->quan = qq; 468 if(iw + weight(obj) > 0) 469 break; 470 } 471 obj->quan = savequan; 472 qq--; 473 /* we can carry qq of them */ 474 if(!qq) goto too_heavy; 475 pline("You can only carry %s of the %s lying here.", 476 (qq == 1) ? "one" : "some", 477 doname(obj)); 478 (void) splitobj(obj, qq); 479 /* note: obj2 is set already, so we'll never 480 * encounter the other half; if it should be 481 * otherwise then write 482 * obj2 = splitobj(obj,qq); 483 */ 484 goto lift_some; 485 } 486 too_heavy: 487 pline("There %s %s here, but %s.", 488 (obj->quan == 1) ? "is" : "are", 489 doname(obj), 490 !invent ? "it is too heavy for you to lift" 491 : "you cannot carry anymore"); 492 break; 493 } 494 lift_some: 495 if(inv_cnt() >= 52) { 496 pline("Your knapsack cannot accomodate anymore items."); 497 break; 498 } 499 if(wt > -5) pline("You have a little trouble lifting"); 500 freeobj(obj); 501 if(Invisible) newsym(u.ux,u.uy); 502 addtobill(obj); /* sets obj->unpaid if necessary */ 503 { int pickquan = obj->quan; 504 int mergquan; 505 if(!Blind) obj->dknown = 1; /* this is done by prinv(), 506 but addinv() needs it already for merging */ 507 obj = addinv(obj); /* might merge it with other objects */ 508 mergquan = obj->quan; 509 obj->quan = pickquan; /* to fool prinv() */ 510 prinv(obj); 511 obj->quan = mergquan; 512 } 513 } 514 } 515 } 516 517 /* stop running if we see something interesting */ 518 /* turn around a corner if that is the only way we can proceed */ 519 /* do not turn left or right twice */ 520 lookaround(){ 521 register x,y,i,x0,y0,m0,i0 = 9; 522 register int corrct = 0, noturn = 0; 523 register struct monst *mtmp; 524 #ifdef lint 525 /* suppress "used before set" message */ 526 x0 = y0 = 0; 527 #endif /* lint /**/ 528 if(Blind || flags.run == 0) return; 529 if(flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) return; 530 for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ 531 if(x == u.ux && y == u.uy) continue; 532 if(!levl[x][y].typ) continue; 533 if((mtmp = m_at(x,y)) && !mtmp->mimic && 534 (!mtmp->minvis || See_invisible)){ 535 if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy)) 536 goto stop; 537 } else mtmp = 0; /* invisible M cannot influence us */ 538 if(x == u.ux-u.dx && y == u.uy-u.dy) continue; 539 #ifdef DGK 540 { 541 register uchar sym = levl[x][y].scrsym; 542 543 if (sym == symbol.vwall || sym == symbol.hwall 544 || sym == symbol.room || sym == ' ' || IS_CORNER(sym)) 545 continue; 546 else if (sym == symbol.door) { 547 if(x != u.ux && y != u.uy) continue; 548 if(flags.run != 1) goto stop; 549 goto corr; 550 } else if (sym == symbol.corr) { 551 corr: 552 if(flags.run == 1 || flags.run == 3) { 553 i = DIST(x,y,u.ux+u.dx,u.uy+u.dy); 554 if(i > 2) continue; 555 if(corrct == 1 && DIST(x,y,x0,y0) != 1) 556 noturn = 1; 557 if(i < i0) { 558 i0 = i; 559 x0 = x; 560 y0 = y; 561 m0 = mtmp ? 1 : 0; 562 } 563 } 564 corrct++; 565 continue; 566 } else if (sym == '^') { 567 if(flags.run == 1) goto corr; /* if you must */ 568 if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 569 continue; 570 } else { /* e.g. objects or trap or stairs */ 571 if(flags.run == 1) goto corr; 572 if(mtmp) continue; /* d */ 573 } 574 stop: 575 nomul(0); 576 return; 577 } 578 #else 579 switch(levl[x][y].scrsym){ 580 case '|': 581 case '-': 582 case '.': 583 case ' ': 584 break; 585 case '+': 586 if(x != u.ux && y != u.uy) break; 587 if(flags.run != 1) goto stop; 588 /* fall into next case */ 589 case CORR_SYM: 590 corr: 591 if(flags.run == 1 || flags.run == 3) { 592 i = DIST(x,y,u.ux+u.dx,u.uy+u.dy); 593 if(i > 2) break; 594 if(corrct == 1 && DIST(x,y,x0,y0) != 1) 595 noturn = 1; 596 if(i < i0) { 597 i0 = i; 598 x0 = x; 599 y0 = y; 600 m0 = mtmp ? 1 : 0; 601 } 602 } 603 corrct++; 604 break; 605 case '^': 606 if(flags.run == 1) goto corr; /* if you must */ 607 if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 608 break; 609 default: /* e.g. objects or trap or stairs */ 610 if(flags.run == 1) goto corr; 611 if(mtmp) break; /* d */ 612 stop: 613 nomul(0); 614 return; 615 } 616 #endif 617 } 618 if(corrct > 1 && flags.run == 2) goto stop; 619 if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 && 620 (corrct == 1 || (corrct == 2 && i0 == 1))) { 621 /* make sure that we do not turn too far */ 622 if(i0 == 2) { 623 if(u.dx == y0-u.uy && u.dy == u.ux-x0) 624 i = 2; /* straight turn right */ 625 else 626 i = -2; /* straight turn left */ 627 } else if(u.dx && u.dy) { 628 if((u.dx == u.dy && y0 == u.uy) || 629 (u.dx != u.dy && y0 != u.uy)) 630 i = -1; /* half turn left */ 631 else 632 i = 1; /* half turn right */ 633 } else { 634 if((x0-u.ux == y0-u.uy && !u.dy) || 635 (x0-u.ux != y0-u.uy && u.dy)) 636 i = 1; /* half turn right */ 637 else 638 i = -1; /* half turn left */ 639 } 640 i += u.last_str_turn; 641 if(i <= 2 && i >= -2) { 642 u.last_str_turn = i; 643 u.dx = x0-u.ux, u.dy = y0-u.uy; 644 } 645 } 646 } 647 648 /* something like lookaround, but we are not running */ 649 /* react only to monsters that might hit us */ 650 monster_nearby() { 651 register int x,y; 652 register struct monst *mtmp; 653 if(!Blind) 654 for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ 655 if(x == u.ux && y == u.uy) continue; 656 if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame && 657 !mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) && 658 !mtmp->mfroz && !mtmp->msleep && /* aplvax!jcn */ 659 (!mtmp->minvis || See_invisible)) 660 return(1); 661 } 662 return(0); 663 } 664 665 cansee(x,y) xchar x,y; { 666 if(Blind || u.uswallow) return(0); 667 if(dist(x,y) < 3) return(1); 668 if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y && 669 y <= seehy) return(1); 670 return(0); 671 } 672 673 sgn(a) register int a; { 674 return((a > 0) ? 1 : (a == 0) ? 0 : -1); 675 } 676 677 setsee() 678 { 679 register x,y; 680 681 if(Blind) { 682 pru(); 683 return; 684 } 685 if(!levl[u.ux][u.uy].lit) { 686 seelx = u.ux-1; 687 seehx = u.ux+1; 688 seely = u.uy-1; 689 seehy = u.uy+1; 690 } else { 691 for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--); 692 for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++); 693 for(seely = u.uy; levl[u.ux][seely-1].lit; seely--); 694 for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++); 695 } 696 for(y = seely; y <= seehy; y++) 697 for(x = seelx; x <= seehx; x++) { 698 prl(x,y); 699 } 700 if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */ 701 else { 702 if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1); 703 if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1); 704 if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y); 705 if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y); 706 } 707 } 708 709 710 nomul(nval) 711 register nval; 712 { 713 #ifdef DGK 714 if(multi < nval) return; /* This is a bug fix by ab@unido */ 715 #else 716 if(multi < 0) return; 717 #endif 718 multi = nval; 719 flags.mv = flags.run = 0; 720 } 721 722 abon() 723 { 724 if(u.ustr == 3) return(-3); 725 else if(u.ustr < 6) return(-2); 726 else if(u.ustr < 8) return(-1); 727 else if(u.ustr < 17) return(0); 728 else if(u.ustr < 69) return(1); /* up to 18/50 */ 729 else if(u.ustr < 118) return(2); 730 else return(3); 731 } 732 733 dbon() 734 { 735 if(u.ustr < 6) return(-1); 736 else if(u.ustr < 16) return(0); 737 else if(u.ustr < 18) return(1); 738 else if(u.ustr == 18) return(2); /* up to 18 */ 739 else if(u.ustr < 94) return(3); /* up to 18/75 */ 740 else if(u.ustr < 109) return(4); /* up to 18/90 */ 741 else if(u.ustr < 118) return(5); /* up to 18/99 */ 742 else return(6); 743 } 744 745 losestr(num) /* may kill you; cause may be poison or monster like 'A' */ 746 register num; 747 { 748 u.ustr -= num; 749 while(u.ustr < 3) { 750 u.ustr++; 751 u.uhp -= 6; 752 u.uhpmax -= 6; 753 } 754 flags.botl = 1; 755 } 756 757 losehp(n,knam) 758 register n; 759 register char *knam; 760 { 761 u.uhp -= n; 762 if(u.uhp > u.uhpmax) 763 u.uhpmax = u.uhp; /* perhaps n was negative */ 764 flags.botl = 1; 765 if(u.uhp < 1) { 766 killer = knam; /* the thing that killed you */ 767 done("died"); 768 } 769 } 770 771 losehp_m(n,mtmp) 772 register n; 773 register struct monst *mtmp; 774 { 775 u.uhp -= n; 776 flags.botl = 1; 777 if(u.uhp < 1) 778 done_in_by(mtmp); 779 } 780 781 losexp() /* hit by V or W */ 782 { 783 register num; 784 extern long newuexp(); 785 786 if(u.ulevel > 1) 787 pline("Goodbye level %u.", u.ulevel--); 788 else 789 u.uhp = -1; 790 num = rnd(10); 791 u.uhp -= num; 792 u.uhpmax -= num; 793 u.uexp = newuexp(); 794 flags.botl = 1; 795 } 796 797 inv_weight(){ 798 register struct obj *otmp = invent; 799 register int wt = (u.ugold + 500)/1000; 800 register int carrcap; 801 if(Levitation) /* pugh@cornell */ 802 carrcap = MAX_CARR_CAP; 803 else { 804 carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel); 805 if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 806 if(Wounded_legs & LEFT_SIDE) carrcap -= 10; 807 if(Wounded_legs & RIGHT_SIDE) carrcap -= 10; 808 } 809 while(otmp){ 810 wt += otmp->owt; 811 otmp = otmp->nobj; 812 } 813 return(wt - carrcap); 814 } 815 816 inv_cnt(){ 817 register struct obj *otmp = invent; 818 register int ct = 0; 819 while(otmp){ 820 ct++; 821 otmp = otmp->nobj; 822 } 823 return(ct); 824 } 825 826 long 827 newuexp() 828 { 829 return(10*(1L << (u.ulevel-1))); 830 }