2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * @(#)inventory.c 8.1 (Berkeley) 5/31/93
33 * $FreeBSD: src/games/rogue/inventory.c,v 1.4 1999/11/30 03:49:23 billf Exp $
39 * This source herein may be modified and/or distributed by anybody who
40 * so desires, with the following restrictions:
41 * 1.) No portion of this notice shall be removed.
42 * 2.) Credit shall not be taken for the creation of this source.
43 * 3.) This code is not to be traded, sold, or used for personal
50 boolean is_wood[WANDS];
51 const char *press_space = " --press space to continue--";
53 static const char *const wand_materials[WAND_MATERIALS] = {
86 static const char *const gems[GEMS] = {
103 static const char *const syllables[MAXSYLLABLES] = {
150 const char *com_desc;
153 static const struct id_com_s com_id_tab[COMS] = {
154 { '?', "? prints help" },
155 { 'r', "r read scroll" },
156 { '/', "/ identify object" },
157 { 'e', "e eat food" },
159 { 'w', "w wield a weapon" },
161 { 'W', "W wear armor" },
163 { 'T', "T take armor off" },
165 { 'P', "P put on ring" },
166 { 'y', "y up & left" },
167 { 'R', "R remove ring" },
168 { 'u', "u up & right" },
169 { 'd', "d drop object" },
170 { 'b', "b down & left" },
171 { 'c', "c call object" },
172 { 'n', "n down & right" },
173 { '\0', "<SHIFT><dir>: run that way" },
174 { ')', ") print current weapon" },
175 { '\0', "<CTRL><dir>: run till adjacent" },
176 { ']', "] print current armor" },
177 { 'f', "f<dir> fight till death or near death" },
178 { '=', "= print current rings" },
179 { 't', "t<dir> throw something" },
180 { '\001', "^A print Hp-raise average" },
181 { 'm', "m<dir> move onto without picking up" },
182 { 'z', "z<dir> zap a wand in a direction" },
183 { 'o', "o examine/set options" },
184 { '^', "^<dir> identify trap type" },
185 { '\022', "^R redraw screen" },
186 { '&', "& save screen into 'rogue.screen'" },
187 { 's', "s search for trap/secret door" },
188 { '\020', "^P repeat last message" },
189 { '>', "> go down a staircase" },
190 { '\033', "^[ cancel command" },
191 { '<', "< go up a staircase" },
192 { 'S', "S save game" },
193 { '.', ". rest for a turn" },
195 { ',', ", pick something up" },
196 { '!', "! shell escape" },
197 { 'i', "i inventory" },
198 { 'F', "F<dir> fight till either of you dies" },
199 { 'I', "I inventory single item" },
200 { 'v', "v print version number" },
201 { 'q', "q quaff potion" }
204 static boolean get_com_id(int *, short);
205 static boolean pr_com_id(int);
206 static boolean pr_motion_char(int);
209 inventory(const object *pack, unsigned short mask)
212 short i = 0, j, maxlen = 0, n;
213 char descs[MAX_PACK_COUNT+1][DCOLS];
216 obj = pack->next_object;
219 message("your pack is empty", 0);
223 if (obj->what_is & mask) {
225 descs[i][1] = obj->ichar;
226 descs[i][2] = ((obj->what_is & ARMOR) && obj->is_protected)
229 get_desc(obj, descs[i]+4);
230 if ((n = strlen(descs[i])) > maxlen) {
235 obj = obj->next_object;
237 strcpy(descs[i++], press_space);
238 if (maxlen < 27) maxlen = 27;
239 col = DCOLS - (maxlen + 2);
241 for (row = 0; ((row < i) && (row < DROWS)); row++) {
243 for (j = col; j < DCOLS; j++) {
244 descs[row-1][j-col] = mvinch(row, j);
246 descs[row-1][j-col] = 0;
248 mvaddstr(row, col, descs[row]);
257 for (j = 1; ((j < i) && (j < DROWS)); j++) {
258 mvaddstr(j, col, descs[j-1]);
268 while (ch != CANCEL) {
270 message("Character you want help for (* for all):", 0);
278 char save[(((COMS / 2) + (COMS % 2)) + 1)][DCOLS];
279 short rows = (((COMS / 2) + (COMS % 2)) + 1);
280 boolean need_two_screens = FALSE;
283 need_two_screens = 1;
288 for (i = 0; i < rows; i++) {
289 for (j = 0; j < DCOLS; j++) {
290 save[i][j] = mvinch(i, j);
294 for (i = 0; i < rows; i++) {
298 for (i = 0; i < (rows-1); i++) {
300 if (((i + i) < COMS) && ((i+i+k) < COMS)) {
301 mvaddstr(i, 0, com_id_tab[i+i+k].com_desc);
303 if (((i + i + 1) < COMS) && ((i+i+k+1) < COMS)) {
304 mvaddstr(i, (DCOLS/2),
305 com_id_tab[i+i+k+1].com_desc);
309 mvaddstr(rows - 1, 0, need_two_screens ? more : press_space);
313 if (need_two_screens) {
315 need_two_screens = 0;
318 for (i = 0; i < rows; i++) {
320 for (j = 0; j < DCOLS; j++) {
327 if (!pr_com_id(ch)) {
328 if (!pr_motion_char(ch)) {
330 message("unknown character", 0);
344 if (!get_com_id(&i, ch)) {
348 message(com_id_tab[i].com_desc, 0);
353 get_com_id(int *idx, short ch)
357 for (i = 0; i < COMS; i++) {
358 if (com_id_tab[i].com_char == ch) {
367 pr_motion_char(int ch)
385 char until[18], buf[DCOLS];
391 strcpy(until, "until adjascent");
397 sprintf(buf, "run %s %s", com_id_tab[n].com_desc + 8, until);
410 char *t[MAX_ID_TITLE_LEN];
412 for (i = 0; i <= 32; i++) {
413 j = get_rand(0, (POTIONS - 1));
414 k = get_rand(0, (POTIONS - 1));
415 memcpy(t, id_potions[j].title, MAX_ID_TITLE_LEN);
416 memcpy(id_potions[j].title, id_potions[k].title, MAX_ID_TITLE_LEN);
417 memcpy(id_potions[k].title, t, MAX_ID_TITLE_LEN);
422 make_scroll_titles(void)
427 for (i = 0; i < SCROLS; i++) {
428 sylls = get_rand(2, 5);
429 strcpy(id_scrolls[i].title, "'");
431 for (j = 0; j < sylls; j++) {
432 s = get_rand(1, (MAXSYLLABLES-1));
433 strcat(id_scrolls[i].title, syllables[s]);
435 n = strlen(id_scrolls[i].title);
436 strcpy(id_scrolls[i].title+(n-1), "' ");
441 get_desc(const object *obj, char *desc)
443 const char *item_name;
448 if (obj->what_is == AMULET) {
449 strcpy(desc, "the amulet of Yendor ");
452 item_name = name_of(obj);
454 if (obj->what_is == GOLD) {
455 sprintf(desc, "%d pieces of gold", obj->quantity);
459 if (obj->what_is != ARMOR) {
460 if (obj->quantity == 1) {
463 sprintf(desc, "%d ", obj->quantity);
466 if (obj->what_is == FOOD) {
467 if (obj->which_kind == RATION) {
468 if (obj->quantity > 1) {
469 sprintf(desc, "%d rations of ", obj->quantity);
471 strcpy(desc, "some ");
476 strcat(desc, item_name);
479 id_table = get_id_table(obj);
484 if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) {
488 switch(id_table[obj->which_kind].id_status) {
491 switch(obj->what_is) {
493 strcat(desc, item_name);
494 strcat(desc, "entitled: ");
495 strcat(desc, id_table[obj->which_kind].title);
498 strcat(desc, id_table[obj->which_kind].title);
499 strcat(desc, item_name);
503 if (obj->identified ||
504 (id_table[obj->which_kind].id_status == IDENTIFIED)) {
507 if (id_table[obj->which_kind].id_status == CALLED) {
510 strcat(desc, id_table[obj->which_kind].title);
511 strcat(desc, item_name);
514 if (obj->identified) {
517 strcpy(desc, id_table[obj->which_kind].title);
520 if (obj->identified) {
523 strcat(desc, name_of(obj));
528 CALL: switch(obj->what_is) {
533 strcat(desc, item_name);
534 strcat(desc, "called ");
535 strcat(desc, id_table[obj->which_kind].title);
540 ID: switch(obj->what_is) {
543 strcat(desc, item_name);
544 strcat(desc, id_table[obj->which_kind].real);
547 if (wizard || obj->identified) {
548 if ((obj->which_kind == DEXTERITY) ||
549 (obj->which_kind == ADD_STRENGTH)) {
550 sprintf(more_info, "%s%d ", ((obj->class > 0) ? "+" : ""),
552 strcat(desc, more_info);
555 strcat(desc, item_name);
556 strcat(desc, id_table[obj->which_kind].real);
559 strcat(desc, item_name);
560 strcat(desc, id_table[obj->which_kind].real);
561 if (wizard || obj->identified) {
562 sprintf(more_info, "[%d]", obj->class);
563 strcat(desc, more_info);
567 sprintf(desc, "%s%d ", ((obj->d_enchant >= 0) ? "+" : ""),
569 strcat(desc, id_table[obj->which_kind].title);
570 sprintf(more_info, "[%d] ", get_armor_class(obj));
571 strcat(desc, more_info);
574 sprintf(desc+strlen(desc), "%s%d,%s%d ",
575 ((obj->hit_enchant >= 0) ? "+" : ""), obj->hit_enchant,
576 ((obj->d_enchant >= 0) ? "+" : ""), obj->d_enchant);
577 strcat(desc, name_of(obj));
583 if (!strncmp(desc, "a ", 2)) {
584 if (is_vowel(desc[2])) {
585 for (i = strlen(desc) + 1; i > 1; i--) {
591 if (obj->in_use_flags & BEING_WIELDED) {
592 strcat(desc, "in hand");
593 } else if (obj->in_use_flags & BEING_WORN) {
594 strcat(desc, "being worn");
595 } else if (obj->in_use_flags & ON_LEFT_HAND) {
596 strcat(desc, "on left hand");
597 } else if (obj->in_use_flags & ON_RIGHT_HAND) {
598 strcat(desc, "on right hand");
603 get_wand_and_ring_materials(void)
606 boolean used[WAND_MATERIALS];
608 for (i = 0; i < WAND_MATERIALS; i++) {
611 for (i = 0; i < WANDS; i++) {
613 j = get_rand(0, WAND_MATERIALS-1);
616 strcpy(id_wands[i].title, wand_materials[j]);
617 is_wood[i] = (j > MAX_METAL);
619 for (i = 0; i < GEMS; i++) {
622 for (i = 0; i < RINGS; i++) {
624 j = get_rand(0, GEMS-1);
627 strcpy(id_rings[i].title, gems[j]);
632 single_inv(short ichar)
638 ch = ichar ? ichar : pack_letter("inventory what?", ALL_OBJECTS);
643 if (!(obj = get_letter_object(ch))) {
644 message("no such item.", 0);
648 desc[1] = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')';
651 get_desc(obj, desc+3);
656 get_id_table(const object *obj)
658 switch(obj->what_is) {
676 inv_armor_weapon(boolean is_weapon)
680 single_inv(rogue.weapon->ichar);
682 message("not wielding anything", 0);
686 single_inv(rogue.armor->ichar);
688 message("not wearing anything", 0);
700 message("what do you want identified?", 0);
704 if ((ch >= 'A') && (ch <= 'Z')) {
705 id = m_names[ch-'A'];
706 } else if (ch < 32) {
725 id = "wall of a room";
746 id = "wand or staff";
761 id = "the Amulet of Yendor";
764 id = "unknown character";
769 sprintf(buf, "'%c': %s", ch, id);