Annotation of early-roguelike/xrogue/pack.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: pack.c - Routines to deal with the pack.
3:
4: XRogue: Expeditions into the Dungeons of Doom
5: Copyright (C) 1991 Robert Pietkivitch
6: All rights reserved.
7:
8: Based on "Advanced Rogue"
9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10: All rights reserved.
11:
12: Based on "Rogue: Exploring the Dungeons of Doom"
13: Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14: All rights reserved.
15:
16: See the file LICENSE.TXT for full copyright and licensing information.
17: */
18:
19: #include <curses.h>
20: #include <ctype.h>
21: #include <string.h>
22: #include "rogue.h"
23:
24: bool is_type(struct object *obj, int type);
25:
26: /*
27: * add_pack:
28: * Pick up an object and add it to the pack. If the argument is non-null
29: * use it as the linked_list pointer instead of gettting it off the ground.
30: */
31:
32: bool
33: add_pack(struct linked_list *item, bool silent)
34: {
35: register struct linked_list *ip, *lp = NULL, *ap;
36: register struct object *obj, *op = NULL;
37: register bool exact, from_floor;
38: bool giveflag = 0;
39: int newclass;
40:
41: if (item == NULL)
42: {
43: from_floor = TRUE;
44: if ((item = find_obj(hero.y, hero.x)) == NULL)
45: return(FALSE);
46: }
47: else
48: from_floor = FALSE;
49: obj = OBJPTR(item);
50: /*
51: * If it is gold, just add its value to rogue's purse and get rid
52: * of it.
53: */
54: if (obj->o_type == GOLD) {
55: register struct linked_list *mitem;
56: register struct thing *tp;
57:
58: if (!silent) {
59: if (!terse) addmsg("You found ");
60: msg("%d gold pieces.", obj->o_count);
61: }
62:
63: /* First make sure no greedy monster is after this gold.
64: * If so, make the monster run after the rogue instead.
65: */
66: for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
67: tp = THINGPTR(mitem);
68: if (tp->t_dest == &obj->o_pos) tp->t_dest = &hero;
69: }
70:
71: purse += obj->o_count;
72: if (from_floor) {
73: detach(lvl_obj, item);
74: if ((ap = find_obj(hero.y, hero.x)) == NULL)
75: mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
76: else
77: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
78: }
79: o_discard(item);
80: return(TRUE);
81: }
82:
83: /*
84: * see if he can carry any more weight
85: */
86: if (itemweight(obj) + pstats.s_pack > pstats.s_carry) {
87: msg("Too much for you to carry.");
88: return FALSE;
89: }
90: /*
91: * Link it into the pack. Search the pack for a object of similar type
92: * if there isn't one, stuff it at the beginning, if there is, look for one
93: * that is exactly the same and just increment the count if there is.
94: * it that. Food is always put at the beginning for ease of access, but
95: * is not ordered so that you can't tell good food from bad. First check
96: * to see if there is something in thr same group and if there is then
97: * increment the count.
98: */
99: if (obj->o_group)
100: {
101: for (ip = pack; ip != NULL; ip = next(ip))
102: {
103: op = OBJPTR(ip);
104: if (op->o_group == obj->o_group)
105: {
106: /*
107: * Put it in the pack and notify the user
108: */
109: op->o_count += obj->o_count;
110: if (from_floor)
111: {
112: detach(lvl_obj, item);
113: if ((ap = find_obj(hero.y, hero.x)) == NULL)
114: mvaddch(hero.y,hero.x,
115: (roomin(&hero)==NULL ? PASSAGE : FLOOR));
116: else
117: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
118: }
119: o_discard(item);
120: item = ip;
121: goto picked_up;
122: }
123: }
124: }
125:
126: /*
127: * Check for and deal with scare monster scrolls
128: */
129: if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
130: if (obj->o_flags & ISCURSED)
131: {
132: msg("The scroll turns to dust as you pick it up.");
133: detach(lvl_obj, item);
134: if ((ap = find_obj(hero.y, hero.x)) == NULL)
135: mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
136: else
137: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
138: return(TRUE);
139: }
140:
141: /*
142: * Search for an object of the same type
143: */
144: exact = FALSE;
145: for (ip = pack; ip != NULL; ip = next(ip))
146: {
147: op = OBJPTR(ip);
148: if (obj->o_type == op->o_type)
149: break;
150: }
151: if (ip == NULL)
152: {
153: /*
154: * Put it at the end of the pack since it is a new type
155: */
156: for (ip = pack; ip != NULL; ip = next(ip))
157: {
158: op = OBJPTR(ip);
159: if (op->o_type != FOOD)
160: break;
161: lp = ip;
162: }
163: }
164: else
165: {
166: /*
167: * Search for an object which is exactly the same
168: */
169: while (ip != NULL && op->o_type == obj->o_type)
170: {
171: if (op->o_which == obj->o_which)
172: {
173: exact = TRUE;
174: break;
175: }
176: lp = ip;
177: if ((ip = next(ip)) == NULL)
178: break;
179: op = OBJPTR(ip);
180: }
181: }
182: /*
183: * Check if there is room
184: */
185: if (ip == NULL || !exact || !ISMULT(obj->o_type)) {
186: if (inpack == MAXPACK-1) {
187: msg(terse ? "No room." : "You can't carry anything else.");
188: return(FALSE);
189: }
190: }
191: inpack++;
192: if (from_floor)
193: {
194: detach(lvl_obj, item);
195: if ((ap = find_obj(hero.y, hero.x)) == NULL)
196: mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
197: else
198: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
199: }
200: if (ip == NULL)
201: {
202: /*
203: * Didn't find an exact match, just stick it here
204: */
205: if (pack == NULL)
206: pack = item;
207: else
208: {
209: lp->l_next = item;
210: item->l_prev = lp;
211: item->l_next = NULL;
212: }
213: }
214: else
215: {
216: /*
217: * If we found an exact match. If it is food,
218: * increase the count, otherwise put it with its clones.
219: */
220: if (exact && ISMULT(obj->o_type))
221: {
222: op->o_count += obj->o_count;
223: inpack--; /* adjust for previous addition */
224: o_discard(item);
225: item = ip;
226: goto picked_up;
227: }
228: if ((item->l_prev = prev(ip)) != NULL)
229: item->l_prev->l_next = item;
230: else
231: pack = item;
232: item->l_next = ip;
233: ip->l_prev = item;
234: }
235: picked_up:
236: /*
237: * Notify the user
238: */
239: obj = OBJPTR(item);
240: if (!silent)
241: {
242: if (!terse)
243: addmsg("You now have ");
244: msg("%s (%c)", inv_name(obj, !terse), pack_char(pack, obj));
245: }
246:
247: /* Relics do strange things when you pick them up */
248: if (obj->o_type == RELIC) {
249: switch (obj->o_which) {
250: /* the ankh of Heil gives you prayers */
251: case HEIL_ANKH:
252: msg("The ankh welds itself into your hand. ");
253: if (player.t_ctype != C_CLERIC && player.t_ctype != C_PALADIN)
254: fuse(prayer_recovery, NULL, SPELLTIME, AFTER);
255: /* start a fuse to change player into a paladin */
256: if (quest_item != HEIL_ANKH) {
257: msg("You hear a strange, distant hypnotic calling... ");
258: if (player.t_ctype != C_PALADIN && obj->o_which ==HEIL_ANKH) {
259: newclass = C_PALADIN;
260: fuse(changeclass, &newclass, roll(8, 8), AFTER);
261: }
262: }
263:
264: /* A cloak must be worn. */
265: when EMORI_CLOAK:
266: if (cur_armor != NULL || cur_misc[WEAR_CLOAK]) {
267: msg("The cloak insists you remove your current garments.");
268: if (!dropcheck(cur_armor != NULL ? cur_armor
269: : cur_misc[WEAR_CLOAK])) {
270: pstats.s_hpt = -1;
271: msg("The cloak constricts around you...");
272: msg("It draws your life force from you!!! --More--");
273: wait_for(' ');
274: death(D_RELIC);
275: }
276: }
277: if (obj->o_charges < 0) /* should never happen, but.... */
278: obj->o_charges = 0;
279: if (obj->o_charges == 0)
280: fuse(cloak_charge, obj, CLOAK_TIME, AFTER);
281: /* start a fuse to change player into a monk */
282: if (quest_item != EMORI_CLOAK) {
283: msg("You suddenly become calm and quiet. ");
284: if (player.t_ctype != C_MONK && obj->o_which == EMORI_CLOAK) {
285: newclass = C_MONK;
286: fuse(changeclass, &newclass, roll(8, 8), AFTER);
287: }
288: }
289:
290: /* The amulet must be worn. */
291: when STONEBONES_AMULET:
292: case YENDOR_AMULET:
293: if (cur_misc[WEAR_JEWEL] || cur_relic[STONEBONES_AMULET] ||
294: cur_relic[YENDOR_AMULET]) {
295: msg("You have an urge to remove your current amulet.");
296: }
297: if((cur_misc[WEAR_JEWEL] && !dropcheck(cur_misc[WEAR_JEWEL])) ||
298: cur_relic[STONEBONES_AMULET] || cur_relic[YENDOR_AMULET]) {
299: pstats.s_hpt = -1;
300: msg("The %s begins pulsating... ",inv_name(obj, TRUE));
301: msg("It fades completely away! --More--");
302: wait_for(' ');
303: death(D_RELIC);
304: }
305: msg("The %s welds itself into your chest. ",inv_name(obj,TRUE));
306: /* start a fuse to change into a magician */
307: if (quest_item != STONEBONES_AMULET) {
308: if (player.t_ctype != C_MAGICIAN &&
309: obj->o_which == STONEBONES_AMULET) {
310: msg("You sense approaching etheric forces... ");
311: newclass = C_MAGICIAN;
312: fuse(changeclass, &newclass, roll(8, 8), AFTER);
313: }
314: }
315:
316: /* The eye is now inserted in forehead */
317: when EYE_VECNA:
318: msg("The eye forces itself into your forehead! ");
319: pstats.s_hpt -= (rnd(80)+21);
320: if (pstats.s_hpt <= 0) {
321: pstats.s_hpt = -1;
322: msg ("The pain is too much for you to bear! --More--");
323: wait_for(' ');
324: death(D_RELIC);
325: }
326: waste_time();
327: msg("The excruciating pain slowly turns into a dull throb.");
328: /* start a fuse to change player into an assassin */
329: if (quest_item != EYE_VECNA) {
330: msg("Your blood rushes and you begin to sweat profusely... ");
331: if (player.t_ctype != C_ASSASSIN && obj->o_which == EYE_VECNA) {
332: newclass = C_ASSASSIN;
333: fuse(changeclass, &newclass, roll(8, 8), AFTER);
334: }
335: }
336:
337: when QUILL_NAGROM:
338: fuse(quill_charge, NULL, 8, AFTER);
339: /* start a fuse to change player into a druid */
340: if (quest_item != QUILL_NAGROM) {
341: msg("You begin to see things differently... ");
342: if (player.t_ctype != C_DRUID && obj->o_which == QUILL_NAGROM) {
343: newclass = C_DRUID;
344: fuse(changeclass, &newclass, roll(8, 8), AFTER);
345: }
346: }
347:
348: /* Weapons will insist on being wielded. */
349: when MUSTY_DAGGER:
350: case HRUGGEK_MSTAR:
351: case YEENOGHU_FLAIL:
352: case AXE_AKLAD:
353: /* set a daemon to eat gold for daggers and axe */
354: if (obj->o_which == MUSTY_DAGGER || obj->o_which == AXE_AKLAD) {
355: if (purse > 0) msg("Your purse feels lighter! ");
356: else purse = 1; /* fudge to get right msg from eat_gold() */
357:
358: eat_gold(obj);
359: start_daemon(eat_gold, obj, AFTER);
360: }
361: /* start a fuse to change player into a thief */
362: if (quest_item != MUSTY_DAGGER) {
363: if (player.t_ctype != C_THIEF &&
364: obj->o_which == MUSTY_DAGGER) {
365: msg("You look about furtively. ");
366: newclass = C_THIEF;
367: fuse(changeclass, &newclass, roll(8, 8), AFTER);
368: }
369: }
370: /* start a fuse to change player into a fighter */
371: if (quest_item != AXE_AKLAD) {
372: if (player.t_ctype != C_FIGHTER &&
373: obj->o_which == AXE_AKLAD) {
374: msg("Your bones feel strengthened. ");
375: newclass = C_FIGHTER;
376: fuse(changeclass, &newclass, roll(8, 8), AFTER);
377: }
378: }
379: if (cur_weapon != NULL) {
380: msg("The artifact insists you release your current weapon!");
381: if (!dropcheck(cur_weapon)) {
382: pstats.s_hpt = -1;
383: msg("The artifact forces your weapon into your heart! ");
384: msg("It hums with satisfaction! --More--");
385: wait_for(' ');
386: death(D_RELIC);
387: }
388: }
389: cur_weapon = obj;
390:
391: /* acquire a sense of smell */
392: when SURTUR_RING:
393: msg("The ring forces itself through your nose!");
394: pstats.s_hpt -= rnd(40)+1;
395: if (pstats.s_hpt < 0) {
396: pstats.s_hpt = -1;
397: msg("The pain is too much for you to bear! --More--");
398: wait_for(' ');
399: death(D_RELIC);
400: }
401: waste_time();
402: turn_on(player, NOFIRE);
403: msg("The pain slowly subsides.. ");
404:
405: /* become a wandering musician */
406: when BRIAN_MANDOLIN:
407: msg("You hear an ancient haunting sound... ");
408: /* start a fuse to change player into a ranger */
409: if (quest_item != BRIAN_MANDOLIN) {
410: msg("You are transfixed with empathy. ");
411: if (player.t_ctype != C_RANGER && obj->o_which == BRIAN_MANDOLIN) {
412: newclass = C_RANGER;
413: fuse(changeclass, &newclass, roll(8, 8), AFTER);
414: }
415: }
416:
417: /* add to the music */
418: when GERYON_HORN:
419: msg("You begin to hear trumpets!");
420: /* start a fuse to change player into a cleric */
421: if (quest_item != GERYON_HORN) {
422: msg("You follow their calling. ");
423: if (player.t_ctype != C_CLERIC && obj->o_which == GERYON_HORN) {
424: newclass = C_CLERIC;
425: fuse(changeclass, &newclass, roll(8, 8), AFTER);
426: }
427: }
428:
429: /* the card can not be picked up, it must be traded for */
430: when ALTERAN_CARD:
431: if (giveflag == FALSE) {
432: if (!wizard) {
433: msg("You look at the dark card and it chills you to the bone!! ");
434: msg("You stand for a moment, face to face with death... --More--");
435: wait_for(' ');
436: pstats.s_hpt = -1;
437: death(D_CARD);
438: }
439: else {
440: msg("Got it! ");
441: if (purse > 0) msg("Your purse feels lighter! ");
442: else purse = 1; /* fudge to get right msg */
443:
444: eat_gold(obj);
445: start_daemon(eat_gold, obj, AFTER);
446: }
447: }
448: else {
449: msg("You accept it hesitantly... ");
450: if (purse > 0) msg("Your purse feels lighter! ");
451: else purse = 1; /* fudge to get right msg */
452:
453: eat_gold(obj);
454: start_daemon(eat_gold, obj, AFTER);
455: }
456:
457: otherwise:
458: break;
459: }
460: cur_relic[obj->o_which]++; /* Note that we have it */
461: }
462:
463: updpack(FALSE, &player);
464: return(TRUE);
465: }
466:
467: /*
468: * inventory:
469: * list what is in the pack
470: */
471:
472: bool
473: inventory(struct linked_list *list, int type)
474: {
475: register struct object *obj;
476: register char ch;
477: register int n_objs, cnt, maxx = 0, curx;
478: char inv_temp[2*LINELEN+1];
479:
480: cnt = 0;
481: n_objs = 0;
482: for (ch = 'a'; list != NULL; ch++, list = next(list)) {
483: obj = OBJPTR(list);
484: if (!is_type(obj, type))
485: continue;
486: switch (n_objs++) {
487: /*
488: * For the first thing in the inventory, just save the string
489: * in case there is only one.
490: */
491: case 0:
492: sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE));
493: break;
494: /*
495: * If there is more than one, clear the screen, print the
496: * saved message and fall through to ...
497: */
498: case 1:
499: if (slow_invent)
500: msg(inv_temp);
501: else
502: {
503: wclear(hw);
504: waddstr(hw, inv_temp);
505: waddch(hw, '\n');
506:
507: maxx = strlen(inv_temp); /* Length of the listing */
508: }
509: /*
510: * Print the line for this object
511: */
512: default:
513: if (ch > 'z')
514: ch = 'A';
515: if (slow_invent)
516: msg("%c) %s", ch, inv_name(obj, FALSE));
517: else {
518: if (++cnt >= lines - 2) { /* if bottom of screen */
519: dbotline(hw, morestr);
520: cnt = 0;
521: wclear(hw);
522: }
523: sprintf(inv_temp, "%c) %s\n", ch, inv_name(obj, FALSE));
524: curx = strlen(inv_temp) - 1; /* Don't count new-line */
525: if (curx > maxx) maxx = curx;
526: waddstr(hw, inv_temp);
527: }
528: }
529: }
530: if (n_objs == 0) {
531: if (terse)
532: msg(type == ALL ? "Empty-handed." :
533: "Nothing appropriate");
534: else
535: msg(type == ALL ? "You are empty-handed." :
536: "You don't have anything appropriate");
537: return FALSE;
538: }
539: if (n_objs == 1) {
540: msg(inv_temp);
541: return TRUE;
542: }
543: if (!slow_invent)
544: {
545: waddstr(hw, spacemsg);
546: curx = strlen(spacemsg);
547: if (curx > maxx) maxx = curx;
548:
549: /*
550: * If we have fewer than half a screenful, don't clear the screen.
551: * Leave an extra blank line at the bottom and 3 blank columns
552: * to he right.
553: */
554: if (menu_overlay && n_objs < lines - 3) {
555: over_win(cw, hw, n_objs + 2, maxx + 3, n_objs, curx, ' ');
556: return TRUE;
557: }
558:
559: draw(hw);
560: wait_for(' ');
561: restscr(cw);
562: }
563: return TRUE;
564: }
565:
566: /*
567: * picky_inven:
568: * Allow player to inventory a single item
569: */
570:
571: void
572: picky_inven(void)
573: {
574: register struct linked_list *item;
575: register char ch, mch;
576:
577: if (pack == NULL)
578: msg("You aren't carrying anything");
579: else if (next(pack) == NULL)
580: msg("a) %s", inv_name(OBJPTR(pack), FALSE));
581: else
582: {
583: msg(terse ? "Item: " : "Which item do you wish to inventory: ");
584: mpos = 0;
585: if ((mch = wgetch(cw)) == ESC)
586: {
587: msg("");
588: return;
589: }
590:
591: /* Check for a special character */
592: switch (mch) {
593: case FOOD:
594: case SCROLL:
595: case POTION:
596: case RING:
597: case STICK:
598: case RELIC:
599: case ARMOR:
600: case WEAPON:
601: case MM:
602: msg("");
603: if (get_item(pack, (char *)NULL, mch, FALSE, FALSE) == NULL) {
604: if (terse) msg("No '%c' in your pack.", mch);
605: else msg("You have no '%c' in your pack.", mch);
606: }
607: return;
608: }
609:
610: for (ch = 'a', item = pack; item != NULL; item = next(item), ch++)
611: if (ch == mch)
612: {
613: msg("%c) %s",ch,inv_name(OBJPTR(item), FALSE));
614: return;
615: }
616: if (!terse)
617: msg("'%s' not in pack.", unctrl(mch));
618: msg("Range is 'a' to '%c'", --ch);
619: }
620: }
621:
622: /*
623: * get_item:
624: * pick something out of a pack for a purpose
625: * purpose: NULL if we should be silent (no prompts)
626: */
627:
628: struct linked_list *
629: get_item(struct linked_list *list, char *purpose, int type, bool askfirst,
630: bool showcost)
631: {
632: reg struct linked_list *item;
633: reg struct object *obj;
634: reg int cnt, pagecnt, ch, och, maxx, curx, confused;
635: struct linked_list *saveitem = NULL;
636: char description[2*LINELEN+1];
637: char cost[LINELEN/2];
638: char cap_purpose[LINELEN]; /* capitalize the "doings" */
639:
640: cap_purpose[0] = '\0';
641:
642: /* Get a capitalized purpose for starting sentences */
643: if (purpose) {
644: strcpy(cap_purpose, purpose);
645: cap_purpose[0] = toupper(cap_purpose[0]);
646: }
647:
648: /*
649: * If this is the player's pack and the player is confused, we
650: * might just take anything.
651: */
652: if (list == player.t_pack && on(player, ISHUH) && rnd(100) < 70)
653: confused = 1;
654: else confused = 0;
655:
656: cnt = 0;
657: if (list == NULL) {
658: msg("You aren't carrying anything.");
659: return NULL;
660: }
661: /* see if we have any of the type requested */
662: for(ch = 'a',item = list ; item != NULL ; item = next(item), ch++) {
663: obj = OBJPTR(item);
664: if (is_type(obj, type)) {
665: cnt++;
666: saveitem = item;
667: }
668: }
669: if (cnt == 0) {
670: if (purpose) msg("Nothing to %s", purpose);
671: after = FALSE;
672: return NULL;
673: }
674: else if (cnt == 1) { /* only found one of 'em */
675: obj = OBJPTR(saveitem);
676: for(;;) {
677: if (purpose) { /* Should we prompt the player? */
678: msg("%s what (* for the item)?", cap_purpose);
679: ch = wgetch(cw);
680: }
681: else {
682: ch = pack_char(list, obj);
683: msg("%c) %s", ch, inv_name(obj,FALSE));
684: }
685:
686: if (ch == '*') {
687: mpos = 0;
688: msg("%c) %s",pack_char(list, obj),inv_name(obj,FALSE));
689: continue;
690: }
691: if (ch == ESC) {
692: msg("");
693: after = FALSE;
694: return NULL;
695: }
696: for(item = list,och = 'a'; item != NULL; item = next(item),och++) {
697: if (ch == och) break;
698: if (och == 'z') och = 'A' - 1;
699: }
700: if (item == NULL) {
701: msg("Please specify a letter between 'a' and '%c'",
702: och == 'A' ? 'z' : och-1);
703: continue;
704: }
705: if (is_type (OBJPTR(item), type)) {
706: if (purpose) mpos = 0;
707: return item;
708: }
709: else
710: msg ("You can't %s that!", purpose);
711:
712: }
713: }
714: for(;;) {
715: if (!askfirst && purpose) {
716: msg("%s what? (* for list): ", cap_purpose);
717: ch = wgetch(cw);
718: }
719: else ch = '*';
720:
721: mpos = 0;
722: if (ch == ESC) { /* abort if escape hit */
723: after = FALSE;
724: msg(""); /* clear display */
725: return NULL;
726: }
727:
728: if (ch == '*') {
729: wclear(hw);
730: pagecnt = 0;
731: maxx = 0;
732: for(item = list,ch = 'a'; item != NULL ; item = next(item), ch++) {
733: obj = OBJPTR(item);
734: if (!is_type(OBJPTR(item), type))
735: continue;
736: cost[0] = '\0';
737: if (showcost) {
738: sprintf(description, "[%ld] ", get_worth(obj));
739: sprintf(cost, "%8.8s", description);
740: }
741: sprintf(description,"%c) %s%s\n\r",ch,cost,inv_name(obj,FALSE));
742: waddstr(hw, description);
743: curx = strlen(description) - 2; /* Don't count \n or \r */
744: if (maxx < curx) maxx = curx;
745: if (++pagecnt >= lines - 2 && next(item) != NULL) {
746: pagecnt = 0;
747: dbotline(hw, spacemsg);
748: wclear(hw);
749: }
750: if (ch == 'z') ch = 'A' - 1;
751: }
752:
753: /* Put in the prompt */
754: if (purpose) sprintf(description, "%s what? ", cap_purpose);
755: else strcpy(description, spacemsg);
756: waddstr(hw, description);
757: curx = strlen(description);
758: if (maxx < curx) maxx = curx;
759:
760: /* Write the screen */
761: if ((menu_overlay && cnt < lines - 3) || cnt == 1) {
762: over_win(cw, hw, cnt + 2, maxx + 3, cnt, curx, '\0');
763: cnt = -1; /* Indicate we used over_win */
764: }
765: else draw(hw);
766:
767: if (purpose) {
768: do {
769: ch = wgetch(cw);
770: } until (isalpha(ch) || ch == ESC);
771: }
772: else {
773: ch = pack_char(list, OBJPTR(saveitem)); /* Pick a valid item */
774: wait_for(' ');
775: }
776:
777: /* Redraw original screen */
778: if (cnt < 0) {
779: clearok(cw, FALSE); /* Setup to redraw current screen */
780: touchwin(cw); /* clearing first */
781: draw(cw);
782: }
783: else restscr(cw);
784:
785: if(ch == ESC) {
786: after = FALSE;
787: msg(""); /* clear top line */
788: return NULL; /* all done if abort */
789: }
790: /* ch has item to get from list */
791: }
792:
793: for (item = list,och = 'a'; item != NULL; item = next(item),och++) {
794: if (confused) {
795: /*
796: * Confused is incremented each time so that if the rnd(cnt)
797: * clause keeps failing, confused will equal cnt for the
798: * last item of the correct type and rnd(cnt) < cnt will
799: * have to be true.
800: */
801: if (is_type(OBJPTR(item), type) && rnd(cnt) < confused++)
802: break;
803: }
804: else if (ch == och) break;
805: if (och == 'z') och = 'A' - 1;
806: }
807:
808: if (item == NULL) {
809: msg("Please specify a letter between 'a' and '%c' ",
810: och == 'A' ? 'z' : och-1);
811: continue;
812: }
813:
814: if (is_type(OBJPTR(item), type))
815: return (item);
816: else
817: msg ("You can't %s that!", purpose);
818: }
819: }
820:
821: char
822: pack_char(struct linked_list *list, struct object *obj)
823: {
824: register struct linked_list *item;
825: register char c;
826:
827: c = 'a';
828: for (item = list; item != NULL; item = next(item)) {
829: if (OBJPTR(item) == obj)
830: return c;
831: else {
832: if (c == 'z') c = 'A';
833: else c++;
834: }
835: }
836: return 'z';
837: }
838:
839: /*
840: * cur_null:
841: * This updates cur_weapon etc for dropping things
842: */
843:
844: void
845: cur_null(struct object *op)
846: {
847: if (op == cur_weapon) cur_weapon = NULL;
848: else if (op == cur_armor) cur_armor = NULL;
849: else if (op == cur_ring[LEFT_1]) cur_ring[LEFT_1] = NULL;
850: else if (op == cur_ring[LEFT_2]) cur_ring[LEFT_2] = NULL;
851: else if (op == cur_ring[LEFT_3]) cur_ring[LEFT_3] = NULL;
852: else if (op == cur_ring[LEFT_4]) cur_ring[LEFT_4] = NULL;
853: else if (op == cur_ring[RIGHT_1]) cur_ring[RIGHT_1] = NULL;
854: else if (op == cur_ring[RIGHT_2]) cur_ring[RIGHT_2] = NULL;
855: else if (op == cur_ring[RIGHT_3]) cur_ring[RIGHT_3] = NULL;
856: else if (op == cur_ring[RIGHT_4]) cur_ring[RIGHT_4] = NULL;
857: else if (op == cur_misc[WEAR_BOOTS]) cur_misc[WEAR_BOOTS] = NULL;
858: else if (op == cur_misc[WEAR_JEWEL]) cur_misc[WEAR_JEWEL] = NULL;
859: else if (op == cur_misc[WEAR_GAUNTLET]) cur_misc[WEAR_GAUNTLET] = NULL;
860: else if (op == cur_misc[WEAR_CLOAK]) cur_misc[WEAR_CLOAK] = NULL;
861: else if (op == cur_misc[WEAR_BRACERS]) cur_misc[WEAR_BRACERS] = NULL;
862: else if (op == cur_misc[WEAR_NECKLACE]) cur_misc[WEAR_NECKLACE] = NULL;
863: }
864:
865: /*
866: * idenpack:
867: * Identify all the items in the pack
868: */
869:
870: void
871: idenpack(void)
872: {
873: reg struct linked_list *pc;
874:
875: for (pc = pack ; pc != NULL ; pc = next(pc))
876: whatis(pc);
877: }
878:
879: bool
880: is_type(struct object *obj, int type)
881: {
882: register bool current;
883:
884: if (type == obj->o_type)
885: return (TRUE);
886:
887: switch (type) {
888: case ALL:
889: return (TRUE);
890: when READABLE:
891: if (obj->o_type == SCROLL ||
892: (obj->o_type == MM && obj->o_which == MM_SKILLS))
893: return (TRUE);
894: when QUAFFABLE:
895: if (obj->o_type == POTION ||
896: (obj->o_type == MM && obj->o_which == MM_JUG))
897: return (TRUE);
898: when ZAPPABLE:
899: if (obj->o_type == STICK) return (TRUE);
900: if (obj->o_type == RELIC)
901: switch (obj->o_which) {
902: case MING_STAFF:
903: case ASMO_ROD:
904: case ORCUS_WAND:
905: case EMORI_CLOAK:
906: return (TRUE);
907: }
908: when WEARABLE:
909: case REMOVABLE:
910: current = is_current(obj);
911:
912: /*
913: * Don't wear thing we are already wearing or remove things
914: * we aren't wearing.
915: */
916: if (type == WEARABLE && current) return (FALSE);
917: else if (type == REMOVABLE && !current) return (FALSE);
918:
919: switch (obj->o_type) {
920: case RELIC:
921: switch (obj->o_which) {
922: case HEIL_ANKH:
923: case EMORI_CLOAK:
924: return (TRUE);
925: }
926: when MM:
927: switch (obj->o_which) {
928: case MM_ELF_BOOTS:
929: case MM_DANCE:
930: case MM_BRACERS:
931: case MM_DISP:
932: case MM_PROTECT:
933: case MM_G_DEXTERITY:
934: case MM_G_OGRE:
935: case MM_JEWEL:
936: case MM_R_POWERLESS:
937: case MM_FUMBLE:
938: case MM_STRANGLE:
939: case MM_ADAPTION:
940: return (TRUE);
941: }
942: when ARMOR:
943: case RING:
944: return (TRUE);
945: }
946: when CALLABLE:
947: switch (obj->o_type) {
948: case RING: if (!r_know[obj->o_which]) return(TRUE);
949: when POTION: if (!p_know[obj->o_which]) return(TRUE);
950: when STICK: if (!ws_know[obj->o_which]) return(TRUE);
951: when SCROLL: if (!s_know[obj->o_which]) return(TRUE);
952: when MM: if (!m_know[obj->o_which]) return(TRUE);
953: }
954: when WIELDABLE:
955: switch (obj->o_type) {
956: case STICK:
957: case WEAPON:
958: return(TRUE);
959: when RELIC:
960: switch (obj->o_which) {
961: case MUSTY_DAGGER:
962: case HRUGGEK_MSTAR:
963: case YEENOGHU_FLAIL:
964: case AXE_AKLAD:
965: case MING_STAFF:
966: case ORCUS_WAND:
967: case ASMO_ROD:
968: return(TRUE);
969: }
970: }
971: when IDENTABLE:
972: if (!(obj->o_flags & ISKNOW) && obj->o_type != FOOD)
973: return (TRUE);
974: if (obj->o_type == MM) {
975: switch (obj->o_which) {
976: case MM_JUG:
977: /* Can still identify a jug if we don't know the potion */
978: if (obj->o_ac != JUG_EMPTY && !p_know[obj->o_ac])
979: return (TRUE);
980: }
981: }
982: when USEABLE:
983: if (obj->o_type == MM) {
984: switch(obj->o_which) {
985: case MM_BEAKER:
986: case MM_BOOK:
987: case MM_OPEN:
988: case MM_HUNGER:
989: case MM_DRUMS:
990: case MM_DISAPPEAR:
991: case MM_CHOKE:
992: case MM_KEOGHTOM:
993: case MM_CRYSTAL:
994: return (TRUE);
995: }
996: }
997: else if (obj->o_type == RELIC) {
998: switch (obj->o_which) {
999: case EMORI_CLOAK:
1000: case BRIAN_MANDOLIN:
1001: case HEIL_ANKH:
1002: case YENDOR_AMULET:
1003: case STONEBONES_AMULET:
1004: case GERYON_HORN:
1005: case EYE_VECNA:
1006: case QUILL_NAGROM:
1007: case SURTUR_RING:
1008: case ALTERAN_CARD:
1009: return (TRUE);
1010: }
1011: }
1012: else if (obj->o_type == POTION) {
1013: /*
1014: * only assassins can use poison
1015: */
1016: if (player.t_ctype == C_ASSASSIN && obj->o_which == P_POISON)
1017: return(TRUE);
1018: }
1019: when PROTECTABLE:
1020: switch (obj->o_type) {
1021: case WEAPON:
1022: if ((obj->o_flags & ISMETAL) == 0) return (FALSE);
1023:
1024: /* Fall through */
1025: case ARMOR:
1026: return (TRUE);
1027:
1028: when MM:
1029: if (obj->o_which == MM_BRACERS) return (TRUE);
1030: }
1031: }
1032: return(FALSE);
1033: }
1034:
1035: void
1036: del_pack(struct linked_list *item)
1037: {
1038: register struct object *obj;
1039:
1040: obj = OBJPTR(item);
1041: if (obj->o_count > 1) {
1042: obj->o_count--;
1043: }
1044: else {
1045: cur_null(obj);
1046: detach(pack, item);
1047: o_discard(item);
1048: inpack--;
1049: }
1050: }
1051:
1052: /*
1053: * carry_obj:
1054: * Check to see if a monster is carrying something and, if so, give
1055: * it to him.
1056: */
1057:
1058: void
1059: carry_obj(struct thing *mp, int chance)
1060: {
1061: reg struct linked_list *item;
1062: reg struct object *obj;
1063:
1064: /*
1065: * If there is no chance, just return.
1066: * Note that this means there must be a "chance" in order for
1067: * the creature to carry a relic.
1068: */
1069: if (chance <= 0) return;
1070:
1071: /*
1072: * check for the relic/artifacts
1073: * Do the relics first so they end up last in the pack. Attach()
1074: * always adds things to the beginning. This way they will be the
1075: * last things dropped when the creature is killed. This will ensure
1076: * the relic will be on top if there is a stack of item lying on the
1077: * floor and so the hero will know where it is if he's trying to
1078: * avoid it. Note that only UNIQUEs carry relics.
1079: */
1080: if (on(*mp, ISUNIQUE)) {
1081: if (on(*mp, CARRYMDAGGER)) {
1082: item = spec_item(RELIC, MUSTY_DAGGER, 0, 0);
1083: obj = OBJPTR(item);
1084: obj->o_pos = mp->t_pos;
1085: attach(mp->t_pack, item);
1086: }
1087:
1088: if (on(*mp, CARRYCLOAK)) {
1089: item = spec_item(RELIC, EMORI_CLOAK, 0, 0);
1090: obj = OBJPTR(item);
1091: obj->o_pos = mp->t_pos;
1092: attach(mp->t_pack, item);
1093: }
1094:
1095: if (on(*mp, CARRYANKH)) {
1096: item = spec_item(RELIC, HEIL_ANKH, 0, 0);
1097: obj = OBJPTR(item);
1098: obj->o_pos = mp->t_pos;
1099: attach(mp->t_pack, item);
1100: }
1101:
1102: if (on(*mp, CARRYSTAFF)) {
1103: item = spec_item(RELIC, MING_STAFF, 0, 0);
1104: obj = OBJPTR(item);
1105: obj->o_pos = mp->t_pos;
1106: attach(mp->t_pack, item);
1107: }
1108:
1109: if (on(*mp, CARRYWAND)) {
1110: item = spec_item(RELIC, ORCUS_WAND, 0, 0);
1111: obj = OBJPTR(item);
1112: obj->o_pos = mp->t_pos;
1113: attach(mp->t_pack, item);
1114: }
1115:
1116: if (on(*mp, CARRYROD)) {
1117: item = spec_item(RELIC, ASMO_ROD, 0, 0);
1118: obj = OBJPTR(item);
1119: obj->o_pos = mp->t_pos;
1120: attach(mp->t_pack, item);
1121: }
1122:
1123: if (on(*mp, CARRYYAMULET)) {
1124: item = spec_item(RELIC, YENDOR_AMULET, 0, 0);
1125: obj = OBJPTR(item);
1126: obj->o_pos = mp->t_pos;
1127: attach(mp->t_pack, item);
1128: }
1129:
1130: if (on(*mp, CARRYBAMULET)) {
1131: item = spec_item(RELIC, STONEBONES_AMULET, 0, 0);
1132: obj = OBJPTR(item);
1133: obj->o_pos = mp->t_pos;
1134: attach(mp->t_pack, item);
1135: }
1136:
1137: if (on(*mp, CARRYMANDOLIN)) {
1138: item = spec_item(RELIC, BRIAN_MANDOLIN, 0, 0);
1139: obj = OBJPTR(item);
1140: obj->o_pos = mp->t_pos;
1141: attach(mp->t_pack, item);
1142: }
1143: if (on(*mp, CARRYEYE)) {
1144: item = spec_item(RELIC, EYE_VECNA, 0, 0);
1145: obj = OBJPTR(item);
1146: obj->o_pos = mp->t_pos;
1147: attach(mp->t_pack, item);
1148: }
1149: if (on(*mp, CARRYAXE)) {
1150: item = spec_item(RELIC, AXE_AKLAD, 0, 0);
1151: obj = OBJPTR(item);
1152: obj->o_pos = mp->t_pos;
1153: attach(mp->t_pack, item);
1154: }
1155: if (on(*mp, CARRYQUILL)) {
1156: register int i, howmany;
1157:
1158: item = spec_item(RELIC, QUILL_NAGROM, 0, 0);
1159: obj = OBJPTR(item);
1160: obj->o_pos = mp->t_pos;
1161: obj->o_charges = rnd(QUILLCHARGES);
1162: attach(mp->t_pack, item);
1163: howmany = roll(4,3);
1164: for (i=0; i<howmany; i++) {
1165: /*
1166: * the quill writes scrolls so give him a bunch
1167: */
1168: item = new_thing(TYP_SCROLL, FALSE);
1169: obj = OBJPTR(item);
1170: obj->o_pos = mp->t_pos;
1171: attach(mp->t_pack, item);
1172: }
1173: }
1174: if (on(*mp, CARRYMSTAR)) {
1175: item = spec_item(RELIC, HRUGGEK_MSTAR, 0, 0);
1176: obj = OBJPTR(item);
1177: obj->o_pos = mp->t_pos;
1178: attach(mp->t_pack, item);
1179: }
1180: if (on(*mp, CARRYFLAIL)) {
1181: item = spec_item(RELIC, YEENOGHU_FLAIL, 0, 0);
1182: obj = OBJPTR(item);
1183: obj->o_pos = mp->t_pos;
1184: attach(mp->t_pack, item);
1185: }
1186: if (on(*mp, CARRYHORN)) {
1187: item = spec_item(RELIC, GERYON_HORN, 0, 0);
1188: obj = OBJPTR(item);
1189: obj->o_pos = mp->t_pos;
1190: attach(mp->t_pack, item);
1191: }
1192: if (on(*mp, CARRYSURTURRING)) {
1193: item = spec_item(RELIC, SURTUR_RING, 0, 0);
1194: obj = OBJPTR(item);
1195: obj->o_pos = mp->t_pos;
1196: attach(mp->t_pack, item);
1197: }
1198: if (on(*mp, CARRYCARD)) {
1199: item = spec_item(RELIC, ALTERAN_CARD, 0, 0);
1200: obj = OBJPTR(item);
1201: obj->o_pos = mp->t_pos;
1202: attach(mp->t_pack, item);
1203: }
1204: }
1205: /*
1206: * If it carries gold, give it some
1207: */
1208: if (on(*mp, CARRYGOLD) && rnd(100) < chance) {
1209: item = spec_item(GOLD, 0, 0, 0);
1210: obj = OBJPTR(item);
1211: obj->o_count = GOLDCALC + GOLDCALC;
1212: obj->o_pos = mp->t_pos;
1213: attach(mp->t_pack, item);
1214: }
1215:
1216: /*
1217: * If it carries food, give it some
1218: */
1219: if (on(*mp, CARRYFOOD) && rnd(100) < chance) {
1220: int type;
1221: switch (rnd(41)) {
1222: case 3: type = E_APPLE;
1223: when 6: type = E_HAGBERRY;
1224: when 9: type = E_SOURSOP;
1225: when 12: type = E_RAMBUTAN;
1226: when 15: type = E_DEWBERRY;
1227: when 18: type = E_CANDLEBERRY;
1228: when 21: type = E_BANANA;
1229: when 24: type = E_CAPRIFIG;
1230: when 27: type = E_STRAWBERRY;
1231: when 30: type = E_GOOSEBERRY;
1232: when 33: type = E_ELDERBERRY;
1233: when 36: type = E_BLUEBERRY;
1234: when 40: type = E_SLIMEMOLD; /* monster food */
1235: otherwise: type = E_RATION;
1236: }
1237: item = spec_item(FOOD, type, 0, 0);
1238: obj = OBJPTR(item);
1239: obj->o_weight = things[TYP_FOOD].mi_wght;
1240: obj->o_pos = mp->t_pos;
1241: attach(mp->t_pack, item);
1242: }
1243:
1244: /*
1245: * If it carries a weapon, give it one
1246: */
1247: if (on(*mp, CARRYWEAPON) && rnd(100) < chance) {
1248: int type, hit, dam;
1249:
1250: /* Get the "bonuses" */
1251: hit = rnd(5 + (vlevel / 5)) - 2;
1252: dam = rnd(5 + (vlevel / 5)) - 2;
1253:
1254: /* Only choose an appropriate type of weapon */
1255: switch (rnd(12)) {
1256: case 0: type = DAGGER;
1257: when 1: type = BATTLEAXE;
1258: when 2: type = MACE;
1259: when 3: type = SWORD;
1260: when 4: type = PIKE;
1261: when 5: type = HALBERD;
1262: when 6: type = SPETUM;
1263: when 7: type = BARDICHE;
1264: when 8: type = TRIDENT;
1265: when 9: type = BASWORD;
1266: when 10:type = DART;
1267: otherwise: type = TWOSWORD;
1268: }
1269:
1270: /* Create the item */
1271: item = spec_item(WEAPON, type, hit, dam);
1272: obj = OBJPTR(item);
1273: obj->o_pos = mp->t_pos;
1274: attach(mp->t_pack, item);
1275: }
1276:
1277: /*
1278: * If it carries a dagger, give it one
1279: */
1280: if (on(*mp, CARRYDAGGER) && rnd(100) < chance) {
1281: int hit, dam;
1282:
1283: /* Get the "bonuses" */
1284: hit = rnd(3 + (vlevel / 5)) - 1;
1285: dam = rnd(3 + (vlevel / 5)) - 1;
1286:
1287: /* Create the item */
1288: item = spec_item(WEAPON, DAGGER, hit, dam);
1289: obj = OBJPTR(item);
1290: obj->o_pos = mp->t_pos;
1291: attach(mp->t_pack, item);
1292: }
1293:
1294: /*
1295: * If it carries a scroll, give it one
1296: */
1297: if (on(*mp, CARRYSCROLL) && rnd(100) < chance) {
1298: item = new_thing(TYP_SCROLL, TRUE);
1299: obj = OBJPTR(item);
1300: obj->o_pos = mp->t_pos;
1301:
1302: /* Can the monster carry this scroll? */
1303: if (obj->o_which == S_SCARE && mp->t_stats.s_intel < 16)
1304: fall(item, FALSE); /* This would scare us! */
1305: else attach(mp->t_pack, item);
1306: }
1307:
1308: /*
1309: * If it carries a potion, give it one
1310: */
1311: if (on(*mp, CARRYPOTION) && rnd(100) < chance) {
1312: item = new_thing(TYP_POTION, TRUE);
1313: obj = OBJPTR(item);
1314: obj->o_pos = mp->t_pos;
1315: attach(mp->t_pack, item);
1316: }
1317:
1318: /*
1319: * If it carries a ring, give it one
1320: */
1321: if (on(*mp, CARRYRING) && rnd(100) < chance) {
1322: item = new_thing(TYP_RING, TRUE);
1323: obj = OBJPTR(item);
1324: obj->o_pos = mp->t_pos;
1325: attach(mp->t_pack, item);
1326: }
1327:
1328: /*
1329: * If it carries a wand or staff, give it one
1330: */
1331: if (on(*mp, CARRYSTICK) && rnd(100) < chance) {
1332: item = new_thing(TYP_STICK, TRUE);
1333: obj = OBJPTR(item);
1334: obj->o_pos = mp->t_pos;
1335: attach(mp->t_pack, item);
1336: }
1337:
1338: /*
1339: * If it carries any miscellaneous magic, give it one
1340: */
1341: if (on(*mp, CARRYMISC) && rnd(100) < chance) {
1342: item = new_thing(TYP_MM, TRUE);
1343: obj = OBJPTR(item);
1344: obj->o_pos = mp->t_pos;
1345: attach(mp->t_pack, item);
1346: }
1347:
1348: /* Update the monster's encumberance */
1349: updpack(TRUE, mp);
1350: }
1351:
1352:
1353: /*
1354: * grab():
1355: * See what is on the spot where the player is standing. If
1356: * nothing is there, do nothing. If there is one thing, pick it
1357: * up. If there are multiple things, prompt the player for what
1358: * he wants (* means everything).
1359: */
1360:
1361: int
1362: grab(int y, int x)
1363: {
1364: register struct linked_list *next_item, *item;
1365: register struct object *obj;
1366: register int cnt, pagecnt;
1367: int num_there = 0, ch, och;
1368:
1369: /*
1370: * Count how many objects there are and move them to the front
1371: * of the level list.
1372: */
1373: for (item = lvl_obj; item != NULL; item = next_item) {
1374: obj = OBJPTR(item);
1375: next_item = next(item);
1376: if (obj->o_pos.y == y && obj->o_pos.x == x) {
1377: num_there++;
1378: detach(lvl_obj, item); /* Remove it from the list */
1379: attach(lvl_obj, item); /* Place it at the front of the list */
1380: }
1381: }
1382:
1383: /* Nothing there. */
1384: if (num_there < 1) msg("Nothing %s", terse ? "there." : "to pick up.");
1385:
1386: /* Something or things there */
1387: else {
1388: char linebuf[2*LINELEN+1];
1389: int curlen, maxlen = 0;
1390:
1391: wclear(hw);
1392: cnt = 0;
1393: pagecnt = 0;
1394: for (item = lvl_obj, ch = 'a'; item != NULL && cnt < num_there;
1395: item = next(item), ch++, cnt++) {
1396: obj = OBJPTR(item);
1397: /* Construct how the line will look */
1398: sprintf(linebuf, "%c) %s\n\r", ch, inv_name(obj,FALSE));
1399:
1400: /* See how long it is */
1401: curlen = strlen(linebuf) - 2; /* Don't count \n or \r */
1402: if (maxlen < curlen) maxlen = curlen;
1403:
1404: /* Draw it in the window */
1405: waddstr(hw, linebuf);
1406:
1407: if (++pagecnt >= lines - 2 && next(item) != NULL) {
1408: pagecnt = 0;
1409: maxlen = 0;
1410: dbotline(hw, spacemsg);
1411: wclear(hw);
1412: }
1413: if (ch == 'z') ch = 'A' - 1;
1414: }
1415:
1416: strcpy(linebuf, "Pick up what? (* for all): ");
1417:
1418: /* See how long it is */
1419: curlen = strlen(linebuf); /* Don't count \n or \r */
1420: if (maxlen < curlen) maxlen = curlen;
1421:
1422: /* Draw it in the window */
1423: waddstr(hw, linebuf);
1424:
1425: /*
1426: * If we have fewer than half a screenful, don't clear the screen.
1427: * Leave 3 blank lines at the bottom and 3 blank columns to he right.
1428: */
1429: if (menu_overlay && num_there < lines - 3) {
1430: over_win(cw, hw, num_there + 2, maxlen + 3, num_there, curlen, '\0');
1431: pagecnt = -1; /* Indicate we used over_win */
1432: }
1433: else draw(hw); /* write screen */
1434:
1435: for (;;) {
1436: do {
1437: ch = wgetch(cw);
1438: } until (isalpha(ch) || ch == '*' || ch == ESC);
1439:
1440: /* Redraw original screen */
1441: if (pagecnt < 0) {
1442: clearok(cw, FALSE); /* Setup to redraw current screen */
1443: touchwin(cw); /* clearing first */
1444: draw(cw);
1445: }
1446: else restscr(cw);
1447:
1448: if (ch == ESC) {
1449: after = FALSE;
1450: msg(""); /* clear top line */
1451: break;
1452: }
1453: if (ch == '*') {
1454: player.t_action = A_PICKUP;
1455: return(1); /* set action to PICKUP and delay for first one */
1456: }
1457: /* ch has item to get from list */
1458:
1459: cnt = 0;
1460: for (item = lvl_obj, och = 'a'; item != NULL && cnt < num_there;
1461: item = next(item), och++, cnt++) {
1462: if (ch == och)
1463: break;
1464: if (och == 'z') och = 'A' - 1;
1465: }
1466: if (item == NULL || cnt >= num_there) {
1467: wmove(hw, pagecnt < 0 ? num_there : pagecnt, 25);
1468: wprintw(hw, " [between 'a' and '%c']: ",
1469: och == 'A' ? 'z' : och-1);
1470: if (maxlen < 49) maxlen = 49;
1471:
1472: /*
1473: * If we have fewer than half a screenful, don't clear the
1474: * screen. Leave an extra blank line at the bottom and
1475: * 3 blank columns to the right.
1476: */
1477: if (menu_overlay && num_there < lines - 3) {
1478: over_win(cw, hw, num_there + 2, maxlen + 3,
1479: num_there, 49, '\0');
1480: cnt = -1; /* Indicate we used over_win */
1481: }
1482: else draw(hw); /* write screen */
1483: continue;
1484: }
1485: else {
1486: detach(lvl_obj, item);
1487: if (add_pack(item, FALSE)) {
1488: /*
1489: * We make sure here that the dungeon floor gets
1490: * updated with what's left on the vacated spot.
1491: */
1492: if ((item = find_obj(y, x)) == NULL) {
1493: coord roomcoord; /* Needed to pass to roomin() */
1494:
1495: roomcoord.y = y;
1496: roomcoord.x = x;
1497: mvaddch(y, x,
1498: (roomin(&roomcoord) == NULL ? PASSAGE : FLOOR));
1499: }
1500: else mvaddch(y, x, (OBJPTR(item))->o_type);
1501: return(1);
1502: }
1503: else attach(lvl_obj, item); /* Couldn't pick it up! */
1504: break;
1505: }
1506: }
1507: }
1508:
1509: return(0);
1510: }
1511:
1512: /*
1513: * make_sell_pack:
1514: *
1515: * Create a pack for sellers (a la quartermaster)
1516: */
1517:
1518: void
1519: make_sell_pack(struct thing *tp)
1520: {
1521: reg struct linked_list *item;
1522: reg struct object *obj;
1523: reg int sell_type = 0, nitems, i;
1524:
1525: /* Select the items */
1526: nitems = rnd(5) + 7;
1527:
1528: switch (rnd(14)) {
1529: /* Armor */
1530: case 0:
1531: case 1:
1532: turn_on(*tp, CARRYARMOR);
1533: sell_type = TYP_ARMOR;
1534: break;
1535:
1536: /* Weapon */
1537: when 2:
1538: case 3:
1539: turn_on(*tp, CARRYWEAPON);
1540: sell_type = TYP_WEAPON;
1541: break;
1542:
1543: /* Staff or wand */
1544: when 4:
1545: case 5:
1546: turn_on(*tp, CARRYSTICK);
1547: sell_type = TYP_STICK;
1548: break;
1549:
1550: /* Ring */
1551: when 6:
1552: case 7:
1553: turn_on(*tp, CARRYRING);
1554: sell_type = TYP_RING;
1555: break;
1556:
1557: /* scroll */
1558: when 8:
1559: case 9:
1560: turn_on(*tp, CARRYSCROLL);
1561: sell_type = TYP_SCROLL;
1562: break;
1563:
1564: /* potions */
1565: when 10:
1566: case 11:
1567: turn_on(*tp, CARRYPOTION);
1568: sell_type = TYP_POTION;
1569: break;
1570:
1571: /* Miscellaneous magic */
1572: when 12:
1573: case 13:
1574: turn_on(*tp, CARRYMISC);
1575: sell_type = TYP_MM;
1576: break;
1577: }
1578: for (i=0; i<nitems; i++) {
1579: item = new_thing(sell_type, FALSE);
1580: obj = OBJPTR(item);
1581: obj->o_pos = tp->t_pos;
1582: attach(tp->t_pack, item);
1583: }
1584: }
1585:
CVSweb