]> git.cameronkatri.com Git - bsdgames-darwin.git/blobdiff - rogue/inventory.c
no longer need -Wno-error=implicit-fallthrough. don't provide common symbols that...
[bsdgames-darwin.git] / rogue / inventory.c
index cc06eeb8fd3ec99c78162dcbfc30bc83a9eed5e5..934e8aa3f5fd4fa011af791686121336d4c744fb 100644 (file)
@@ -1,6 +1,8 @@
+/*     $NetBSD: inventory.c,v 1.15 2011/08/26 06:18:17 dholland Exp $  */
+
 /*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1988, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Timothy C. Stoehr.
  * 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
+ * 3. 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.
  *
  * SUCH DAMAGE.
  */
 
+#include <sys/cdefs.h>
 #ifndef lint
-static char sccsid[] = "@(#)inventory.c        5.4 (Berkeley) 6/1/90";
+#if 0
+static char sccsid[] = "@(#)inventory.c        8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: inventory.c,v 1.15 2011/08/26 06:18:17 dholland Exp $");
+#endif
 #endif /* not lint */
 
 /*
@@ -50,12 +53,13 @@ static char sccsid[] = "@(#)inventory.c     5.4 (Berkeley) 6/1/90";
  *
  */
 
+#include <stdarg.h>
 #include "rogue.h"
 
 boolean is_wood[WANDS];
-char *press_space = " --press space to continue--";
+const char *press_space = " --press space to continue--";
 
-char *wand_materials[WAND_MATERIALS] = {
+static const char *const wand_materials[WAND_MATERIALS] = {
        "steel ",
        "bronze ",
        "gold ",
@@ -89,7 +93,7 @@ char *wand_materials[WAND_MATERIALS] = {
        "wooden "
 };
 
-char *gems[GEMS] = {
+static const char *const gems[GEMS] = {
        "diamond ",
        "stibotantalite ",
        "lapi-lazuli ",
@@ -106,7 +110,7 @@ char *gems[GEMS] = {
        "garnet "
 };
 
-char *syllables[MAXSYLLABLES] = {
+static const char *const syllables[MAXSYLLABLES] = {
        "blech ",
        "foo ",
        "barf ",
@@ -153,105 +157,118 @@ char *syllables[MAXSYLLABLES] = {
 
 struct id_com_s {
        short com_char;
-       char *com_desc;
+       const 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"
+static const 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"},
+       {'\0',  "<SHIFT><dir>: run that way"},
+       {')',   ")       print current weapon"},
+       {'\0',  "<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;
+static int get_com_id(int *, short);
+static int pr_com_id(int);
+static int pr_motion_char(int);
 
-inventory(pack, mask)
-object *pack;
-unsigned short mask;
+void
+inventory(const object *pack, unsigned short mask)
 {
        object *obj;
-       short i = 0, j, maxlen = 0, n;
-       char descs[MAX_PACK_COUNT+1][DCOLS];
+       short i = 0, j;
+       size_t maxlen = 0, n;
        short row, col;
 
+       struct {
+               short letter;
+               short sepchar;
+               char desc[DCOLS];
+               char savebuf[DCOLS+8];
+       } descs[MAX_PACK_COUNT+1];
+
+
        obj = pack->next_object;
 
        if (!obj) {
-               message("your pack is empty", 0);
+               messagef(0, "your pack is empty");
                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].letter = obj->ichar;
+                       descs[i].sepchar = ((obj->what_is & ARMOR) && obj->is_protected)
                                ? '}' : ')';
-                       descs[i][3] = ' ';
-                       get_desc(obj, descs[i]+4);
-                       if ((n = strlen(descs[i])) > maxlen) {
+                       get_desc(obj, descs[i].desc, sizeof(descs[i].desc));
+                       n = strlen(descs[i].desc) + 4;
+                       if (n > maxlen) {
                                maxlen = n;
                        }
-               i++;
+                       i++;
+                       /*assert(i<=MAX_PACK_COUNT);*/
                }
                obj = obj->next_object;
        }
-       (void) strcpy(descs[i++], press_space);
        if (maxlen < 27) maxlen = 27;
+       if (maxlen > DCOLS-2) maxlen = DCOLS-2;
        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;
+       for (row = 0; ((row <= i) && (row < DROWS)); row++) {
+               for (j = col; j < DCOLS; j++) {
+                       descs[row].savebuf[j-col] = mvinch(row, j);
+               }
+               descs[row].savebuf[j-col] = 0;
+               if (row < i) {
+                       mvprintw(row, col, " %c%c %s",
+                               descs[row].letter, descs[row].sepchar,
+                               descs[row].desc);
+               }
+               else {
+                       mvaddstr(row, col, press_space);
                }
-               mvaddstr(row, col, descs[row]);
                clrtoeol();
        }
        refresh();
@@ -260,19 +277,20 @@ unsigned short mask;
        move(0, 0);
        clrtoeol();
 
-       for (j = 1; ((j < i) && (j < DROWS)); j++) {
-               mvaddstr(j, col, descs[j-1]);
+       for (j = 1; ((j <= i) && (j < DROWS)); j++) {
+               mvaddstr(j, col, descs[j].savebuf);
        }
 }
 
-id_com()
+void
+id_com(void)
 {
        int ch = 0;
        short i, j, k;
 
        while (ch != CANCEL) {
                check_message();
-               message("Character you want help for (* for all):", 0);
+               messagef(0, "Character you want help for (* for all):");
 
                refresh();
                ch = getchar();
@@ -282,7 +300,7 @@ id_com()
                        {
                                char save[(((COMS / 2) + (COMS % 2)) + 1)][DCOLS];
                                short rows = (((COMS / 2) + (COMS % 2)) + 1);
-                               boolean need_two_screens;
+                               boolean need_two_screens = FALSE;
 
                                if (rows > LINES) {
                                        need_two_screens = 1;
@@ -332,7 +350,7 @@ MORE:
                        if (!pr_com_id(ch)) {
                                if (!pr_motion_char(ch)) {
                                        check_message();
-                                       message("unknown character", 0);
+                                       messagef(0, "unknown character");
                                }
                        }
                        ch = CANCEL;
@@ -341,8 +359,8 @@ MORE:
        }
 }
 
-pr_com_id(ch)
-int ch;
+static int
+pr_com_id(int ch)
 {
        int i;
 
@@ -350,27 +368,26 @@ int ch;
                return(0);
        }
        check_message();
-       message(com_id_tab[i].com_desc, 0);
+       messagef(0, "%s", com_id_tab[i].com_desc);
        return(1);
 }
 
-get_com_id(index, ch)
-int *index;
-short ch;
+static int
+get_com_id(int *indexp, short ch)
 {
        short i;
 
        for (i = 0; i < COMS; i++) {
                if (com_id_tab[i].com_char == ch) {
-                       *index = i;
+                       *indexp = i;
                        return(1);
                }
        }
        return(0);
 }
 
-pr_motion_char(ch)
-int ch;
+static int
+pr_motion_char(int ch)
 {
        if (    (ch == 'J') ||
                        (ch == 'K') ||
@@ -388,222 +405,275 @@ int ch;
                        (ch == '\031') ||
                        (ch == '\016') ||
                        (ch == '\002')) {
-               char until[18], buf[DCOLS];
-               int n;
-
+               const char *until;
+               int n = 0;      /* XXX: GCC */
                if (ch <= '\031') {
                        ch += 96;
-                       (void) strcpy(until, "until adjascent");
+                       until = " until adjacent";
                } else {
                        ch += 32;
-                       until[0] = '\0';
+                       until = "";
                }
-               (void) get_com_id(&n, ch);
-               sprintf(buf, "run %s %s", com_id_tab[n].com_desc + 8, until);
+               (void)get_com_id(&n, ch);
                check_message();
-               message(buf, 0);
+               messagef(0, "run %s%s", com_id_tab[n].com_desc + 8, until);
                return(1);
        } else {
                return(0);
        }
 }
 
-mix_colors()
+void
+mix_colors(void)
 {
        short i, j, k;
-       char *t;
+       char t[MAX_ID_TITLE_LEN];
 
        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;
+               strlcpy(t, id_potions[j].title, sizeof(t));
+               strlcpy(id_potions[j].title, id_potions[k].title,
+                       sizeof(id_potions[j].title));
+               strlcpy(id_potions[k].title, t, sizeof(id_potions[k].title));
        }
 }
 
-make_scroll_titles()
+void
+make_scroll_titles(void)
 {
        short i, j, n;
        short sylls, s;
+       size_t maxlen = sizeof(id_scrolls[0].title);
 
        for (i = 0; i < SCROLS; i++) {
                sylls = get_rand(2, 5);
-               (void) strcpy(id_scrolls[i].title, "'");
+               (void)strlcpy(id_scrolls[i].title, "'", maxlen);
 
                for (j = 0; j < sylls; j++) {
                        s = get_rand(1, (MAXSYLLABLES-1));
-                       (void) strcat(id_scrolls[i].title, syllables[s]);
+                       (void)strlcat(id_scrolls[i].title, syllables[s],
+                                       maxlen);
                }
+               /* trim trailing space */
                n = strlen(id_scrolls[i].title);
-               (void) strcpy(id_scrolls[i].title+(n-1), "' ");
+               id_scrolls[i].title[n-1] = 0;
+
+               (void)strlcat(id_scrolls[i].title, "' ", maxlen);
        }
 }
 
-get_desc(obj, desc)
-object *obj;
-char *desc;
+struct sbuf {
+       char *buf;
+       size_t maxlen;
+};
+
+static void sbuf_init(struct sbuf *s, char *buf, size_t maxlen);
+static void sbuf_addstr(struct sbuf *s, const char *str);
+static void sbuf_addf(struct sbuf *s, const char *fmt, ...) __printflike(2,3);
+static void desc_count(struct sbuf *s, int n);
+static void desc_called(struct sbuf *s, const object *);
+
+static
+void
+sbuf_init(struct sbuf *s, char *buf, size_t maxlen)
+{
+       s->buf = buf;
+       s->maxlen = maxlen;
+       /*assert(maxlen>0);*/
+       s->buf[0] = 0;
+}
+
+static
+void
+sbuf_addstr(struct sbuf *s, const char *str)
+{
+       strlcat(s->buf, str, s->maxlen);
+}
+
+static
+void
+sbuf_addf(struct sbuf *s, const char *fmt, ...)
+{
+       va_list ap;
+       size_t initlen;
+
+       initlen = strlen(s->buf);
+       va_start(ap, fmt);
+       vsnprintf(s->buf+initlen, s->maxlen-initlen, fmt, ap);
+       va_end(ap);
+}
+
+static
+void
+desc_count(struct sbuf *s, int n)
+{
+       if (n == 1) {
+               sbuf_addstr(s, "an ");
+       } else {
+               sbuf_addf(s, "%d ", n);
+       }
+}
+
+static
+void
+desc_called(struct sbuf *s, const object *obj)
 {
-       char *item_name;
        struct id *id_table;
-       char more_info[32];
-       short i;
+
+       id_table = get_id_table(obj);
+       sbuf_addstr(s, name_of(obj));
+       sbuf_addstr(s, "called ");
+       sbuf_addstr(s, id_table[obj->which_kind].title);
+}
+
+void
+get_desc(const object *obj, char *desc, size_t desclen)
+{
+       const char *item_name;
+       struct id *id_table;
+       struct sbuf db;
+       unsigned short objtype_id_status;
 
        if (obj->what_is == AMULET) {
-               (void) strcpy(desc, "the amulet of Yendor ");
+               (void)strlcpy(desc, "the amulet of Yendor ", desclen);
                return;
        }
-       item_name = name_of(obj);
 
        if (obj->what_is == GOLD) {
-               sprintf(desc, "%d pieces of gold", obj->quantity);
+               snprintf(desc, desclen, "%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);
+       item_name = name_of(obj);
+       id_table = get_id_table(obj);
+       if (wizard || id_table == NULL) {
+               objtype_id_status = IDENTIFIED;
+       }
+       else {
+               objtype_id_status = id_table[obj->which_kind].id_status;
+       }
+       if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) {
+               if (obj->identified) {
+                       objtype_id_status = IDENTIFIED;
                }
        }
-       if (obj->what_is == FOOD) {
+
+       sbuf_init(&db, desc, desclen);
+
+       switch (obj->what_is) {
+       case FOOD:
                if (obj->which_kind == RATION) {
                        if (obj->quantity > 1) {
-                               sprintf(desc, "%d rations of ", obj->quantity);
+                               sbuf_addf(&db,
+                                        "%d rations of %s", obj->quantity,
+                                        item_name);
                        } else {
-                               (void) strcpy(desc, "some ");
+                               sbuf_addf(&db, "some %s", item_name);
                        }
                } else {
-                       (void) strcpy(desc, "a ");
+                       sbuf_addf(&db, "an %s", item_name);
                }
-               (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 SCROL:
+               desc_count(&db, obj->quantity);
+               if (objtype_id_status==UNIDENTIFIED) {
+                       sbuf_addstr(&db, item_name);
+                       sbuf_addstr(&db, "entitled: ");
+                       sbuf_addstr(&db, id_table[obj->which_kind].title);
+               } else if (objtype_id_status==CALLED) {
+                       desc_called(&db, obj);
+               } else {
+                       sbuf_addstr(&db, item_name);
+                       sbuf_addstr(&db, id_table[obj->which_kind].real);
                }
                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;
+       case POTION:
+               desc_count(&db, obj->quantity);
+               if (objtype_id_status==UNIDENTIFIED) {
+                       sbuf_addstr(&db, id_table[obj->which_kind].title);
+                       sbuf_addstr(&db, item_name);
+               } else if (objtype_id_status==CALLED) {
+                       desc_called(&db, obj);
+               } else {
+                       sbuf_addstr(&db, item_name);
+                       sbuf_addstr(&db, id_table[obj->which_kind].real);
                }
                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);
+       case WAND:
+               desc_count(&db, obj->quantity);
+               if (objtype_id_status==UNIDENTIFIED) {
+                       sbuf_addstr(&db, id_table[obj->which_kind].title);
+                       sbuf_addstr(&db, item_name);
+               } else if (objtype_id_status==CALLED) {
+                       desc_called(&db, obj);
+               } else {
+                       sbuf_addstr(&db, item_name);
+                       sbuf_addstr(&db, id_table[obj->which_kind].real);
                        if (wizard || obj->identified) {
-                               sprintf(more_info, "[%d]", obj->class);
-                               (void) strcat(desc, more_info);
+                               sbuf_addf(&db, "[%d]", obj->class);
                        }
-                       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];
+       case RING:
+               desc_count(&db, obj->quantity);
+               if (objtype_id_status==UNIDENTIFIED) {
+                       sbuf_addstr(&db, id_table[obj->which_kind].title);
+                       sbuf_addstr(&db, item_name);
+               } else if (objtype_id_status==CALLED) {
+                       desc_called(&db, obj);
+               } else {
+                       if ((wizard || obj->identified) &&
+                           (obj->which_kind == DEXTERITY ||
+                            obj->which_kind == ADD_STRENGTH)) {
+                               sbuf_addf(&db, "%+d ", obj->class);
                        }
-                       desc[1] = 'n';
+                       sbuf_addstr(&db, item_name);
+                       sbuf_addstr(&db, id_table[obj->which_kind].real);
+               }
+               break;
+       case ARMOR:
+               /* no desc_count() */
+               if (objtype_id_status==UNIDENTIFIED) {
+                       sbuf_addstr(&db, id_table[obj->which_kind].title);
+               } else {
+                       sbuf_addf(&db, "%+d %s[%d] ", obj->d_enchant,
+                               id_table[obj->which_kind].title,
+                               get_armor_class(obj));
+               }
+               break;
+       case WEAPON:
+               desc_count(&db, obj->quantity);
+               if (objtype_id_status==UNIDENTIFIED) {
+                       sbuf_addstr(&db, name_of(obj));
+               } else {
+                       sbuf_addf(&db, "%+d,%+d %s",
+                               obj->hit_enchant, obj->d_enchant,
+                               name_of(obj));
                }
+               break;
        }
+
        if (obj->in_use_flags & BEING_WIELDED) {
-               (void) strcat(desc, "in hand");
+               sbuf_addstr(&db, "in hand");
        } else if (obj->in_use_flags & BEING_WORN) {
-               (void) strcat(desc, "being worn");
+               sbuf_addstr(&db, "being worn");
        } else if (obj->in_use_flags & ON_LEFT_HAND) {
-               (void) strcat(desc, "on left hand");
+               sbuf_addstr(&db, "on left hand");
        } else if (obj->in_use_flags & ON_RIGHT_HAND) {
-               (void) strcat(desc, "on right hand");
+               sbuf_addstr(&db, "on right hand");
+       }
+
+       if (!strncmp(db.buf, "an ", 3)) {
+               if (!is_vowel(db.buf[3])) {
+                       memmove(db.buf+2, db.buf+3, strlen(db.buf+3)+1);
+                       db.buf[1] = ' ';
+               }
        }
 }
 
-get_wand_and_ring_materials()
+void
+get_wand_and_ring_materials(void)
 {
        short i, j;
        boolean used[WAND_MATERIALS];
@@ -616,7 +686,8 @@ get_wand_and_ring_materials()
                        j = get_rand(0, WAND_MATERIALS-1);
                } while (used[j]);
                used[j] = 1;
-               (void) strcpy(id_wands[i].title, wand_materials[j]);
+               (void)strlcpy(id_wands[i].title, wand_materials[j],
+                              sizeof(id_wands[i].title));
                is_wood[i] = (j > MAX_METAL);
        }
        for (i = 0; i < GEMS; i++) {
@@ -627,14 +698,15 @@ get_wand_and_ring_materials()
                        j = get_rand(0, GEMS-1);
                } while (used[j]);
                used[j] = 1;
-               (void) strcpy(id_rings[i].title, gems[j]);
+               (void)strlcpy(id_rings[i].title, gems[j],
+                              sizeof(id_rings[i].title));
        }
 }
 
-single_inv(ichar)
-short ichar;
+void
+single_inv(short ichar)
 {
-       short ch;
+       short ch, ch2;
        char desc[DCOLS];
        object *obj;
 
@@ -644,20 +716,16 @@ short ichar;
                return;
        }
        if (!(obj = get_letter_object(ch))) {
-               message("no such item.", 0);
+               messagef(0, "no such item.");
                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);
+       ch2 = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')';
+       get_desc(obj, desc, sizeof(desc));
+       messagef(0, "%c%c %s", ch, ch2, desc);
 }
 
 struct id *
-get_id_table(obj)
-object *obj;
+get_id_table(const object *obj)
 {
        switch(obj->what_is) {
        case SCROL:
@@ -673,34 +741,34 @@ object *obj;
        case ARMOR:
                return(id_armors);
        }
-       return((struct id *) 0);
+       return((struct id *)0);
 }
 
-inv_armor_weapon(is_weapon)
-boolean is_weapon;
+void
+inv_armor_weapon(boolean is_weapon)
 {
        if (is_weapon) {
                if (rogue.weapon) {
                        single_inv(rogue.weapon->ichar);
                } else {
-                       message("not wielding anything", 0);
+                       messagef(0, "not wielding anything");
                }
        } else {
                if (rogue.armor) {
                        single_inv(rogue.armor->ichar);
                } else {
-                       message("not wearing anything", 0);
+                       messagef(0, "not wearing anything");
                }
        }
 }
 
-id_type()
+void
+id_type(void)
 {
-       char *id;
+       const char *id;
        int ch;
-       char buf[DCOLS];
 
-       message("what do you want identified?", 0);
+       messagef(0, "what do you want identified?");
 
        ch = rgetchar();
 
@@ -769,6 +837,5 @@ id_type()
                }
        }
        check_message();
-       sprintf(buf, "'%c': %s", ch, id);
-       message(buf, 0);
+       messagef(0, "'%c': %s", ch, id);
 }