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