]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - rogue/inventory.c
1 /* $NetBSD: inventory.c,v 1.13 2008/01/14 03:50:01 dholland Exp $ */
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
38 static char sccsid
[] = "@(#)inventory.c 8.1 (Berkeley) 5/31/93";
40 __RCSID("$NetBSD: inventory.c,v 1.13 2008/01/14 03:50:01 dholland Exp $");
47 * This source herein may be modified and/or distributed by anybody who
48 * so desires, with the following restrictions:
49 * 1.) No portion of this notice shall be removed.
50 * 2.) Credit shall not be taken for the creation of this source.
51 * 3.) This code is not to be traded, sold, or used for personal
59 boolean is_wood
[WANDS
];
60 const char *press_space
= " --press space to continue--";
62 static const char *const wand_materials
[WAND_MATERIALS
] = {
96 static const char *const gems
[GEMS
] = {
113 static const char *const syllables
[MAXSYLLABLES
] = {
160 const char *com_desc
;
163 static const struct id_com_s com_id_tab
[COMS
] = {
164 {'?', "? prints help"},
165 {'r', "r read scroll"},
166 {'/', "/ identify object"},
169 {'w', "w wield a weapon"},
171 {'W', "W wear armor"},
173 {'T', "T take armor off"},
175 {'P', "P put on ring"},
176 {'y', "y up & left"},
177 {'R', "R remove ring"},
178 {'u', "u up & right"},
179 {'d', "d drop object"},
180 {'b', "b down & left"},
181 {'c', "c call object"},
182 {'n', "n down & right"},
183 {'\0', "<SHIFT><dir>: run that way"},
184 {')', ") print current weapon"},
185 {'\0', "<CTRL><dir>: run till adjacent"},
186 {']', "] print current armor"},
187 {'f', "f<dir> fight till death or near death"},
188 {'=', "= print current rings"},
189 {'t', "t<dir> throw something"},
190 {'\001', "^A print Hp-raise average"},
191 {'m', "m<dir> move onto without picking up"},
192 {'z', "z<dir> zap a wand in a direction"},
193 {'o', "o examine/set options"},
194 {'^', "^<dir> identify trap type"},
195 {'\022', "^R redraw screen"},
196 {'&', "& save screen into 'rogue.screen'"},
197 {'s', "s search for trap/secret door"},
198 {'\020', "^P repeat last message"},
199 {'>', "> go down a staircase"},
200 {'\033', "^[ cancel command"},
201 {'<', "< go up a staircase"},
202 {'S', "S save game"},
203 {'.', ". rest for a turn"},
205 {',', ", pick something up"},
206 {'!', "! shell escape"},
207 {'i', "i inventory"},
208 {'F', "F<dir> fight till either of you dies"},
209 {'I', "I inventory single item"},
210 {'v', "v print version number"},
211 {'q', "q quaff potion" }
215 inventory(const object
*pack
, unsigned short mask
)
219 size_t maxlen
= 0, n
;
226 char savebuf
[DCOLS
+8];
227 } descs
[MAX_PACK_COUNT
+1];
230 obj
= pack
->next_object
;
233 messagef(0, "your pack is empty");
237 if (obj
->what_is
& mask
) {
238 descs
[i
].letter
= obj
->ichar
;
239 descs
[i
].sepchar
= ((obj
->what_is
& ARMOR
) && obj
->is_protected
)
241 get_desc(obj
, descs
[i
].desc
, sizeof(descs
[i
].desc
));
242 n
= strlen(descs
[i
].desc
) + 4;
247 /*assert(i<=MAX_PACK_COUNT);*/
249 obj
= obj
->next_object
;
251 if (maxlen
< 27) maxlen
= 27;
252 if (maxlen
> DCOLS
-2) maxlen
= DCOLS
-2;
253 col
= DCOLS
- (maxlen
+ 2);
255 for (row
= 0; ((row
<= i
) && (row
< DROWS
)); row
++) {
256 for (j
= col
; j
< DCOLS
; j
++) {
257 descs
[row
].savebuf
[j
-col
] = mvinch(row
, j
);
259 descs
[row
].savebuf
[j
-col
] = 0;
261 mvprintw(row
, col
, " %c%c %s",
262 descs
[row
].letter
, descs
[row
].sepchar
,
266 mvaddstr(row
, col
, press_space
);
276 for (j
= 1; ((j
<= i
) && (j
< DROWS
)); j
++) {
277 mvaddstr(j
, col
, descs
[j
].savebuf
);
287 while (ch
!= CANCEL
) {
289 messagef(0, "Character you want help for (* for all):");
297 char save
[(((COMS
/ 2) + (COMS
% 2)) + 1)][DCOLS
];
298 short rows
= (((COMS
/ 2) + (COMS
% 2)) + 1);
299 boolean need_two_screens
= FALSE
;
302 need_two_screens
= 1;
307 for (i
= 0; i
< rows
; i
++) {
308 for (j
= 0; j
< DCOLS
; j
++) {
309 save
[i
][j
] = mvinch(i
, j
);
313 for (i
= 0; i
< rows
; i
++) {
317 for (i
= 0; i
< (rows
-1); i
++) {
319 if (((i
+ i
) < COMS
) && ((i
+i
+k
) < COMS
)) {
320 mvaddstr(i
, 0, com_id_tab
[i
+i
+k
].com_desc
);
322 if (((i
+ i
+ 1) < COMS
) && ((i
+i
+k
+1) < COMS
)) {
323 mvaddstr(i
, (DCOLS
/2),
324 com_id_tab
[i
+i
+k
+1].com_desc
);
328 mvaddstr(rows
- 1, 0, need_two_screens
? more
: press_space
);
332 if (need_two_screens
) {
334 need_two_screens
= 0;
337 for (i
= 0; i
< rows
; i
++) {
339 for (j
= 0; j
< DCOLS
; j
++) {
346 if (!pr_com_id(ch
)) {
347 if (!pr_motion_char(ch
)) {
349 messagef(0, "unknown character");
363 if (!get_com_id(&i
, ch
)) {
367 messagef(0, "%s", com_id_tab
[i
].com_desc
);
372 get_com_id(int *indexp
, short ch
)
376 for (i
= 0; i
< COMS
; i
++) {
377 if (com_id_tab
[i
].com_char
== ch
) {
386 pr_motion_char(int ch
)
405 int n
= 0; /* XXX: GCC */
408 until
= " until adjacent";
413 (void)get_com_id(&n
, ch
);
415 messagef(0, "run %s%s", com_id_tab
[n
].com_desc
+ 8, until
);
426 char t
[MAX_ID_TITLE_LEN
];
428 for (i
= 0; i
<= 32; i
++) {
429 j
= get_rand(0, (POTIONS
- 1));
430 k
= get_rand(0, (POTIONS
- 1));
431 strlcpy(t
, id_potions
[j
].title
, sizeof(t
));
432 strlcpy(id_potions
[j
].title
, id_potions
[k
].title
,
433 sizeof(id_potions
[j
].title
));
434 strlcpy(id_potions
[k
].title
, t
, sizeof(id_potions
[k
].title
));
439 make_scroll_titles(void)
443 size_t maxlen
= sizeof(id_scrolls
[0].title
);
445 for (i
= 0; i
< SCROLS
; i
++) {
446 sylls
= get_rand(2, 5);
447 (void)strlcpy(id_scrolls
[i
].title
, "'", maxlen
);
449 for (j
= 0; j
< sylls
; j
++) {
450 s
= get_rand(1, (MAXSYLLABLES
-1));
451 (void)strlcat(id_scrolls
[i
].title
, syllables
[s
],
454 /* trim trailing space */
455 n
= strlen(id_scrolls
[i
].title
);
456 id_scrolls
[i
].title
[n
-1] = 0;
458 (void)strlcat(id_scrolls
[i
].title
, "' ", maxlen
);
467 static void sbuf_init(struct sbuf
*s
, char *buf
, size_t maxlen
);
468 static void sbuf_addstr(struct sbuf
*s
, const char *str
);
469 static void sbuf_addf(struct sbuf
*s
, const char *fmt
, ...)
470 __attribute__((__format__(__printf__
, 2, 3)));
471 static void desc_count(struct sbuf
*s
, int n
);
472 static void desc_called(struct sbuf
*s
, const object
*);
476 sbuf_init(struct sbuf
*s
, char *buf
, size_t maxlen
)
480 /*assert(maxlen>0);*/
486 sbuf_addstr(struct sbuf
*s
, const char *str
)
488 strlcat(s
->buf
, str
, s
->maxlen
);
493 sbuf_addf(struct sbuf
*s
, const char *fmt
, ...)
498 initlen
= strlen(s
->buf
);
500 vsnprintf(s
->buf
+initlen
, s
->maxlen
-initlen
, fmt
, ap
);
506 desc_count(struct sbuf
*s
, int n
)
509 sbuf_addstr(s
, "an ");
511 sbuf_addf(s
, "%d ", n
);
517 desc_called(struct sbuf
*s
, const object
*obj
)
521 id_table
= get_id_table(obj
);
522 sbuf_addstr(s
, name_of(obj
));
523 sbuf_addstr(s
, "called ");
524 sbuf_addstr(s
, id_table
[obj
->which_kind
].title
);
528 get_desc(const object
*obj
, char *desc
, size_t desclen
)
530 const char *item_name
;
533 unsigned short objtype_id_status
;
535 if (obj
->what_is
== AMULET
) {
536 (void)strlcpy(desc
, "the amulet of Yendor ", desclen
);
540 if (obj
->what_is
== GOLD
) {
541 snprintf(desc
, desclen
, "%d pieces of gold", obj
->quantity
);
545 item_name
= name_of(obj
);
546 id_table
= get_id_table(obj
);
547 if (wizard
|| id_table
== NULL
) {
548 objtype_id_status
= IDENTIFIED
;
551 objtype_id_status
= id_table
[obj
->which_kind
].id_status
;
553 if (obj
->what_is
& (WEAPON
| ARMOR
| WAND
| RING
)) {
554 if (obj
->identified
) {
555 objtype_id_status
= IDENTIFIED
;
559 sbuf_init(&db
, desc
, desclen
);
561 switch (obj
->what_is
) {
563 if (obj
->which_kind
== RATION
) {
564 if (obj
->quantity
> 1) {
566 "%d rations of %s", obj
->quantity
,
569 sbuf_addf(&db
, "some %s", item_name
);
572 sbuf_addf(&db
, "an %s", item_name
);
576 desc_count(&db
, obj
->quantity
);
577 if (objtype_id_status
==UNIDENTIFIED
) {
578 sbuf_addstr(&db
, item_name
);
579 sbuf_addstr(&db
, "entitled: ");
580 sbuf_addstr(&db
, id_table
[obj
->which_kind
].title
);
581 } else if (objtype_id_status
==CALLED
) {
582 desc_called(&db
, obj
);
584 sbuf_addstr(&db
, item_name
);
585 sbuf_addstr(&db
, id_table
[obj
->which_kind
].real
);
589 desc_count(&db
, obj
->quantity
);
590 if (objtype_id_status
==UNIDENTIFIED
) {
591 sbuf_addstr(&db
, id_table
[obj
->which_kind
].title
);
592 sbuf_addstr(&db
, item_name
);
593 } else if (objtype_id_status
==CALLED
) {
594 desc_called(&db
, obj
);
596 sbuf_addstr(&db
, item_name
);
597 sbuf_addstr(&db
, id_table
[obj
->which_kind
].real
);
601 desc_count(&db
, obj
->quantity
);
602 if (objtype_id_status
==UNIDENTIFIED
) {
603 sbuf_addstr(&db
, id_table
[obj
->which_kind
].title
);
604 sbuf_addstr(&db
, item_name
);
605 } else if (objtype_id_status
==CALLED
) {
606 desc_called(&db
, obj
);
608 sbuf_addstr(&db
, item_name
);
609 sbuf_addstr(&db
, id_table
[obj
->which_kind
].real
);
610 if (wizard
|| obj
->identified
) {
611 sbuf_addf(&db
, "[%d]", obj
->class);
616 desc_count(&db
, obj
->quantity
);
617 if (objtype_id_status
==UNIDENTIFIED
) {
618 sbuf_addstr(&db
, id_table
[obj
->which_kind
].title
);
619 sbuf_addstr(&db
, item_name
);
620 } else if (objtype_id_status
==CALLED
) {
621 desc_called(&db
, obj
);
623 if ((wizard
|| obj
->identified
) &&
624 (obj
->which_kind
== DEXTERITY
||
625 obj
->which_kind
== ADD_STRENGTH
)) {
626 sbuf_addf(&db
, "%+d ", obj
->class);
628 sbuf_addstr(&db
, item_name
);
629 sbuf_addstr(&db
, id_table
[obj
->which_kind
].real
);
633 /* no desc_count() */
634 if (objtype_id_status
==UNIDENTIFIED
) {
635 sbuf_addstr(&db
, id_table
[obj
->which_kind
].title
);
637 sbuf_addf(&db
, "%+d %s[%d] ", obj
->d_enchant
,
638 id_table
[obj
->which_kind
].title
,
639 get_armor_class(obj
));
643 desc_count(&db
, obj
->quantity
);
644 if (objtype_id_status
==UNIDENTIFIED
) {
645 sbuf_addstr(&db
, name_of(obj
));
647 sbuf_addf(&db
, "%+d,%+d %s",
648 obj
->hit_enchant
, obj
->d_enchant
,
654 if (obj
->in_use_flags
& BEING_WIELDED
) {
655 sbuf_addstr(&db
, "in hand");
656 } else if (obj
->in_use_flags
& BEING_WORN
) {
657 sbuf_addstr(&db
, "being worn");
658 } else if (obj
->in_use_flags
& ON_LEFT_HAND
) {
659 sbuf_addstr(&db
, "on left hand");
660 } else if (obj
->in_use_flags
& ON_RIGHT_HAND
) {
661 sbuf_addstr(&db
, "on right hand");
664 if (!strncmp(db
.buf
, "an ", 3)) {
665 if (!is_vowel(db
.buf
[3])) {
666 memmove(db
.buf
+2, db
.buf
+3, strlen(db
.buf
+3)+1);
673 get_wand_and_ring_materials(void)
676 boolean used
[WAND_MATERIALS
];
678 for (i
= 0; i
< WAND_MATERIALS
; i
++) {
681 for (i
= 0; i
< WANDS
; i
++) {
683 j
= get_rand(0, WAND_MATERIALS
-1);
686 (void)strlcpy(id_wands
[i
].title
, wand_materials
[j
],
687 sizeof(id_wands
[i
].title
));
688 is_wood
[i
] = (j
> MAX_METAL
);
690 for (i
= 0; i
< GEMS
; i
++) {
693 for (i
= 0; i
< RINGS
; i
++) {
695 j
= get_rand(0, GEMS
-1);
698 (void)strlcpy(id_rings
[i
].title
, gems
[j
],
699 sizeof(id_rings
[i
].title
));
704 single_inv(short ichar
)
710 ch
= ichar
? ichar
: pack_letter("inventory what?", ALL_OBJECTS
);
715 if (!(obj
= get_letter_object(ch
))) {
716 messagef(0, "no such item.");
719 ch2
= ((obj
->what_is
& ARMOR
) && obj
->is_protected
) ? '}' : ')';
720 get_desc(obj
, desc
, sizeof(desc
));
721 messagef(0, "%c%c %s", ch
, ch2
, desc
);
725 get_id_table(const object
*obj
)
727 switch(obj
->what_is
) {
741 return((struct id
*)0);
745 inv_armor_weapon(boolean is_weapon
)
749 single_inv(rogue
.weapon
->ichar
);
751 messagef(0, "not wielding anything");
755 single_inv(rogue
.armor
->ichar
);
757 messagef(0, "not wearing anything");
768 messagef(0, "what do you want identified?");
772 if ((ch
>= 'A') && (ch
<= 'Z')) {
773 id
= m_names
[ch
-'A'];
774 } else if (ch
< 32) {
793 id
= "wall of a room";
814 id
= "wand or staff";
829 id
= "the Amulet of Yendor";
832 id
= "unknown character";
837 messagef(0, "'%c': %s", ch
, id
);