4 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6 * This software may be copied and distributed for educational, research,
7 * and not for profit purposes provided that this copyright and statement
8 * are included in all such copies. Other copyrights may also apply.
16 * Max sizes of the following arrays.
18 #define MAX_TITLES 50 /* Used with scrolls (min 48) */
22 * Hold the titles of scrolls, 6 to 14 characters each.
24 * Also keep an array of scroll colors (always WHITE for now).
27 static char scroll_adj
[MAX_TITLES
][16];
30 static void flavor_assign_fixed(void)
34 for (i
= 0; i
< z_info
->flavor_max
; i
++)
36 flavor_type
*flavor_ptr
= &flavor_info
[i
];
38 /* Skip random flavors */
39 if (flavor_ptr
->sval
== SV_UNKNOWN
) continue;
41 for (j
= 0; j
< z_info
->k_max
; j
++)
43 /* Skip other objects */
44 if ((k_info
[j
].tval
== flavor_ptr
->tval
) &&
45 (k_info
[j
].sval
== flavor_ptr
->sval
))
47 /* Store the flavor index */
55 static void flavor_assign_random(byte tval
)
61 /* Count the random flavors for the given tval */
62 for (i
= 0; i
< z_info
->flavor_max
; i
++)
64 if ((flavor_info
[i
].tval
== tval
) &&
65 (flavor_info
[i
].sval
== SV_UNKNOWN
))
71 for (i
= 0; i
< z_info
->k_max
; i
++)
73 /* Skip other object types */
74 if (k_info
[i
].tval
!= tval
) continue;
76 /* Skip objects that already are flavored */
77 if (k_info
[i
].flavor
!= 0) continue;
79 /* HACK - Ordinary food is "boring" */
80 if ((tval
== TV_FOOD
) && (k_info
[i
].sval
>= SV_FOOD_MIN_FOOD
))
83 if (!flavor_count
) quit_fmt("Not enough flavors for tval %d.", tval
);
86 choice
= rand_int(flavor_count
);
88 /* Find and store the flavor */
89 for (j
= 0; j
< z_info
->flavor_max
; j
++)
91 /* Skip other tvals */
92 if (flavor_info
[j
].tval
!= tval
) continue;
94 /* Skip assigned svals */
95 if (flavor_info
[j
].sval
!= SV_UNKNOWN
) continue;
99 /* Store the flavor index */
100 k_info
[i
].flavor
= j
;
102 /* Mark the flavor as used */
103 flavor_info
[j
].sval
= k_info
[i
].sval
;
105 /* One less flavor to choose from */
118 * Prepare the "variable" part of the "k_info" array.
120 * The "color"/"metal"/"type" of an item is its "flavor".
121 * For the most part, flavors are assigned randomly each game.
123 * Initialize descriptions for the "colored" objects, including:
124 * Rings, Amulets, Staffs, Wands, Rods, Food, Potions, Scrolls.
126 * The first 4 entries for potions are fixed (Water, Apple Juice,
127 * Slime Mold Juice, Unused Potion).
129 * Scroll titles are always between 6 and 14 letters long. This is
130 * ensured because every title is composed of whole words, where every
131 * word is from 2 to 8 letters long, and that no scroll is finished
132 * until it attempts to grow beyond 15 letters. The first time this
133 * can happen is when the current title has 6 letters and the new word
134 * has 8 letters, which would result in a 6 letter scroll title.
136 * Hack -- make sure everything stays the same for each saved game
137 * This is accomplished by the use of a saved "random seed", as in
138 * "town_gen()". Since no other functions are called while the special
139 * seed is in effect, so this function is pretty "safe".
141 void flavor_init(void)
145 /* Hack -- Use the "simple" RNG */
148 /* Hack -- Induce consistant flavors */
149 Rand_value
= seed_flavor
;
151 flavor_assign_fixed();
153 flavor_assign_random(TV_RING
);
154 flavor_assign_random(TV_AMULET
);
155 flavor_assign_random(TV_STAFF
);
156 flavor_assign_random(TV_WAND
);
157 flavor_assign_random(TV_ROD
);
158 flavor_assign_random(TV_FOOD
);
159 flavor_assign_random(TV_POTION
);
160 flavor_assign_random(TV_SCROLL
);
162 /* Scrolls (random titles, always white) */
163 for (i
= 0; i
< MAX_TITLES
; i
++)
171 wordlen
= randname_make(RANDNAME_SCROLL
, 2, 8, end
, 24);
172 while (titlelen
+ wordlen
< (int)(sizeof(scroll_adj
[0]) - 1))
175 titlelen
+= wordlen
+ 1;
177 wordlen
= randname_make(RANDNAME_SCROLL
, 2, 8, end
, 24 - titlelen
);
179 buf
[titlelen
- 1] = '\0';
181 /* Check the scroll name hasn't already been generated */
182 for (j
= 0; j
< i
; j
++)
184 if (streq(buf
, scroll_adj
[j
]))
193 my_strcpy(scroll_adj
[i
], buf
, sizeof(scroll_adj
[0]));
197 /* Have another go at making a name */
202 /* Hack -- Use the "complex" RNG */
205 /* Analyze every object */
206 for (i
= 1; i
< z_info
->k_max
; i
++)
208 object_kind
*k_ptr
= &k_info
[i
];
210 /* Skip "empty" objects */
211 if (!k_ptr
->name
) continue;
213 /* No flavor yields aware */
214 if (!k_ptr
->flavor
) k_ptr
->aware
= TRUE
;
220 #ifdef ALLOW_BORG_GRAPHICS
221 extern void init_translate_visuals(void);
222 #endif /* ALLOW_BORG_GRAPHICS */
226 * Reset the "visual" lists
228 * This involves resetting various things to their "default" state.
230 * If the "prefs" flag is TRUE, then we will also load the appropriate
231 * "user pref file" based on the current setting of the "use_graphics"
232 * flag. This is useful for switching "graphics" on/off.
234 * The features, objects, and monsters, should all be encoded in the
235 * relevant "font.pref" and/or "graf.prf" files. XXX XXX XXX
237 * The "prefs" parameter is no longer meaningful. XXX XXX XXX
239 void reset_visuals(bool unused
)
244 /* Unused parameter */
247 /* Extract default attr/char code for features */
248 for (i
= 0; i
< z_info
->f_max
; i
++)
250 feature_type
*f_ptr
= &f_info
[i
];
252 /* Assume we will use the underlying values */
253 f_ptr
->x_attr
= f_ptr
->d_attr
;
254 f_ptr
->x_char
= f_ptr
->d_char
;
257 /* Extract default attr/char code for objects */
258 for (i
= 0; i
< z_info
->k_max
; i
++)
260 object_kind
*k_ptr
= &k_info
[i
];
262 /* Default attr/char */
263 k_ptr
->x_attr
= k_ptr
->d_attr
;
264 k_ptr
->x_char
= k_ptr
->d_char
;
267 /* Extract default attr/char code for monsters */
268 for (i
= 0; i
< z_info
->r_max
; i
++)
270 monster_race
*r_ptr
= &r_info
[i
];
272 /* Default attr/char */
273 r_ptr
->x_attr
= r_ptr
->d_attr
;
274 r_ptr
->x_char
= r_ptr
->d_char
;
277 /* Extract default attr/char code for flavors */
278 for (i
= 0; i
< z_info
->flavor_max
; i
++)
280 flavor_type
*flavor_ptr
= &flavor_info
[i
];
282 /* Default attr/char */
283 flavor_ptr
->x_attr
= flavor_ptr
->d_attr
;
284 flavor_ptr
->x_char
= flavor_ptr
->d_char
;
287 /* Extract attr/chars for inventory objects (by tval) */
288 for (i
= 0; i
< (int)N_ELEMENTS(tval_to_attr
); i
++)
290 /* Default to white */
291 tval_to_attr
[i
] = TERM_WHITE
;
295 /* Graphic symbols */
298 /* Process "graf.prf" */
299 process_pref_file("graf.prf");
305 /* Process "font.prf" */
306 process_pref_file("font.prf");
309 #ifdef ALLOW_BORG_GRAPHICS
310 /* Initialize the translation table for the borg */
311 init_translate_visuals();
312 #endif /* ALLOW_BORG_GRAPHICS */
317 * Modes of object_flags_aux()
319 #define OBJECT_FLAGS_FULL 1 /* Full info */
320 #define OBJECT_FLAGS_KNOWN 2 /* Only flags known to the player */
321 #define OBJECT_FLAGS_RANDOM 3 /* Only known random flags */
325 * Obtain the "flags" for an item
327 static void object_flags_aux(int mode
, const object_type
*o_ptr
, u32b
*f1
, u32b
*f2
, u32b
*f3
)
331 if (mode
!= OBJECT_FLAGS_FULL
)
334 (*f1
) = (*f2
) = (*f3
) = 0L;
336 /* Must be identified */
337 if (!object_known_p(o_ptr
)) return;
340 if (mode
!= OBJECT_FLAGS_RANDOM
)
342 k_ptr
= &k_info
[o_ptr
->k_idx
];
345 (*f1
) = k_ptr
->flags1
;
346 (*f2
) = k_ptr
->flags2
;
347 (*f3
) = k_ptr
->flags3
;
349 if (mode
== OBJECT_FLAGS_FULL
)
354 artifact_type
*a_ptr
= &a_info
[o_ptr
->name1
];
356 (*f1
) = a_ptr
->flags1
;
357 (*f2
) = a_ptr
->flags2
;
358 (*f3
) = a_ptr
->flags3
;
365 ego_item_type
*e_ptr
= &e_info
[o_ptr
->name2
];
367 (*f1
) |= e_ptr
->flags1
;
368 (*f2
) |= e_ptr
->flags2
;
369 (*f3
) |= e_ptr
->flags3
;
372 if (mode
== OBJECT_FLAGS_KNOWN
)
374 /* Obvious artifact flags */
377 artifact_type
*a_ptr
= &a_info
[o_ptr
->name1
];
379 /* Obvious flags (pval) */
380 (*f1
) = (a_ptr
->flags1
& (TR1_PVAL_MASK
));
382 (*f3
) = (a_ptr
->flags3
& (TR3_IGNORE_MASK
));
387 if (mode
!= OBJECT_FLAGS_FULL
)
391 #ifdef SPOIL_ARTIFACTS
392 /* Full knowledge for some artifacts */
393 if (artifact_p(o_ptr
)) spoil
= TRUE
;
394 #endif /* SPOIL_ARTIFACTS */
396 #ifdef SPOIL_EGO_ITEMS
397 /* Full knowledge for some ego-items */
398 if (ego_item_p(o_ptr
)) spoil
= TRUE
;
399 #endif /* SPOIL_ARTIFACTS */
401 /* Need full knowledge or spoilers */
402 if (!spoil
&& !(o_ptr
->ident
& IDENT_MENTAL
)) return;
407 artifact_type
*a_ptr
= &a_info
[o_ptr
->name1
];
409 (*f1
) = a_ptr
->flags1
;
410 (*f2
) = a_ptr
->flags2
;
411 (*f3
) = a_ptr
->flags3
;
413 if (mode
== OBJECT_FLAGS_RANDOM
)
415 /* Hack - remove 'ignore' flags */
416 (*f3
) &= ~(TR3_IGNORE_MASK
);
420 /* Full knowledge for *identified* objects */
421 if (!(o_ptr
->ident
& IDENT_MENTAL
)) return;
425 switch (o_ptr
->xtra1
)
427 case OBJECT_XTRA_TYPE_SUSTAIN
:
429 /* OBJECT_XTRA_WHAT_SUSTAIN == 2 */
430 (*f2
) |= (OBJECT_XTRA_BASE_SUSTAIN
<< o_ptr
->xtra2
);
434 case OBJECT_XTRA_TYPE_RESIST
:
436 /* OBJECT_XTRA_WHAT_RESIST == 2 */
437 (*f2
) |= (OBJECT_XTRA_BASE_RESIST
<< o_ptr
->xtra2
);
441 case OBJECT_XTRA_TYPE_POWER
:
443 /* OBJECT_XTRA_WHAT_POWER == 3 */
444 (*f3
) |= (OBJECT_XTRA_BASE_POWER
<< o_ptr
->xtra2
);
453 * Puts a very stripped-down version of an object's name into buf.
454 * If easy_know is TRUE, then the IDed names are used, otherwise
455 * flavours, scroll names, etc will be used.
457 * Just truncates if the buffer isn't big enough.
459 void object_kind_name(char *buf
, size_t max
, int k_idx
, bool easy_know
)
463 object_kind
*k_ptr
= &k_info
[k_idx
];
465 /* If not aware, use flavor */
466 if (!easy_know
&& !k_ptr
->aware
&& k_ptr
->flavor
)
468 if (k_ptr
->tval
== TV_SCROLL
)
470 strnfmt(buf
, max
, "\"%s\"", scroll_adj
[k_ptr
->sval
]);
472 else if (k_ptr
->tval
== TV_FOOD
&& k_ptr
->sval
< SV_FOOD_MIN_FOOD
)
474 strnfmt(buf
, max
, "%s Mushroom", flavor_text
+ flavor_info
[k_ptr
->flavor
].text
);
478 /* Plain flavour (e.g. Copper) will do. */
479 my_strcpy(buf
, flavor_text
+ flavor_info
[k_ptr
->flavor
].text
, max
);
483 /* Use proper name (Healing, or whatever) */
486 cptr str
= (k_name
+ k_ptr
->name
);
488 if (k_ptr
->tval
== TV_FOOD
&& k_ptr
->sval
< SV_FOOD_MIN_FOOD
)
490 my_strcpy(buf
, "Mushroom of ", max
);
492 t
= buf
+ strlen(buf
);
499 /* Skip past leading characters */
500 while ((*str
== ' ') || (*str
== '&')) str
++;
502 /* Copy useful chars */
503 for (; *str
&& max
> 1; str
++)
505 /* Pluralizer for irregular plurals */
506 /* Useful for languages where adjective changes for plural */
509 /* Process singular part */
510 for (str
++; *str
!= '|' && max
> 1; str
++)
516 /* Process plural part */
517 for (str
++; *str
!= '|'; str
++) ;
520 /* English plural indicator can simply be skipped */
521 else if (*str
!= '~')
528 /* Terminate the new name */
536 * Obtain the "flags" for an item
538 void object_flags(const object_type
*o_ptr
, u32b
*f1
, u32b
*f2
, u32b
*f3
)
540 object_flags_aux(OBJECT_FLAGS_FULL
, o_ptr
, f1
, f2
, f3
);
546 * Obtain the "flags" for an item which are known to the player
548 void object_flags_known(const object_type
*o_ptr
, u32b
*f1
, u32b
*f2
, u32b
*f3
)
550 object_flags_aux(OBJECT_FLAGS_KNOWN
, o_ptr
, f1
, f2
, f3
);
555 * Efficient version of '(T) += sprintf((T), "%c", (C))'
557 #define object_desc_chr_macro(T,C) do { \
559 /* Copy the char */ \
567 * Efficient version of '(T) += sprintf((T), "%s", (S))'
569 #define object_desc_str_macro(T,S) do { \
573 /* Copy the string */ \
574 while (*s) *(T)++ = *s++; \
581 * Efficient version of '(T) += sprintf((T), "%u", (N))'
583 #define object_desc_num_macro(T,N) do { \
589 /* Find "size" of "n" */ \
590 for (p = 1; n >= p * 10; p = p * 10) /* loop */; \
592 /* Dump each digit */ \
595 /* Dump the digit */ \
596 *(T)++ = I2D(n / p); \
598 /* Remove the digit */ \
601 /* Process next digit */ \
610 * Efficient version of '(T) += sprintf((T), "%+d", (I))'
612 #define object_desc_int_macro(T,I) do { \
619 /* Take the absolute value */ \
622 /* Use a "minus" sign */ \
626 /* Positive (or zero) */ \
629 /* Use a "plus" sign */ \
633 /* Dump the number itself */ \
634 object_desc_num_macro(T, i); \
642 * Creates a description of the item "o_ptr", and stores it in "buf".
644 * One can choose the "verbosity" of the description, including whether
645 * or not the "number" of items should be described, and how much detail
646 * should be used when describing the item.
648 * The given "buf" should be at least 80 chars long to hold the longest
649 * possible description, which can get pretty long, including inscriptions,
651 * "no more Maces of Disruption (Defender) (+10,+10) [+5] (+3 to stealth)".
653 * Note that the object description will be clipped to fit into the given
656 * Note the use of "object_desc_int_macro()" and "object_desc_num_macro()"
657 * and "object_desc_str_macro()" and "object_desc_chr_macro()" as extremely
658 * efficient, portable, versions of some common "sprintf()" commands (without
659 * the bounds checking or termination writing), which allow a pointer to
660 * efficiently move through a buffer while modifying it in various ways.
662 * Various improper uses and/or placements of "&" or "~" characters can
663 * easily induce out-of-bounds memory accesses. Some of these could be
664 * easily checked for, if efficiency was not a concern.
666 * Note that all ego-items (when known) append an "Ego-Item Name", unless
667 * the item is also an artifact, which should never happen.
669 * Note that all artifacts (when known) append an "Artifact Name", so we
670 * have special processing for "Specials" (artifact Lites, Rings, Amulets).
671 * The "Specials" never use "modifiers" if they are "known", since they
672 * have special "descriptions", such as "The Necklace of the Dwarves".
674 * Special Lite's use the "k_info" base-name (Phial, Star, or Arkenstone),
675 * plus the artifact name, just like any other artifact, if known.
677 * Special Ring's and Amulet's, if not "aware", use the same code as normal
678 * rings and amulets, and if "aware", use the "k_info" base-name (Ring or
679 * Amulet or Necklace). They will NEVER "append" the "k_info" name. But,
680 * they will append the artifact name, just like any artifact, if known.
682 * None of the Special Rings/Amulets are "EASY_KNOW", though they could be,
683 * at least, those which have no "pluses", such as the three artifact lites.
685 * The "pluralization" rules are extremely hackish, in fact, for efficiency,
686 * we only handle things like "torch"/"torches" and "cutlass"/"cutlasses",
687 * and we would not handle "box"/"boxes", or "knife"/"knives", correctly.
688 * Of course, it would be easy to add rules for these forms.
690 * If "pref" is true then a "numeric" prefix will be pre-pended, else is is
691 * assumed that a string such as "The" or "Your" will be pre-pended later.
693 * Modes ("pref" is TRUE):
694 * 0 -- Chain Mail of Death
695 * 1 -- A Cloak of Death [1,+3]
696 * 2 -- An Amulet of Death [1,+3] (+2 to Stealth)
697 * 3 -- 5 Rings of Death [1,+3] (+2 to Stealth) {nifty} (squelch)
698 * 4 -- 5 Rings of Death [1,+3] (+2 to Stealth) {nifty}
700 * Modes ("pref" is FALSE):
701 * 0 -- Chain Mail of Death
702 * 1 -- Cloak of Death [1,+3]
703 * 2 -- Amulet of Death [1,+3] (+2 to Stealth)
704 * 3 -- Rings of Death [1,+3] (+2 to Stealth) {nifty} (squelch)
705 * 4 -- Rings of Death [1,+3] (+2 to Stealth) {nifty}
707 void object_desc(char *buf
, size_t max
, const object_type
*o_ptr
, int pref
, int mode
)
733 char p1
= '(', p2
= ')';
734 char b1
= '[', b2
= ']';
735 char c1
= '{', c2
= '}';
741 object_kind
*k_ptr
= &k_info
[o_ptr
->k_idx
];
744 /* Extract some flags */
745 object_flags(o_ptr
, &f1
, &f2
, &f3
);
748 /* See if the object is "aware" */
749 aware
= (object_aware_p(o_ptr
) ? TRUE
: FALSE
);
751 /* See if the object is "known" */
752 known
= (object_known_p(o_ptr
) ? TRUE
: FALSE
);
754 /* See if the object is "flavored" */
755 flavor
= (k_ptr
->flavor
? TRUE
: FALSE
);
757 /* Allow flavors to be hidden when aware */
758 if (aware
&& !show_flavors
) flavor
= FALSE
;
760 /* Hack -- mark-to-squelch worthless items XXX */
761 if (!k_ptr
->everseen
&& aware
&& OPTION(squelch_worthless
))
763 if (object_value(o_ptr
) == 0)
765 k_ptr
->squelch
= TRUE
;
766 p_ptr
->notice
|= PN_SQUELCH
;
770 /* We've seen it at least once now we're aware of it */
771 if (aware
) k_ptr
->everseen
= TRUE
;
773 /* Object is in the inventory of a store */
774 if (o_ptr
->ident
& IDENT_STORE
)
776 /* Don't show flavors */
779 /* Pretend known and aware */
785 /* XXX anything object_desc'd can be squelched */
786 if (aware
) k_ptr
->everseen
= TRUE
;
788 /* Assume no name appending */
791 /* Assume no need to show "weapon" bonuses */
794 /* Assume no need to show "armour" bonuses */
797 /* Extract default "base" string */
798 basenm
= (k_name
+ k_ptr
->name
);
800 /* Assume no "modifier" string */
804 /* Analyze the object */
807 /* Some objects are easy to describe */
818 /* Missiles/Bows/Weapons */
847 /* Lites (including a few "Specials") */
853 /* Amulets (including a few "Specials") */
856 /* Hack -- Known artifacts */
857 if (artifact_p(o_ptr
) && aware
) break;
859 /* Color the object */
860 modstr
= flavor_text
+ flavor_info
[k_ptr
->flavor
].text
;
861 if (aware
) append_name
= TRUE
;
862 basenm
= (flavor
? "& # Amulet~" : "& Amulet~");
867 /* Rings (including a few "Specials") */
870 /* Hack -- Known artifacts */
871 if (artifact_p(o_ptr
) && aware
) break;
873 /* Color the object */
874 modstr
= flavor_text
+ flavor_info
[k_ptr
->flavor
].text
;
875 if (aware
) append_name
= TRUE
;
876 basenm
= (flavor
? "& # Ring~" : "& Ring~");
884 /* Color the object */
885 modstr
= flavor_text
+ flavor_info
[k_ptr
->flavor
].text
;
886 if (aware
) append_name
= TRUE
;
887 basenm
= (flavor
? "& # Staff~" : "& Staff~");
895 /* Color the object */
896 modstr
= flavor_text
+ flavor_info
[k_ptr
->flavor
].text
;
897 if (aware
) append_name
= TRUE
;
898 basenm
= (flavor
? "& # Wand~" : "& Wand~");
906 /* Color the object */
907 modstr
= flavor_text
+ flavor_info
[k_ptr
->flavor
].text
;
908 if (aware
) append_name
= TRUE
;
909 basenm
= (flavor
? "& # Rod~" : "& Rod~");
917 /* Color the object */
918 modstr
= scroll_adj
[o_ptr
->sval
];
919 if (aware
) append_name
= TRUE
;
920 basenm
= (flavor
? "& Scroll~ titled \"#\"" : "& Scroll~");
928 /* Color the object */
929 modstr
= flavor_text
+ flavor_info
[k_ptr
->flavor
].text
;
930 if (aware
) append_name
= TRUE
;
931 basenm
= (flavor
? "& # Potion~" : "& Potion~");
939 /* Ordinary food is "boring" */
940 if (o_ptr
->sval
>= SV_FOOD_MIN_FOOD
) break;
942 /* Color the object */
943 modstr
= flavor_text
+ flavor_info
[k_ptr
->flavor
].text
;
944 if (aware
) append_name
= TRUE
;
945 basenm
= (flavor
? "& # Mushroom~" : "& Mushroom~");
954 basenm
= "& Book~ of Magic Spells #";
962 basenm
= "& Holy Book~ of Prayers #";
966 /* Hack -- Gold/Gems */
969 my_strcpy(buf
, basenm
, max
);
973 /* Hack -- Default -- Used in the "inventory" routine */
976 my_strcpy(buf
, "(nothing)", max
);
982 /* Start dumping the result */
988 /* Handle objects which sometimes use "a" or "an" */
991 /* Paranoia XXX XXX XXX */
992 /* ASSERT(s[1] == ' '); */
994 /* Skip the ampersand and the following space */
1003 /* Hack -- None left */
1004 else if (o_ptr
->number
<= 0)
1006 object_desc_str_macro(t
, "no more ");
1009 /* Extract the number */
1010 else if (o_ptr
->number
> 1)
1012 object_desc_num_macro(t
, o_ptr
->number
);
1013 object_desc_chr_macro(t
, ' ');
1016 /* Hack -- The only one of its kind */
1017 else if (known
&& artifact_p(o_ptr
))
1019 object_desc_str_macro(t
, "The ");
1022 /* Hack -- A single one, and next character will be a vowel */
1023 else if ((*s
== '#') ? is_a_vowel(modstr
[0]) : is_a_vowel(*s
))
1025 object_desc_str_macro(t
, "an ");
1028 /* A single one, and next character will be a non-vowel */
1031 object_desc_str_macro(t
, "a ");
1035 /* Handle objects which never use "a" or "an" */
1044 /* Hack -- all gone */
1045 else if (o_ptr
->number
<= 0)
1047 object_desc_str_macro(t
, "no more ");
1050 /* Prefix a number if required */
1051 else if (o_ptr
->number
> 1)
1053 object_desc_num_macro(t
, o_ptr
->number
);
1054 object_desc_chr_macro(t
, ' ');
1057 /* Hack -- The only one of its kind */
1058 else if (known
&& artifact_p(o_ptr
))
1060 object_desc_str_macro(t
, "The ");
1063 /* Hack -- A single item, so no prefix needed */
1071 /* Paranoia XXX XXX XXX */
1072 /* ASSERT(*s != '~'); */
1074 /* Copy the string */
1077 /* Pluralizer (regular English plurals) */
1080 /* Add a plural if needed */
1081 if ((o_ptr
->number
!= 1) && !(known
&& artifact_p(o_ptr
)))
1085 /* Hack -- "Cutlass-es" and "Torch-es" */
1086 if ((k
== 's') || (k
== 'h')) *t
++ = 'e';
1093 /* Pluralizer for irregular plurals */
1096 bool singular
= (o_ptr
->number
== 1);
1098 /* Process singular part */
1099 for (s
++; *s
!= '|'; s
++)
1101 if (singular
) *t
++ = *s
;
1104 /* Process plural part */
1105 for (s
++; *s
!= '|'; s
++)
1107 if (!singular
) *t
++ = *s
;
1114 /* Append the modifier */
1119 /* Handle pluralization in the modifier */
1122 /* Normal character - copy */
1128 bool singular
= (o_ptr
->number
== 1);
1130 /* Process singular part */
1131 for (m
++; *m
!= '|'; m
++)
1133 if (singular
) *t
++ = *m
;
1136 /* Process plural part */
1137 for (m
++; *m
!= '|'; m
++)
1139 if (!singular
) *t
++ = *m
;
1154 /* Append the "kind name" to the "base name" */
1157 object_desc_str_macro(t
, " of ");
1158 object_desc_str_macro(t
, (k_name
+ k_ptr
->name
));
1162 /* Hack -- Append "Artifact" or "Special" names */
1165 /* Grab any artifact name */
1168 artifact_type
*a_ptr
= &a_info
[o_ptr
->name1
];
1170 object_desc_chr_macro(t
, ' ');
1171 object_desc_str_macro(t
, (a_name
+ a_ptr
->name
));
1174 /* Grab any ego-item name */
1175 else if (o_ptr
->name2
)
1177 ego_item_type
*e_ptr
= &e_info
[o_ptr
->name2
];
1179 object_desc_chr_macro(t
, ' ');
1180 object_desc_str_macro(t
, (e_name
+ e_ptr
->name
));
1182 /* Hack - Now we know about the ego-item type */
1183 e_info
[o_ptr
->name2
].everseen
= TRUE
;
1189 /* No more details wanted */
1190 if (mode
< 1) goto object_desc_done
;
1193 /* Hack -- Chests must be described in detail */
1194 if (o_ptr
->tval
== TV_CHEST
)
1198 /* Not searched yet */
1204 /* May be "empty" */
1205 else if (!o_ptr
->pval
)
1210 /* May be "disarmed" */
1211 else if (o_ptr
->pval
< 0)
1213 if (chest_traps
[0 - o_ptr
->pval
])
1215 tail
= " (disarmed)";
1219 tail
= " (unlocked)";
1223 /* Describe the traps, if any */
1226 /* Describe the traps */
1227 switch (chest_traps
[o_ptr
->pval
])
1234 case CHEST_LOSE_STR
:
1236 tail
= " (Poison Needle)";
1239 case CHEST_LOSE_CON
:
1241 tail
= " (Poison Needle)";
1246 tail
= " (Gas Trap)";
1249 case CHEST_PARALYZE
:
1251 tail
= " (Gas Trap)";
1256 tail
= " (Explosion Device)";
1261 tail
= " (Summoning Runes)";
1266 tail
= " (Multiple Traps)";
1272 /* Append the tail */
1273 object_desc_str_macro(t
, tail
);
1277 /* Display the item like a weapon */
1278 if (f3
& (TR3_SHOW_MODS
)) show_weapon
= TRUE
;
1280 /* Display the item like a weapon */
1281 if (o_ptr
->to_h
&& o_ptr
->to_d
) show_weapon
= TRUE
;
1283 /* Display the item like armour */
1284 if (o_ptr
->ac
) show_armour
= TRUE
;
1287 /* Dump base weapon info */
1288 switch (o_ptr
->tval
)
1304 /* Append a "damage" string */
1305 object_desc_chr_macro(t
, ' ');
1306 object_desc_chr_macro(t
, p1
);
1307 object_desc_num_macro(t
, o_ptr
->dd
);
1308 object_desc_chr_macro(t
, 'd');
1309 object_desc_num_macro(t
, o_ptr
->ds
);
1310 object_desc_chr_macro(t
, p2
);
1319 /* Hack -- Extract the "base power" */
1320 power
= (o_ptr
->sval
% 10);
1322 /* Append a "power" string */
1323 object_desc_chr_macro(t
, ' ');
1324 object_desc_chr_macro(t
, p1
);
1325 object_desc_chr_macro(t
, 'x');
1326 object_desc_num_macro(t
, power
);
1327 object_desc_chr_macro(t
, p2
);
1335 /* Add the weapon bonuses */
1338 /* Show the tohit/todam on request */
1341 object_desc_chr_macro(t
, ' ');
1342 object_desc_chr_macro(t
, p1
);
1343 object_desc_int_macro(t
, o_ptr
->to_h
);
1344 object_desc_chr_macro(t
, ',');
1345 object_desc_int_macro(t
, o_ptr
->to_d
);
1346 object_desc_chr_macro(t
, p2
);
1349 /* Show the tohit if needed */
1350 else if (o_ptr
->to_h
)
1352 object_desc_chr_macro(t
, ' ');
1353 object_desc_chr_macro(t
, p1
);
1354 object_desc_int_macro(t
, o_ptr
->to_h
);
1355 object_desc_chr_macro(t
, p2
);
1358 /* Show the todam if needed */
1359 else if (o_ptr
->to_d
)
1361 object_desc_chr_macro(t
, ' ');
1362 object_desc_chr_macro(t
, p1
);
1363 object_desc_int_macro(t
, o_ptr
->to_d
);
1364 object_desc_chr_macro(t
, p2
);
1369 /* Add the armor bonuses */
1372 /* Show the armor class info */
1375 object_desc_chr_macro(t
, ' ');
1376 object_desc_chr_macro(t
, b1
);
1377 object_desc_num_macro(t
, o_ptr
->ac
);
1378 object_desc_chr_macro(t
, ',');
1379 object_desc_int_macro(t
, o_ptr
->to_a
);
1380 object_desc_chr_macro(t
, b2
);
1383 /* No base armor, but does increase armor */
1384 else if (o_ptr
->to_a
)
1386 object_desc_chr_macro(t
, ' ');
1387 object_desc_chr_macro(t
, b1
);
1388 object_desc_int_macro(t
, o_ptr
->to_a
);
1389 object_desc_chr_macro(t
, b2
);
1393 /* Hack -- always show base armor */
1394 else if (show_armour
)
1396 object_desc_chr_macro(t
, ' ');
1397 object_desc_chr_macro(t
, b1
);
1398 object_desc_num_macro(t
, o_ptr
->ac
);
1399 object_desc_chr_macro(t
, b2
);
1403 /* No more details wanted */
1404 if (mode
< 2) goto object_desc_done
;
1406 /* Fuelled light sources get number of remaining turns appended */
1407 if ((o_ptr
->tval
== TV_LITE
) && !(f3
& TR3_NO_FUEL
))
1409 /* Turns of light for normal lites */
1410 object_desc_str_macro(t
, " (");
1411 object_desc_num_macro(t
, o_ptr
->timeout
);
1412 object_desc_str_macro(t
, " turns)");
1416 /* Dump "pval" flags for wearable items */
1417 if (known
&& (f1
& (TR1_PVAL_MASK
)))
1422 /* Start the display */
1423 object_desc_chr_macro(t
, ' ');
1424 object_desc_chr_macro(t
, p1
);
1426 /* Dump the "pval" itself */
1427 object_desc_int_macro(t
, o_ptr
->pval
);
1429 /* Do not display the "pval" flags */
1430 if (f3
& (TR3_HIDE_TYPE
))
1436 else if (f1
& (TR1_STEALTH
))
1438 /* Dump " to stealth" */
1439 tail
= " to stealth";
1443 else if (f1
& (TR1_SEARCH
))
1445 /* Dump " to searching" */
1446 tail
= " to searching";
1450 else if (f1
& (TR1_INFRA
))
1452 /* Dump " to infravision" */
1453 tail
= " to infravision";
1459 else if (f1
& (TR1_TUNNEL
))
1461 /* Dump " to digging" */
1462 tail
= " to digging";
1468 else if (f1
& (TR1_SPEED
))
1470 /* Dump " to speed" */
1475 else if (f1
& (TR1_BLOWS
))
1481 if (ABS(o_ptr
->pval
) != 1) tail2
= "s";
1487 else if (f1
& (TR1_SHOTS
))
1493 else if (f1
& (TR1_MIGHT
))
1500 /* Add the descriptor */
1501 object_desc_str_macro(t
, tail
);
1502 object_desc_str_macro(t
, tail2
);
1504 /* Finish the display */
1505 object_desc_chr_macro(t
, p2
);
1508 /* Hack -- Wands and Staffs have charges */
1510 ((o_ptr
->tval
== TV_STAFF
) ||
1511 (o_ptr
->tval
== TV_WAND
)))
1513 /* Dump " (N charges)" */
1514 object_desc_chr_macro(t
, ' ');
1515 object_desc_chr_macro(t
, p1
);
1516 object_desc_num_macro(t
, o_ptr
->pval
);
1517 object_desc_str_macro(t
, " charge");
1518 if (o_ptr
->pval
!= 1)
1520 object_desc_chr_macro(t
, 's');
1522 object_desc_chr_macro(t
, p2
);
1525 /* Hack -- Rods have a "charging" indicator */
1526 else if (known
&& (o_ptr
->tval
== TV_ROD
))
1528 /* Hack -- Dump " (# charging)" if relevant */
1529 if (o_ptr
->timeout
> 0)
1531 /* Stacks of rods display an exact count of charging rods. */
1532 if (o_ptr
->number
> 1)
1535 if (k_ptr
->pval
== 0) k_ptr
->pval
= 1;
1537 /* Find out how many rods are charging, by dividing
1538 * current timeout by each rod's maximum timeout.
1539 * Ensure that any remainder is rounded up. Display
1540 * very discharged stacks as merely fully discharged.
1542 power
= (o_ptr
->timeout
+ (k_ptr
->pval
- 1)) / k_ptr
->pval
;
1544 if (power
> o_ptr
->number
) power
= o_ptr
->number
;
1546 /* Display prettily */
1547 object_desc_str_macro(t
, " (");
1548 object_desc_num_macro(t
, power
);
1549 object_desc_str_macro(t
, " charging)");
1554 object_desc_str_macro(t
, " (charging)");
1559 /* Indicate "charging" artifacts */
1560 else if (known
&& o_ptr
->timeout
&& !(o_ptr
->tval
== TV_LITE
&& !artifact_p(o_ptr
)))
1562 /* Hack -- Dump " (charging)" if relevant */
1563 object_desc_str_macro(t
, " (charging)");
1567 /* No more details wanted */
1568 if (mode
< 3) goto object_desc_done
;
1571 /* Use standard inscription */
1574 u
= quark_str(o_ptr
->note
);
1585 /* Use special inscription, if any */
1588 v
= inscrip_text
[o_ptr
->pseudo
];
1591 /* Use "cursed" if the item is known to be cursed */
1592 else if (cursed_p(o_ptr
) && known
)
1597 /* Hack -- Use "empty" for empty wands/staffs */
1598 else if (!known
&& (o_ptr
->ident
& (IDENT_EMPTY
)))
1603 /* Use "tried" if the object has been tested unsuccessfully */
1604 else if (!aware
&& object_tried_p(o_ptr
))
1619 /* Begin the inscription */
1623 /* Standard inscription */
1626 /* Append the inscription */
1627 while ((t
< b
+ 75) && *u
) *t
++ = *u
++;
1630 /* Special inscription too */
1631 if (u
&& v
&& (t
< b
+ 75))
1638 /* Special inscription */
1641 /* Append the inscription */
1642 while ((t
< b
+ 75) && *v
) *t
++ = *v
++;
1645 /* Terminate the inscription */
1650 /* Add squelch marker unless mode == 4 (in-store) */
1651 if (mode
!= 4 && !hide_squelchable
&& squelch_item_ok(o_ptr
))
1652 object_desc_str_macro(t
, " (squelch)");
1660 /* Copy the string over */
1661 my_strcpy(buf
, tmp_buf
, max
);
1666 * Describe an item and pretend the item is fully known and has no flavor.
1668 void object_desc_spoil(char *buf
, size_t max
, const object_type
*o_ptr
, int pref
, int mode
)
1670 object_type object_type_body
;
1671 object_type
*i_ptr
= &object_type_body
;
1674 object_copy(i_ptr
, o_ptr
);
1676 /* HACK - Pretend the object is in a store inventory */
1677 i_ptr
->ident
|= IDENT_STORE
;
1680 object_desc(buf
, max
, i_ptr
, pref
, mode
);
1685 * Describe an item's random attributes for "character dumps"
1687 void identify_random_gen(const object_type
*o_ptr
)
1689 /* Set hooks for character dump */
1690 object_info_out_flags
= object_flags_known
;
1692 /* Set the indent/wrap */
1693 text_out_indent
= 3;
1697 if (object_info_out(o_ptr
))
1700 /* Reset indent/wrap */
1701 text_out_indent
= 0;
1707 * Convert an inventory index into a one character label.
1709 * Note that the label does NOT distinguish inven/equip.
1711 char index_to_label(int i
)
1713 /* Indexes for "inven" are easy */
1714 if (i
< INVEN_WIELD
) return (I2A(i
));
1716 /* Indexes for "equip" are offset */
1717 return (I2A(i
- INVEN_WIELD
));
1722 * Convert a label into the index of an item in the "inven".
1724 * Return "-1" if the label does not indicate a real item.
1726 s16b
label_to_inven(int c
)
1731 i
= (islower((unsigned char)c
) ? A2I(c
) : -1);
1733 /* Verify the index */
1734 if ((i
< 0) || (i
> INVEN_PACK
)) return (-1);
1736 /* Empty slots can never be chosen */
1737 if (!inventory
[i
].k_idx
) return (-1);
1739 /* Return the index */
1745 * Convert a label into the index of a item in the "equip".
1747 * Return "-1" if the label does not indicate a real item.
1749 s16b
label_to_equip(int c
)
1754 i
= (islower((unsigned char)c
) ? A2I(c
) : -1) + INVEN_WIELD
;
1756 /* Verify the index */
1757 if ((i
< INVEN_WIELD
) || (i
>= INVEN_TOTAL
)) return (-1);
1759 /* Empty slots can never be chosen */
1760 if (!inventory
[i
].k_idx
) return (-1);
1762 /* Return the index */
1769 * Determine which equipment slot (if any) an item likes
1771 s16b
wield_slot(const object_type
*o_ptr
)
1773 /* Slot for equipment */
1774 switch (o_ptr
->tval
)
1781 return (INVEN_WIELD
);
1791 /* Use the right hand first */
1792 if (!inventory
[INVEN_RIGHT
].k_idx
) return (INVEN_RIGHT
);
1794 /* Use the left hand for swapping (by default) */
1795 return (INVEN_LEFT
);
1800 return (INVEN_NECK
);
1805 return (INVEN_LITE
);
1812 return (INVEN_BODY
);
1817 return (INVEN_OUTER
);
1828 return (INVEN_HEAD
);
1833 return (INVEN_HANDS
);
1838 return (INVEN_FEET
);
1842 /* No slot available */
1848 * Return a string mentioning how a given item is carried
1850 cptr
mention_use(int i
)
1854 /* Examine the location */
1857 case INVEN_WIELD
: p
= "Wielding"; break;
1858 case INVEN_BOW
: p
= "Shooting"; break;
1859 case INVEN_LEFT
: p
= "On left hand"; break;
1860 case INVEN_RIGHT
: p
= "On right hand"; break;
1861 case INVEN_NECK
: p
= "Around neck"; break;
1862 case INVEN_LITE
: p
= "Light source"; break;
1863 case INVEN_BODY
: p
= "On body"; break;
1864 case INVEN_OUTER
: p
= "About body"; break;
1865 case INVEN_ARM
: p
= "On arm"; break;
1866 case INVEN_HEAD
: p
= "On head"; break;
1867 case INVEN_HANDS
: p
= "On hands"; break;
1868 case INVEN_FEET
: p
= "On feet"; break;
1869 default: p
= "In pack"; break;
1872 /* Hack -- Heavy weapon */
1873 if (i
== INVEN_WIELD
)
1876 o_ptr
= &inventory
[i
];
1877 if (adj_str_hold
[p_ptr
->stat_ind
[A_STR
]] < o_ptr
->weight
/ 10)
1883 /* Hack -- Heavy bow */
1887 o_ptr
= &inventory
[i
];
1888 if (adj_str_hold
[p_ptr
->stat_ind
[A_STR
]] < o_ptr
->weight
/ 10)
1894 /* Return the result */
1900 * Return a string describing how a given item is being worn.
1901 * Currently, only used for items in the equipment, not inventory.
1903 cptr
describe_use(int i
)
1909 case INVEN_WIELD
: p
= "attacking monsters with"; break;
1910 case INVEN_BOW
: p
= "shooting missiles with"; break;
1911 case INVEN_LEFT
: p
= "wearing on your left hand"; break;
1912 case INVEN_RIGHT
: p
= "wearing on your right hand"; break;
1913 case INVEN_NECK
: p
= "wearing around your neck"; break;
1914 case INVEN_LITE
: p
= "using to light the way"; break;
1915 case INVEN_BODY
: p
= "wearing on your body"; break;
1916 case INVEN_OUTER
: p
= "wearing on your back"; break;
1917 case INVEN_ARM
: p
= "wearing on your arm"; break;
1918 case INVEN_HEAD
: p
= "wearing on your head"; break;
1919 case INVEN_HANDS
: p
= "wearing on your hands"; break;
1920 case INVEN_FEET
: p
= "wearing on your feet"; break;
1921 default: p
= "carrying in your pack"; break;
1924 /* Hack -- Heavy weapon */
1925 if (i
== INVEN_WIELD
)
1928 o_ptr
= &inventory
[i
];
1929 if (adj_str_hold
[p_ptr
->stat_ind
[A_STR
]] < o_ptr
->weight
/ 10)
1935 /* Hack -- Heavy bow */
1939 o_ptr
= &inventory
[i
];
1940 if (adj_str_hold
[p_ptr
->stat_ind
[A_STR
]] < o_ptr
->weight
/ 10)
1946 /* Return the result */
1955 * Check an item against the item tester info
1957 bool item_tester_okay(const object_type
*o_ptr
)
1959 /* Hack -- allow listing empty slots */
1960 if (item_tester_full
) return (TRUE
);
1962 /* Require an item */
1963 if (!o_ptr
->k_idx
) return (FALSE
);
1965 /* Hack -- ignore "gold" */
1966 if (o_ptr
->tval
== TV_GOLD
) return (FALSE
);
1968 /* Check the tval */
1969 if (item_tester_tval
)
1971 if (!(item_tester_tval
== o_ptr
->tval
)) return (FALSE
);
1974 /* Check the hook */
1975 if (item_tester_hook
)
1977 if (!(*item_tester_hook
)(o_ptr
)) return (FALSE
);
1987 * Get the indexes of objects at a given floor location. -TNB-
1989 * Return the number of object indexes acquired.
1991 * Valid flags are any combination of the bits:
1992 * 0x01 -- Verify item tester
1993 * 0x02 -- Marked/visible items only
1994 * 0x04 -- Only the top item
1996 bool scan_floor(int *items
, int *item_num
, int y
, int x
, int mode
)
1998 int this_o_idx
, next_o_idx
;
2005 if (!in_bounds(y
, x
)) return (FALSE
);
2007 /* Scan all objects in the grid */
2008 for (this_o_idx
= cave_o_idx
[y
][x
]; this_o_idx
; this_o_idx
= next_o_idx
)
2012 /* Get the object */
2013 o_ptr
= &o_list
[this_o_idx
];
2015 /* Get the next object */
2016 next_o_idx
= o_ptr
->next_o_idx
;
2019 if ((mode
& 0x01) && !item_tester_okay(o_ptr
)) continue;
2022 if ((mode
& 0x02) && (!o_ptr
->marked
|| squelch_hide_item(o_ptr
)))
2025 /* Accept this item */
2026 items
[num
++] = this_o_idx
;
2029 if (mode
& 0x04) break;
2031 /* XXX Hack -- Enforce limit */
2032 if (num
== MAX_FLOOR_STACK
) break;
2035 /* Number of items */
2045 * Choice window "shadow" of the "show_inven()" function
2047 void display_inven(void)
2049 register int i
, n
, z
= 0;
2060 /* Find the "final" slot */
2061 for (i
= 0; i
< INVEN_PACK
; i
++)
2063 o_ptr
= &inventory
[i
];
2065 /* Skip non-objects */
2066 if (!o_ptr
->k_idx
) continue;
2072 /* Display the pack */
2073 for (i
= 0; i
< z
; i
++)
2075 /* Examine the item */
2076 o_ptr
= &inventory
[i
];
2078 /* Start with an empty "index" */
2079 tmp_val
[0] = tmp_val
[1] = tmp_val
[2] = ' ';
2081 /* Is this item "acceptable"? */
2082 if (item_tester_okay(o_ptr
))
2084 /* Prepare an "index" */
2085 tmp_val
[0] = index_to_label(i
);
2087 /* Bracket the "index" --(-- */
2091 /* Display the index (or blank space) */
2092 Term_putstr(0, i
, 3, TERM_WHITE
, tmp_val
);
2094 /* Obtain an item description */
2095 object_desc(o_name
, sizeof(o_name
), o_ptr
, TRUE
, 3);
2097 /* Obtain the length of the description */
2100 /* Get inventory color */
2101 attr
= tval_to_attr
[o_ptr
->tval
% N_ELEMENTS(tval_to_attr
)];
2103 /* Display the entry itself */
2104 Term_putstr(3, i
, n
, attr
, o_name
);
2106 /* Erase the rest of the line */
2107 Term_erase(3+n
, i
, 255);
2109 /* Display the weight if needed */
2112 int wgt
= o_ptr
->weight
* o_ptr
->number
;
2113 strnfmt(tmp_val
, sizeof(tmp_val
), "%3d.%1d lb", wgt
/ 10, wgt
% 10);
2114 Term_putstr(71, i
, -1, TERM_WHITE
, tmp_val
);
2118 /* Erase the rest of the window */
2119 for (i
= z
; i
< Term
->hgt
; i
++)
2121 /* Erase the line */
2122 Term_erase(0, i
, 255);
2129 * Choice window "shadow" of the "show_equip()" function
2131 void display_equip(void)
2142 /* Display the equipment */
2143 for (i
= INVEN_WIELD
; i
< INVEN_TOTAL
; i
++)
2145 /* Examine the item */
2146 o_ptr
= &inventory
[i
];
2148 /* Start with an empty "index" */
2149 tmp_val
[0] = tmp_val
[1] = tmp_val
[2] = ' ';
2151 /* Is this item "acceptable"? */
2152 if (item_tester_okay(o_ptr
))
2154 /* Prepare an "index" */
2155 tmp_val
[0] = index_to_label(i
);
2157 /* Bracket the "index" --(-- */
2161 /* Display the index (or blank space) */
2162 Term_putstr(0, i
- INVEN_WIELD
, 3, TERM_WHITE
, tmp_val
);
2164 /* Obtain an item description */
2165 object_desc(o_name
, sizeof(o_name
), o_ptr
, TRUE
, 3);
2167 /* Obtain the length of the description */
2170 /* Get inventory color */
2171 attr
= tval_to_attr
[o_ptr
->tval
% N_ELEMENTS(tval_to_attr
)];
2173 /* Display the entry itself */
2174 Term_putstr(3, i
- INVEN_WIELD
, n
, attr
, o_name
);
2176 /* Erase the rest of the line */
2177 Term_erase(3+n
, i
- INVEN_WIELD
, 255);
2179 /* Display the slot description (if needed) */
2182 Term_putstr(61, i
- INVEN_WIELD
, -1, TERM_WHITE
, "<--");
2183 Term_putstr(65, i
- INVEN_WIELD
, -1, TERM_WHITE
, mention_use(i
));
2186 /* Display the weight (if needed) */
2189 int wgt
= o_ptr
->weight
* o_ptr
->number
;
2190 int col
= (show_labels
? 52 : 71);
2191 strnfmt(tmp_val
, sizeof(tmp_val
), "%3d.%1d lb", wgt
/ 10, wgt
% 10);
2192 Term_putstr(col
, i
- INVEN_WIELD
, -1, TERM_WHITE
, tmp_val
);
2196 /* Erase the rest of the window */
2197 for (i
= INVEN_TOTAL
- INVEN_WIELD
; i
< Term
->hgt
; i
++)
2199 /* Clear that line */
2200 Term_erase(0, i
, 255);
2207 * Display the inventory.
2209 * Hack -- do not display "trailing" empty slots
2211 void show_inven(void)
2213 int i
, j
, k
, l
, z
= 0;
2224 char out_desc
[24][80];
2227 /* Default length */
2230 /* Maximum space allowed for descriptions */
2231 /* screen width - "a) " - weight */
2235 /* Find the "final" slot */
2236 for (i
= 0; i
< INVEN_PACK
; i
++)
2238 o_ptr
= &inventory
[i
];
2240 /* Skip non-objects */
2241 if (!o_ptr
->k_idx
) continue;
2247 /* Display the inventory */
2248 for (k
= 0, i
= 0; i
< z
; i
++)
2250 o_ptr
= &inventory
[i
];
2252 /* Is this item acceptable? */
2253 if (!item_tester_okay(o_ptr
)) continue;
2255 /* Describe the object */
2256 object_desc(o_name
, sizeof(o_name
), o_ptr
, TRUE
, 3);
2258 /* Hack -- enforce max length */
2261 /* Save the index */
2264 /* Get inventory color */
2265 out_color
[k
] = tval_to_attr
[o_ptr
->tval
% N_ELEMENTS(tval_to_attr
)];
2267 /* Save the object description */
2268 my_strcpy(out_desc
[k
], o_name
, sizeof(out_desc
[0]));
2270 /* Find the predicted "line length" */
2271 l
= strlen(out_desc
[k
]) + 5;
2273 /* Be sure to account for the weight */
2276 /* Maintain the maximum length */
2277 if (l
> len
) len
= l
;
2279 /* Advance to next "line" */
2283 /* Find the column to start in */
2284 col
= (len
> 76) ? 0 : (79 - len
);
2286 /* Output each entry */
2287 for (j
= 0; j
< k
; j
++)
2295 o_ptr
= &inventory
[i
];
2297 /* Clear the line */
2298 prt("", j
+ 1, col
? col
- 2 : col
);
2300 /* Prepare an index --(-- */
2301 strnfmt(tmp_val
, sizeof(tmp_val
), "%c)", index_to_label(i
));
2303 /* Clear the line with the (possibly indented) index */
2304 put_str(tmp_val
, j
+ 1, col
);
2306 /* Display the entry itself */
2307 c_put_str(out_color
[j
], out_desc
[j
], j
+ 1, col
+ 3);
2309 /* Display the weight if needed */
2310 wgt
= o_ptr
->weight
* o_ptr
->number
;
2311 strnfmt(tmp_val
, sizeof(tmp_val
), "%3d.%1d lb", wgt
/ 10, wgt
% 10);
2312 put_str(tmp_val
, j
+ 1, 71);
2315 /* Make a "shadow" below the list (only if needed) */
2316 if (j
&& (j
< 23)) prt("", j
+ 1, col
? col
- 2 : col
);
2321 * Display the equipment.
2323 void show_equip(void)
2336 char out_desc
[24][80];
2339 /* Default length */
2342 /* Maximum space allowed for descriptions */
2345 /* Require space for labels (if needed) */
2346 if (show_labels
) lim
-= (14 + 2);
2348 /* Require space for weight */
2351 /* Scan the equipment list */
2352 for (k
= 0, i
= INVEN_WIELD
; i
< INVEN_TOTAL
; i
++)
2354 o_ptr
= &inventory
[i
];
2356 /* Is this item acceptable? */
2357 if (!item_tester_okay(o_ptr
)) continue;
2360 object_desc(o_name
, sizeof(o_name
), o_ptr
, TRUE
, 3);
2362 /* Truncate the description */
2365 /* Save the index */
2368 /* Get inventory color */
2369 out_color
[k
] = tval_to_attr
[o_ptr
->tval
% N_ELEMENTS(tval_to_attr
)];
2371 /* Save the description */
2372 my_strcpy(out_desc
[k
], o_name
, sizeof(out_desc
[0]));
2374 /* Extract the maximal length (see below) */
2375 l
= strlen(out_desc
[k
]) + (2 + 3);
2377 /* Increase length for labels (if needed) */
2378 if (show_labels
) l
+= (14 + 2);
2380 /* Increase length for weight */
2383 /* Maintain the max-length */
2384 if (l
> len
) len
= l
;
2386 /* Advance the entry */
2390 /* Hack -- Find a column to start in */
2391 col
= (len
> 76) ? 0 : (79 - len
);
2393 /* Output each entry */
2394 for (j
= 0; j
< k
; j
++)
2402 o_ptr
= &inventory
[i
];
2404 /* Clear the line */
2405 prt("", j
+ 1, col
? col
- 2 : col
);
2407 /* Prepare an index --(-- */
2408 strnfmt(tmp_val
, sizeof(tmp_val
), "%c)", index_to_label(i
));
2410 /* Clear the line with the (possibly indented) index */
2411 put_str(tmp_val
, j
+1, col
);
2416 /* Mention the use */
2417 strnfmt(tmp_val
, sizeof(tmp_val
), "%-14s: ", mention_use(i
));
2418 put_str(tmp_val
, j
+1, col
+ 3);
2420 /* Display the entry itself */
2421 c_put_str(out_color
[j
], out_desc
[j
], j
+1, col
+ 3 + 14 + 2);
2427 /* Display the entry itself */
2428 c_put_str(out_color
[j
], out_desc
[j
], j
+1, col
+ 3);
2431 /* Display the weight if needed */
2432 wgt
= o_ptr
->weight
* o_ptr
->number
;
2433 strnfmt(tmp_val
, sizeof(tmp_val
), "%3d.%d lb", wgt
/ 10, wgt
% 10);
2434 put_str(tmp_val
, j
+1, 71);
2437 /* Make a "shadow" below the list (only if needed) */
2438 if (j
&& (j
< 23)) prt("", j
+ 1, col
? col
- 2 : col
);
2443 * Display a list of the items on the floor at the given location. -TNB-
2445 void show_floor(const int *floor_list
, int floor_num
, bool gold
)
2456 int out_index
[MAX_FLOOR_STACK
];
2457 byte out_color
[MAX_FLOOR_STACK
];
2458 char out_desc
[MAX_FLOOR_STACK
][80];
2461 /* Default length */
2464 /* Maximum space allowed for descriptions */
2467 /* Require space for weight */
2470 /* Limit displayed floor items to 23 (screen limits) */
2471 if (floor_num
> MAX_FLOOR_STACK
) floor_num
= MAX_FLOOR_STACK
;
2473 /* Display the floor */
2474 for (k
= 0, i
= 0; i
< floor_num
; i
++)
2476 o_ptr
= &o_list
[floor_list
[i
]];
2478 /* Optionally, show gold */
2479 if ((o_ptr
->tval
!= TV_GOLD
) || (!gold
))
2481 /* Is this item acceptable? (always rejects gold) */
2482 if (!item_tester_okay(o_ptr
)) continue;
2485 /* Describe the object */
2486 object_desc(o_name
, sizeof(o_name
), o_ptr
, TRUE
, 3);
2488 /* Hack -- enforce max length */
2491 /* Save the index */
2494 /* Get inventory color */
2495 out_color
[k
] = tval_to_attr
[o_ptr
->tval
% N_ELEMENTS(tval_to_attr
)];
2497 /* Save the object description */
2498 my_strcpy(out_desc
[k
], o_name
, sizeof(out_desc
[0]));
2500 /* Find the predicted "line length" */
2501 l
= strlen(out_desc
[k
]) + 5;
2503 /* Be sure to account for the weight */
2506 /* Maintain the maximum length */
2507 if (l
> len
) len
= l
;
2509 /* Advance to next "line" */
2513 /* Find the column to start in */
2514 col
= (len
> 76) ? 0 : (79 - len
);
2516 /* Output each entry */
2517 for (j
= 0; j
< k
; j
++)
2522 i
= floor_list
[out_index
[j
]];
2527 /* Clear the line */
2528 prt("", j
+ 1, col
? col
- 2 : col
);
2530 /* Prepare an index --(-- */
2531 strnfmt(tmp_val
, sizeof(tmp_val
), "%c)", index_to_label(out_index
[j
]));
2533 /* Clear the line with the (possibly indented) index */
2534 put_str(tmp_val
, j
+ 1, col
);
2536 /* Display the entry itself */
2537 c_put_str(out_color
[j
], out_desc
[j
], j
+ 1, col
+ 3);
2539 /* Display the weight if needed */
2540 wgt
= o_ptr
->weight
* o_ptr
->number
;
2541 strnfmt(tmp_val
, sizeof(tmp_val
), "%3d.%1d lb", wgt
/ 10, wgt
% 10);
2542 put_str(tmp_val
, j
+ 1, 71);
2545 /* Make a "shadow" below the list (only if needed) */
2546 if (j
&& (j
< 23)) prt("", j
+ 1, col
? col
- 2 : col
);
2552 * Flip "inven" and "equip" in any sub-windows
2554 void toggle_inven_equip(void)
2559 for (j
= 0; j
< ANGBAND_TERM_MAX
; j
++)
2562 if (!angband_term
[j
]) continue;
2564 /* Flip inven to equip */
2565 if (op_ptr
->window_flag
[j
] & (PW_INVEN
))
2568 op_ptr
->window_flag
[j
] &= ~(PW_INVEN
);
2569 op_ptr
->window_flag
[j
] |= (PW_EQUIP
);
2572 p_ptr
->window
|= (PW_EQUIP
);
2575 /* Flip inven to equip */
2576 else if (op_ptr
->window_flag
[j
] & (PW_EQUIP
))
2579 op_ptr
->window_flag
[j
] &= ~(PW_EQUIP
);
2580 op_ptr
->window_flag
[j
] |= (PW_INVEN
);
2583 p_ptr
->window
|= (PW_INVEN
);
2592 * Verify the choice of an item.
2594 * The item can be negative to mean "item on floor".
2596 bool verify_item(cptr prompt
, int item
)
2607 o_ptr
= &inventory
[item
];
2613 o_ptr
= &o_list
[0 - item
];
2617 object_desc(o_name
, sizeof(o_name
), o_ptr
, TRUE
, 3);
2620 strnfmt(out_val
, sizeof(out_val
), "%s %s? ", prompt
, o_name
);
2623 return (get_check(out_val
));
2628 * Hack -- allow user to "prevent" certain choices.
2630 * The item can be negative to mean "item on floor".
2632 static bool get_item_allow(int item
)
2635 char verify_inscrip
[] = "!*";
2640 o_ptr
= &inventory
[item
];
2646 o_ptr
= &o_list
[0 - item
];
2649 /* Check for a "prevention" inscription */
2650 verify_inscrip
[1] = p_ptr
->command_cmd
;
2652 if (o_ptr
->note
&& (check_for_inscrip(o_ptr
, "!*") ||
2653 check_for_inscrip(o_ptr
, verify_inscrip
)))
2655 /* Verify the choice */
2656 if (!verify_item("Really try", item
)) return (FALSE
);
2665 * Verify the "okayness" of a given item.
2667 * The item can be negative to mean "item on floor".
2669 static bool get_item_okay(int item
)
2676 o_ptr
= &inventory
[item
];
2682 o_ptr
= &o_list
[0 - item
];
2685 /* Verify the item */
2686 return (item_tester_okay(o_ptr
));
2692 * Find the "first" inventory object with the given "tag".
2694 * A "tag" is a char "n" appearing as "@n" anywhere in the
2695 * inscription of an object.
2697 * Also, the tag "@xn" will work as well, where "n" is a tag-char,
2698 * and "x" is the "current" p_ptr->command_cmd code.
2700 static int get_tag(int *cp
, char tag
)
2706 /* Check every object */
2707 for (i
= 0; i
< INVEN_TOTAL
; ++i
)
2709 object_type
*o_ptr
= &inventory
[i
];
2711 /* Skip non-objects */
2712 if (!o_ptr
->k_idx
) continue;
2714 /* Skip empty inscriptions */
2715 if (!o_ptr
->note
) continue;
2718 s
= strchr(quark_str(o_ptr
->note
), '@');
2720 /* Process all tags */
2723 /* Check the normal tags */
2726 /* Save the actual inventory ID */
2733 /* Check the special tags */
2734 if ((s
[1] == p_ptr
->command_cmd
) && (s
[2] == tag
))
2736 /* Save the actual inventory ID */
2743 /* Find another '@' */
2744 s
= strchr(s
+ 1, '@');
2755 * Let the user select an item, save its "index"
2757 * Return TRUE only if an acceptable item was chosen by the user.
2759 * The selected item must satisfy the "item_tester_hook()" function,
2760 * if that hook is set, and the "item_tester_tval", if that value is set.
2762 * All "item_tester" restrictions are cleared before this function returns.
2764 * The user is allowed to choose acceptable items from the equipment,
2765 * inventory, or floor, respectively, if the proper flag was given,
2766 * and there are any acceptable items in that location.
2768 * The equipment or inventory are displayed (even if no acceptable
2769 * items are in that location) if the proper flag was given.
2771 * If there are no acceptable items available anywhere, and "str" is
2772 * not NULL, then it will be used as the text of a warning message
2773 * before the function returns.
2775 * Note that the user must press "-" to specify the item on the floor,
2776 * and there is no way to "examine" the item on the floor, while the
2777 * use of "capital" letters will "examine" an inventory/equipment item,
2778 * and prompt for its use.
2780 * If a legal item is selected from the inventory, we save it in "cp"
2781 * directly (0 to 35), and return TRUE.
2783 * If a legal item is selected from the floor, we save it in "cp" as
2784 * a negative (-1 to -511), and return TRUE.
2786 * If no item is available, we do nothing to "cp", and we display a
2787 * warning message, using "str" if available, and return FALSE.
2789 * If no item is selected, we do nothing to "cp", and return FALSE.
2791 * Global "p_ptr->command_new" is used when viewing the inventory or equipment
2792 * to allow the user to enter a command while viewing those screens, and
2793 * also to induce "auto-enter" of stores, and other such stuff.
2795 * Global "p_ptr->command_see" may be set before calling this function to start
2796 * out in "browse" mode. It is cleared before this function returns.
2798 * Global "p_ptr->command_wrk" is used to choose between equip/inven/floor
2799 * listings. It is equal to USE_INVEN or USE_EQUIP or USE_FLOOR, except
2800 * when this function is first called, when it is equal to zero, which will
2801 * cause it to be set to USE_INVEN.
2803 * We always erase the prompt when we are done, leaving a blank line,
2804 * or a warning message, if appropriate, if no items are available.
2806 * Note that only "acceptable" floor objects get indexes, so between two
2807 * commands, the indexes of floor objects may change. XXX XXX XXX
2809 bool get_item(int *cp
, cptr pmt
, cptr str
, int mode
)
2826 bool use_inven
= ((mode
& USE_INVEN
) ? TRUE
: FALSE
);
2827 bool use_equip
= ((mode
& USE_EQUIP
) ? TRUE
: FALSE
);
2828 bool use_floor
= ((mode
& USE_FLOOR
) ? TRUE
: FALSE
);
2829 bool can_squelch
= ((mode
& CAN_SQUELCH
) ? TRUE
: FALSE
);
2831 bool allow_inven
= FALSE
;
2832 bool allow_equip
= FALSE
;
2833 bool allow_floor
= FALSE
;
2835 bool toggle
= FALSE
;
2840 int floor_list
[MAX_FLOOR_STACK
];
2844 /* Get the item index */
2845 if (repeat_pull(cp
))
2847 /* Verify the item */
2848 if (get_item_okay(*cp
))
2850 /* Forget the item_tester_tval restriction */
2851 item_tester_tval
= 0;
2853 /* Forget the item_tester_hook restriction */
2854 item_tester_hook
= NULL
;
2861 /* Invalid repeat - reset it */
2867 /* Paranoia XXX XXX XXX */
2874 /* No item selected */
2878 /* Full inventory */
2880 i2
= INVEN_PACK
- 1;
2882 /* Forbid inventory */
2883 if (!use_inven
) i2
= -1;
2885 /* Restrict inventory indexes */
2886 while ((i1
<= i2
) && (!get_item_okay(i1
))) i1
++;
2887 while ((i1
<= i2
) && (!get_item_okay(i2
))) i2
--;
2889 /* Accept inventory */
2890 if (i1
<= i2
) allow_inven
= TRUE
;
2893 /* Full equipment */
2895 e2
= INVEN_TOTAL
- 1;
2897 /* Forbid equipment */
2898 if (!use_equip
) e2
= -1;
2900 /* Restrict equipment indexes */
2901 while ((e1
<= e2
) && (!get_item_okay(e1
))) e1
++;
2902 while ((e1
<= e2
) && (!get_item_okay(e2
))) e2
--;
2904 /* Accept equipment */
2905 if (e1
<= e2
) allow_equip
= TRUE
;
2908 /* Scan all non-gold objects in the grid */
2909 (void)scan_floor(floor_list
, &floor_num
, py
, px
, 0x01);
2916 if (!use_floor
) f2
= -1;
2918 /* Restrict floor indexes */
2919 while ((f1
<= f2
) && (!get_item_okay(0 - floor_list
[f1
]))) f1
++;
2920 while ((f1
<= f2
) && (!get_item_okay(0 - floor_list
[f2
]))) f2
--;
2923 if (f1
<= f2
) allow_floor
= TRUE
;
2926 /* Require at least one legal choice */
2927 if (!allow_inven
&& !allow_equip
&& !allow_floor
)
2929 /* Cancel p_ptr->command_see */
2930 p_ptr
->command_see
= FALSE
;
2939 /* Analyze choices */
2942 /* Hack -- Start on equipment if requested */
2943 if (p_ptr
->command_see
&&
2944 (p_ptr
->command_wrk
== (USE_EQUIP
)) &&
2947 p_ptr
->command_wrk
= (USE_EQUIP
);
2950 /* Use inventory if allowed */
2953 p_ptr
->command_wrk
= (USE_INVEN
);
2956 /* Use equipment if allowed */
2959 p_ptr
->command_wrk
= (USE_EQUIP
);
2962 /* Use floor if allowed */
2965 p_ptr
->command_wrk
= (USE_FLOOR
);
2968 /* Hack -- Use (empty) inventory */
2971 p_ptr
->command_wrk
= (USE_INVEN
);
2976 /* Start out in "display" mode */
2977 if (p_ptr
->command_see
)
2984 /* Repeat until done */
2991 for (j
= 0; j
< ANGBAND_TERM_MAX
; j
++)
2994 if (!angband_term
[j
]) continue;
2996 /* Count windows displaying inven */
2997 if (op_ptr
->window_flag
[j
] & (PW_INVEN
)) ni
++;
2999 /* Count windows displaying equip */
3000 if (op_ptr
->window_flag
[j
] & (PW_EQUIP
)) ne
++;
3003 /* Toggle if needed */
3004 if (((p_ptr
->command_wrk
== (USE_EQUIP
)) && ni
&& !ne
) ||
3005 ((p_ptr
->command_wrk
== (USE_INVEN
)) && !ni
&& ne
))
3008 toggle_inven_equip();
3015 p_ptr
->window
|= (PW_INVEN
| PW_EQUIP
);
3017 /* Redraw windows */
3020 /* Viewing inventory */
3021 if (p_ptr
->command_wrk
== (USE_INVEN
))
3023 /* Redraw if needed */
3024 if (p_ptr
->command_see
) show_inven();
3026 /* Begin the prompt */
3027 strnfmt(out_val
, sizeof(out_val
), "Inven:");
3032 /* Build the prompt */
3033 strnfmt(tmp_val
, sizeof(tmp_val
), " %c-%c,",
3034 index_to_label(i1
), index_to_label(i2
));
3037 my_strcat(out_val
, tmp_val
, sizeof(out_val
));
3040 /* Indicate ability to "view" */
3041 if (!p_ptr
->command_see
) my_strcat(out_val
, " * to see,", sizeof(out_val
));
3043 /* Indicate legality of "toggle" */
3044 if (use_equip
) my_strcat(out_val
, " / for Equip,", sizeof(out_val
));
3046 /* Indicate legality of the "floor" */
3047 if (allow_floor
) my_strcat(out_val
, " - for floor,", sizeof(out_val
));
3049 /* Indicate that squelched items can be selected */
3050 if (can_squelch
) my_strcat(out_val
, " ! for squelched,", sizeof(out_val
));
3053 /* Viewing equipment */
3054 else if (p_ptr
->command_wrk
== (USE_EQUIP
))
3056 /* Redraw if needed */
3057 if (p_ptr
->command_see
) show_equip();
3059 /* Begin the prompt */
3060 strnfmt(out_val
, sizeof(out_val
), "Equip:");
3065 /* Build the prompt */
3066 strnfmt(tmp_val
, sizeof(tmp_val
), " %c-%c,",
3067 index_to_label(e1
), index_to_label(e2
));
3070 my_strcat(out_val
, tmp_val
, sizeof(out_val
));
3073 /* Indicate ability to "view" */
3074 if (!p_ptr
->command_see
) my_strcat(out_val
, " * to see,", sizeof(out_val
));
3076 /* Indicate legality of "toggle" */
3077 if (use_inven
) my_strcat(out_val
, " / for Inven,", sizeof(out_val
));
3079 /* Indicate legality of the "floor" */
3080 if (allow_floor
) my_strcat(out_val
, " - for floor,", sizeof(out_val
));
3086 /* Redraw if needed */
3087 if (p_ptr
->command_see
) show_floor(floor_list
, floor_num
, FALSE
);
3089 /* Begin the prompt */
3090 strnfmt(out_val
, sizeof(out_val
), "Floor:");
3095 /* Build the prompt */
3096 strnfmt(tmp_val
, sizeof(tmp_val
), " %c-%c,", I2A(f1
), I2A(f2
));
3099 my_strcat(out_val
, tmp_val
, sizeof(out_val
));
3102 /* Indicate ability to "view" */
3103 if (!p_ptr
->command_see
) my_strcat(out_val
, " * to see,", sizeof(out_val
));
3106 if (use_inven
) my_strcat(out_val
, " / for Inven,", sizeof(out_val
));
3109 else if (use_equip
) my_strcat(out_val
, " / for Equip,", sizeof(out_val
));
3111 /* Indicate that squelched items can be selected */
3112 if (can_squelch
) my_strcat(out_val
, " ! for squelched,", sizeof(out_val
));
3115 /* Finish the prompt */
3116 my_strcat(out_val
, " ESC", sizeof(out_val
));
3118 /* Build the prompt */
3119 strnfmt(tmp_val
, sizeof(tmp_val
), "(%s) %s", out_val
, pmt
);
3121 /* Show the prompt */
3142 if (p_ptr
->command_see
)
3145 p_ptr
->command_see
= FALSE
;
3158 p_ptr
->command_see
= TRUE
;
3166 /* Toggle to inventory */
3167 if (use_inven
&& (p_ptr
->command_wrk
!= (USE_INVEN
)))
3169 p_ptr
->command_wrk
= (USE_INVEN
);
3172 /* Toggle to equipment */
3173 else if (use_equip
&& (p_ptr
->command_wrk
!= (USE_EQUIP
)))
3175 p_ptr
->command_wrk
= (USE_EQUIP
);
3178 /* No toggle allowed */
3181 bell("Cannot switch item selector!");
3185 /* Hack -- Fix screen */
3186 if (p_ptr
->command_see
)
3195 /* Need to redraw */
3204 bell("Cannot select floor!");
3208 /* There is only one item */
3212 if (p_ptr
->command_wrk
== (USE_FLOOR
))
3215 k
= 0 - floor_list
[0];
3217 /* Allow player to "refuse" certain actions */
3218 if (!get_item_allow(k
))
3224 /* Accept that choice */
3233 /* Hack -- Fix screen */
3234 if (p_ptr
->command_see
)
3243 p_ptr
->command_wrk
= (USE_FLOOR
);
3246 /* Check each legal object */
3247 for (i
= 0; i
< floor_num
; ++i
)
3250 k
= 0 - floor_list
[i
];
3252 /* Skip non-okay objects */
3253 if (!get_item_okay(k
)) continue;
3255 /* Allow player to "refuse" certain actions */
3256 if (!get_item_allow(k
)) continue;
3258 /* Accept that choice */
3270 case '1': case '2': case '3':
3271 case '4': case '5': case '6':
3272 case '7': case '8': case '9':
3274 /* Look up the tag */
3275 if (!get_tag(&k
, which
))
3277 bell("Illegal object choice (tag)!");
3281 /* Hack -- Validate the item */
3282 if ((k
< INVEN_WIELD
) ? !allow_inven
: !allow_equip
)
3284 bell("Illegal object choice (tag)!");
3288 /* Validate the item */
3289 if (!get_item_okay(k
))
3291 bell("Illegal object choice (tag)!");
3295 /* Allow player to "refuse" certain actions */
3296 if (!get_item_allow(k
))
3302 /* Accept that choice */
3312 /* Choose "default" inventory item */
3313 if (p_ptr
->command_wrk
== (USE_INVEN
))
3317 bell("Illegal object choice (default)!");
3324 /* Choose "default" equipment item */
3325 else if (p_ptr
->command_wrk
== (USE_EQUIP
))
3329 bell("Illegal object choice (default)!");
3336 /* Choose "default" floor item */
3341 bell("Illegal object choice (default)!");
3345 k
= 0 - floor_list
[f1
];
3348 /* Validate the item */
3349 if (!get_item_okay(k
))
3351 bell("Illegal object choice (default)!");
3355 /* Allow player to "refuse" certain actions */
3356 if (!get_item_allow(k
))
3362 /* Accept that choice */
3371 /* Try squelched items */
3374 (*cp
) = ALL_SQUELCHED
;
3380 /* Just fall through */
3388 verify
= (isupper((unsigned char)which
) ? TRUE
: FALSE
);
3391 which
= tolower((unsigned char)which
);
3393 /* Convert letter to inventory index */
3394 if (p_ptr
->command_wrk
== (USE_INVEN
))
3396 k
= label_to_inven(which
);
3400 bell("Illegal object choice (inven)!");
3405 /* Convert letter to equipment index */
3406 else if (p_ptr
->command_wrk
== (USE_EQUIP
))
3408 k
= label_to_equip(which
);
3412 bell("Illegal object choice (equip)!");
3417 /* Convert letter to floor index */
3420 k
= (islower((unsigned char)which
) ? A2I(which
) : -1);
3422 if (k
< 0 || k
>= floor_num
)
3424 bell("Illegal object choice (floor)!");
3429 k
= 0 - floor_list
[k
];
3432 /* Validate the item */
3433 if (!get_item_okay(k
))
3435 bell("Illegal object choice (normal)!");
3439 /* Verify the item */
3440 if (verify
&& !verify_item("Try", k
))
3446 /* Allow player to "refuse" certain actions */
3447 if (!get_item_allow(k
))
3453 /* Accept that choice */
3463 /* Fix the screen if necessary */
3464 if (p_ptr
->command_see
)
3469 /* Hack -- Cancel "display" */
3470 p_ptr
->command_see
= FALSE
;
3474 /* Forget the item_tester_tval restriction */
3475 item_tester_tval
= 0;
3477 /* Forget the item_tester_hook restriction */
3478 item_tester_hook
= NULL
;
3481 /* Toggle again if needed */
3482 if (toggle
) toggle_inven_equip();
3485 p_ptr
->window
|= (PW_INVEN
| PW_EQUIP
);
3491 /* Clear the prompt line */
3494 /* Warning if needed */
3495 if (oops
&& str
) msg_print(str
);
3497 /* Save item if available */
3498 if (item
) repeat_push(*cp
);