Annotation of early-roguelike/arogue5/pack.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * Routines to deal with the pack
3: *
4: * Advanced Rogue
5: * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
6: * All rights reserved.
7: *
8: * Based on "Rogue: Exploring the Dungeons of Doom"
9: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
10: * All rights reserved.
11: *
12: * See the file LICENSE.TXT for full copyright and licensing information.
13: */
14:
15: #include "curses.h"
16: #include <ctype.h>
17: #include "rogue.h"
18:
19: char outstring[512]; /* ridiculously long string for use with msg */
20:
21: bool is_type (struct object *obj, int type);
22:
23: /*
24: * add_pack:
25: * Pick up an object and add it to the pack. If the argument is non-null
26: * use it as the linked_list pointer instead of gettting it off the ground.
27: */
28: bool
29: add_pack(struct linked_list *item, bool silent, struct linked_list **packret)
30: {
31: register struct linked_list *ip, *lp = NULL, *ap;
32: register struct object *obj, *op = NULL;
33: register bool exact, from_floor;
34:
35: if (packret != NULL)
36: *packret = NULL;
37:
38: if (item == NULL)
39: {
40: from_floor = TRUE;
41: if ((item = find_obj(hero.y, hero.x)) == NULL)
42: return(FALSE);
43: }
44: else
45: from_floor = FALSE;
46: obj = OBJPTR(item);
47: /*
48: * If it is gold, just add its value to rogue's purse and get rid
49: * of it.
50: */
51: if (obj->o_type == GOLD) {
52: register struct linked_list *mitem;
53: register struct thing *tp;
54:
55: if (!silent) {
56: if (!terse) addmsg("You found ");
57: msg("%d gold pieces.", obj->o_count);
58: }
59:
60: /* First make sure no greedy monster is after this gold.
61: * If so, make the monster run after the rogue instead.
62: */
63: for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
64: tp = THINGPTR(mitem);
65: if (tp->t_dest == &obj->o_pos) tp->t_dest = &hero;
66: }
67:
68: purse += obj->o_count;
69: if (from_floor) {
70: detach(lvl_obj, item);
71: if ((ap = find_obj(hero.y, hero.x)) == NULL)
72: mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
73: else
74: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
75: }
76: o_discard(item);
77: return(TRUE);
78: }
79:
80: /*
81: * see if he can carry any more weight
82: */
83: if (itemweight(obj) + pstats.s_pack > pstats.s_carry) {
84: msg("Too much for you to carry.");
85: return FALSE;
86: }
87: /*
88: * Link it into the pack. Search the pack for a object of similar type
89: * if there isn't one, stuff it at the beginning, if there is, look for one
90: * that is exactly the same and just increment the count if there is.
91: * it that. Food is always put at the beginning for ease of access, but
92: * is not ordered so that you can't tell good food from bad. First check
93: * to see if there is something in thr same group and if there is then
94: * increment the count.
95: */
96: if (obj->o_group)
97: {
98: for (ip = pack; ip != NULL; ip = next(ip))
99: {
100: op = OBJPTR(ip);
101: if (op->o_group == obj->o_group)
102: {
103: /*
104: * Put it in the pack and notify the user
105: */
106: op->o_count += obj->o_count;
107: if (from_floor)
108: {
109: detach(lvl_obj, item);
110: if ((ap = find_obj(hero.y, hero.x)) == NULL)
111: mvaddch(hero.y,hero.x,
112: (roomin(&hero)==NULL ? PASSAGE : FLOOR));
113: else
114: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
115: }
116: o_discard(item);
117: item = ip;
118: goto picked_up;
119: }
120: }
121: }
122:
123: /*
124: * Check for and deal with scare monster scrolls
125: */
126: if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
127: if (obj->o_flags & ISCURSED)
128: {
129: msg("The scroll turns to dust as you pick it up.");
130: detach(lvl_obj, item);
131: if ((ap = find_obj(hero.y, hero.x)) == NULL)
132: mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
133: else
134: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
135: return(TRUE);
136: }
137:
138: /*
139: * Search for an object of the same type
140: */
141: exact = FALSE;
142: for (ip = pack; ip != NULL; ip = next(ip))
143: {
144: op = OBJPTR(ip);
145: if (obj->o_type == op->o_type)
146: break;
147: }
148: if (ip == NULL)
149: {
150: /*
151: * Put it at the end of the pack since it is a new type
152: */
153: for (ip = pack; ip != NULL; ip = next(ip))
154: {
155: op = OBJPTR(ip);
156: if (op->o_type != FOOD)
157: break;
158: lp = ip;
159: }
160: }
161: else
162: {
163: /*
164: * Search for an object which is exactly the same
165: */
166: while (ip != NULL && op->o_type == obj->o_type)
167: {
168: if (op->o_which == obj->o_which)
169: {
170: exact = TRUE;
171: break;
172: }
173: lp = ip;
174: if ((ip = next(ip)) == NULL)
175: break;
176: op = OBJPTR(ip);
177: }
178: }
179: /*
180: * Check if there is room
181: */
182: if (ip == NULL || !exact || !ISMULT(obj->o_type)) {
183: if (inpack == MAXPACK-1) {
184: msg(terse ? "No room." : "You can't carry anything else.");
185: return(FALSE);
186: }
187: }
188: inpack++;
189: if (from_floor)
190: {
191: detach(lvl_obj, item);
192: if ((ap = find_obj(hero.y, hero.x)) == NULL)
193: mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
194: else
195: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
196: }
197: if (ip == NULL)
198: {
199: /*
200: * Didn't find an exact match, just stick it here
201: */
202: if (pack == NULL)
203: pack = item;
204: else
205: {
206: lp->l_next = item;
207: item->l_prev = lp;
208: item->l_next = NULL;
209: }
210: }
211: else
212: {
213: /*
214: * If we found an exact match. If it is food,
215: * increase the count, otherwise put it with its clones.
216: */
217: if (exact && ISMULT(obj->o_type))
218: {
219: op->o_count += obj->o_count;
220: inpack--; /* adjust for previous addition */
221: o_discard(item);
222: item = ip;
223: goto picked_up;
224: }
225: if ((item->l_prev = prev(ip)) != NULL)
226: item->l_prev->l_next = item;
227: else
228: pack = item;
229: item->l_next = ip;
230: ip->l_prev = item;
231: }
232: picked_up:
233: /*
234: * Notify the user
235: */
236: obj = OBJPTR(item);
237: if (!silent)
238: {
239: if (!terse)
240: addmsg("You now have ");
241: sprintf(outstring,"%s (%c)", inv_name(obj, !terse), pack_char(pack, obj));
242: msg(outstring);
243: }
244:
245: /* Relics can do strange things when you pick them up */
246: if (obj->o_type == RELIC) {
247: cur_relic[obj->o_which]++; /* Note that we have it */
248: switch (obj->o_which) {
249: case HEIL_ANKH:
250: msg("The ankh welds itself into your hand.");
251:
252: /* A cloak must be worn. */
253: when EMORI_CLOAK:
254: if (cur_armor != NULL || cur_misc[WEAR_CLOAK]) {
255: msg("The cloak insists you remove your current garments.");
256: if (!dropcheck(cur_armor != NULL ? cur_armor
257: : cur_misc[WEAR_CLOAK])) {
258: pstats.s_hpt = -1;
259: msg("The cloak constricts around you.");
260: msg("It draws your life force from you!!! -- More --");
261: wait_for(cw,' ');
262: death(D_RELIC);
263: }
264: }
265:
266: /* The amulet must be worn. */
267: when YENDOR_AMULET:
268: if (cur_misc[WEAR_JEWEL]) {
269: msg("You have an urge to remove your current amulet.");
270: if (!dropcheck(cur_misc[WEAR_JEWEL])) {
271: pstats.s_hpt = -1;
272: msg("The Amulet of Yendor begins pulsing.");
273: msg("It fades away.... -- More --");
274: wait_for(cw,' ');
275: death(D_RELIC);
276: }
277: }
278: msg("The amulet welds itself into your chest.");
279:
280: /* Weapons will insist on being wielded. */
281: when MUSTY_DAGGER:
282: case HRUGGEK_MSTAR:
283: case YEENOGHU_FLAIL:
284: if (cur_weapon != NULL) {
285: msg("The artifact insists you release your current weapon.");
286: if (!dropcheck(cur_weapon)) {
287: pstats.s_hpt = -1;
288: msg("The artifact forces your weapon into your heart.");
289: msg("It hums with satisfaction. -- More --");
290: wait_for(cw,' ');
291: death(D_RELIC);
292: }
293: }
294: cur_weapon = obj;
295: }
296: }
297:
298: updpack(FALSE);
299: if (packret != NULL)
300: *packret = item;
301: return(TRUE);
302: }
303:
304: /*
305: * inventory:
306: * list what is in the pack
307: */
308: bool
309: inventory(struct linked_list *list, int type)
310: {
311: register struct object *obj;
312: register char ch;
313: register int n_objs;
314: register int cnt;
315: char inv_temp[LINELEN];
316:
317: cnt = 0;
318: n_objs = 0;
319: for (ch = 'a'; list != NULL; ch++, list = next(list)) {
320: obj = OBJPTR(list);
321: if (!is_type(obj, type))
322: continue;
323: switch (n_objs++) {
324: /*
325: * For the first thing in the inventory, just save the string
326: * in case there is only one.
327: */
328: case 0:
329: sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE));
330: break;
331: /*
332: * If there is more than one, clear the screen, print the
333: * saved message and fall through to ...
334: */
335: case 1:
336: if (slow_invent)
337: msg(inv_temp);
338: else
339: {
340: wclear(hw);
341: waddstr(hw, inv_temp);
342: waddch(hw, '\n');
343: }
344: /*
345: * Print the line for this object
346: */
347: default:
348: if (ch > 'z')
349: ch = 'A';
350: if (slow_invent){
351: sprintf(outstring,"%c) %s", ch, inv_name(obj, FALSE));
352: msg(outstring);
353: }
354: else {
355: if (++cnt >= LINES - 2) { /* if bottom of screen */
356: dbotline(hw, morestr);
357: cnt = 0;
358: wclear(hw);
359: }
360: wprintw(hw, "%c) %s\n", ch, inv_name(obj, FALSE));
361: }
362: }
363: }
364: if (n_objs == 0) {
365: if (terse)
366: msg(type == 0 ? "Empty handed." :
367: "Nothing appropriate");
368: else
369: msg(type == 0 ? "You are empty handed." :
370: "You don't have anything appropriate");
371: return FALSE;
372: }
373: if (n_objs == 1) {
374: msg(inv_temp);
375: return TRUE;
376: }
377: if (!slow_invent)
378: {
379: mvwaddstr(hw, LINES-1, 0, spacemsg);
380: draw(hw);
381: wait_for(hw,' ');
382: clearok(cw, TRUE);
383: touchwin(cw);
384: }
385: return TRUE;
386: }
387:
388: /*
389: * pick_up:
390: * Add something to characters pack.
391: */
392: void
393: pick_up(char ch)
394: {
395: switch (ch) {
396: default:
397: debug("Where did you pick that up???");
398: case GOLD:
399: case ARMOR:
400: case POTION:
401: case FOOD:
402: case WEAPON:
403: case SCROLL:
404: case MM:
405: case RING:
406: case STICK:
407: case RELIC:
408: while (add_pack(NULL, FALSE, NULL)); /* pick up everything there */
409: break;
410: }
411: }
412:
413: /*
414: * picky_inven:
415: * Allow player to inventory a single item
416: */
417: void
418: picky_inven(void)
419: {
420: register struct linked_list *item;
421: register char ch, mch;
422:
423: if (pack == NULL)
424: msg("You aren't carrying anything");
425: else if (next(pack) == NULL)
426: msg("a) %s", inv_name(OBJPTR(pack), FALSE));
427: else
428: {
429: msg(terse ? "Item: " : "Which item do you wish to inventory: ");
430: mpos = 0;
431: if ((mch = readchar()) == ESCAPE)
432: {
433: msg("");
434: return;
435: }
436:
437: /* Check for a special character */
438: switch (mch) {
439: case FOOD:
440: case SCROLL:
441: case POTION:
442: case RING:
443: case STICK:
444: case RELIC:
445: case ARMOR:
446: case WEAPON:
447: case MM:
448: msg("");
449: if (get_item(pack, NULL, mch) == NULL) {
450: if (terse) msg("None in pack.");
451: else msg("You have no %c in your pack.", mch);
452: }
453: return;
454: }
455:
456: for (ch = 'a', item = pack; item != NULL; item = next(item), ch++)
457: if (ch == mch)
458: {
459: sprintf(outstring, "%c) %s",ch ,inv_name(OBJPTR(item), FALSE));
460: msg(outstring);
461: return;
462: }
463: if (!terse)
464: msg("'%s' not in pack.", unctrl(mch));
465: msg("Range is 'a' to '%c'", --ch);
466: }
467: }
468:
469:
470: /*
471: * get_item:
472: * pick something out of a pack for a purpose
473: * purpose: NULL if we should be silent (no prompts) *
474: */
475: struct linked_list *
476: get_item(struct linked_list *list, char *purpose, int type)
477: {
478: reg struct linked_list *item;
479: reg struct object *obj;
480: reg int cnt, ch, och;
481: struct linked_list *saveitem = NULL;
482:
483: cnt = 0;
484: if (list == NULL) {
485: msg("You aren't carrying anything.");
486: return NULL;
487: }
488: /* see if we have any of the type requested */
489: for(ch = 'a',item = list ; item != NULL ; item = next(item), ch++) {
490: obj = OBJPTR(item);
491: if (is_type(obj, type)) {
492: cnt++;
493: saveitem = item;
494: }
495: }
496: if (cnt == 0) {
497: if (purpose) msg("Nothing to %s",purpose);
498: after = FALSE;
499: return NULL;
500: }
501: else if (cnt == 1) { /* only found one of 'em */
502: obj = OBJPTR(saveitem);
503: for(;;) {
504: if (purpose) { /* Should we prompt the player? */
505: msg("%s what (* for the item)? ",purpose);
506: ch = tolower(readchar());
507: }
508: else {
509: sprintf(outstring, "%c) %s", pack_char(list, obj), inv_name(obj,FALSE));
510: msg(outstring);
511: }
512:
513: if (ch == '*') {
514: mpos = 0;
515: sprintf(outstring, "%c) %s", pack_char(list, obj), inv_name(obj,FALSE));
516: msg(outstring);
517: continue;
518: }
519: if (ch == ESCAPE) {
520: msg("");
521: after = FALSE;
522: return NULL;
523: }
524: for(item = list,och = 'a'; item != NULL; item = next(item),och++) {
525: if (ch == och) break;
526: if (och == 'z') och = 'A' - 1;
527: }
528: if (item == NULL) {
529: msg("Please specify a letter between 'a' and '%c'",
530: och == 'A' ? 'z' : och-1);
531: continue;
532: }
533: if (is_type (OBJPTR(item), type)) {
534: if (purpose) mpos = 0;
535: return item;
536: }
537: else
538: msg ("You can't %s that!", purpose);
539:
540: }
541: }
542: for(;;) {
543: if (purpose) {
544: msg("%s what? (* for list): ",purpose);
545: ch = readchar();
546: }
547: else ch = '*';
548:
549: mpos = 0;
550: if (ch == ESCAPE) { /* abort if escape hit */
551: after = FALSE;
552: msg(""); /* clear display */
553: return NULL;
554: }
555: if (ch == '*') {
556: wclear(hw);
557: cnt = 0;
558: for(item = list,ch = 'a'; item != NULL ; item = next(item), ch++) {
559: obj = OBJPTR(item);
560: if (!is_type(OBJPTR(item), type))
561: continue;
562: wprintw(hw,"%c) %s\n\r",ch,inv_name(obj,FALSE));
563: if (++cnt >= LINES - 2 && next(item) != NULL) {
564: cnt = 0;
565: dbotline(hw, spacemsg);
566: wclear(hw);
567: }
568: if (ch == 'z') ch = 'A' - 1;
569: }
570: wmove(hw, LINES - 1,0);
571: if (purpose) wprintw(hw,"%s what? ",purpose);
572: else waddstr(hw, spacemsg);
573:
574: draw(hw); /* write screen */
575:
576: if (purpose) {
577: do {
578: ch = tolower(wgetch(hw));
579: } until (isalpha(ch) || ch == ESCAPE);
580: }
581: else {
582: ch = pack_char(list, OBJPTR(saveitem)); /* Pick a valid item */
583: wait_for(hw,' ');
584: }
585:
586: restscr(cw); /* redraw orig screen */
587: if(ch == ESCAPE) {
588: after = FALSE;
589: msg(""); /* clear top line */
590: return NULL; /* all done if abort */
591: }
592: /* ch has item to get from list */
593: }
594: for(item = list,och = 'a'; item != NULL; item = next(item),och++) {
595: if (ch == och) break;
596: if (och == 'z') och = 'A' - 1;
597: }
598: if (item == NULL) {
599: msg("Please specify a letter between 'a' and '%c'",
600: och == 'A' ? 'z' : och-1);
601: continue;
602: }
603: if (is_type(OBJPTR(item), type))
604: return (item);
605: else
606: msg ("You can't %s that!", purpose);
607: }
608: }
609:
610: char
611: pack_char(struct linked_list *list, struct object *obj)
612: {
613: register struct linked_list *item;
614: register char c;
615:
616: c = 'a';
617: for (item = list; item != NULL; item = next(item)) {
618: if (OBJPTR(item) == obj)
619: return c;
620: else {
621: if (c == 'z') c = 'A';
622: else c++;
623: }
624: }
625: return 'z';
626: }
627:
628:
629: /*
630: * cur_null:
631: * This updates cur_weapon etc for dropping things
632: */
633: void
634: cur_null(struct object *op)
635: {
636: if (op == cur_weapon) cur_weapon = NULL;
637: else if (op == cur_armor) cur_armor = NULL;
638: else if (op == cur_ring[LEFT_1]) cur_ring[LEFT_1] = NULL;
639: else if (op == cur_ring[LEFT_2]) cur_ring[LEFT_2] = NULL;
640: else if (op == cur_ring[LEFT_3]) cur_ring[LEFT_3] = NULL;
641: else if (op == cur_ring[LEFT_4]) cur_ring[LEFT_4] = NULL;
642: else if (op == cur_ring[RIGHT_1]) cur_ring[RIGHT_1] = NULL;
643: else if (op == cur_ring[RIGHT_2]) cur_ring[RIGHT_2] = NULL;
644: else if (op == cur_ring[RIGHT_3]) cur_ring[RIGHT_3] = NULL;
645: else if (op == cur_ring[RIGHT_4]) cur_ring[RIGHT_4] = NULL;
646: else if (op == cur_misc[WEAR_BOOTS]) cur_misc[WEAR_BOOTS] = NULL;
647: else if (op == cur_misc[WEAR_JEWEL]) cur_misc[WEAR_JEWEL] = NULL;
648: else if (op == cur_misc[WEAR_GAUNTLET]) cur_misc[WEAR_GAUNTLET] = NULL;
649: else if (op == cur_misc[WEAR_CLOAK]) cur_misc[WEAR_CLOAK] = NULL;
650: else if (op == cur_misc[WEAR_BRACERS]) cur_misc[WEAR_BRACERS] = NULL;
651: else if (op == cur_misc[WEAR_NECKLACE]) cur_misc[WEAR_NECKLACE] = NULL;
652: }
653:
654: /*
655: * idenpack:
656: * Identify all the items in the pack
657: */
658: void
659: idenpack(void)
660: {
661: reg struct linked_list *pc;
662:
663: for (pc = pack ; pc != NULL ; pc = next(pc))
664: whatis(pc);
665: }
666:
667: bool
668: is_type (struct object *obj, int type)
669: {
670: register bool current;
671:
672: if (type == obj->o_type)
673: return (TRUE);
674:
675: switch (type) {
676: case ALL:
677: return (TRUE);
678: when ZAPPABLE:
679: if (obj->o_type == STICK) return (TRUE);
680: if (obj->o_type == RELIC)
681: switch (obj->o_which) {
682: case MING_STAFF:
683: case ASMO_ROD:
684: case ORCUS_WAND:
685: return (TRUE);
686: }
687: when WEARABLE:
688: case REMOVABLE:
689: current = is_current(obj);
690:
691: /*
692: * Don't wear thing we are already wearing or remove things
693: * we aren't wearing.
694: */
695: if (type == WEARABLE && current) return (FALSE);
696: else if (type == REMOVABLE && !current) return (FALSE);
697:
698: switch (obj->o_type) {
699: case RELIC:
700: switch (obj->o_which) {
701: case HEIL_ANKH:
702: case EMORI_CLOAK:
703: return (TRUE);
704: }
705: when MM:
706: switch (obj->o_which) {
707: case MM_ELF_BOOTS:
708: case MM_DANCE:
709: case MM_BRACERS:
710: case MM_DISP:
711: case MM_PROTECT:
712: case MM_G_DEXTERITY:
713: case MM_G_OGRE:
714: case MM_JEWEL:
715: case MM_R_POWERLESS:
716: case MM_FUMBLE:
717: case MM_STRANGLE:
718: case MM_ADAPTION:
719: return (TRUE);
720: }
721: when ARMOR:
722: case RING:
723: return (TRUE);
724: }
725: when CALLABLE:
726: switch (obj->o_type) {
727: case RING:
728: case POTION:
729: case STICK:
730: case SCROLL:
731: case MM:
732: return(TRUE);
733: }
734: when WIELDABLE:
735: switch (obj->o_type) {
736: case STICK:
737: case WEAPON:
738: return(TRUE);
739: when RELIC:
740: switch (obj->o_which) {
741: case MUSTY_DAGGER:
742: case HRUGGEK_MSTAR:
743: case YEENOGHU_FLAIL:
744: case MING_STAFF:
745: case ORCUS_WAND:
746: case ASMO_ROD:
747: return(TRUE);
748: }
749: }
750: when IDENTABLE:
751: if (!(obj->o_flags & ISKNOW) && obj->o_type != FOOD)
752: return (TRUE);
753: if (obj->o_type == MM) {
754: switch (obj->o_which) {
755: case MM_JUG:
756: /* Can still identify a jug if we don't know the potion */
757: if (obj->o_ac != JUG_EMPTY && !p_know[obj->o_ac])
758: return (TRUE);
759: }
760: }
761: when USEABLE:
762: if (obj->o_type == MM) {
763: switch(obj->o_which) {
764: case MM_JUG:
765: case MM_BEAKER:
766: case MM_BOOK:
767: case MM_SKILLS:
768: case MM_OPEN:
769: case MM_HUNGER:
770: case MM_DRUMS:
771: case MM_DISAPPEAR:
772: case MM_CHOKE:
773: case MM_KEOGHTOM:
774: return (TRUE);
775: }
776: }
777: else if (obj->o_type == RELIC) {
778: switch (obj->o_which) {
779: case EMORI_CLOAK:
780: case BRIAN_MANDOLIN:
781: case HEIL_ANKH:
782: case YENDOR_AMULET:
783: case GERYON_HORN:
784: return (TRUE);
785: }
786: }
787: when PROTECTABLE:
788: switch (obj->o_type) {
789: case WEAPON:
790: if ((obj->o_flags & ISMETAL) == 0) return (FALSE);
791:
792: /* Fall through */
793: case ARMOR:
794: return (TRUE);
795:
796: when MM:
797: if (obj->o_which == MM_BRACERS) return (TRUE);
798: }
799: }
800: return(FALSE);
801: }
802:
803: void
804: del_pack(struct linked_list *item)
805: {
806: register struct object *obj;
807:
808: obj = OBJPTR(item);
809: if (obj->o_count > 1) {
810: obj->o_count--;
811: }
812: else {
813: cur_null(obj);
814: detach(pack, item);
815: o_discard(item);
816: inpack--;
817: }
818: }
819:
820: /*
821: * carry_obj:
822: * Check to see if a monster is carrying something and, if so, give
823: * it to him.
824: */
825:
826: void
827: carry_obj(struct thing *mp, int chance)
828: {
829: reg struct linked_list *item;
830: reg struct object *obj;
831:
832: /*
833: * If there is no chance, just return.
834: * Note that this means there must be a "chance" in order for
835: * the creature to carry a relic.
836: */
837: if (chance <= 0) return;
838:
839: /*
840: * check for the relic/artifacts
841: * Do the relics first so they end up last in the pack. Attach()
842: * always adds things to the beginning. This way they will be the
843: * last things dropped when the creature is killed. This will ensure
844: * the relic will be on top if there is a stack of item lying on the
845: * floor and so the hero will know where it is if he's trying to
846: * avoid it
847: */
848: if (on(*mp, CARRYDAGGER)) {
849: item = spec_item(RELIC, MUSTY_DAGGER, 0, 0);
850: obj = OBJPTR(item);
851: obj->o_pos = mp->t_pos;
852: attach(mp->t_pack, item);
853: }
854:
855: if (on(*mp, CARRYCLOAK)) {
856: item = spec_item(RELIC, EMORI_CLOAK, 0, 0);
857: obj = OBJPTR(item);
858: obj->o_pos = mp->t_pos;
859: attach(mp->t_pack, item);
860: }
861:
862: if (on(*mp, CARRYANKH)) {
863: item = spec_item(RELIC, HEIL_ANKH, 0, 0);
864: obj = OBJPTR(item);
865: obj->o_pos = mp->t_pos;
866: attach(mp->t_pack, item);
867: }
868:
869: if (on(*mp, CARRYSTAFF)) {
870: item = spec_item(RELIC, MING_STAFF, 0, 0);
871: obj = OBJPTR(item);
872: obj->o_pos = mp->t_pos;
873: attach(mp->t_pack, item);
874: }
875:
876: if (on(*mp, CARRYWAND)) {
877: item = spec_item(RELIC, ORCUS_WAND, 0, 0);
878: obj = OBJPTR(item);
879: obj->o_pos = mp->t_pos;
880: attach(mp->t_pack, item);
881: }
882:
883: if (on(*mp, CARRYROD)) {
884: item = spec_item(RELIC, ASMO_ROD, 0, 0);
885: obj = OBJPTR(item);
886: obj->o_pos = mp->t_pos;
887: attach(mp->t_pack, item);
888: }
889:
890: if (on(*mp, CARRYAMULET)) {
891: item = spec_item(RELIC, YENDOR_AMULET, 0, 0);
892: obj = OBJPTR(item);
893: obj->o_pos = mp->t_pos;
894: attach(mp->t_pack, item);
895: }
896:
897: if (on(*mp, CARRYMANDOLIN)) {
898: item = spec_item(RELIC, BRIAN_MANDOLIN, 0, 0);
899: obj = OBJPTR(item);
900: obj->o_pos = mp->t_pos;
901: attach(mp->t_pack, item);
902: }
903: if (on(*mp, CARRYMSTAR)) {
904: item = spec_item(RELIC, HRUGGEK_MSTAR, 0, 0);
905: obj = OBJPTR(item);
906: obj->o_pos = mp->t_pos;
907: attach(mp->t_pack, item);
908: }
909: if (on(*mp, CARRYFLAIL)) {
910: item = spec_item(RELIC, YEENOGHU_FLAIL, 0, 0);
911: obj = OBJPTR(item);
912: obj->o_pos = mp->t_pos;
913: attach(mp->t_pack, item);
914: }
915: if (on(*mp, CARRYHORN)) {
916: item = spec_item(RELIC, GERYON_HORN, 0, 0);
917: obj = OBJPTR(item);
918: obj->o_pos = mp->t_pos;
919: attach(mp->t_pack, item);
920: }
921: /*
922: * If it carries gold, give it some
923: */
924: if (on(*mp, CARRYGOLD) && rnd(100) < chance) {
925: item = spec_item(GOLD, 0, 0, 0);
926: obj = OBJPTR(item);
927: obj->o_count = GOLDCALC + GOLDCALC;
928: obj->o_pos = mp->t_pos;
929: attach(mp->t_pack, item);
930: }
931:
932: /*
933: * If it carries food, give it some
934: */
935: if (on(*mp, CARRYFOOD) && rnd(100) < chance) {
936: item = spec_item(FOOD, 0, 0, 0);
937: obj = OBJPTR(item);
938: obj->o_weight = things[TYP_FOOD].mi_wght;
939: obj->o_pos = mp->t_pos;
940: attach(mp->t_pack, item);
941: }
942:
943: /*
944: * If it carries a weapon, give it one
945: */
946: if (on(*mp, CARRYWEAPON) && rnd(100) < chance) {
947: int type, hit, dam;
948:
949: /* Get the "bonuses" */
950: hit = rnd(5) - 2;
951: dam = rnd(5) - 2;
952:
953: /* Only choose an appropriate type of weapon */
954: switch (rnd(11)) {
955: case 0: type = DAGGER;
956: when 1: type = BATTLEAXE;
957: when 2: type = MACE;
958: when 3: type = SWORD;
959: when 4: type = PIKE;
960: when 5: type = HALBERD;
961: when 6: type = SPETUM;
962: when 7: type = BARDICHE;
963: when 8: type = TRIDENT;
964: when 9: type = BASWORD;
965: otherwise: type = TWOSWORD;
966: }
967:
968: /* Create the item */
969: item = spec_item(WEAPON, type, hit, dam);
970: obj = OBJPTR(item);
971: obj->o_pos = mp->t_pos;
972: attach(mp->t_pack, item);
973: }
974:
975: /*
976: * If it carries a scroll, give it one
977: */
978: if (on(*mp, CARRYSCROLL) && rnd(100) < chance) {
979: item = new_thing(TYP_SCROLL);
980: obj = OBJPTR(item);
981: obj->o_pos = mp->t_pos;
982:
983: /* Can the monster carry this scroll? */
984: if (obj->o_which == S_SCARE && mp->t_stats.s_intel < 16)
985: fall(item, FALSE); /* This would scare us! */
986: else attach(mp->t_pack, item);
987: }
988:
989: /*
990: * If it carries a potion, give it one
991: */
992: if (on(*mp, CARRYPOTION) && rnd(100) < chance) {
993: item = new_thing(TYP_POTION);
994: obj = OBJPTR(item);
995: obj->o_pos = mp->t_pos;
996: attach(mp->t_pack, item);
997: }
998:
999: /*
1000: * If it carries a ring, give it one
1001: */
1002: if (on(*mp, CARRYRING) && rnd(100) < chance) {
1003: item = new_thing(TYP_RING);
1004: obj = OBJPTR(item);
1005: obj->o_pos = mp->t_pos;
1006: attach(mp->t_pack, item);
1007: }
1008:
1009: /*
1010: * If it carries a wand or staff, give it one
1011: */
1012: if (on(*mp, CARRYSTICK) && rnd(100) < chance) {
1013: item = new_thing(TYP_STICK);
1014: obj = OBJPTR(item);
1015: obj->o_pos = mp->t_pos;
1016: attach(mp->t_pack, item);
1017: }
1018:
1019: /*
1020: * If it carries any miscellaneous magic, give it one
1021: */
1022: if (on(*mp, CARRYMISC) && rnd(100) < chance) {
1023: item = new_thing(TYP_MM);
1024: obj = OBJPTR(item);
1025: obj->o_pos = mp->t_pos;
1026: attach(mp->t_pack, item);
1027: }
1028: }
1029:
1030:
1031: /*
1032: * grab():
1033: * See what is on the spot where the player is standing. If
1034: * nothing is there, do nothing. If there is one thing, pick it
1035: * up. If there are multiple things, prompt the player for what
1036: * he wants (* means everything).
1037: */
1038:
1039: int
1040: grab(int y, int x)
1041: {
1042: register struct linked_list *next_item, *item;
1043: register struct object *obj;
1044: register int cnt;
1045: int num_there = 0, ch, och;
1046:
1047: /*
1048: * Count how many objects there are and move them to the front
1049: * of the level list.
1050: */
1051: for (item = lvl_obj; item != NULL; item = next_item) {
1052: obj = OBJPTR(item);
1053: next_item = next(item);
1054: if (obj->o_pos.y == y && obj->o_pos.x == x) {
1055: num_there++;
1056: detach(lvl_obj, item); /* Remove it from the list */
1057: attach(lvl_obj, item); /* Place it at the front of the list */
1058: }
1059: }
1060:
1061: /* Nothing there. */
1062: if (num_there < 1) msg("Nothing %s", terse ? "there." : "to pick up.");
1063:
1064: /* One thing there */
1065: else if (num_there == 1) {
1066: add_pack(FALSE, FALSE, NULL);
1067: return(1);
1068: }
1069:
1070: /* Multiple things there */
1071: else {
1072: wclear(hw);
1073: cnt = 0;
1074: for (item = lvl_obj, ch = 'a'; item != NULL && cnt < num_there;
1075: item = next(item), ch++) {
1076: obj = OBJPTR(item);
1077: wprintw(hw,"%c) %s\n\r", ch, inv_name(obj,FALSE));
1078: if (++cnt >= LINES - 2 && next(item) != NULL) {
1079: cnt = 0;
1080: dbotline(hw, spacemsg);
1081: wclear(hw);
1082: }
1083: if (ch == 'z') ch = 'A' - 1;
1084: }
1085: wmove(hw, LINES - 1,0);
1086: wprintw(hw, "Pick up what? (* for all): ");
1087: draw(hw); /* write screen */
1088:
1089: for (;;) {
1090: do {
1091: ch = tolower(wgetch(hw));
1092: } until (isalpha(ch) || ch == '*' || ch == ESCAPE);
1093: restscr(cw); /* redraw orig screen */
1094: if (ch == ESCAPE) {
1095: after = FALSE;
1096: msg(""); /* clear top line */
1097: break;
1098: }
1099: if (ch == '*') {
1100: while (add_pack(NULL, TRUE, NULL)); /* pick up everything there */
1101: return(num_there);
1102: }
1103: /* ch has item to get from list */
1104:
1105: cnt = 0;
1106: for (item = lvl_obj, och = 'a'; item != NULL && cnt < num_there;
1107: item = next(item), och++, cnt++) {
1108: if (ch == och)
1109: break;
1110: if (och == 'z') och = 'A' - 1;
1111: }
1112: if (item == NULL || cnt >= num_there) {
1113: wmove(hw, LINES - 1, 25);
1114: wprintw(hw, " [between 'a' and '%c']:%c ",
1115: och == 'A' ? 'z' : och-1, '\007');
1116: draw(hw); /* write screen */
1117: continue;
1118: }
1119: else {
1120: detach(lvl_obj, item);
1121: if (add_pack(item, FALSE, NULL)) {
1122: /*
1123: * There should always be at least one item left since we
1124: * handle the one item case up above. But it never hurts
1125: * to make sure we don't have a NULL pointer.
1126: */
1127: if ((item = find_obj(hero.y, hero.x)) == NULL)
1128: mvaddch(y, x, (OBJPTR(item))->o_type);
1129: return(1);
1130: }
1131: else attach(lvl_obj, item); /* Couldn't pick it up! */
1132: break;
1133: }
1134: }
1135: }
1136:
1137: return(0);
1138: }
CVSweb