]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.invent.c
banner, the game, really does belong here, contrary to what CSRG says.
[bsdgames-darwin.git] / hack / hack.invent.c
1 /*
2 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
3 */
4
5 #ifndef lint
6 static char rcsid[] = "$NetBSD: hack.invent.c,v 1.4 1995/03/23 08:30:25 cgd Exp $";
7 #endif /* not lint */
8
9 #include "hack.h"
10 #include <stdio.h>
11 extern struct obj *splitobj();
12 extern struct obj zeroobj;
13 extern char morc;
14 extern char quitchars[];
15 static char *xprname();
16
17 #ifndef NOWORM
18 #include "def.wseg.h"
19 extern struct wseg *wsegs[32];
20 #endif NOWORM
21
22 #define NOINVSYM '#'
23
24 static int lastinvnr = 51; /* 0 ... 51 */
25 static
26 assigninvlet(otmp)
27 register struct obj *otmp;
28 {
29 boolean inuse[52];
30 register int i;
31 register struct obj *obj;
32
33 for(i = 0; i < 52; i++) inuse[i] = FALSE;
34 for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) {
35 i = obj->invlet;
36 if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else
37 if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE;
38 if(i == otmp->invlet) otmp->invlet = 0;
39 }
40 if((i = otmp->invlet) &&
41 (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
42 return;
43 for(i = lastinvnr+1; i != lastinvnr; i++) {
44 if(i == 52) { i = -1; continue; }
45 if(!inuse[i]) break;
46 }
47 otmp->invlet = (inuse[i] ? NOINVSYM :
48 (i < 26) ? ('a'+i) : ('A'+i-26));
49 lastinvnr = i;
50 }
51
52 struct obj *
53 addinv(obj)
54 register struct obj *obj;
55 {
56 register struct obj *otmp;
57
58 /* merge or attach to end of chain */
59 if(!invent) {
60 invent = obj;
61 otmp = 0;
62 } else
63 for(otmp = invent; /* otmp */; otmp = otmp->nobj) {
64 if(merged(otmp, obj, 0))
65 return(otmp);
66 if(!otmp->nobj) {
67 otmp->nobj = obj;
68 break;
69 }
70 }
71 obj->nobj = 0;
72
73 if(flags.invlet_constant) {
74 assigninvlet(obj);
75 /*
76 * The ordering of the chain is nowhere significant
77 * so in case you prefer some other order than the
78 * historical one, change the code below.
79 */
80 if(otmp) { /* find proper place in chain */
81 otmp->nobj = 0;
82 if((invent->invlet ^ 040) > (obj->invlet ^ 040)) {
83 obj->nobj = invent;
84 invent = obj;
85 } else
86 for(otmp = invent; ; otmp = otmp->nobj) {
87 if(!otmp->nobj ||
88 (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){
89 obj->nobj = otmp->nobj;
90 otmp->nobj = obj;
91 break;
92 }
93 }
94 }
95 }
96
97 return(obj);
98 }
99
100 useup(obj)
101 register struct obj *obj;
102 {
103 if(obj->quan > 1){
104 obj->quan--;
105 obj->owt = weight(obj);
106 } else {
107 setnotworn(obj);
108 freeinv(obj);
109 obfree(obj, (struct obj *) 0);
110 }
111 }
112
113 freeinv(obj)
114 register struct obj *obj;
115 {
116 register struct obj *otmp;
117
118 if(obj == invent)
119 invent = invent->nobj;
120 else {
121 for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)
122 if(!otmp->nobj) panic("freeinv");
123 otmp->nobj = obj->nobj;
124 }
125 }
126
127 /* destroy object in fobj chain (if unpaid, it remains on the bill) */
128 delobj(obj) register struct obj *obj; {
129 freeobj(obj);
130 unpobj(obj);
131 obfree(obj, (struct obj *) 0);
132 }
133
134 /* unlink obj from chain starting with fobj */
135 freeobj(obj) register struct obj *obj; {
136 register struct obj *otmp;
137
138 if(obj == fobj) fobj = fobj->nobj;
139 else {
140 for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj)
141 if(!otmp) panic("error in freeobj");
142 otmp->nobj = obj->nobj;
143 }
144 }
145
146 /* Note: freegold throws away its argument! */
147 freegold(gold) register struct gold *gold; {
148 register struct gold *gtmp;
149
150 if(gold == fgold) fgold = gold->ngold;
151 else {
152 for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold)
153 if(!gtmp) panic("error in freegold");
154 gtmp->ngold = gold->ngold;
155 }
156 free((char *) gold);
157 }
158
159 deltrap(trap)
160 register struct trap *trap;
161 {
162 register struct trap *ttmp;
163
164 if(trap == ftrap)
165 ftrap = ftrap->ntrap;
166 else {
167 for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
168 ttmp->ntrap = trap->ntrap;
169 }
170 free((char *) trap);
171 }
172
173 struct wseg *m_atseg;
174
175 struct monst *
176 m_at(x,y)
177 register x,y;
178 {
179 register struct monst *mtmp;
180 #ifndef NOWORM
181 register struct wseg *wtmp;
182 #endif NOWORM
183
184 m_atseg = 0;
185 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
186 if(mtmp->mx == x && mtmp->my == y)
187 return(mtmp);
188 #ifndef NOWORM
189 if(mtmp->wormno){
190 for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg)
191 if(wtmp->wx == x && wtmp->wy == y){
192 m_atseg = wtmp;
193 return(mtmp);
194 }
195 }
196 #endif NOWORM
197 }
198 return(0);
199 }
200
201 struct obj *
202 o_at(x,y)
203 register x,y;
204 {
205 register struct obj *otmp;
206
207 for(otmp = fobj; otmp; otmp = otmp->nobj)
208 if(otmp->ox == x && otmp->oy == y) return(otmp);
209 return(0);
210 }
211
212 struct obj *
213 sobj_at(n,x,y)
214 register n,x,y;
215 {
216 register struct obj *otmp;
217
218 for(otmp = fobj; otmp; otmp = otmp->nobj)
219 if(otmp->ox == x && otmp->oy == y && otmp->otyp == n)
220 return(otmp);
221 return(0);
222 }
223
224 carried(obj) register struct obj *obj; {
225 register struct obj *otmp;
226 for(otmp = invent; otmp; otmp = otmp->nobj)
227 if(otmp == obj) return(1);
228 return(0);
229 }
230
231 carrying(type)
232 register int type;
233 {
234 register struct obj *otmp;
235
236 for(otmp = invent; otmp; otmp = otmp->nobj)
237 if(otmp->otyp == type)
238 return(TRUE);
239 return(FALSE);
240 }
241
242 struct obj *
243 o_on(id, objchn) unsigned int id; register struct obj *objchn; {
244 while(objchn) {
245 if(objchn->o_id == id) return(objchn);
246 objchn = objchn->nobj;
247 }
248 return((struct obj *) 0);
249 }
250
251 struct trap *
252 t_at(x,y)
253 register x,y;
254 {
255 register struct trap *trap = ftrap;
256 while(trap) {
257 if(trap->tx == x && trap->ty == y) return(trap);
258 trap = trap->ntrap;
259 }
260 return(0);
261 }
262
263 struct gold *
264 g_at(x,y)
265 register x,y;
266 {
267 register struct gold *gold = fgold;
268 while(gold) {
269 if(gold->gx == x && gold->gy == y) return(gold);
270 gold = gold->ngold;
271 }
272 return(0);
273 }
274
275 /* make dummy object structure containing gold - for temporary use only */
276 struct obj *
277 mkgoldobj(q)
278 register long q;
279 {
280 register struct obj *otmp;
281
282 otmp = newobj(0);
283 /* should set o_id etc. but otmp will be freed soon */
284 otmp->olet = '$';
285 u.ugold -= q;
286 OGOLD(otmp) = q;
287 flags.botl = 1;
288 return(otmp);
289 }
290
291 /*
292 * getobj returns:
293 * struct obj *xxx: object to do something with.
294 * (struct obj *) 0 error return: no object.
295 * &zeroobj explicitly no object (as in w-).
296 */
297 struct obj *
298 getobj(let,word)
299 register char *let,*word;
300 {
301 register struct obj *otmp;
302 register char ilet,ilet1,ilet2;
303 char buf[BUFSZ];
304 char lets[BUFSZ];
305 register int foo = 0, foo2;
306 register char *bp = buf;
307 xchar allowcnt = 0; /* 0, 1 or 2 */
308 boolean allowgold = FALSE;
309 boolean allowall = FALSE;
310 boolean allownone = FALSE;
311 xchar foox = 0;
312 long cnt;
313
314 if(*let == '0') let++, allowcnt = 1;
315 if(*let == '$') let++, allowgold = TRUE;
316 if(*let == '#') let++, allowall = TRUE;
317 if(*let == '-') let++, allownone = TRUE;
318 if(allownone) *bp++ = '-';
319 if(allowgold) *bp++ = '$';
320 if(bp > buf && bp[-1] == '-') *bp++ = ' ';
321
322 ilet = 'a';
323 for(otmp = invent; otmp; otmp = otmp->nobj){
324 if(!*let || index(let, otmp->olet)) {
325 bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;
326
327 /* ugly check: remove inappropriate things */
328 if((!strcmp(word, "take off") &&
329 !(otmp->owornmask & (W_ARMOR - W_ARM2)))
330 || (!strcmp(word, "wear") &&
331 (otmp->owornmask & (W_ARMOR | W_RING)))
332 || (!strcmp(word, "wield") &&
333 (otmp->owornmask & W_WEP))) {
334 foo--;
335 foox++;
336 }
337 }
338 if(ilet == 'z') ilet = 'A'; else ilet++;
339 }
340 bp[foo] = 0;
341 if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
342 (void) strcpy(lets, bp); /* necessary since we destroy buf */
343 if(foo > 5) { /* compactify string */
344 foo = foo2 = 1;
345 ilet2 = bp[0];
346 ilet1 = bp[1];
347 while(ilet = bp[++foo2] = bp[++foo]){
348 if(ilet == ilet1+1){
349 if(ilet1 == ilet2+1)
350 bp[foo2 - 1] = ilet1 = '-';
351 else if(ilet2 == '-') {
352 bp[--foo2] = ++ilet1;
353 continue;
354 }
355 }
356 ilet2 = ilet1;
357 ilet1 = ilet;
358 }
359 }
360 if(!foo && !allowall && !allowgold && !allownone) {
361 pline("You don't have anything %sto %s.",
362 foox ? "else " : "", word);
363 return(0);
364 }
365 for(;;) {
366 if(!buf[0])
367 pline("What do you want to %s [*]? ", word);
368 else
369 pline("What do you want to %s [%s or ?*]? ",
370 word, buf);
371
372 cnt = 0;
373 ilet = readchar();
374 while(digit(ilet) && allowcnt) {
375 if (cnt < 100000000)
376 cnt = 10*cnt + (ilet - '0');
377 else
378 cnt = 999999999;
379 allowcnt = 2; /* signal presence of cnt */
380 ilet = readchar();
381 }
382 if(digit(ilet)) {
383 pline("No count allowed with this command.");
384 continue;
385 }
386 if(index(quitchars,ilet))
387 return((struct obj *)0);
388 if(ilet == '-') {
389 return(allownone ? &zeroobj : (struct obj *) 0);
390 }
391 if(ilet == '$') {
392 if(!allowgold){
393 pline("You cannot %s gold.", word);
394 continue;
395 }
396 if(!(allowcnt == 2 && cnt < u.ugold))
397 cnt = u.ugold;
398 return(mkgoldobj(cnt));
399 }
400 if(ilet == '?') {
401 doinv(lets);
402 if(!(ilet = morc)) continue;
403 /* he typed a letter (not a space) to more() */
404 } else if(ilet == '*') {
405 doinv((char *) 0);
406 if(!(ilet = morc)) continue;
407 /* ... */
408 }
409 if(flags.invlet_constant) {
410 for(otmp = invent; otmp; otmp = otmp->nobj)
411 if(otmp->invlet == ilet) break;
412 } else {
413 if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1;
414 ilet -= 'a';
415 for(otmp = invent; otmp && ilet;
416 ilet--, otmp = otmp->nobj) ;
417 }
418 if(!otmp) {
419 pline("You don't have that object.");
420 continue;
421 }
422 if(cnt < 0 || otmp->quan < cnt) {
423 pline("You don't have that many! [You have %u]"
424 , otmp->quan);
425 continue;
426 }
427 break;
428 }
429 if(!allowall && let && !index(let,otmp->olet)) {
430 pline("That is a silly thing to %s.",word);
431 return(0);
432 }
433 if(allowcnt == 2) { /* cnt given */
434 if(cnt == 0) return(0);
435 if(cnt != otmp->quan) {
436 register struct obj *obj;
437 obj = splitobj(otmp, (int) cnt);
438 if(otmp == uwep) setuwep(obj);
439 }
440 }
441 return(otmp);
442 }
443
444 ckunpaid(otmp) register struct obj *otmp; {
445 return( otmp->unpaid );
446 }
447
448 /* interactive version of getobj - used for Drop and Identify */
449 /* return the number of times fn was called successfully */
450 ggetobj(word, fn, max)
451 char *word;
452 int (*fn)(), max;
453 {
454 char buf[BUFSZ];
455 register char *ip;
456 register char sym;
457 register int oletct = 0, iletct = 0;
458 register boolean allflag = FALSE;
459 char olets[20], ilets[20];
460 int (*ckfn)() = (int (*)()) 0;
461 xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */
462 if(!invent && !allowgold){
463 pline("You have nothing to %s.", word);
464 return(0);
465 } else {
466 register struct obj *otmp = invent;
467 register int uflg = 0;
468
469 if(allowgold) ilets[iletct++] = '$';
470 ilets[iletct] = 0;
471 while(otmp) {
472 if(!index(ilets, otmp->olet)){
473 ilets[iletct++] = otmp->olet;
474 ilets[iletct] = 0;
475 }
476 if(otmp->unpaid) uflg = 1;
477 otmp = otmp->nobj;
478 }
479 ilets[iletct++] = ' ';
480 if(uflg) ilets[iletct++] = 'u';
481 if(invent) ilets[iletct++] = 'a';
482 ilets[iletct] = 0;
483 }
484 pline("What kinds of thing do you want to %s? [%s] ",
485 word, ilets);
486 getlin(buf);
487 if(buf[0] == '\033') {
488 clrlin();
489 return(0);
490 }
491 ip = buf;
492 olets[0] = 0;
493 while(sym = *ip++){
494 if(sym == ' ') continue;
495 if(sym == '$') {
496 if(allowgold == 1)
497 (*fn)(mkgoldobj(u.ugold));
498 else if(!u.ugold)
499 pline("You have no gold.");
500 allowgold = 2;
501 } else
502 if(sym == 'a' || sym == 'A') allflag = TRUE; else
503 if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else
504 if(index("!%?[()=*/\"0", sym)){
505 if(!index(olets, sym)){
506 olets[oletct++] = sym;
507 olets[oletct] = 0;
508 }
509 }
510 else pline("You don't have any %c's.", sym);
511 }
512 if(allowgold == 2 && !oletct)
513 return(1); /* he dropped gold (or at least tried to) */
514 else
515 return(askchain(invent, olets, allflag, fn, ckfn, max));
516 }
517
518 /*
519 * Walk through the chain starting at objchn and ask for all objects
520 * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL)
521 * whether the action in question (i.e., fn) has to be performed.
522 * If allflag then no questions are asked. Max gives the max nr of
523 * objects to be treated. Return the number of objects treated.
524 */
525 askchain(objchn, olets, allflag, fn, ckfn, max)
526 struct obj *objchn;
527 register char *olets;
528 int allflag;
529 int (*fn)(), (*ckfn)();
530 int max;
531 {
532 register struct obj *otmp, *otmp2;
533 register char sym, ilet;
534 register int cnt = 0;
535 ilet = 'a'-1;
536 for(otmp = objchn; otmp; otmp = otmp2){
537 if(ilet == 'z') ilet = 'A'; else ilet++;
538 otmp2 = otmp->nobj;
539 if(olets && *olets && !index(olets, otmp->olet)) continue;
540 if(ckfn && !(*ckfn)(otmp)) continue;
541 if(!allflag) {
542 pline(xprname(otmp, ilet));
543 addtopl(" [nyaq]? ");
544 sym = readchar();
545 }
546 else sym = 'y';
547
548 switch(sym){
549 case 'a':
550 allflag = 1;
551 case 'y':
552 cnt += (*fn)(otmp);
553 if(--max == 0) goto ret;
554 case 'n':
555 default:
556 break;
557 case 'q':
558 goto ret;
559 }
560 }
561 pline(cnt ? "That was all." : "No applicable objects.");
562 ret:
563 return(cnt);
564 }
565
566 obj_to_let(obj) /* should of course only be called for things in invent */
567 register struct obj *obj;
568 {
569 register struct obj *otmp;
570 register char ilet;
571
572 if(flags.invlet_constant)
573 return(obj->invlet);
574 ilet = 'a';
575 for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj)
576 if(++ilet > 'z') ilet = 'A';
577 return(otmp ? ilet : NOINVSYM);
578 }
579
580 prinv(obj)
581 register struct obj *obj;
582 {
583 pline(xprname(obj, obj_to_let(obj)));
584 }
585
586 static char *
587 xprname(obj,let)
588 register struct obj *obj;
589 register char let;
590 {
591 static char li[BUFSZ];
592
593 (void) sprintf(li, "%c - %s.",
594 flags.invlet_constant ? obj->invlet : let,
595 doname(obj));
596 return(li);
597 }
598
599 ddoinv()
600 {
601 doinv((char *) 0);
602 return(0);
603 }
604
605 /* called with 0 or "": all objects in inventory */
606 /* otherwise: all objects with (serial) letter in lets */
607 doinv(lets)
608 register char *lets;
609 {
610 register struct obj *otmp;
611 register char ilet;
612 int ct = 0;
613 char any[BUFSZ];
614
615 morc = 0; /* just to be sure */
616
617 if(!invent){
618 pline("Not carrying anything.");
619 return;
620 }
621
622 cornline(0, (char *) 0);
623 ilet = 'a';
624 for(otmp = invent; otmp; otmp = otmp->nobj) {
625 if(flags.invlet_constant) ilet = otmp->invlet;
626 if(!lets || !*lets || index(lets, ilet)) {
627 cornline(1, xprname(otmp, ilet));
628 any[ct++] = ilet;
629 }
630 if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
631 }
632 any[ct] = 0;
633 cornline(2, any);
634 }
635
636 dotypeinv () /* free after Robert Viduya */
637 /* Changed to one type only, so he doesnt have to type cr */
638 {
639 char c, ilet;
640 char stuff[BUFSZ];
641 register int stct;
642 register struct obj *otmp;
643 boolean billx = inshop() && doinvbill(0);
644 boolean unpd = FALSE;
645
646 if (!invent && !u.ugold && !billx) {
647 pline ("You aren't carrying anything.");
648 return(0);
649 }
650
651 stct = 0;
652 if(u.ugold) stuff[stct++] = '$';
653 stuff[stct] = 0;
654 for(otmp = invent; otmp; otmp = otmp->nobj) {
655 if (!index (stuff, otmp->olet)) {
656 stuff[stct++] = otmp->olet;
657 stuff[stct] = 0;
658 }
659 if(otmp->unpaid)
660 unpd = TRUE;
661 }
662 if(unpd) stuff[stct++] = 'u';
663 if(billx) stuff[stct++] = 'x';
664 stuff[stct] = 0;
665
666 if(stct > 1) {
667 pline ("What type of object [%s] do you want an inventory of? ",
668 stuff);
669 c = readchar();
670 if(index(quitchars,c)) return(0);
671 } else
672 c = stuff[0];
673
674 if(c == '$')
675 return(doprgold());
676
677 if(c == 'x' || c == 'X') {
678 if(billx)
679 (void) doinvbill(1);
680 else
681 pline("No used-up objects on the shopping bill.");
682 return(0);
683 }
684
685 if((c == 'u' || c == 'U') && !unpd) {
686 pline("You are not carrying any unpaid objects.");
687 return(0);
688 }
689
690 stct = 0;
691 ilet = 'a';
692 for (otmp = invent; otmp; otmp = otmp -> nobj) {
693 if(flags.invlet_constant) ilet = otmp->invlet;
694 if (c == otmp -> olet || (c == 'u' && otmp -> unpaid))
695 stuff[stct++] = ilet;
696 if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
697 }
698 stuff[stct] = '\0';
699 if(stct == 0)
700 pline("You have no such objects.");
701 else
702 doinv (stuff);
703
704 return(0);
705 }
706
707 /* look at what is here */
708 dolook() {
709 register struct obj *otmp, *otmp0;
710 register struct gold *gold;
711 char *verb = Blind ? "feel" : "see";
712 int ct = 0;
713
714 if(!u.uswallow) {
715 if(Blind) {
716 pline("You try to feel what is lying here on the floor.");
717 if(Levitation) { /* ab@unido */
718 pline("You cannot reach the floor!");
719 return(1);
720 }
721 }
722 otmp0 = o_at(u.ux, u.uy);
723 gold = g_at(u.ux, u.uy);
724 }
725
726 if(u.uswallow || (!otmp0 && !gold)) {
727 pline("You %s no objects here.", verb);
728 return(!!Blind);
729 }
730
731 cornline(0, "Things that are here:");
732 for(otmp = otmp0; otmp; otmp = otmp->nobj) {
733 if(otmp->ox == u.ux && otmp->oy == u.uy) {
734 ct++;
735 cornline(1, doname(otmp));
736 if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) {
737 pline("Touching the dead cockatrice is a fatal mistake ...");
738 pline("You die ...");
739 killer = "dead cockatrice";
740 done("died");
741 }
742 }
743 }
744
745 if(gold) {
746 char gbuf[30];
747
748 (void) sprintf(gbuf, "%ld gold piece%s",
749 gold->amount, plur(gold->amount));
750 if(!ct++)
751 pline("You %s here %s.", verb, gbuf);
752 else
753 cornline(1, gbuf);
754 }
755
756 if(ct == 1 && !gold) {
757 pline("You %s here %s.", verb, doname(otmp0));
758 cornline(3, (char *) 0);
759 }
760 if(ct > 1)
761 cornline(2, (char *) 0);
762 return(!!Blind);
763 }
764
765 stackobj(obj) register struct obj *obj; {
766 register struct obj *otmp = fobj;
767 for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj)
768 if(otmp->ox == obj->ox && otmp->oy == obj->oy &&
769 merged(obj,otmp,1))
770 return;
771 }
772
773 /* merge obj with otmp and delete obj if types agree */
774 merged(otmp,obj,lose) register struct obj *otmp, *obj; {
775 if(obj->otyp == otmp->otyp &&
776 obj->unpaid == otmp->unpaid &&
777 obj->spe == otmp->spe &&
778 obj->dknown == otmp->dknown &&
779 obj->cursed == otmp->cursed &&
780 (index("%*?!", obj->olet) ||
781 (obj->known == otmp->known &&
782 (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) {
783 otmp->quan += obj->quan;
784 otmp->owt += obj->owt;
785 if(lose) freeobj(obj);
786 obfree(obj,otmp); /* free(obj), bill->otmp */
787 return(1);
788 } else return(0);
789 }
790
791 /*
792 * Gold is no longer displayed; in fact, when you have a lot of money,
793 * it may take a while before you have counted it all.
794 * [Bug: d$ and pickup still tell you how much it was.]
795 */
796 extern int (*occupation)();
797 extern char *occtxt;
798 static long goldcounted;
799
800 countgold(){
801 if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) {
802 long eps = 0;
803 if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1));
804 pline("You probably have about %ld gold pieces.",
805 u.ugold + eps);
806 return(0); /* done */
807 }
808 return(1); /* continue */
809 }
810
811 doprgold(){
812 if(!u.ugold)
813 pline("You do not carry any gold.");
814 else if(u.ugold <= 500)
815 pline("You are carrying %ld gold pieces.", u.ugold);
816 else {
817 pline("You sit down in order to count your gold pieces.");
818 goldcounted = 500;
819 occupation = countgold;
820 occtxt = "counting your gold";
821 }
822 return(1);
823 }
824
825 /* --- end of gold counting section --- */
826
827 doprwep(){
828 if(!uwep) pline("You are empty handed.");
829 else prinv(uwep);
830 return(0);
831 }
832
833 doprarm(){
834 if(!uarm && !uarmg && !uarms && !uarmh)
835 pline("You are not wearing any armor.");
836 else {
837 char lets[6];
838 register int ct = 0;
839
840 if(uarm) lets[ct++] = obj_to_let(uarm);
841 if(uarm2) lets[ct++] = obj_to_let(uarm2);
842 if(uarmh) lets[ct++] = obj_to_let(uarmh);
843 if(uarms) lets[ct++] = obj_to_let(uarms);
844 if(uarmg) lets[ct++] = obj_to_let(uarmg);
845 lets[ct] = 0;
846 doinv(lets);
847 }
848 return(0);
849 }
850
851 doprring(){
852 if(!uleft && !uright)
853 pline("You are not wearing any rings.");
854 else {
855 char lets[3];
856 register int ct = 0;
857
858 if(uleft) lets[ct++] = obj_to_let(uleft);
859 if(uright) lets[ct++] = obj_to_let(uright);
860 lets[ct] = 0;
861 doinv(lets);
862 }
863 return(0);
864 }
865
866 digit(c) char c; {
867 return(c >= '0' && c <= '9');
868 }