summaryrefslogtreecommitdiffstats
path: root/rogue/inventory.c
diff options
context:
space:
mode:
Diffstat (limited to 'rogue/inventory.c')
-rw-r--r--rogue/inventory.c774
1 files changed, 774 insertions, 0 deletions
diff --git a/rogue/inventory.c b/rogue/inventory.c
new file mode 100644
index 00000000..cc06eeb8
--- /dev/null
+++ b/rogue/inventory.c
@@ -0,0 +1,774 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)inventory.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * inventory.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#include "rogue.h"
+
+boolean is_wood[WANDS];
+char *press_space = " --press space to continue--";
+
+char *wand_materials[WAND_MATERIALS] = {
+ "steel ",
+ "bronze ",
+ "gold ",
+ "silver ",
+ "copper ",
+ "nickel ",
+ "cobalt ",
+ "tin ",
+ "iron ",
+ "magnesium ",
+ "chrome ",
+ "carbon ",
+ "platinum ",
+ "silicon ",
+ "titanium ",
+
+ "teak ",
+ "oak ",
+ "cherry ",
+ "birch ",
+ "pine ",
+ "cedar ",
+ "redwood ",
+ "balsa ",
+ "ivory ",
+ "walnut ",
+ "maple ",
+ "mahogany ",
+ "elm ",
+ "palm ",
+ "wooden "
+};
+
+char *gems[GEMS] = {
+ "diamond ",
+ "stibotantalite ",
+ "lapi-lazuli ",
+ "ruby ",
+ "emerald ",
+ "sapphire ",
+ "amethyst ",
+ "quartz ",
+ "tiger-eye ",
+ "opal ",
+ "agate ",
+ "turquoise ",
+ "pearl ",
+ "garnet "
+};
+
+char *syllables[MAXSYLLABLES] = {
+ "blech ",
+ "foo ",
+ "barf ",
+ "rech ",
+ "bar ",
+ "blech ",
+ "quo ",
+ "bloto ",
+ "oh ",
+ "caca ",
+ "blorp ",
+ "erp ",
+ "festr ",
+ "rot ",
+ "slie ",
+ "snorf ",
+ "iky ",
+ "yuky ",
+ "ooze ",
+ "ah ",
+ "bahl ",
+ "zep ",
+ "druhl ",
+ "flem ",
+ "behil ",
+ "arek ",
+ "mep ",
+ "zihr ",
+ "grit ",
+ "kona ",
+ "kini ",
+ "ichi ",
+ "tims ",
+ "ogr ",
+ "oo ",
+ "ighr ",
+ "coph ",
+ "swerr ",
+ "mihln ",
+ "poxi "
+};
+
+#define COMS 48
+
+struct id_com_s {
+ short com_char;
+ char *com_desc;
+};
+
+struct id_com_s com_id_tab[COMS] = {
+ '?', "? prints help",
+ 'r', "r read scroll",
+ '/', "/ identify object",
+ 'e', "e eat food",
+ 'h', "h left ",
+ 'w', "w wield a weapon",
+ 'j', "j down",
+ 'W', "W wear armor",
+ 'k', "k up",
+ 'T', "T take armor off",
+ 'l', "l right",
+ 'P', "P put on ring",
+ 'y', "y up & left",
+ 'R', "R remove ring",
+ 'u', "u up & right",
+ 'd', "d drop object",
+ 'b', "b down & left",
+ 'c', "c call object",
+ 'n', "n down & right",
+ NULL, "<SHIFT><dir>: run that way",
+ ')', ") print current weapon",
+ NULL, "<CTRL><dir>: run till adjacent",
+ ']', "] print current armor",
+ 'f', "f<dir> fight till death or near death",
+ '=', "= print current rings",
+ 't', "t<dir> throw something",
+ '\001', "^A print Hp-raise average",
+ 'm', "m<dir> move onto without picking up",
+ 'z', "z<dir> zap a wand in a direction",
+ 'o', "o examine/set options",
+ '^', "^<dir> identify trap type",
+ '\022', "^R redraw screen",
+ '&', "& save screen into 'rogue.screen'",
+ 's', "s search for trap/secret door",
+ '\020', "^P repeat last message",
+ '>', "> go down a staircase",
+ '\033', "^[ cancel command",
+ '<', "< go up a staircase",
+ 'S', "S save game",
+ '.', ". rest for a turn",
+ 'Q', "Q quit",
+ ',', ", pick something up",
+ '!', "! shell escape",
+ 'i', "i inventory",
+ 'F', "F<dir> fight till either of you dies",
+ 'I', "I inventory single item",
+ 'v', "v print version number",
+ 'q', "q quaff potion"
+};
+
+extern boolean wizard;
+extern char *m_names[], *more;
+
+inventory(pack, mask)
+object *pack;
+unsigned short mask;
+{
+ object *obj;
+ short i = 0, j, maxlen = 0, n;
+ char descs[MAX_PACK_COUNT+1][DCOLS];
+ short row, col;
+
+ obj = pack->next_object;
+
+ if (!obj) {
+ message("your pack is empty", 0);
+ return;
+ }
+ while (obj) {
+ if (obj->what_is & mask) {
+ descs[i][0] = ' ';
+ descs[i][1] = obj->ichar;
+ descs[i][2] = ((obj->what_is & ARMOR) && obj->is_protected)
+ ? '}' : ')';
+ descs[i][3] = ' ';
+ get_desc(obj, descs[i]+4);
+ if ((n = strlen(descs[i])) > maxlen) {
+ maxlen = n;
+ }
+ i++;
+ }
+ obj = obj->next_object;
+ }
+ (void) strcpy(descs[i++], press_space);
+ if (maxlen < 27) maxlen = 27;
+ col = DCOLS - (maxlen + 2);
+
+ for (row = 0; ((row < i) && (row < DROWS)); row++) {
+ if (row > 0) {
+ for (j = col; j < DCOLS; j++) {
+ descs[row-1][j-col] = mvinch(row, j);
+ }
+ descs[row-1][j-col] = 0;
+ }
+ mvaddstr(row, col, descs[row]);
+ clrtoeol();
+ }
+ refresh();
+ wait_for_ack();
+
+ move(0, 0);
+ clrtoeol();
+
+ for (j = 1; ((j < i) && (j < DROWS)); j++) {
+ mvaddstr(j, col, descs[j-1]);
+ }
+}
+
+id_com()
+{
+ int ch = 0;
+ short i, j, k;
+
+ while (ch != CANCEL) {
+ check_message();
+ message("Character you want help for (* for all):", 0);
+
+ refresh();
+ ch = getchar();
+
+ switch(ch) {
+ case LIST:
+ {
+ char save[(((COMS / 2) + (COMS % 2)) + 1)][DCOLS];
+ short rows = (((COMS / 2) + (COMS % 2)) + 1);
+ boolean need_two_screens;
+
+ if (rows > LINES) {
+ need_two_screens = 1;
+ rows = LINES;
+ }
+ k = 0;
+
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < DCOLS; j++) {
+ save[i][j] = mvinch(i, j);
+ }
+ }
+MORE:
+ for (i = 0; i < rows; i++) {
+ move(i, 0);
+ clrtoeol();
+ }
+ for (i = 0; i < (rows-1); i++) {
+ if (i < (LINES-1)) {
+ if (((i + i) < COMS) && ((i+i+k) < COMS)) {
+ mvaddstr(i, 0, com_id_tab[i+i+k].com_desc);
+ }
+ if (((i + i + 1) < COMS) && ((i+i+k+1) < COMS)) {
+ mvaddstr(i, (DCOLS/2),
+ com_id_tab[i+i+k+1].com_desc);
+ }
+ }
+ }
+ mvaddstr(rows - 1, 0, need_two_screens ? more : press_space);
+ refresh();
+ wait_for_ack();
+
+ if (need_two_screens) {
+ k += ((rows-1) * 2);
+ need_two_screens = 0;
+ goto MORE;
+ }
+ for (i = 0; i < rows; i++) {
+ move(i, 0);
+ for (j = 0; j < DCOLS; j++) {
+ addch(save[i][j]);
+ }
+ }
+ }
+ break;
+ default:
+ if (!pr_com_id(ch)) {
+ if (!pr_motion_char(ch)) {
+ check_message();
+ message("unknown character", 0);
+ }
+ }
+ ch = CANCEL;
+ break;
+ }
+ }
+}
+
+pr_com_id(ch)
+int ch;
+{
+ int i;
+
+ if (!get_com_id(&i, ch)) {
+ return(0);
+ }
+ check_message();
+ message(com_id_tab[i].com_desc, 0);
+ return(1);
+}
+
+get_com_id(index, ch)
+int *index;
+short ch;
+{
+ short i;
+
+ for (i = 0; i < COMS; i++) {
+ if (com_id_tab[i].com_char == ch) {
+ *index = i;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+pr_motion_char(ch)
+int ch;
+{
+ if ( (ch == 'J') ||
+ (ch == 'K') ||
+ (ch == 'L') ||
+ (ch == 'H') ||
+ (ch == 'Y') ||
+ (ch == 'U') ||
+ (ch == 'N') ||
+ (ch == 'B') ||
+ (ch == '\012') ||
+ (ch == '\013') ||
+ (ch == '\010') ||
+ (ch == '\014') ||
+ (ch == '\025') ||
+ (ch == '\031') ||
+ (ch == '\016') ||
+ (ch == '\002')) {
+ char until[18], buf[DCOLS];
+ int n;
+
+ if (ch <= '\031') {
+ ch += 96;
+ (void) strcpy(until, "until adjascent");
+ } else {
+ ch += 32;
+ until[0] = '\0';
+ }
+ (void) get_com_id(&n, ch);
+ sprintf(buf, "run %s %s", com_id_tab[n].com_desc + 8, until);
+ check_message();
+ message(buf, 0);
+ return(1);
+ } else {
+ return(0);
+ }
+}
+
+mix_colors()
+{
+ short i, j, k;
+ char *t;
+
+ for (i = 0; i <= 32; i++) {
+ j = get_rand(0, (POTIONS - 1));
+ k = get_rand(0, (POTIONS - 1));
+ t = id_potions[j].title;
+ id_potions[j].title = id_potions[k].title;
+ id_potions[k].title = t;
+ }
+}
+
+make_scroll_titles()
+{
+ short i, j, n;
+ short sylls, s;
+
+ for (i = 0; i < SCROLS; i++) {
+ sylls = get_rand(2, 5);
+ (void) strcpy(id_scrolls[i].title, "'");
+
+ for (j = 0; j < sylls; j++) {
+ s = get_rand(1, (MAXSYLLABLES-1));
+ (void) strcat(id_scrolls[i].title, syllables[s]);
+ }
+ n = strlen(id_scrolls[i].title);
+ (void) strcpy(id_scrolls[i].title+(n-1), "' ");
+ }
+}
+
+get_desc(obj, desc)
+object *obj;
+char *desc;
+{
+ char *item_name;
+ struct id *id_table;
+ char more_info[32];
+ short i;
+
+ if (obj->what_is == AMULET) {
+ (void) strcpy(desc, "the amulet of Yendor ");
+ return;
+ }
+ item_name = name_of(obj);
+
+ if (obj->what_is == GOLD) {
+ sprintf(desc, "%d pieces of gold", obj->quantity);
+ return;
+ }
+
+ if (obj->what_is != ARMOR) {
+ if (obj->quantity == 1) {
+ (void) strcpy(desc, "a ");
+ } else {
+ sprintf(desc, "%d ", obj->quantity);
+ }
+ }
+ if (obj->what_is == FOOD) {
+ if (obj->which_kind == RATION) {
+ if (obj->quantity > 1) {
+ sprintf(desc, "%d rations of ", obj->quantity);
+ } else {
+ (void) strcpy(desc, "some ");
+ }
+ } else {
+ (void) strcpy(desc, "a ");
+ }
+ (void) strcat(desc, item_name);
+ goto ANA;
+ }
+ id_table = get_id_table(obj);
+
+ if (wizard) {
+ goto ID;
+ }
+ if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) {
+ goto CHECK;
+ }
+
+ switch(id_table[obj->which_kind].id_status) {
+ case UNIDENTIFIED:
+CHECK:
+ switch(obj->what_is) {
+ case SCROL:
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, "entitled: ");
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ break;
+ case POTION:
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ (void) strcat(desc, item_name);
+ break;
+ case WAND:
+ case RING:
+ if (obj->identified ||
+ (id_table[obj->which_kind].id_status == IDENTIFIED)) {
+ goto ID;
+ }
+ if (id_table[obj->which_kind].id_status == CALLED) {
+ goto CALL;
+ }
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ (void) strcat(desc, item_name);
+ break;
+ case ARMOR:
+ if (obj->identified) {
+ goto ID;
+ }
+ (void) strcpy(desc, id_table[obj->which_kind].title);
+ break;
+ case WEAPON:
+ if (obj->identified) {
+ goto ID;
+ }
+ (void) strcat(desc, name_of(obj));
+ break;
+ }
+ break;
+ case CALLED:
+CALL: switch(obj->what_is) {
+ case SCROL:
+ case POTION:
+ case WAND:
+ case RING:
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, "called ");
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ break;
+ }
+ break;
+ case IDENTIFIED:
+ID: switch(obj->what_is) {
+ case SCROL:
+ case POTION:
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, id_table[obj->which_kind].real);
+ break;
+ case RING:
+ if (wizard || obj->identified) {
+ if ((obj->which_kind == DEXTERITY) ||
+ (obj->which_kind == ADD_STRENGTH)) {
+ sprintf(more_info, "%s%d ", ((obj->class > 0) ? "+" : ""),
+ obj->class);
+ (void) strcat(desc, more_info);
+ }
+ }
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, id_table[obj->which_kind].real);
+ break;
+ case WAND:
+ (void) strcat(desc, item_name);
+ (void) strcat(desc, id_table[obj->which_kind].real);
+ if (wizard || obj->identified) {
+ sprintf(more_info, "[%d]", obj->class);
+ (void) strcat(desc, more_info);
+ }
+ break;
+ case ARMOR:
+ sprintf(desc, "%s%d ", ((obj->d_enchant >= 0) ? "+" : ""),
+ obj->d_enchant);
+ (void) strcat(desc, id_table[obj->which_kind].title);
+ sprintf(more_info, "[%d] ", get_armor_class(obj));
+ (void) strcat(desc, more_info);
+ break;
+ case WEAPON:
+ sprintf(desc+strlen(desc), "%s%d,%s%d ",
+ ((obj->hit_enchant >= 0) ? "+" : ""), obj->hit_enchant,
+ ((obj->d_enchant >= 0) ? "+" : ""), obj->d_enchant);
+ (void) strcat(desc, name_of(obj));
+ break;
+ }
+ break;
+ }
+ANA:
+ if (!strncmp(desc, "a ", 2)) {
+ if (is_vowel(desc[2])) {
+ for (i = strlen(desc) + 1; i > 1; i--) {
+ desc[i] = desc[i-1];
+ }
+ desc[1] = 'n';
+ }
+ }
+ if (obj->in_use_flags & BEING_WIELDED) {
+ (void) strcat(desc, "in hand");
+ } else if (obj->in_use_flags & BEING_WORN) {
+ (void) strcat(desc, "being worn");
+ } else if (obj->in_use_flags & ON_LEFT_HAND) {
+ (void) strcat(desc, "on left hand");
+ } else if (obj->in_use_flags & ON_RIGHT_HAND) {
+ (void) strcat(desc, "on right hand");
+ }
+}
+
+get_wand_and_ring_materials()
+{
+ short i, j;
+ boolean used[WAND_MATERIALS];
+
+ for (i = 0; i < WAND_MATERIALS; i++) {
+ used[i] = 0;
+ }
+ for (i = 0; i < WANDS; i++) {
+ do {
+ j = get_rand(0, WAND_MATERIALS-1);
+ } while (used[j]);
+ used[j] = 1;
+ (void) strcpy(id_wands[i].title, wand_materials[j]);
+ is_wood[i] = (j > MAX_METAL);
+ }
+ for (i = 0; i < GEMS; i++) {
+ used[i] = 0;
+ }
+ for (i = 0; i < RINGS; i++) {
+ do {
+ j = get_rand(0, GEMS-1);
+ } while (used[j]);
+ used[j] = 1;
+ (void) strcpy(id_rings[i].title, gems[j]);
+ }
+}
+
+single_inv(ichar)
+short ichar;
+{
+ short ch;
+ char desc[DCOLS];
+ object *obj;
+
+ ch = ichar ? ichar : pack_letter("inventory what?", ALL_OBJECTS);
+
+ if (ch == CANCEL) {
+ return;
+ }
+ if (!(obj = get_letter_object(ch))) {
+ message("no such item.", 0);
+ return;
+ }
+ desc[0] = ch;
+ desc[1] = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')';
+ desc[2] = ' ';
+ desc[3] = 0;
+ get_desc(obj, desc+3);
+ message(desc, 0);
+}
+
+struct id *
+get_id_table(obj)
+object *obj;
+{
+ switch(obj->what_is) {
+ case SCROL:
+ return(id_scrolls);
+ case POTION:
+ return(id_potions);
+ case WAND:
+ return(id_wands);
+ case RING:
+ return(id_rings);
+ case WEAPON:
+ return(id_weapons);
+ case ARMOR:
+ return(id_armors);
+ }
+ return((struct id *) 0);
+}
+
+inv_armor_weapon(is_weapon)
+boolean is_weapon;
+{
+ if (is_weapon) {
+ if (rogue.weapon) {
+ single_inv(rogue.weapon->ichar);
+ } else {
+ message("not wielding anything", 0);
+ }
+ } else {
+ if (rogue.armor) {
+ single_inv(rogue.armor->ichar);
+ } else {
+ message("not wearing anything", 0);
+ }
+ }
+}
+
+id_type()
+{
+ char *id;
+ int ch;
+ char buf[DCOLS];
+
+ message("what do you want identified?", 0);
+
+ ch = rgetchar();
+
+ if ((ch >= 'A') && (ch <= 'Z')) {
+ id = m_names[ch-'A'];
+ } else if (ch < 32) {
+ check_message();
+ return;
+ } else {
+ switch(ch) {
+ case '@':
+ id = "you";
+ break;
+ case '%':
+ id = "staircase";
+ break;
+ case '^':
+ id = "trap";
+ break;
+ case '+':
+ id = "door";
+ break;
+ case '-':
+ case '|':
+ id = "wall of a room";
+ break;
+ case '.':
+ id = "floor";
+ break;
+ case '#':
+ id = "passage";
+ break;
+ case ' ':
+ id = "solid rock";
+ break;
+ case '=':
+ id = "ring";
+ break;
+ case '?':
+ id = "scroll";
+ break;
+ case '!':
+ id = "potion";
+ break;
+ case '/':
+ id = "wand or staff";
+ break;
+ case ')':
+ id = "weapon";
+ break;
+ case ']':
+ id = "armor";
+ break;
+ case '*':
+ id = "gold";
+ break;
+ case ':':
+ id = "food";
+ break;
+ case ',':
+ id = "the Amulet of Yendor";
+ break;
+ default:
+ id = "unknown character";
+ break;
+ }
+ }
+ check_message();
+ sprintf(buf, "'%c': %s", ch, id);
+ message(buf, 0);
+}