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 $
34 * $DragonFly: src/games/rogue/inventory.c,v 1.4 2006/09/02 19:31:07 pavalos Exp $
40 * This source herein may be modified and/or distributed by anybody who
41 * so desires, with the following restrictions:
42 * 1.) No portion of this notice shall be removed.
43 * 2.) Credit shall not be taken for the creation of this source.
44 * 3.) This code is not to be traded, sold, or used for personal
51 static boolean
pr_com_id(int);
52 static boolean
get_com_id(int *, short);
53 static boolean
pr_motion_char(int);
55 boolean is_wood
[WANDS
];
56 const char *press_space
= " --press space to continue--";
58 const char *const wand_materials
[WAND_MATERIALS
] = {
91 const char *const gems
[GEMS
] = {
108 const char *const syllables
[MAXSYLLABLES
] = {
155 const char *com_desc
;
158 const struct id_com_s com_id_tab
[COMS
] = {
159 { '?', "? prints help" },
160 { 'r', "r read scroll" },
161 { '/', "/ identify object" },
162 { 'e', "e eat food" },
164 { 'w', "w wield a weapon" },
166 { 'W', "W wear armor" },
168 { 'T', "T take armor off" },
170 { 'P', "P put on ring" },
171 { 'y', "y up & left" },
172 { 'R', "R remove ring" },
173 { 'u', "u up & right" },
174 { 'd', "d drop object" },
175 { 'b', "b down & left" },
176 { 'c', "c call object" },
177 { 'n', "n down & right" },
178 { '\0', "<SHIFT><dir>: run that way" },
179 { ')', ") print current weapon" },
180 { '\0', "<CTRL><dir>: run till adjacent" },
181 { ']', "] print current armor" },
182 { 'f', "f<dir> fight till death or near death" },
183 { '=', "= print current rings" },
184 { 't', "t<dir> throw something" },
185 { '\001', "^A print Hp-raise average" },
186 { 'm', "m<dir> move onto without picking up" },
187 { 'z', "z<dir> zap a wand in a direction" },
188 { 'o', "o examine/set options" },
189 { '^', "^<dir> identify trap type" },
190 { '\022', "^R redraw screen" },
191 { '&', "& save screen into 'rogue.screen'" },
192 { 's', "s search for trap/secret door" },
193 { '\020', "^P repeat last message" },
194 { '>', "> go down a staircase" },
195 { '\033', "^[ cancel command" },
196 { '<', "< go up a staircase" },
197 { 'S', "S save game" },
198 { '.', ". rest for a turn" },
200 { ',', ", pick something up" },
201 { '!', "! shell escape" },
202 { 'i', "i inventory" },
203 { 'F', "F<dir> fight till either of you dies" },
204 { 'I', "I inventory single item" },
205 { 'v', "v print version number" },
206 { 'q', "q quaff potion" }
209 extern boolean wizard
;
210 extern char *m_names
[], *more
;
213 inventory(const object
*pack
, unsigned short mask
)
216 short i
= 0, j
, maxlen
= 0, n
;
217 char descs
[MAX_PACK_COUNT
+1][DCOLS
];
220 obj
= pack
->next_object
;
223 message("your pack is empty", 0);
227 if (obj
->what_is
& mask
) {
229 descs
[i
][1] = obj
->ichar
;
230 descs
[i
][2] = ((obj
->what_is
& ARMOR
) && obj
->is_protected
)
233 get_desc(obj
, descs
[i
]+4);
234 if ((n
= strlen(descs
[i
])) > maxlen
) {
239 obj
= obj
->next_object
;
241 strcpy(descs
[i
++], press_space
);
242 if (maxlen
< 27) maxlen
= 27;
243 col
= DCOLS
- (maxlen
+ 2);
245 for (row
= 0; ((row
< i
) && (row
< DROWS
)); row
++) {
247 for (j
= col
; j
< DCOLS
; j
++) {
248 descs
[row
-1][j
-col
] = mvinch(row
, j
);
250 descs
[row
-1][j
-col
] = 0;
252 mvaddstr(row
, col
, descs
[row
]);
261 for (j
= 1; ((j
< i
) && (j
< DROWS
)); j
++) {
262 mvaddstr(j
, col
, descs
[j
-1]);
272 while (ch
!= CANCEL
) {
274 message("Character you want help for (* for all):", 0);
282 char save
[(((COMS
/ 2) + (COMS
% 2)) + 1)][DCOLS
];
283 short rows
= (((COMS
/ 2) + (COMS
% 2)) + 1);
284 boolean need_two_screens
= FALSE
;
287 need_two_screens
= 1;
292 for (i
= 0; i
< rows
; i
++) {
293 for (j
= 0; j
< DCOLS
; j
++) {
294 save
[i
][j
] = mvinch(i
, j
);
298 for (i
= 0; i
< rows
; i
++) {
302 for (i
= 0; i
< (rows
-1); i
++) {
304 if (((i
+ i
) < COMS
) && ((i
+i
+k
) < COMS
)) {
305 mvaddstr(i
, 0, com_id_tab
[i
+i
+k
].com_desc
);
307 if (((i
+ i
+ 1) < COMS
) && ((i
+i
+k
+1) < COMS
)) {
308 mvaddstr(i
, (DCOLS
/2),
309 com_id_tab
[i
+i
+k
+1].com_desc
);
313 mvaddstr(rows
- 1, 0, need_two_screens
? more
: press_space
);
317 if (need_two_screens
) {
319 need_two_screens
= 0;
322 for (i
= 0; i
< rows
; i
++) {
324 for (j
= 0; j
< DCOLS
; j
++) {
331 if (!pr_com_id(ch
)) {
332 if (!pr_motion_char(ch
)) {
334 message("unknown character", 0);
348 if (!get_com_id(&i
, ch
)) {
352 message(com_id_tab
[i
].com_desc
, 0);
357 get_com_id(int *idx
, short ch
)
361 for (i
= 0; i
< COMS
; i
++) {
362 if (com_id_tab
[i
].com_char
== ch
) {
371 pr_motion_char(int ch
)
389 char until
[18], buf
[DCOLS
];
394 strcpy(until
, "until adjascent");
400 sprintf(buf
, "run %s %s", com_id_tab
[n
].com_desc
+ 8, until
);
413 char *t
[MAX_ID_TITLE_LEN
];
415 for (i
= 0; i
<= 32; i
++) {
416 j
= get_rand(0, (POTIONS
- 1));
417 k
= get_rand(0, (POTIONS
- 1));
418 memcpy(t
, id_potions
[j
].title
, MAX_ID_TITLE_LEN
);
419 memcpy(id_potions
[j
].title
, id_potions
[k
].title
, MAX_ID_TITLE_LEN
);
424 make_scroll_titles(void)
429 for (i
= 0; i
< SCROLS
; i
++) {
430 sylls
= get_rand(2, 5);
431 strcpy(id_scrolls
[i
].title
, "'");
433 for (j
= 0; j
< sylls
; j
++) {
434 s
= get_rand(1, (MAXSYLLABLES
-1));
435 strcat(id_scrolls
[i
].title
, syllables
[s
]);
437 n
= strlen(id_scrolls
[i
].title
);
438 strcpy(id_scrolls
[i
].title
+(n
-1), "' ");
443 get_desc(const object
*obj
, char *desc
)
445 const char *item_name
;
450 if (obj
->what_is
== AMULET
) {
451 strcpy(desc
, "the amulet of Yendor ");
454 item_name
= name_of(obj
);
456 if (obj
->what_is
== GOLD
) {
457 sprintf(desc
, "%d pieces of gold", obj
->quantity
);
461 if (obj
->what_is
!= ARMOR
) {
462 if (obj
->quantity
== 1) {
465 sprintf(desc
, "%d ", obj
->quantity
);
468 if (obj
->what_is
== FOOD
) {
469 if (obj
->which_kind
== RATION
) {
470 if (obj
->quantity
> 1) {
471 sprintf(desc
, "%d rations of ", obj
->quantity
);
473 strcpy(desc
, "some ");
478 strcat(desc
, item_name
);
481 id_table
= get_id_table(obj
);
486 if (obj
->what_is
& (WEAPON
| ARMOR
| WAND
| RING
)) {
490 switch(id_table
[obj
->which_kind
].id_status
) {
493 switch(obj
->what_is
) {
495 strcat(desc
, item_name
);
496 strcat(desc
, "entitled: ");
497 strcat(desc
, id_table
[obj
->which_kind
].title
);
500 strcat(desc
, id_table
[obj
->which_kind
].title
);
501 strcat(desc
, item_name
);
505 if (obj
->identified
||
506 (id_table
[obj
->which_kind
].id_status
== IDENTIFIED
)) {
509 if (id_table
[obj
->which_kind
].id_status
== CALLED
) {
512 strcat(desc
, id_table
[obj
->which_kind
].title
);
513 strcat(desc
, item_name
);
516 if (obj
->identified
) {
519 strcpy(desc
, id_table
[obj
->which_kind
].title
);
522 if (obj
->identified
) {
525 strcat(desc
, name_of(obj
));
530 CALL
: switch(obj
->what_is
) {
535 strcat(desc
, item_name
);
536 strcat(desc
, "called ");
537 strcat(desc
, id_table
[obj
->which_kind
].title
);
542 ID
: switch(obj
->what_is
) {
545 strcat(desc
, item_name
);
546 strcat(desc
, id_table
[obj
->which_kind
].real
);
549 if (wizard
|| obj
->identified
) {
550 if ((obj
->which_kind
== DEXTERITY
) ||
551 (obj
->which_kind
== ADD_STRENGTH
)) {
552 sprintf(more_info
, "%s%d ", ((obj
->class > 0) ? "+" : ""),
554 strcat(desc
, more_info
);
557 strcat(desc
, item_name
);
558 strcat(desc
, id_table
[obj
->which_kind
].real
);
561 strcat(desc
, item_name
);
562 strcat(desc
, id_table
[obj
->which_kind
].real
);
563 if (wizard
|| obj
->identified
) {
564 sprintf(more_info
, "[%d]", obj
->class);
565 strcat(desc
, more_info
);
569 sprintf(desc
, "%s%d ", ((obj
->d_enchant
>= 0) ? "+" : ""),
571 strcat(desc
, id_table
[obj
->which_kind
].title
);
572 sprintf(more_info
, "[%d] ", get_armor_class(obj
));
573 strcat(desc
, more_info
);
576 sprintf(desc
+strlen(desc
), "%s%d,%s%d ",
577 ((obj
->hit_enchant
>= 0) ? "+" : ""), obj
->hit_enchant
,
578 ((obj
->d_enchant
>= 0) ? "+" : ""), obj
->d_enchant
);
579 strcat(desc
, name_of(obj
));
585 if (!strncmp(desc
, "a ", 2)) {
586 if (is_vowel(desc
[2])) {
587 for (i
= strlen(desc
) + 1; i
> 1; i
--) {
593 if (obj
->in_use_flags
& BEING_WIELDED
) {
594 strcat(desc
, "in hand");
595 } else if (obj
->in_use_flags
& BEING_WORN
) {
596 strcat(desc
, "being worn");
597 } else if (obj
->in_use_flags
& ON_LEFT_HAND
) {
598 strcat(desc
, "on left hand");
599 } else if (obj
->in_use_flags
& ON_RIGHT_HAND
) {
600 strcat(desc
, "on right hand");
605 get_wand_and_ring_materials(void)
608 boolean used
[WAND_MATERIALS
];
610 for (i
= 0; i
< WAND_MATERIALS
; i
++) {
613 for (i
= 0; i
< WANDS
; i
++) {
615 j
= get_rand(0, WAND_MATERIALS
-1);
618 strcpy(id_wands
[i
].title
, wand_materials
[j
]);
619 is_wood
[i
] = (j
> MAX_METAL
);
621 for (i
= 0; i
< GEMS
; i
++) {
624 for (i
= 0; i
< RINGS
; i
++) {
626 j
= get_rand(0, GEMS
-1);
629 strcpy(id_rings
[i
].title
, gems
[j
]);
634 single_inv(short ichar
)
640 ch
= ichar
? ichar
: pack_letter("inventory what?", ALL_OBJECTS
);
645 if (!(obj
= get_letter_object(ch
))) {
646 message("no such item.", 0);
650 desc
[1] = ((obj
->what_is
& ARMOR
) && obj
->is_protected
) ? '}' : ')';
653 get_desc(obj
, desc
+3);
658 get_id_table(const object
*obj
)
660 switch(obj
->what_is
) {
678 inv_armor_weapon(boolean is_weapon
)
682 single_inv(rogue
.weapon
->ichar
);
684 message("not wielding anything", 0);
688 single_inv(rogue
.armor
->ichar
);
690 message("not wearing anything", 0);
702 message("what do you want identified?", 0);
706 if ((ch
>= 'A') && (ch
<= 'Z')) {
707 id
= m_names
[ch
-'A'];
708 } else if (ch
< 32) {
727 id
= "wall of a room";
748 id
= "wand or staff";
763 id
= "the Amulet of Yendor";
766 id
= "unknown character";
771 sprintf(buf
, "'%c': %s", ch
, id
);