|
|
1.1 root 1: /*
2: * Copyright (c) 1988 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Timothy C. Stoehr.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that: (1) source distributions retain this entire copyright
10: * notice and comment, and (2) distributions including binaries display
11: * the following acknowledgement: ``This product includes software
12: * developed by the University of California, Berkeley and its contributors''
13: * in the documentation or other materials provided with the distribution
14: * and in all advertising materials mentioning features or use of this
15: * software. Neither the name of the University nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)inventory.c 5.4 (Berkeley) 6/1/90";
25: #endif /* not lint */
26:
27: /*
28: * inventory.c
29: *
30: * This source herein may be modified and/or distributed by anybody who
31: * so desires, with the following restrictions:
32: * 1.) No portion of this notice shall be removed.
33: * 2.) Credit shall not be taken for the creation of this source.
34: * 3.) This code is not to be traded, sold, or used for personal
35: * gain or profit.
36: *
37: */
38:
39: #include "rogue.h"
40:
41: boolean is_wood[WANDS];
42: char *press_space = " --press space to continue--";
43:
44: char *wand_materials[WAND_MATERIALS] = {
45: "steel ",
46: "bronze ",
47: "gold ",
48: "silver ",
49: "copper ",
50: "nickel ",
51: "cobalt ",
52: "tin ",
53: "iron ",
54: "magnesium ",
55: "chrome ",
56: "carbon ",
57: "platinum ",
58: "silicon ",
59: "titanium ",
60:
61: "teak ",
62: "oak ",
63: "cherry ",
64: "birch ",
65: "pine ",
66: "cedar ",
67: "redwood ",
68: "balsa ",
69: "ivory ",
70: "walnut ",
71: "maple ",
72: "mahogany ",
73: "elm ",
74: "palm ",
75: "wooden "
76: };
77:
78: char *gems[GEMS] = {
79: "diamond ",
80: "stibotantalite ",
81: "lapi-lazuli ",
82: "ruby ",
83: "emerald ",
84: "sapphire ",
85: "amethyst ",
86: "quartz ",
87: "tiger-eye ",
88: "opal ",
89: "agate ",
90: "turquoise ",
91: "pearl ",
92: "garnet "
93: };
94:
95: char *syllables[MAXSYLLABLES] = {
96: "blech ",
97: "foo ",
98: "barf ",
99: "rech ",
100: "bar ",
101: "blech ",
102: "quo ",
103: "bloto ",
104: "oh ",
105: "caca ",
106: "blorp ",
107: "erp ",
108: "festr ",
109: "rot ",
110: "slie ",
111: "snorf ",
112: "iky ",
113: "yuky ",
114: "ooze ",
115: "ah ",
116: "bahl ",
117: "zep ",
118: "druhl ",
119: "flem ",
120: "behil ",
121: "arek ",
122: "mep ",
123: "zihr ",
124: "grit ",
125: "kona ",
126: "kini ",
127: "ichi ",
128: "tims ",
129: "ogr ",
130: "oo ",
131: "ighr ",
132: "coph ",
133: "swerr ",
134: "mihln ",
135: "poxi "
136: };
137:
138: #define COMS 48
139:
140: struct id_com_s {
141: short com_char;
142: char *com_desc;
143: };
144:
145: struct id_com_s com_id_tab[COMS] = {
146: '?', "? prints help",
147: 'r', "r read scroll",
148: '/', "/ identify object",
149: 'e', "e eat food",
150: 'h', "h left ",
151: 'w', "w wield a weapon",
152: 'j', "j down",
153: 'W', "W wear armor",
154: 'k', "k up",
155: 'T', "T take armor off",
156: 'l', "l right",
157: 'P', "P put on ring",
158: 'y', "y up & left",
159: 'R', "R remove ring",
160: 'u', "u up & right",
161: 'd', "d drop object",
162: 'b', "b down & left",
163: 'c', "c call object",
164: 'n', "n down & right",
165: NULL, "<SHIFT><dir>: run that way",
166: ')', ") print current weapon",
167: NULL, "<CTRL><dir>: run till adjacent",
168: ']', "] print current armor",
169: 'f', "f<dir> fight till death or near death",
170: '=', "= print current rings",
171: 't', "t<dir> throw something",
172: '\001', "^A print Hp-raise average",
173: 'm', "m<dir> move onto without picking up",
174: 'z', "z<dir> zap a wand in a direction",
175: 'o', "o examine/set options",
176: '^', "^<dir> identify trap type",
177: '\022', "^R redraw screen",
178: '&', "& save screen into 'rogue.screen'",
179: 's', "s search for trap/secret door",
180: '\020', "^P repeat last message",
181: '>', "> go down a staircase",
182: '\033', "^[ cancel command",
183: '<', "< go up a staircase",
184: 'S', "S save game",
185: '.', ". rest for a turn",
186: 'Q', "Q quit",
187: ',', ", pick something up",
188: '!', "! shell escape",
189: 'i', "i inventory",
190: 'F', "F<dir> fight till either of you dies",
191: 'I', "I inventory single item",
192: 'v', "v print version number",
193: 'q', "q quaff potion"
194: };
195:
196: extern boolean wizard;
197: extern char *m_names[], *more;
198:
199: inventory(pack, mask)
200: object *pack;
201: unsigned short mask;
202: {
203: object *obj;
204: short i = 0, j, maxlen = 0, n;
205: char descs[MAX_PACK_COUNT+1][DCOLS];
206: short row, col;
207:
208: obj = pack->next_object;
209:
210: if (!obj) {
211: message("your pack is empty", 0);
212: return;
213: }
214: while (obj) {
215: if (obj->what_is & mask) {
216: descs[i][0] = ' ';
217: descs[i][1] = obj->ichar;
218: descs[i][2] = ((obj->what_is & ARMOR) && obj->is_protected)
219: ? '}' : ')';
220: descs[i][3] = ' ';
221: get_desc(obj, descs[i]+4);
222: if ((n = strlen(descs[i])) > maxlen) {
223: maxlen = n;
224: }
225: i++;
226: }
227: obj = obj->next_object;
228: }
229: (void) strcpy(descs[i++], press_space);
230: if (maxlen < 27) maxlen = 27;
231: col = DCOLS - (maxlen + 2);
232:
233: for (row = 0; ((row < i) && (row < DROWS)); row++) {
234: if (row > 0) {
235: for (j = col; j < DCOLS; j++) {
236: descs[row-1][j-col] = mvinch(row, j);
237: }
238: descs[row-1][j-col] = 0;
239: }
240: mvaddstr(row, col, descs[row]);
241: clrtoeol();
242: }
243: refresh();
244: wait_for_ack();
245:
246: move(0, 0);
247: clrtoeol();
248:
249: for (j = 1; ((j < i) && (j < DROWS)); j++) {
250: mvaddstr(j, col, descs[j-1]);
251: }
252: }
253:
254: id_com()
255: {
256: int ch = 0;
257: short i, j, k;
258:
259: while (ch != CANCEL) {
260: check_message();
261: message("Character you want help for (* for all):", 0);
262:
263: refresh();
264: ch = getchar();
265:
266: switch(ch) {
267: case LIST:
268: {
269: char save[(((COMS / 2) + (COMS % 2)) + 1)][DCOLS];
270: short rows = (((COMS / 2) + (COMS % 2)) + 1);
271: boolean need_two_screens;
272:
273: if (rows > LINES) {
274: need_two_screens = 1;
275: rows = LINES;
276: }
277: k = 0;
278:
279: for (i = 0; i < rows; i++) {
280: for (j = 0; j < DCOLS; j++) {
281: save[i][j] = mvinch(i, j);
282: }
283: }
284: MORE:
285: for (i = 0; i < rows; i++) {
286: move(i, 0);
287: clrtoeol();
288: }
289: for (i = 0; i < (rows-1); i++) {
290: if (i < (LINES-1)) {
291: if (((i + i) < COMS) && ((i+i+k) < COMS)) {
292: mvaddstr(i, 0, com_id_tab[i+i+k].com_desc);
293: }
294: if (((i + i + 1) < COMS) && ((i+i+k+1) < COMS)) {
295: mvaddstr(i, (DCOLS/2),
296: com_id_tab[i+i+k+1].com_desc);
297: }
298: }
299: }
300: mvaddstr(rows - 1, 0, need_two_screens ? more : press_space);
301: refresh();
302: wait_for_ack();
303:
304: if (need_two_screens) {
305: k += ((rows-1) * 2);
306: need_two_screens = 0;
307: goto MORE;
308: }
309: for (i = 0; i < rows; i++) {
310: move(i, 0);
311: for (j = 0; j < DCOLS; j++) {
312: addch(save[i][j]);
313: }
314: }
315: }
316: break;
317: default:
318: if (!pr_com_id(ch)) {
319: if (!pr_motion_char(ch)) {
320: check_message();
321: message("unknown character", 0);
322: }
323: }
324: ch = CANCEL;
325: break;
326: }
327: }
328: }
329:
330: pr_com_id(ch)
331: int ch;
332: {
333: int i;
334:
335: if (!get_com_id(&i, ch)) {
336: return(0);
337: }
338: check_message();
339: message(com_id_tab[i].com_desc, 0);
340: return(1);
341: }
342:
343: get_com_id(index, ch)
344: int *index;
345: short ch;
346: {
347: short i;
348:
349: for (i = 0; i < COMS; i++) {
350: if (com_id_tab[i].com_char == ch) {
351: *index = i;
352: return(1);
353: }
354: }
355: return(0);
356: }
357:
358: pr_motion_char(ch)
359: int ch;
360: {
361: if ( (ch == 'J') ||
362: (ch == 'K') ||
363: (ch == 'L') ||
364: (ch == 'H') ||
365: (ch == 'Y') ||
366: (ch == 'U') ||
367: (ch == 'N') ||
368: (ch == 'B') ||
369: (ch == '\012') ||
370: (ch == '\013') ||
371: (ch == '\010') ||
372: (ch == '\014') ||
373: (ch == '\025') ||
374: (ch == '\031') ||
375: (ch == '\016') ||
376: (ch == '\002')) {
377: char until[18], buf[DCOLS];
378: int n;
379:
380: if (ch <= '\031') {
381: ch += 96;
382: (void) strcpy(until, "until adjascent");
383: } else {
384: ch += 32;
385: until[0] = '\0';
386: }
387: (void) get_com_id(&n, ch);
388: sprintf(buf, "run %s %s", com_id_tab[n].com_desc + 8, until);
389: check_message();
390: message(buf, 0);
391: return(1);
392: } else {
393: return(0);
394: }
395: }
396:
397: mix_colors()
398: {
399: short i, j, k;
400: char *t;
401:
402: for (i = 0; i <= 32; i++) {
403: j = get_rand(0, (POTIONS - 1));
404: k = get_rand(0, (POTIONS - 1));
405: t = id_potions[j].title;
406: id_potions[j].title = id_potions[k].title;
407: id_potions[k].title = t;
408: }
409: }
410:
411: make_scroll_titles()
412: {
413: short i, j, n;
414: short sylls, s;
415:
416: for (i = 0; i < SCROLS; i++) {
417: sylls = get_rand(2, 5);
418: (void) strcpy(id_scrolls[i].title, "'");
419:
420: for (j = 0; j < sylls; j++) {
421: s = get_rand(1, (MAXSYLLABLES-1));
422: (void) strcat(id_scrolls[i].title, syllables[s]);
423: }
424: n = strlen(id_scrolls[i].title);
425: (void) strcpy(id_scrolls[i].title+(n-1), "' ");
426: }
427: }
428:
429: get_desc(obj, desc)
430: object *obj;
431: char *desc;
432: {
433: char *item_name;
434: struct id *id_table;
435: char more_info[32];
436: short i;
437:
438: if (obj->what_is == AMULET) {
439: (void) strcpy(desc, "the amulet of Yendor ");
440: return;
441: }
442: item_name = name_of(obj);
443:
444: if (obj->what_is == GOLD) {
445: sprintf(desc, "%d pieces of gold", obj->quantity);
446: return;
447: }
448:
449: if (obj->what_is != ARMOR) {
450: if (obj->quantity == 1) {
451: (void) strcpy(desc, "a ");
452: } else {
453: sprintf(desc, "%d ", obj->quantity);
454: }
455: }
456: if (obj->what_is == FOOD) {
457: if (obj->which_kind == RATION) {
458: if (obj->quantity > 1) {
459: sprintf(desc, "%d rations of ", obj->quantity);
460: } else {
461: (void) strcpy(desc, "some ");
462: }
463: } else {
464: (void) strcpy(desc, "a ");
465: }
466: (void) strcat(desc, item_name);
467: goto ANA;
468: }
469: id_table = get_id_table(obj);
470:
471: if (wizard) {
472: goto ID;
473: }
474: if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) {
475: goto CHECK;
476: }
477:
478: switch(id_table[obj->which_kind].id_status) {
479: case UNIDENTIFIED:
480: CHECK:
481: switch(obj->what_is) {
482: case SCROL:
483: (void) strcat(desc, item_name);
484: (void) strcat(desc, "entitled: ");
485: (void) strcat(desc, id_table[obj->which_kind].title);
486: break;
487: case POTION:
488: (void) strcat(desc, id_table[obj->which_kind].title);
489: (void) strcat(desc, item_name);
490: break;
491: case WAND:
492: case RING:
493: if (obj->identified ||
494: (id_table[obj->which_kind].id_status == IDENTIFIED)) {
495: goto ID;
496: }
497: if (id_table[obj->which_kind].id_status == CALLED) {
498: goto CALL;
499: }
500: (void) strcat(desc, id_table[obj->which_kind].title);
501: (void) strcat(desc, item_name);
502: break;
503: case ARMOR:
504: if (obj->identified) {
505: goto ID;
506: }
507: (void) strcpy(desc, id_table[obj->which_kind].title);
508: break;
509: case WEAPON:
510: if (obj->identified) {
511: goto ID;
512: }
513: (void) strcat(desc, name_of(obj));
514: break;
515: }
516: break;
517: case CALLED:
518: CALL: switch(obj->what_is) {
519: case SCROL:
520: case POTION:
521: case WAND:
522: case RING:
523: (void) strcat(desc, item_name);
524: (void) strcat(desc, "called ");
525: (void) strcat(desc, id_table[obj->which_kind].title);
526: break;
527: }
528: break;
529: case IDENTIFIED:
530: ID: switch(obj->what_is) {
531: case SCROL:
532: case POTION:
533: (void) strcat(desc, item_name);
534: (void) strcat(desc, id_table[obj->which_kind].real);
535: break;
536: case RING:
537: if (wizard || obj->identified) {
538: if ((obj->which_kind == DEXTERITY) ||
539: (obj->which_kind == ADD_STRENGTH)) {
540: sprintf(more_info, "%s%d ", ((obj->class > 0) ? "+" : ""),
541: obj->class);
542: (void) strcat(desc, more_info);
543: }
544: }
545: (void) strcat(desc, item_name);
546: (void) strcat(desc, id_table[obj->which_kind].real);
547: break;
548: case WAND:
549: (void) strcat(desc, item_name);
550: (void) strcat(desc, id_table[obj->which_kind].real);
551: if (wizard || obj->identified) {
552: sprintf(more_info, "[%d]", obj->class);
553: (void) strcat(desc, more_info);
554: }
555: break;
556: case ARMOR:
557: sprintf(desc, "%s%d ", ((obj->d_enchant >= 0) ? "+" : ""),
558: obj->d_enchant);
559: (void) strcat(desc, id_table[obj->which_kind].title);
560: sprintf(more_info, "[%d] ", get_armor_class(obj));
561: (void) strcat(desc, more_info);
562: break;
563: case WEAPON:
564: sprintf(desc+strlen(desc), "%s%d,%s%d ",
565: ((obj->hit_enchant >= 0) ? "+" : ""), obj->hit_enchant,
566: ((obj->d_enchant >= 0) ? "+" : ""), obj->d_enchant);
567: (void) strcat(desc, name_of(obj));
568: break;
569: }
570: break;
571: }
572: ANA:
573: if (!strncmp(desc, "a ", 2)) {
574: if (is_vowel(desc[2])) {
575: for (i = strlen(desc) + 1; i > 1; i--) {
576: desc[i] = desc[i-1];
577: }
578: desc[1] = 'n';
579: }
580: }
581: if (obj->in_use_flags & BEING_WIELDED) {
582: (void) strcat(desc, "in hand");
583: } else if (obj->in_use_flags & BEING_WORN) {
584: (void) strcat(desc, "being worn");
585: } else if (obj->in_use_flags & ON_LEFT_HAND) {
586: (void) strcat(desc, "on left hand");
587: } else if (obj->in_use_flags & ON_RIGHT_HAND) {
588: (void) strcat(desc, "on right hand");
589: }
590: }
591:
592: get_wand_and_ring_materials()
593: {
594: short i, j;
595: boolean used[WAND_MATERIALS];
596:
597: for (i = 0; i < WAND_MATERIALS; i++) {
598: used[i] = 0;
599: }
600: for (i = 0; i < WANDS; i++) {
601: do {
602: j = get_rand(0, WAND_MATERIALS-1);
603: } while (used[j]);
604: used[j] = 1;
605: (void) strcpy(id_wands[i].title, wand_materials[j]);
606: is_wood[i] = (j > MAX_METAL);
607: }
608: for (i = 0; i < GEMS; i++) {
609: used[i] = 0;
610: }
611: for (i = 0; i < RINGS; i++) {
612: do {
613: j = get_rand(0, GEMS-1);
614: } while (used[j]);
615: used[j] = 1;
616: (void) strcpy(id_rings[i].title, gems[j]);
617: }
618: }
619:
620: single_inv(ichar)
621: short ichar;
622: {
623: short ch;
624: char desc[DCOLS];
625: object *obj;
626:
627: ch = ichar ? ichar : pack_letter("inventory what?", ALL_OBJECTS);
628:
629: if (ch == CANCEL) {
630: return;
631: }
632: if (!(obj = get_letter_object(ch))) {
633: message("no such item.", 0);
634: return;
635: }
636: desc[0] = ch;
637: desc[1] = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')';
638: desc[2] = ' ';
639: desc[3] = 0;
640: get_desc(obj, desc+3);
641: message(desc, 0);
642: }
643:
644: struct id *
645: get_id_table(obj)
646: object *obj;
647: {
648: switch(obj->what_is) {
649: case SCROL:
650: return(id_scrolls);
651: case POTION:
652: return(id_potions);
653: case WAND:
654: return(id_wands);
655: case RING:
656: return(id_rings);
657: case WEAPON:
658: return(id_weapons);
659: case ARMOR:
660: return(id_armors);
661: }
662: return((struct id *) 0);
663: }
664:
665: inv_armor_weapon(is_weapon)
666: boolean is_weapon;
667: {
668: if (is_weapon) {
669: if (rogue.weapon) {
670: single_inv(rogue.weapon->ichar);
671: } else {
672: message("not wielding anything", 0);
673: }
674: } else {
675: if (rogue.armor) {
676: single_inv(rogue.armor->ichar);
677: } else {
678: message("not wearing anything", 0);
679: }
680: }
681: }
682:
683: id_type()
684: {
685: char *id;
686: int ch;
687: char buf[DCOLS];
688:
689: message("what do you want identified?", 0);
690:
691: ch = rgetchar();
692:
693: if ((ch >= 'A') && (ch <= 'Z')) {
694: id = m_names[ch-'A'];
695: } else if (ch < 32) {
696: check_message();
697: return;
698: } else {
699: switch(ch) {
700: case '@':
701: id = "you";
702: break;
703: case '%':
704: id = "staircase";
705: break;
706: case '^':
707: id = "trap";
708: break;
709: case '+':
710: id = "door";
711: break;
712: case '-':
713: case '|':
714: id = "wall of a room";
715: break;
716: case '.':
717: id = "floor";
718: break;
719: case '#':
720: id = "passage";
721: break;
722: case ' ':
723: id = "solid rock";
724: break;
725: case '=':
726: id = "ring";
727: break;
728: case '?':
729: id = "scroll";
730: break;
731: case '!':
732: id = "potion";
733: break;
734: case '/':
735: id = "wand or staff";
736: break;
737: case ')':
738: id = "weapon";
739: break;
740: case ']':
741: id = "armor";
742: break;
743: case '*':
744: id = "gold";
745: break;
746: case ':':
747: id = "food";
748: break;
749: case ',':
750: id = "the Amulet of Yendor";
751: break;
752: default:
753: id = "unknown character";
754: break;
755: }
756: }
757: check_message();
758: sprintf(buf, "'%c': %s", ch, id);
759: message(buf, 0);
760: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.