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