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