1 /* NetHack 3.6 do_wear.c $NHDT-Date: 1455667557 2016/02/17 00:05:57 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.90 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
7 static NEARDATA
const char see_yourself
[] = "see yourself";
8 static NEARDATA
const char unknown_type
[] = "Unknown type of %s (%d)";
9 static NEARDATA
const char c_armor
[] = "armor", c_suit
[] = "suit",
10 c_shirt
[] = "shirt", c_cloak
[] = "cloak",
11 c_gloves
[] = "gloves", c_boots
[] = "boots",
12 c_helmet
[] = "helmet", c_shield
[] = "shield",
13 c_weapon
[] = "weapon", c_sword
[] = "sword",
14 c_axe
[] = "axe", c_that_
[] = "that";
16 static NEARDATA
const long takeoff_order
[] = {
17 WORN_BLINDF
, W_WEP
, WORN_SHIELD
, WORN_GLOVES
, LEFT_RING
,
18 RIGHT_RING
, WORN_CLOAK
, WORN_HELMET
, WORN_AMUL
, WORN_ARMOR
,
19 WORN_SHIRT
, WORN_BOOTS
, W_SWAPWEP
, W_QUIVER
, 0L
22 STATIC_DCL
void FDECL(on_msg
, (struct obj
*));
23 STATIC_DCL
void FDECL(toggle_stealth
, (struct obj
*, long, BOOLEAN_P
));
24 STATIC_DCL
void FDECL(toggle_displacement
, (struct obj
*, long, BOOLEAN_P
));
25 STATIC_PTR
int NDECL(Armor_on
);
26 STATIC_PTR
int NDECL(Boots_on
);
27 STATIC_PTR
int NDECL(Cloak_on
);
28 STATIC_PTR
int NDECL(Helmet_on
);
29 STATIC_PTR
int NDECL(Gloves_on
);
30 STATIC_DCL
void FDECL(wielding_corpse
, (struct obj
*, BOOLEAN_P
));
31 STATIC_PTR
int NDECL(Shield_on
);
32 STATIC_PTR
int NDECL(Shirt_on
);
33 STATIC_DCL
void NDECL(Amulet_on
);
34 STATIC_DCL
void FDECL(learnring
, (struct obj
*, BOOLEAN_P
));
35 STATIC_DCL
void FDECL(Ring_off_or_gone
, (struct obj
*, BOOLEAN_P
));
36 STATIC_PTR
int FDECL(select_off
, (struct obj
*));
37 STATIC_DCL
struct obj
*NDECL(do_takeoff
);
38 STATIC_PTR
int NDECL(take_off
);
39 STATIC_DCL
int FDECL(menu_remarm
, (int));
40 STATIC_DCL
void FDECL(count_worn_stuff
, (struct obj
**, BOOLEAN_P
));
41 STATIC_PTR
int FDECL(armor_or_accessory_off
, (struct obj
*));
42 STATIC_PTR
int FDECL(accessory_or_armor_on
, (struct obj
*));
43 STATIC_DCL
void FDECL(already_wearing
, (const char *));
44 STATIC_DCL
void FDECL(already_wearing2
, (const char *, const char *));
51 You("were wearing %s.", doname(otmp
));
54 /* for items that involve no delay */
61 /* call xname() before obj_is_pname(); formatting obj's name
62 might set obj->dknown and that affects the pname test */
63 const char *otmp_name
= xname(otmp
);
66 if (otmp
->otyp
== TOWEL
)
67 Sprintf(how
, " around your %s", body_part(HEAD
));
68 You("are now wearing %s%s.",
69 obj_is_pname(otmp
) ? the(otmp_name
) : an(otmp_name
), how
);
73 /* starting equipment gets auto-worn at beginning of new game,
74 and we don't want stealth or displacement feedback then */
75 static boolean initial_don
= FALSE
; /* manipulated in set_wear() */
77 /* putting on or taking off an item which confers stealth;
78 give feedback and discover it iff stealth state is changing */
81 toggle_stealth(obj
, oldprop
, on
)
83 long oldprop
; /* prop[].extrinsic, with obj->owornmask stripped by caller */
86 if (on
? initial_don
: context
.takeoff
.cancelled_don
)
89 if (!oldprop
/* extrinsic stealth from something else */
90 && !HStealth
/* intrinsic stealth */
91 && !BStealth
) { /* stealth blocked by something */
92 if (obj
->otyp
== RIN_STEALTH
)
99 You("move very quietly.");
100 else if (Levitation
|| Flying
)
101 You("float imperceptibly.");
103 You("walk very quietly.");
105 You("sure are noisy.");
110 /* putting on or taking off an item which confers displacement;
111 give feedback and discover it iff displacement state is changing *and*
112 hero is able to see self (or sense monsters) */
115 toggle_displacement(obj
, oldprop
, on
)
117 long oldprop
; /* prop[].extrinsic, with obj->owornmask stripped by caller */
120 if (on
? initial_don
: context
.takeoff
.cancelled_don
)
123 if (!oldprop
/* extrinsic displacement from something else */
124 && !(u
.uprops
[DISPLACED
].intrinsic
) /* (theoretical) */
125 && !(u
.uprops
[DISPLACED
].blocked
) /* (also theoretical) */
126 /* we don't use canseeself() here because it augments vision
127 with touch, which isn't appropriate for deciding whether
128 we'll notice that monsters have trouble spotting the hero */
129 && ((!Blind
/* see anything */
130 && !u
.uswallow
/* see surroundings */
131 && !Invisible
) /* see self */
132 /* actively sensing nearby monsters via telepathy or extended
133 monster detection overrides vision considerations because
134 hero also senses self in this situation */
136 || (Blind_telepat
&& Blind
)
137 || Detect_monsters
))) {
138 makeknown(obj
->otyp
);
140 You_feel("that monsters%s have difficulty pinpointing your location.",
141 on
? "" : " no longer");
146 * The Type_on() functions should be called *after* setworn().
147 * The Type_off() functions call setworn() themselves.
148 * [Blindf_on() is an exception and calls setworn() itself.]
156 u
.uprops
[objects
[uarmf
->otyp
].oc_oprop
].extrinsic
& ~WORN_BOOTS
;
158 switch (uarmf
->otyp
) {
165 case WATER_WALKING_BOOTS
:
168 /* (we don't need a lava check here since boots can't be
169 put on while feet are stuck) */
172 /* Speed boots are still better than intrinsic speed, */
173 /* though not better than potion speed */
174 if (!oldprop
&& !(HFast
& TIMEOUT
)) {
175 makeknown(uarmf
->otyp
);
176 You_feel("yourself speed up%s.",
177 (oldprop
|| HFast
) ? " a bit more" : "");
181 toggle_stealth(uarmf
, oldprop
, TRUE
);
184 if (!oldprop
&& !(HFumbling
& ~TIMEOUT
))
185 incr_itimeout(&HFumbling
, rnd(20));
187 case LEVITATION_BOOTS
:
188 if (!oldprop
&& !HLevitation
&& !BLevitation
) {
189 makeknown(uarmf
->otyp
);
193 float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */
197 impossible(unknown_type
, c_boots
, uarmf
->otyp
);
205 struct obj
*otmp
= uarmf
;
206 int otyp
= otmp
->otyp
;
207 long oldprop
= u
.uprops
[objects
[otyp
].oc_oprop
].extrinsic
& ~WORN_BOOTS
;
209 context
.takeoff
.mask
&= ~W_ARMF
;
210 /* For levitation, float_down() returns if Levitation, so we
211 * must do a setworn() _before_ the levitation case.
213 setworn((struct obj
*) 0, W_ARMF
);
216 if (!Very_fast
&& !context
.takeoff
.cancelled_don
) {
218 You_feel("yourself slow down%s.", Fast
? " a bit" : "");
221 case WATER_WALKING_BOOTS
:
222 /* check for lava since fireproofed boots make it viable */
223 if ((is_pool(u
.ux
, u
.uy
) || is_lava(u
.ux
, u
.uy
))
224 && !Levitation
&& !Flying
&& !is_clinger(youmonst
.data
)
225 && !context
.takeoff
.cancelled_don
226 /* avoid recursive call to lava_effects() */
227 && !iflags
.in_lava_effects
) {
228 /* make boots known in case you survive the drowning */
234 toggle_stealth(otmp
, oldprop
, FALSE
);
237 if (!oldprop
&& !(HFumbling
& ~TIMEOUT
))
238 HFumbling
= EFumbling
= 0;
240 case LEVITATION_BOOTS
:
241 if (!oldprop
&& !HLevitation
&& !BLevitation
242 && !context
.takeoff
.cancelled_don
) {
243 (void) float_down(0L, 0L);
246 float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */
256 impossible(unknown_type
, c_boots
, otyp
);
258 context
.takeoff
.cancelled_don
= FALSE
;
266 u
.uprops
[objects
[uarmc
->otyp
].oc_oprop
].extrinsic
& ~WORN_CLOAK
;
268 switch (uarmc
->otyp
) {
271 case CLOAK_OF_MAGIC_RESISTANCE
:
275 case CLOAK_OF_PROTECTION
:
276 makeknown(uarmc
->otyp
);
279 toggle_stealth(uarmc
, oldprop
, TRUE
);
281 case CLOAK_OF_DISPLACEMENT
:
282 toggle_displacement(uarmc
, oldprop
, TRUE
);
285 /* Note: it's already being worn, so we have to cheat here. */
286 if ((HInvis
|| EInvis
) && !Blind
) {
288 You("can %s!", See_invisible
? "no longer see through yourself"
292 case CLOAK_OF_INVISIBILITY
:
293 /* since cloak of invisibility was worn, we know mummy wrapping
294 wasn't, so no need to check `oldprop' against blocked */
295 if (!oldprop
&& !HInvis
&& !Blind
) {
296 makeknown(uarmc
->otyp
);
298 pline("Suddenly you can%s yourself.",
299 See_invisible
? " see through" : "not see");
303 pline("%s very tightly.", Tobjnam(uarmc
, "fit"));
305 /* Alchemy smock gives poison _and_ acid resistance */
307 EAcid_resistance
|= WORN_CLOAK
;
310 impossible(unknown_type
, c_cloak
, uarmc
->otyp
);
318 struct obj
*otmp
= uarmc
;
319 int otyp
= otmp
->otyp
;
320 long oldprop
= u
.uprops
[objects
[otyp
].oc_oprop
].extrinsic
& ~WORN_CLOAK
;
322 context
.takeoff
.mask
&= ~W_ARMC
;
323 /* For mummy wrapping, taking it off first resets `Invisible'. */
324 setworn((struct obj
*) 0, W_ARMC
);
328 case CLOAK_OF_PROTECTION
:
329 case CLOAK_OF_MAGIC_RESISTANCE
:
335 toggle_stealth(otmp
, oldprop
, FALSE
);
337 case CLOAK_OF_DISPLACEMENT
:
338 toggle_displacement(otmp
, oldprop
, FALSE
);
341 if (Invis
&& !Blind
) {
343 You("can %s.", See_invisible
? "see through yourself"
344 : "no longer see yourself");
347 case CLOAK_OF_INVISIBILITY
:
348 if (!oldprop
&& !HInvis
&& !Blind
) {
349 makeknown(CLOAK_OF_INVISIBILITY
);
351 pline("Suddenly you can %s.",
352 See_invisible
? "no longer see through yourself"
356 /* Alchemy smock gives poison _and_ acid resistance */
358 EAcid_resistance
&= ~WORN_CLOAK
;
361 impossible(unknown_type
, c_cloak
, otyp
);
370 switch (uarmh
->otyp
) {
374 case ELVEN_LEATHER_HELM
:
375 case DWARVISH_IRON_HELM
:
377 case HELM_OF_TELEPATHY
:
379 case HELM_OF_BRILLIANCE
:
380 adj_abon(uarmh
, uarmh
->spe
);
383 /* people think marked wizards know what they're talking
384 * about, but it takes trained arrogance to pull it off,
385 * and the actual enchantment of the hat is irrelevant.
387 ABON(A_CHA
) += (Role_if(PM_WIZARD
) ? 1 : -1);
389 makeknown(uarmh
->otyp
);
391 case HELM_OF_OPPOSITE_ALIGNMENT
:
392 /* changing alignment can toggle off active artifact
393 properties, including levitation; uarmh could get
394 dropped or destroyed here */
395 uchangealign((u
.ualign
.type
!= A_NEUTRAL
)
397 : (uarmh
->o_id
% 2) ? A_CHAOTIC
: A_LAWFUL
,
399 /* makeknown(uarmh->otyp); -- moved below, after xname() */
402 if (uarmh
&& !uarmh
->cursed
) {
404 pline("%s for a moment.", Tobjnam(uarmh
, "vibrate"));
406 pline("%s %s for a moment.", Tobjnam(uarmh
, "glow"),
410 context
.botl
= 1; /* reveal new alignment or INT & WIS */
412 pline("My brain hurts!"); /* Monty Python's Flying Circus */
413 } else if (uarmh
&& uarmh
->otyp
== DUNCE_CAP
) {
414 You_feel("%s.", /* track INT change; ignore WIS */
416 <= (ABASE(A_INT
) + ABON(A_INT
) + ATEMP(A_INT
))
417 ? "like sitting in a corner"
420 /* [message moved to uchangealign()] */
421 makeknown(HELM_OF_OPPOSITE_ALIGNMENT
);
425 impossible(unknown_type
, c_helmet
, uarmh
->otyp
);
431 Helmet_off(VOID_ARGS
)
433 context
.takeoff
.mask
&= ~W_ARMH
;
435 switch (uarmh
->otyp
) {
439 case ELVEN_LEATHER_HELM
:
440 case DWARVISH_IRON_HELM
:
447 if (!context
.takeoff
.cancelled_don
) {
448 ABON(A_CHA
) += (Role_if(PM_WIZARD
) ? -1 : 1);
452 case HELM_OF_TELEPATHY
:
453 /* need to update ability before calling see_monsters() */
454 setworn((struct obj
*) 0, W_ARMH
);
457 case HELM_OF_BRILLIANCE
:
458 if (!context
.takeoff
.cancelled_don
)
459 adj_abon(uarmh
, -uarmh
->spe
);
461 case HELM_OF_OPPOSITE_ALIGNMENT
:
462 /* changing alignment can toggle off active artifact
463 properties, including levitation; uarmh could get
464 dropped or destroyed here */
465 uchangealign(u
.ualignbase
[A_CURRENT
], 2);
468 impossible(unknown_type
, c_helmet
, uarmh
->otyp
);
470 setworn((struct obj
*) 0, W_ARMH
);
471 context
.takeoff
.cancelled_don
= FALSE
;
480 u
.uprops
[objects
[uarmg
->otyp
].oc_oprop
].extrinsic
& ~WORN_GLOVES
;
482 switch (uarmg
->otyp
) {
485 case GAUNTLETS_OF_FUMBLING
:
486 if (!oldprop
&& !(HFumbling
& ~TIMEOUT
))
487 incr_itimeout(&HFumbling
, rnd(20));
489 case GAUNTLETS_OF_POWER
:
490 makeknown(uarmg
->otyp
);
491 context
.botl
= 1; /* taken care of in attrib.c */
493 case GAUNTLETS_OF_DEXTERITY
:
494 adj_abon(uarmg
, uarmg
->spe
);
497 impossible(unknown_type
, c_gloves
, uarmg
->otyp
);
503 wielding_corpse(obj
, voluntary
)
505 boolean voluntary
; /* taking gloves off on purpose? */
509 if (!obj
|| obj
->otyp
!= CORPSE
)
511 if (obj
!= uwep
&& (obj
!= uswapwep
|| !u
.twoweap
))
514 if (touch_petrifies(&mons
[obj
->corpsenm
]) && !Stone_resistance
) {
515 You("now wield %s in your bare %s.",
516 corpse_xname(obj
, (const char *) 0, CXN_ARTICLE
),
517 makeplural(body_part(HAND
)));
518 Sprintf(kbuf
, "%s gloves while wielding %s",
519 voluntary
? "removing" : "losing", killer_xname(obj
));
521 /* life-saved; can't continue wielding cockatrice corpse though */
522 remove_worn_item(obj
, FALSE
);
527 Gloves_off(VOID_ARGS
)
530 u
.uprops
[objects
[uarmg
->otyp
].oc_oprop
].extrinsic
& ~WORN_GLOVES
;
531 boolean on_purpose
= !context
.mon_moving
&& !uarmg
->in_use
;
533 context
.takeoff
.mask
&= ~W_ARMG
;
535 switch (uarmg
->otyp
) {
538 case GAUNTLETS_OF_FUMBLING
:
539 if (!oldprop
&& !(HFumbling
& ~TIMEOUT
))
540 HFumbling
= EFumbling
= 0;
542 case GAUNTLETS_OF_POWER
:
543 makeknown(uarmg
->otyp
);
544 context
.botl
= 1; /* taken care of in attrib.c */
546 case GAUNTLETS_OF_DEXTERITY
:
547 if (!context
.takeoff
.cancelled_don
)
548 adj_abon(uarmg
, -uarmg
->spe
);
551 impossible(unknown_type
, c_gloves
, uarmg
->otyp
);
553 setworn((struct obj
*) 0, W_ARMG
);
554 context
.takeoff
.cancelled_don
= FALSE
;
555 (void) encumber_msg(); /* immediate feedback for GoP */
557 /* prevent wielding cockatrice when not wearing gloves */
558 if (uwep
&& uwep
->otyp
== CORPSE
)
559 wielding_corpse(uwep
, on_purpose
);
561 /* KMH -- ...or your secondary weapon when you're wielding it
562 [This case can't actually happen; twoweapon mode won't
563 engage if a corpse has been set up as the alternate weapon.] */
564 if (u
.twoweap
&& uswapwep
&& uswapwep
->otyp
== CORPSE
)
565 wielding_corpse(uswapwep
, on_purpose
);
573 /* no shield currently requires special handling when put on, but we
574 keep this uncommented in case somebody adds a new one which does */
575 switch (uarms
->otyp
) {
578 case URUK_HAI_SHIELD
:
580 case DWARVISH_ROUNDSHIELD
:
582 case SHIELD_OF_REFLECTION
:
585 impossible(unknown_type
, c_shield
, uarms
->otyp
);
592 Shield_off(VOID_ARGS
)
594 context
.takeoff
.mask
&= ~W_ARMS
;
596 /* no shield currently requires special handling when taken off, but we
597 keep this uncommented in case somebody adds a new one which does */
598 switch (uarms
->otyp
) {
601 case URUK_HAI_SHIELD
:
603 case DWARVISH_ROUNDSHIELD
:
605 case SHIELD_OF_REFLECTION
:
608 impossible(unknown_type
, c_shield
, uarms
->otyp
);
611 setworn((struct obj
*) 0, W_ARMS
);
618 /* no shirt currently requires special handling when put on, but we
619 keep this uncommented in case somebody adds a new one which does */
620 switch (uarmu
->otyp
) {
625 impossible(unknown_type
, c_shirt
, uarmu
->otyp
);
634 context
.takeoff
.mask
&= ~W_ARMU
;
636 /* no shirt currently requires special handling when taken off, but we
637 keep this uncommented in case somebody adds a new one which does */
638 switch (uarmu
->otyp
) {
643 impossible(unknown_type
, c_shirt
, uarmu
->otyp
);
646 setworn((struct obj
*) 0, W_ARMU
);
650 /* This must be done in worn.c, because one of the possible intrinsics
651 * conferred is fire resistance, and we have to immediately set
652 * HFire_resistance in worn.c since worn.c will check it before returning.
664 context
.takeoff
.mask
&= ~W_ARM
;
665 setworn((struct obj
*) 0, W_ARM
);
666 context
.takeoff
.cancelled_don
= FALSE
;
670 /* The gone functions differ from the off functions in that if you die from
671 * taking it off and have life saving, you still die.
676 context
.takeoff
.mask
&= ~W_ARM
;
678 context
.takeoff
.cancelled_don
= FALSE
;
685 /* make sure amulet isn't wielded; can't use remove_worn_item()
686 here because it has already been set worn in amulet slot */
688 setuwep((struct obj
*) 0);
689 else if (uamul
== uswapwep
)
690 setuswapwep((struct obj
*) 0);
691 else if (uamul
== uquiver
)
692 setuqwep((struct obj
*) 0);
694 switch (uamul
->otyp
) {
696 case AMULET_OF_LIFE_SAVING
:
697 case AMULET_VERSUS_POISON
:
698 case AMULET_OF_REFLECTION
:
699 case AMULET_OF_MAGICAL_BREATHING
:
700 case FAKE_AMULET_OF_YENDOR
:
702 case AMULET_OF_UNCHANGING
:
704 make_slimed(0L, (char *) 0);
706 case AMULET_OF_CHANGE
: {
707 int orig_sex
= poly_gender();
712 /* Don't use same message as polymorph */
713 if (orig_sex
!= poly_gender()) {
714 makeknown(AMULET_OF_CHANGE
);
715 You("are suddenly very %s!",
716 flags
.female
? "feminine" : "masculine");
719 /* already polymorphed into single-gender monster; only
720 changed the character's base sex */
721 You("don't feel like yourself.");
722 pline_The("amulet disintegrates!");
723 if (orig_sex
== poly_gender() && uamul
->dknown
724 && !objects
[AMULET_OF_CHANGE
].oc_name_known
725 && !objects
[AMULET_OF_CHANGE
].oc_uname
)
730 case AMULET_OF_STRANGULATION
:
731 if (can_be_strangled(&youmonst
)) {
732 makeknown(AMULET_OF_STRANGULATION
);
735 pline("It constricts your throat!");
738 case AMULET_OF_RESTFUL_SLEEP
: {
739 long newnap
= (long) rnd(100), oldnap
= (HSleepy
& TIMEOUT
);
741 /* avoid clobbering FROMOUTSIDE bit, which might have
742 gotten set by previously eating one of these amulets */
743 if (newnap
< oldnap
|| oldnap
== 0L)
744 HSleepy
= (HSleepy
& ~TIMEOUT
) | newnap
;
746 case AMULET_OF_YENDOR
:
754 context
.takeoff
.mask
&= ~W_AMUL
;
756 switch (uamul
->otyp
) {
758 /* need to update ability before calling see_monsters() */
759 setworn((struct obj
*) 0, W_AMUL
);
762 case AMULET_OF_LIFE_SAVING
:
763 case AMULET_VERSUS_POISON
:
764 case AMULET_OF_REFLECTION
:
765 case AMULET_OF_CHANGE
:
766 case AMULET_OF_UNCHANGING
:
767 case FAKE_AMULET_OF_YENDOR
:
769 case AMULET_OF_MAGICAL_BREATHING
:
771 /* HMagical_breathing must be set off
772 before calling drown() */
773 setworn((struct obj
*) 0, W_AMUL
);
774 if (!breathless(youmonst
.data
) && !amphibious(youmonst
.data
)
776 You("suddenly inhale an unhealthy amount of %s!",
783 case AMULET_OF_STRANGULATION
:
788 Your("%s is no longer constricted!", body_part(NECK
));
790 You("can breathe more easily!");
793 case AMULET_OF_RESTFUL_SLEEP
:
794 setworn((struct obj
*) 0, W_AMUL
);
795 /* HSleepy = 0L; -- avoid clobbering FROMOUTSIDE bit */
796 if (!ESleepy
&& !(HSleepy
& ~TIMEOUT
))
797 HSleepy
&= ~TIMEOUT
; /* clear timeout bits */
799 case AMULET_OF_YENDOR
:
802 setworn((struct obj
*) 0, W_AMUL
);
806 /* handle ring discovery; comparable to learnwand() */
808 learnring(ring
, observed
)
812 int ringtype
= ring
->otyp
;
814 /* if effect was observeable then we usually discover the type */
816 /* if we already know the ring type which accomplishes this
817 effect (assumes there is at most one type for each effect),
818 mark this ring as having been seen (no need for makeknown);
819 otherwise if we have seen this ring, discover its type */
820 if (objects
[ringtype
].oc_name_known
)
822 else if (ring
->dknown
)
824 #if 0 /* see learnwand() */
830 /* make enchantment of charged ring known (might be +0) and update
831 perm invent window if we've seen this ring and know its type */
832 if (ring
->dknown
&& objects
[ringtype
].oc_name_known
) {
833 if (objects
[ringtype
].oc_charged
)
841 register struct obj
*obj
;
843 long oldprop
= u
.uprops
[objects
[obj
->otyp
].oc_oprop
].extrinsic
;
844 int old_attrib
, which
;
847 /* make sure ring isn't wielded; can't use remove_worn_item()
848 here because it has already been set worn in a ring slot */
850 setuwep((struct obj
*) 0);
851 else if (obj
== uswapwep
)
852 setuswapwep((struct obj
*) 0);
853 else if (obj
== uquiver
)
854 setuqwep((struct obj
*) 0);
856 /* only mask out W_RING when we don't have both
857 left and right rings of the same type */
858 if ((oldprop
& W_RING
) != W_RING
)
862 case RIN_TELEPORTATION
:
863 case RIN_REGENERATION
:
866 case RIN_AGGRAVATE_MONSTER
:
867 case RIN_POISON_RESISTANCE
:
868 case RIN_FIRE_RESISTANCE
:
869 case RIN_COLD_RESISTANCE
:
870 case RIN_SHOCK_RESISTANCE
:
872 case RIN_TELEPORT_CONTROL
:
874 case RIN_POLYMORPH_CONTROL
:
875 case RIN_FREE_ACTION
:
876 case RIN_SLOW_DIGESTION
:
877 case RIN_SUSTAIN_ABILITY
:
881 toggle_stealth(obj
, oldprop
, TRUE
);
886 case RIN_SEE_INVISIBLE
:
887 /* can now see invisible monsters */
888 set_mimic_blocking(); /* do special mimic handling */
891 if (Invis
&& !oldprop
&& !HSee_invisible
&& !Blind
) {
893 pline("Suddenly you are transparent, but there!");
894 learnring(obj
, TRUE
);
897 case RIN_INVISIBILITY
:
898 if (!oldprop
&& !HInvis
&& !BInvis
&& !Blind
) {
899 learnring(obj
, TRUE
);
901 self_invis_message();
905 if (!oldprop
&& !HLevitation
&& !BLevitation
) {
907 learnring(obj
, TRUE
);
908 spoteffects(FALSE
); /* for sinks */
910 float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */
913 case RIN_GAIN_STRENGTH
:
916 case RIN_GAIN_CONSTITUTION
:
922 old_attrib
= ACURR(which
);
923 ABON(which
) += obj
->spe
;
924 observable
= (old_attrib
!= ACURR(which
));
925 /* if didn't change, usually means ring is +0 but might
926 be because nonzero couldn't go below min or above max;
927 learn +0 enchantment if attribute value is not stuck
928 at a limit [and ring has been seen and its type is
929 already discovered, both handled by learnring()] */
930 if (observable
|| !extremeattr(which
))
931 learnring(obj
, observable
);
934 case RIN_INCREASE_ACCURACY
: /* KMH */
935 u
.uhitinc
+= obj
->spe
;
937 case RIN_INCREASE_DAMAGE
:
938 u
.udaminc
+= obj
->spe
;
940 case RIN_PROTECTION_FROM_SHAPE_CHAN
:
944 /* usually learn enchantment and discover type;
945 won't happen if ring is unseen or if it's +0
946 and the type hasn't been discovered yet */
947 observable
= (obj
->spe
!= 0);
948 learnring(obj
, observable
);
950 find_ac(); /* updates botl */
956 Ring_off_or_gone(obj
, gone
)
957 register struct obj
*obj
;
960 long mask
= (obj
->owornmask
& W_RING
);
961 int old_attrib
, which
;
964 context
.takeoff
.mask
&= ~mask
;
965 if (!(u
.uprops
[objects
[obj
->otyp
].oc_oprop
].extrinsic
& mask
))
966 impossible("Strange... I didn't know you had that ring.");
970 setworn((struct obj
*) 0, obj
->owornmask
);
973 case RIN_TELEPORTATION
:
974 case RIN_REGENERATION
:
977 case RIN_AGGRAVATE_MONSTER
:
978 case RIN_POISON_RESISTANCE
:
979 case RIN_FIRE_RESISTANCE
:
980 case RIN_COLD_RESISTANCE
:
981 case RIN_SHOCK_RESISTANCE
:
983 case RIN_TELEPORT_CONTROL
:
985 case RIN_POLYMORPH_CONTROL
:
986 case RIN_FREE_ACTION
:
987 case RIN_SLOW_DIGESTION
:
988 case RIN_SUSTAIN_ABILITY
:
992 toggle_stealth(obj
, (EStealth
& ~mask
), FALSE
);
997 case RIN_SEE_INVISIBLE
:
998 /* Make invisible monsters go away */
999 if (!See_invisible
) {
1000 set_mimic_blocking(); /* do special mimic handling */
1004 if (Invisible
&& !Blind
) {
1006 pline("Suddenly you cannot see yourself.");
1007 learnring(obj
, TRUE
);
1010 case RIN_INVISIBILITY
:
1011 if (!Invis
&& !BInvis
&& !Blind
) {
1013 Your("body seems to unfade%s.",
1014 See_invisible
? " completely" : "..");
1015 learnring(obj
, TRUE
);
1018 case RIN_LEVITATION
:
1020 (void) float_down(0L, 0L);
1022 learnring(obj
, TRUE
);
1024 float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */
1027 case RIN_GAIN_STRENGTH
:
1030 case RIN_GAIN_CONSTITUTION
:
1036 old_attrib
= ACURR(which
);
1037 ABON(which
) -= obj
->spe
;
1038 observable
= (old_attrib
!= ACURR(which
));
1039 /* same criteria as Ring_on() */
1040 if (observable
|| !extremeattr(which
))
1041 learnring(obj
, observable
);
1044 case RIN_INCREASE_ACCURACY
: /* KMH */
1045 u
.uhitinc
-= obj
->spe
;
1047 case RIN_INCREASE_DAMAGE
:
1048 u
.udaminc
-= obj
->spe
;
1050 case RIN_PROTECTION
:
1051 /* might have been put on while blind and we can now see
1052 or perhaps been forgotten due to amnesia */
1053 observable
= (obj
->spe
!= 0);
1054 learnring(obj
, observable
);
1056 find_ac(); /* updates botl */
1058 case RIN_PROTECTION_FROM_SHAPE_CHAN
:
1059 /* If you're no longer protected, let the chameleons
1060 * change shape again -dgk
1071 Ring_off_or_gone(obj
, FALSE
);
1078 Ring_off_or_gone(obj
, TRUE
);
1083 register struct obj
*otmp
;
1085 boolean already_blind
= Blind
, changed
= FALSE
;
1087 /* blindfold might be wielded; release it for wearing */
1088 if (otmp
->owornmask
& W_WEAPON
)
1089 remove_worn_item(otmp
, FALSE
);
1090 setworn(otmp
, W_TOOL
);
1093 if (Blind
&& !already_blind
) {
1096 You_cant("see any more.");
1097 /* set ball&chain variables before the hero goes blind */
1100 } else if (already_blind
&& !Blind
) {
1102 /* "You are now wearing the Eyes of the Overworld." */
1103 if (u
.uroleplay
.blind
) {
1104 /* this can only happen by putting on the Eyes of the Overworld;
1105 that shouldn't actually produce a permanent cure, but we
1106 can't let the "blind from birth" conduct remain intact */
1107 pline("For the first time in your life, you can see!");
1108 u
.uroleplay
.blind
= FALSE
;
1113 /* blindness has just been toggled */
1114 if (Blind_telepat
|| Infravision
)
1116 vision_full_recalc
= 1; /* recalc vision limits */
1118 learn_unseen_invent();
1125 register struct obj
*otmp
;
1127 boolean was_blind
= Blind
, changed
= FALSE
;
1130 impossible("Blindf_off without otmp");
1133 context
.takeoff
.mask
&= ~W_TOOL
;
1134 setworn((struct obj
*) 0, otmp
->owornmask
);
1139 /* "still cannot see" makes no sense when removing lenses
1140 since they can't have been the cause of your blindness */
1141 if (otmp
->otyp
!= LENSES
)
1142 You("still cannot see.");
1144 changed
= TRUE
; /* !was_blind */
1145 /* "You were wearing the Eyes of the Overworld." */
1146 You_cant("see anything now!");
1147 /* set ball&chain variables before the hero goes blind */
1151 } else if (was_blind
) {
1152 if (!gulp_blnd_check()) {
1153 changed
= TRUE
; /* !Blind */
1154 You("can see again.");
1158 /* blindness has just been toggled */
1159 if (Blind_telepat
|| Infravision
)
1161 vision_full_recalc
= 1; /* recalc vision limits */
1163 learn_unseen_invent();
1168 /* called in moveloop()'s prologue to set side-effects of worn start-up items;
1169 also used by poly_obj() when a worn item gets transformed */
1172 struct obj
*obj
; /* if null, do all worn items; otherwise just obj itself */
1176 if (!obj
? ublindf
!= 0 : (obj
== ublindf
))
1177 (void) Blindf_on(ublindf
);
1178 if (!obj
? uright
!= 0 : (obj
== uright
))
1179 (void) Ring_on(uright
);
1180 if (!obj
? uleft
!= 0 : (obj
== uleft
))
1181 (void) Ring_on(uleft
);
1182 if (!obj
? uamul
!= 0 : (obj
== uamul
))
1185 if (!obj
? uarmu
!= 0 : (obj
== uarmu
))
1187 if (!obj
? uarm
!= 0 : (obj
== uarm
))
1189 if (!obj
? uarmc
!= 0 : (obj
== uarmc
))
1191 if (!obj
? uarmf
!= 0 : (obj
== uarmf
))
1193 if (!obj
? uarmg
!= 0 : (obj
== uarmg
))
1195 if (!obj
? uarmh
!= 0 : (obj
== uarmh
))
1197 if (!obj
? uarms
!= 0 : (obj
== uarms
))
1200 initial_don
= FALSE
;
1203 /* check whether the target object is currently being put on (or taken off--
1204 also checks for doffing) */
1209 /* long what = (occupation == take_off) ? context.takeoff.what : 0L; */
1210 long what
= context
.takeoff
.what
; /* if nonzero, occupation is implied */
1211 boolean result
= FALSE
;
1213 /* 'W' and 'T' set afternmv, 'A' sets context.takeoff.what */
1215 result
= (afternmv
== Armor_on
|| afternmv
== Armor_off
1216 || what
== WORN_ARMOR
);
1217 else if (otmp
== uarmu
)
1218 result
= (afternmv
== Shirt_on
|| afternmv
== Shirt_off
1219 || what
== WORN_SHIRT
);
1220 else if (otmp
== uarmc
)
1221 result
= (afternmv
== Cloak_on
|| afternmv
== Cloak_off
1222 || what
== WORN_CLOAK
);
1223 else if (otmp
== uarmf
)
1224 result
= (afternmv
== Boots_on
|| afternmv
== Boots_off
1225 || what
== WORN_BOOTS
);
1226 else if (otmp
== uarmh
)
1227 result
= (afternmv
== Helmet_on
|| afternmv
== Helmet_off
1228 || what
== WORN_HELMET
);
1229 else if (otmp
== uarmg
)
1230 result
= (afternmv
== Gloves_on
|| afternmv
== Gloves_off
1231 || what
== WORN_GLOVES
);
1232 else if (otmp
== uarms
)
1233 result
= (afternmv
== Shield_on
|| afternmv
== Shield_off
1234 || what
== WORN_SHIELD
);
1239 /* check whether the target object is currently being taken off,
1240 so that stop_donning() and steal() can vary messages */
1245 long what
= context
.takeoff
.what
;
1246 boolean result
= FALSE
;
1248 /* 'T' (also 'W') sets afternmv, 'A' sets context.takeoff.what */
1250 result
= (afternmv
== Armor_off
|| what
== WORN_ARMOR
);
1251 else if (otmp
== uarmu
)
1252 result
= (afternmv
== Shirt_off
|| what
== WORN_SHIRT
);
1253 else if (otmp
== uarmc
)
1254 result
= (afternmv
== Cloak_off
|| what
== WORN_CLOAK
);
1255 else if (otmp
== uarmf
)
1256 result
= (afternmv
== Boots_off
|| what
== WORN_BOOTS
);
1257 else if (otmp
== uarmh
)
1258 result
= (afternmv
== Helmet_off
|| what
== WORN_HELMET
);
1259 else if (otmp
== uarmg
)
1260 result
= (afternmv
== Gloves_off
|| what
== WORN_GLOVES
);
1261 else if (otmp
== uarms
)
1262 result
= (afternmv
== Shield_off
|| what
== WORN_SHIELD
);
1270 /* the piece of armor we were donning/doffing has vanished, so stop
1271 * wasting time on it (and don't dereference it when donning would
1274 context
.takeoff
.cancelled_don
=
1275 (afternmv
== Boots_on
|| afternmv
== Helmet_on
1276 || afternmv
== Gloves_on
|| afternmv
== Armor_on
);
1278 nomovemsg
= (char *) 0;
1280 context
.takeoff
.delay
= 0;
1281 context
.takeoff
.what
= 0L;
1284 /* called by steal() during theft from hero; interrupt donning/doffing */
1286 stop_donning(stolenobj
)
1287 struct obj
*stolenobj
; /* no message if stolenobj is already being doffing */
1294 for (otmp
= invent
; otmp
; otmp
= otmp
->nobj
)
1295 if ((otmp
->owornmask
& W_ARMOR
) && donning(otmp
))
1297 /* at most one item will pass donning() test at any given time */
1301 /* donning() returns True when doffing too; doffing() is more specific */
1302 putting_on
= !doffing(otmp
);
1303 /* cancel_don() looks at afternmv; it also serves as cancel_doff() */
1305 /* don't want <armor>_on() or <armor>_off() being called
1306 by unmul() since the on or off action isn't completing */
1308 if (putting_on
|| otmp
!= stolenobj
) {
1309 Sprintf(buf
, "You stop %s %s.",
1310 putting_on
? "putting on" : "taking off",
1311 thesimpleoname(otmp
));
1313 buf
[0] = '\0'; /* silently stop doffing stolenobj */
1314 result
= -multi
; /* remember this before calling unmul() */
1317 /* while putting on, item becomes worn immediately but side-effects are
1318 deferred until the delay expires; when interrupted, make it unworn
1319 (while taking off, item stays worn until the delay expires; when
1320 interrupted, leave it worn) */
1322 remove_worn_item(otmp
, FALSE
);
1327 /* both 'clothes' and 'accessories' now include both armor and accessories;
1328 TOOL_CLASS is for eyewear, FOOD_CLASS is for MEAT_RING */
1329 static NEARDATA
const char clothes
[] = {
1330 ARMOR_CLASS
, RING_CLASS
, AMULET_CLASS
, TOOL_CLASS
, FOOD_CLASS
, 0
1332 static NEARDATA
const char accessories
[] = {
1333 RING_CLASS
, AMULET_CLASS
, TOOL_CLASS
, FOOD_CLASS
, ARMOR_CLASS
, 0
1335 STATIC_VAR NEARDATA
int Narmorpieces
, Naccessories
;
1337 /* assign values to Narmorpieces and Naccessories */
1339 count_worn_stuff(which
, accessorizing
)
1340 struct obj
**which
; /* caller wants this when count is 1 */
1341 boolean accessorizing
;
1345 Narmorpieces
= Naccessories
= 0;
1347 #define MOREWORN(x,wtyp) do { if (x) { wtyp++; otmp = x; } } while (0)
1349 MOREWORN(uarmh
, Narmorpieces
);
1350 MOREWORN(uarms
, Narmorpieces
);
1351 MOREWORN(uarmg
, Narmorpieces
);
1352 MOREWORN(uarmf
, Narmorpieces
);
1353 /* for cloak/suit/shirt, we only count the outermost item so that it
1354 can be taken off without confirmation if final count ends up as 1 */
1356 MOREWORN(uarmc
, Narmorpieces
);
1358 MOREWORN(uarm
, Narmorpieces
);
1360 MOREWORN(uarmu
, Narmorpieces
);
1362 *which
= otmp
; /* default item iff Narmorpieces is 1 */
1365 MOREWORN(uleft
, Naccessories
);
1366 MOREWORN(uright
, Naccessories
);
1367 MOREWORN(uamul
, Naccessories
);
1368 MOREWORN(ublindf
, Naccessories
);
1370 *which
= otmp
; /* default item iff Naccessories is 1 */
1374 /* take off one piece or armor or one accessory;
1375 shared by dotakeoff('T') and doremring('R') */
1377 armor_or_accessory_off(obj
)
1380 if (!(obj
->owornmask
& (W_ARMOR
| W_ACCESSORY
))) {
1381 You("are not wearing that.");
1385 || ((obj
== uarm
) && uarmc
)
1386 || ((obj
== uarmu
) && (uarmc
|| uarm
))) {
1387 char why
[QBUFSZ
], what
[QBUFSZ
];
1389 why
[0] = what
[0] = '\0';
1392 Strcat(what
, cloak_simple_name(uarmc
));
1393 if ((obj
== uarmu
) && uarm
) {
1395 Strcat(what
, " and ");
1396 Strcat(what
, suit_simple_name(uarm
));
1398 Sprintf(why
, " without taking off your %s first", what
);
1400 Strcpy(why
, "; it's embedded");
1402 You_cant("take that off%s.", why
);
1406 reset_remarm(); /* clear context.takeoff.mask and context.takeoff.what */
1407 (void) select_off(obj
);
1408 if (!context
.takeoff
.mask
)
1410 /* none of armoroff()/Ring_/Amulet/Blindf_off() use context.takeoff.mask */
1413 if (obj
->owornmask
& W_ARMOR
) {
1414 (void) armoroff(obj
);
1415 } else if (obj
== uright
|| obj
== uleft
) {
1416 /* Sometimes we want to give the off_msg before removing and
1417 * sometimes after; for instance, "you were wearing a moonstone
1418 * ring (on right hand)" is desired but "you were wearing a
1419 * square amulet (being worn)" is not because of the redundant
1424 } else if (obj
== uamul
) {
1427 } else if (obj
== ublindf
) {
1428 Blindf_off(obj
); /* does its own off_msg */
1430 impossible("removing strange accessory?");
1432 remove_worn_item(obj
, FALSE
);
1437 /* the 'T' command */
1441 struct obj
*otmp
= (struct obj
*) 0;
1443 count_worn_stuff(&otmp
, FALSE
);
1444 if (!Narmorpieces
&& !Naccessories
) {
1445 /* assert( GRAY_DRAGON_SCALES > YELLOW_DRAGON_SCALE_MAIL ); */
1447 pline_The("%s merged with your skin!",
1448 uskin
->otyp
>= GRAY_DRAGON_SCALES
1449 ? "dragon scales are"
1450 : "dragon scale mail is");
1452 pline("Not wearing any armor or accessories.");
1455 if (Narmorpieces
!= 1 || ParanoidRemove
)
1456 otmp
= getobj(clothes
, "take off");
1460 return armor_or_accessory_off(otmp
);
1463 /* the 'R' command */
1467 struct obj
*otmp
= 0;
1469 count_worn_stuff(&otmp
, TRUE
);
1470 if (!Naccessories
&& !Narmorpieces
) {
1471 pline("Not wearing any accessories or armor.");
1474 if (Naccessories
!= 1 || ParanoidRemove
)
1475 otmp
= getobj(accessories
, "remove");
1479 return armor_or_accessory_off(otmp
);
1482 /* Check if something worn is cursed _and_ unremovable. */
1485 register struct obj
*otmp
;
1487 /* Curses, like chickens, come home to roost. */
1488 if ((otmp
== uwep
) ? welded(otmp
) : (int) otmp
->cursed
) {
1489 boolean use_plural
= (is_boots(otmp
) || is_gloves(otmp
)
1490 || otmp
->otyp
== LENSES
|| otmp
->quan
> 1L);
1492 You("can't. %s cursed.", use_plural
? "They are" : "It is");
1493 otmp
->bknown
= TRUE
;
1501 register struct obj
*otmp
;
1503 register int delay
= -objects
[otmp
->otyp
].oc_delay
;
1509 multi_reason
= "disrobing";
1510 if (is_helmet(otmp
)) {
1512 nomovemsg
= !strcmp(helm_simple_name(otmp
), "hat")
1513 ? "You finish taking off your hat."
1514 : "You finish taking off your helmet.";
1515 afternmv
= Helmet_off
;
1516 } else if (is_gloves(otmp
)) {
1517 nomovemsg
= "You finish taking off your gloves.";
1518 afternmv
= Gloves_off
;
1519 } else if (is_boots(otmp
)) {
1520 nomovemsg
= "You finish taking off your boots.";
1521 afternmv
= Boots_off
;
1523 nomovemsg
= "You finish taking off your suit.";
1524 afternmv
= Armor_off
;
1527 /* Be warned! We want off_msg after removing the item to
1528 * avoid "You were wearing ____ (being worn)." However, an
1529 * item which grants fire resistance might cause some trouble
1530 * if removed in Hell and lifesaving puts it back on; in this
1531 * case the message will be printed at the wrong time (after
1532 * the messages saying you died and were lifesaved). Luckily,
1533 * no cloak, shield, or fast-removable armor grants fire
1534 * resistance, so we can safely do the off_msg afterwards.
1535 * Rings do grant fire resistance, but for rings we want the
1536 * off_msg before removal anyway so there's no problem. Take
1537 * care in adding armors granting fire resistance; this code
1538 * might need modification.
1539 * 3.2 (actually 3.1 even): that comment is obsolete since
1540 * fire resistance is not required for Gehennom so setworn()
1541 * doesn't force the resistance granting item to be re-worn
1542 * after being lifesaved anymore.
1546 else if (is_shield(otmp
))
1547 (void) Shield_off();
1549 setworn((struct obj
*) 0, otmp
->owornmask
& W_ARMOR
);
1552 context
.takeoff
.mask
= context
.takeoff
.what
= 0L;
1560 You("are already wearing %s%c", cc
, (cc
== c_that_
) ? '!' : '.');
1564 already_wearing2(cc1
, cc2
)
1565 const char *cc1
, *cc2
;
1567 You_cant("wear %s because you're wearing %s there already.", cc1
, cc2
);
1571 * canwearobj checks to see whether the player can wear a piece of armor
1573 * inputs: otmp (the piece of armor)
1574 * noisy (if TRUE give error messages, otherwise be quiet about it)
1575 * output: mask (otmp's armor type)
1578 canwearobj(otmp
, mask
, noisy
)
1586 which
= is_cloak(otmp
)
1593 if (which
&& cantweararm(youmonst
.data
)
1594 /* same exception for cloaks as used in m_dowear() */
1595 && (which
!= c_cloak
|| youmonst
.data
->msize
!= MZ_SMALL
)
1596 && (racial_exception(&youmonst
, otmp
) < 1)) {
1598 pline_The("%s will not fit on your body.", which
);
1600 } else if (otmp
->owornmask
& W_ARMOR
) {
1602 already_wearing(c_that_
);
1606 if (welded(uwep
) && bimanual(uwep
) && (is_suit(otmp
) || is_shirt(otmp
))) {
1608 You("cannot do that while holding your %s.",
1609 is_sword(uwep
) ? c_sword
: c_weapon
);
1613 if (is_helmet(otmp
)) {
1616 already_wearing(an(helm_simple_name(uarmh
)));
1618 } else if (Upolyd
&& has_horns(youmonst
.data
) && !is_flimsy(otmp
)) {
1619 /* (flimsy exception matches polyself handling) */
1621 pline_The("%s won't fit over your horn%s.",
1622 helm_simple_name(otmp
),
1623 plur(num_horns(youmonst
.data
)));
1627 } else if (is_shield(otmp
)) {
1630 already_wearing(an(c_shield
));
1632 } else if (uwep
&& bimanual(uwep
)) {
1634 You("cannot wear a shield while wielding a two-handed %s.",
1635 is_sword(uwep
) ? c_sword
: (uwep
->otyp
== BATTLE_AXE
)
1639 } else if (u
.twoweap
) {
1641 You("cannot wear a shield while wielding two weapons.");
1645 } else if (is_boots(otmp
)) {
1648 already_wearing(c_boots
);
1650 } else if (Upolyd
&& slithy(youmonst
.data
)) {
1652 You("have no feet..."); /* not body_part(FOOT) */
1654 } else if (Upolyd
&& youmonst
.data
->mlet
== S_CENTAUR
) {
1655 /* break_armor() pushes boots off for centaurs,
1656 so don't let dowear() put them back on... */
1658 pline("You have too many hooves to wear %s.",
1659 c_boots
); /* makeplural(body_part(FOOT)) yields
1660 "rear hooves" which sounds odd */
1663 && (u
.utraptype
== TT_BEARTRAP
|| u
.utraptype
== TT_INFLOOR
1664 || u
.utraptype
== TT_LAVA
1665 || u
.utraptype
== TT_BURIEDBALL
)) {
1666 if (u
.utraptype
== TT_BEARTRAP
) {
1668 Your("%s is trapped!", body_part(FOOT
));
1669 } else if (u
.utraptype
== TT_INFLOOR
|| u
.utraptype
== TT_LAVA
) {
1671 Your("%s are stuck in the %s!",
1672 makeplural(body_part(FOOT
)), surface(u
.ux
, u
.uy
));
1673 } else { /*TT_BURIEDBALL*/
1675 Your("%s is attached to the buried ball!",
1681 } else if (is_gloves(otmp
)) {
1684 already_wearing(c_gloves
);
1686 } else if (welded(uwep
)) {
1688 You("cannot wear gloves over your %s.",
1689 is_sword(uwep
) ? c_sword
: c_weapon
);
1693 } else if (is_shirt(otmp
)) {
1694 if (uarm
|| uarmc
|| uarmu
) {
1697 already_wearing(an(c_shirt
));
1700 You_cant("wear that over your %s.",
1701 (uarm
&& !uarmc
) ? c_armor
1702 : cloak_simple_name(uarmc
));
1707 } else if (is_cloak(otmp
)) {
1710 already_wearing(an(cloak_simple_name(uarmc
)));
1714 } else if (is_suit(otmp
)) {
1717 You("cannot wear armor over a %s.", cloak_simple_name(uarmc
));
1721 already_wearing("some armor");
1726 /* getobj can't do this after setting its allow_all flag; that
1727 happens if you have armor for slots that are covered up or
1728 extra armor for slots that are filled */
1730 silly_thing("wear", otmp
);
1733 /* Unnecessary since now only weapons and special items like pick-axes get
1734 * welded to your hand, not armor
1737 if (noisy) weldmsg(otmp);
1745 accessory_or_armor_on(obj
)
1749 boolean armor
, ring
, eyewear
;
1751 if (obj
->owornmask
& (W_ACCESSORY
| W_ARMOR
)) {
1752 already_wearing(c_that_
);
1755 armor
= (obj
->oclass
== ARMOR_CLASS
);
1756 ring
= (obj
->oclass
== RING_CLASS
|| obj
->otyp
== MEAT_RING
);
1757 eyewear
= (obj
->otyp
== BLINDFOLD
|| obj
->otyp
== TOWEL
1758 || obj
->otyp
== LENSES
);
1759 /* checks which are performed prior to actually touching the item */
1761 if (!canwearobj(obj
, &mask
, TRUE
))
1764 if (obj
->otyp
== HELM_OF_OPPOSITE_ALIGNMENT
1765 && qstart_level
.dnum
== u
.uz
.dnum
) { /* in quest */
1766 if (u
.ualignbase
[A_CURRENT
] == u
.ualignbase
[A_ORIGINAL
])
1767 You("narrowly avoid losing all chance at your goal.");
1768 else /* converted */
1769 You("are suddenly overcome with shame and change your mind.");
1770 u
.ublessed
= 0; /* lose your god's protection */
1771 makeknown(obj
->otyp
);
1772 context
.botl
= 1; /*for AC after zeroing u.ublessed */
1778 char answer
, qbuf
[QBUFSZ
];
1781 if (nolimbs(youmonst
.data
)) {
1782 You("cannot make the ring stick to your body.");
1785 if (uleft
&& uright
) {
1786 There("are no more %s%s to fill.",
1787 humanoid(youmonst
.data
) ? "ring-" : "",
1788 makeplural(body_part(FINGER
)));
1793 } else if (uright
) {
1797 Sprintf(qbuf
, "Which %s%s, Right or Left?",
1798 humanoid(youmonst
.data
) ? "ring-" : "",
1800 answer
= yn_function(qbuf
, "rl", '\0');
1815 if (uarmg
&& uarmg
->cursed
) {
1816 res
= !uarmg
->bknown
;
1818 You("cannot remove your gloves to put on the ring.");
1819 return res
; /* uses move iff we learned gloves are cursed */
1822 res
= !uwep
->bknown
; /* check this before calling welded() */
1823 if ((mask
== RIGHT_RING
|| bimanual(uwep
)) && welded(uwep
)) {
1824 const char *hand
= body_part(HAND
);
1826 /* welded will set bknown */
1828 hand
= makeplural(hand
);
1829 You("cannot free your weapon %s to put on the ring.",
1831 return res
; /* uses move iff we learned weapon is cursed */
1834 } else if (obj
->oclass
== AMULET_CLASS
) {
1836 already_wearing("an amulet");
1839 } else if (eyewear
) {
1841 if (ublindf
->otyp
== TOWEL
)
1842 Your("%s is already covered by a towel.",
1844 else if (ublindf
->otyp
== BLINDFOLD
) {
1845 if (obj
->otyp
== LENSES
)
1846 already_wearing2("lenses", "a blindfold");
1848 already_wearing("a blindfold");
1849 } else if (ublindf
->otyp
== LENSES
) {
1850 if (obj
->otyp
== BLINDFOLD
)
1851 already_wearing2("a blindfold", "some lenses");
1853 already_wearing("some lenses");
1855 already_wearing(something
); /* ??? */
1860 /* neither armor nor accessory */
1861 You_cant("wear that!");
1866 if (!retouch_object(&obj
, FALSE
))
1867 return 1; /* costs a turn even though it didn't get worn */
1872 obj
->known
= 1; /* since AC is shown on the status line */
1873 /* if the armor is wielded, release it for wearing */
1874 if (obj
->owornmask
& W_WEAPON
)
1875 remove_worn_item(obj
, FALSE
);
1877 delay
= -objects
[obj
->otyp
].oc_delay
;
1880 multi_reason
= "dressing up";
1882 afternmv
= Boots_on
;
1884 afternmv
= Helmet_on
;
1886 afternmv
= Gloves_on
;
1888 afternmv
= Armor_on
;
1889 nomovemsg
= "You finish your dressing maneuver.";
1899 context
.takeoff
.mask
= context
.takeoff
.what
= 0L;
1900 } else { /* not armor */
1901 boolean give_feedback
= FALSE
;
1903 /* [releasing wielded accessory handled in Xxx_on()] */
1907 give_feedback
= TRUE
;
1908 } else if (obj
->oclass
== AMULET_CLASS
) {
1909 setworn(obj
, W_AMUL
);
1911 /* no feedback here if amulet of change got used up */
1912 give_feedback
= (uamul
!= 0);
1913 } else if (eyewear
) {
1914 /* setworn() handled by Blindf_on() */
1916 /* message handled by Blindf_on(); leave give_feedback False */
1918 /* feedback for ring or for amulet other than 'change' */
1919 if (give_feedback
&& is_worn(obj
))
1920 prinv((char *) 0, obj
, 0L);
1925 /* the 'W' command */
1931 /* cantweararm() checks for suits of armor, not what we want here;
1932 verysmall() or nohands() checks for shields, gloves, etc... */
1933 if ((verysmall(youmonst
.data
) || nohands(youmonst
.data
))) {
1934 pline("Don't even bother.");
1937 if (uarm
&& uarmu
&& uarmc
&& uarmh
&& uarms
&& uarmg
&& uarmf
1938 && uleft
&& uright
&& uamul
&& ublindf
) {
1939 /* 'W' message doesn't mention accessories */
1940 You("are already wearing a full complement of armor.");
1943 otmp
= getobj(clothes
, "wear");
1944 return otmp
? accessory_or_armor_on(otmp
) : 0;
1947 /* the 'P' command */
1953 if (uleft
&& uright
&& uamul
&& ublindf
1954 && uarm
&& uarmu
&& uarmc
&& uarmh
&& uarms
&& uarmg
&& uarmf
) {
1955 /* 'P' message doesn't mention armor */
1956 Your("%s%s are full, and you're already wearing an amulet and %s.",
1957 humanoid(youmonst
.data
) ? "ring-" : "",
1958 makeplural(body_part(FINGER
)),
1959 (ublindf
->otyp
== LENSES
) ? "some lenses" : "a blindfold");
1962 otmp
= getobj(accessories
, "put on");
1963 return otmp
? accessory_or_armor_on(otmp
) : 0;
1966 /* calculate current armor class */
1970 int uac
= mons
[u
.umonnum
].ac
; /* base armor class for current form */
1972 /* armor class from worn gear */
1974 uac
-= ARM_BONUS(uarm
);
1976 uac
-= ARM_BONUS(uarmc
);
1978 uac
-= ARM_BONUS(uarmh
);
1980 uac
-= ARM_BONUS(uarmf
);
1982 uac
-= ARM_BONUS(uarms
);
1984 uac
-= ARM_BONUS(uarmg
);
1986 uac
-= ARM_BONUS(uarmu
);
1987 if (uleft
&& uleft
->otyp
== RIN_PROTECTION
)
1989 if (uright
&& uright
->otyp
== RIN_PROTECTION
)
1992 /* armor class from other sources */
1993 if (HProtection
& INTRINSIC
)
1995 uac
-= u
.uspellprot
;
1997 /* [The magic binary numbers 127 and -128 should be replaced with the
1998 * mystic decimal numbers 99 and -99 which require no explanation to
1999 * the uninitiated and would cap the width of a status line value at
2000 * one less character.]
2003 uac
= -128; /* u.uac is an schar */
2005 uac
= 127; /* for completeness */
2016 register struct obj
*otmp
;
2018 boolean leftfall
, rightfall
, wastwoweap
= FALSE
;
2019 const char *otherwep
= 0, *thiswep
, *which
, *hand
;
2021 leftfall
= (uleft
&& !uleft
->cursed
2022 && (!uwep
|| !welded(uwep
) || !bimanual(uwep
)));
2023 rightfall
= (uright
&& !uright
->cursed
&& (!welded(uwep
)));
2024 if (!uarmg
&& (leftfall
|| rightfall
) && !nolimbs(youmonst
.data
)) {
2025 /* changed so cursed rings don't fall off, GAN 10/30/86 */
2026 Your("%s off your %s.",
2027 (leftfall
&& rightfall
) ? "rings slip" : "ring slips",
2028 (leftfall
&& rightfall
) ? makeplural(body_part(FINGER
))
2029 : body_part(FINGER
));
2044 if (u
.twoweap
&& otmp
) {
2045 /* secondary weapon doesn't need nearly as much handling as
2046 primary; when in two-weapon mode, we know it's one-handed
2047 with something else in the other hand and also that it's
2048 a weapon or weptool rather than something unusual, plus
2049 we don't need to compare its type with the primary */
2050 otherwep
= is_sword(otmp
) ? c_sword
: weapon_descr(otmp
);
2051 if (otmp
->quan
> 1L)
2052 otherwep
= makeplural(otherwep
);
2053 hand
= body_part(HAND
);
2055 Your("%s %s%s from your %s%s.", otherwep
, xfl
? "also " : "",
2056 otense(otmp
, "slip"), which
, hand
);
2059 setuswapwep((struct obj
*) 0); /* clears u.twoweap */
2060 if (canletgo(otmp
, ""))
2064 if (otmp
&& !welded(otmp
)) {
2065 long savequan
= otmp
->quan
;
2067 /* nice wording if both weapons are the same type */
2068 thiswep
= is_sword(otmp
) ? c_sword
: weapon_descr(otmp
);
2069 if (otherwep
&& strcmp(thiswep
, makesingular(otherwep
)))
2071 if (otmp
->quan
> 1L) {
2072 /* most class names for unconventional wielded items
2073 are ok, but if wielding multiple apples or rations
2074 we don't want "your foods slip", so force non-corpse
2075 food to be singular; skipping makeplural() isn't
2076 enough--we need to fool otense() too */
2077 if (!strcmp(thiswep
, "food"))
2080 thiswep
= makeplural(thiswep
);
2082 hand
= body_part(HAND
);
2085 hand
= makeplural(hand
);
2086 else if (wastwoweap
)
2087 which
= "right "; /* preceding msg was about left */
2088 pline("%s %s%s %s%s from your %s%s.",
2089 !strncmp(thiswep
, "corpse", 6) ? "The" : "Your",
2090 otherwep
? "other " : "", thiswep
, xfl
? "also " : "",
2091 otense(otmp
, "slip"), which
, hand
);
2093 otmp
->quan
= savequan
;
2094 setuwep((struct obj
*) 0);
2095 if (canletgo(otmp
, ""))
2102 struct monst
*victim
;
2104 register struct obj
*otmph
, *otmp
;
2106 otmph
= (victim
== &youmonst
) ? uarmc
: which_armor(victim
, W_ARMC
);
2108 otmph
= (victim
== &youmonst
) ? uarm
: which_armor(victim
, W_ARM
);
2110 otmph
= (victim
== &youmonst
) ? uarmu
: which_armor(victim
, W_ARMU
);
2112 otmp
= (victim
== &youmonst
) ? uarmh
: which_armor(victim
, W_ARMH
);
2113 if (otmp
&& (!otmph
|| !rn2(4)))
2115 otmp
= (victim
== &youmonst
) ? uarmg
: which_armor(victim
, W_ARMG
);
2116 if (otmp
&& (!otmph
|| !rn2(4)))
2118 otmp
= (victim
== &youmonst
) ? uarmf
: which_armor(victim
, W_ARMF
);
2119 if (otmp
&& (!otmph
|| !rn2(4)))
2121 otmp
= (victim
== &youmonst
) ? uarms
: which_armor(victim
, W_ARMS
);
2122 if (otmp
&& (!otmph
|| !rn2(4)))
2127 /* used for praying to check and fix levitation trouble */
2129 stuck_ring(ring
, otyp
)
2133 if (ring
!= uleft
&& ring
!= uright
) {
2134 impossible("stuck_ring: neither left nor right?");
2135 return (struct obj
*) 0;
2138 if (ring
&& ring
->otyp
== otyp
) {
2139 /* reasons ring can't be removed match those checked by select_off();
2140 limbless case has extra checks because ordinarily it's temporary */
2141 if (nolimbs(youmonst
.data
) && uamul
2142 && uamul
->otyp
== AMULET_OF_UNCHANGING
&& uamul
->cursed
)
2144 if (welded(uwep
) && (ring
== uright
|| bimanual(uwep
)))
2146 if (uarmg
&& uarmg
->cursed
)
2151 /* either no ring or not right type or nothing prevents its removal */
2152 return (struct obj
*) 0;
2155 /* also for praying; find worn item that confers "Unchanging" attribute */
2159 if (uamul
&& uamul
->otyp
== AMULET_OF_UNCHANGING
)
2167 register struct obj
*otmp
;
2174 *buf
= '\0'; /* lint suppression */
2176 /* special ring checks */
2177 if (otmp
== uright
|| otmp
== uleft
) {
2178 if (nolimbs(youmonst
.data
)) {
2179 pline_The("ring is stuck.");
2182 why
= 0; /* the item which prevents ring removal */
2183 if (welded(uwep
) && (otmp
== uright
|| bimanual(uwep
))) {
2184 Sprintf(buf
, "free a weapon %s", body_part(HAND
));
2186 } else if (uarmg
&& uarmg
->cursed
) {
2187 Sprintf(buf
, "take off your %s", c_gloves
);
2191 You("cannot %s to remove the ring.", buf
);
2196 /* special glove checks */
2197 if (otmp
== uarmg
) {
2199 You("are unable to take off your %s while wielding that %s.",
2200 c_gloves
, is_sword(uwep
) ? c_sword
: c_weapon
);
2201 uwep
->bknown
= TRUE
;
2204 You_cant("take off the slippery %s with your slippery %s.",
2205 c_gloves
, makeplural(body_part(FINGER
)));
2209 /* special boot checks */
2210 if (otmp
== uarmf
) {
2211 if (u
.utrap
&& u
.utraptype
== TT_BEARTRAP
) {
2212 pline_The("bear trap prevents you from pulling your %s out.",
2215 } else if (u
.utrap
&& u
.utraptype
== TT_INFLOOR
) {
2216 You("are stuck in the %s, and cannot pull your %s out.",
2217 surface(u
.ux
, u
.uy
), makeplural(body_part(FOOT
)));
2221 /* special suit and shirt checks */
2222 if (otmp
== uarm
|| otmp
== uarmu
) {
2223 why
= 0; /* the item which prevents disrobing */
2224 if (uarmc
&& uarmc
->cursed
) {
2225 Sprintf(buf
, "remove your %s", cloak_simple_name(uarmc
));
2227 } else if (otmp
== uarmu
&& uarm
&& uarm
->cursed
) {
2228 Sprintf(buf
, "remove your %s", c_suit
);
2230 } else if (welded(uwep
) && bimanual(uwep
)) {
2231 Sprintf(buf
, "release your %s",
2232 is_sword(uwep
) ? c_sword
: (uwep
->otyp
== BATTLE_AXE
)
2238 You("cannot %s to take off %s.", buf
, the(xname(otmp
)));
2243 /* basic curse check */
2244 if (otmp
== uquiver
|| (otmp
== uswapwep
&& !u
.twoweap
)) {
2245 ; /* some items can be removed even when cursed */
2247 /* otherwise, this is fundamental */
2253 context
.takeoff
.mask
|= WORN_ARMOR
;
2254 else if (otmp
== uarmc
)
2255 context
.takeoff
.mask
|= WORN_CLOAK
;
2256 else if (otmp
== uarmf
)
2257 context
.takeoff
.mask
|= WORN_BOOTS
;
2258 else if (otmp
== uarmg
)
2259 context
.takeoff
.mask
|= WORN_GLOVES
;
2260 else if (otmp
== uarmh
)
2261 context
.takeoff
.mask
|= WORN_HELMET
;
2262 else if (otmp
== uarms
)
2263 context
.takeoff
.mask
|= WORN_SHIELD
;
2264 else if (otmp
== uarmu
)
2265 context
.takeoff
.mask
|= WORN_SHIRT
;
2266 else if (otmp
== uleft
)
2267 context
.takeoff
.mask
|= LEFT_RING
;
2268 else if (otmp
== uright
)
2269 context
.takeoff
.mask
|= RIGHT_RING
;
2270 else if (otmp
== uamul
)
2271 context
.takeoff
.mask
|= WORN_AMUL
;
2272 else if (otmp
== ublindf
)
2273 context
.takeoff
.mask
|= WORN_BLINDF
;
2274 else if (otmp
== uwep
)
2275 context
.takeoff
.mask
|= W_WEP
;
2276 else if (otmp
== uswapwep
)
2277 context
.takeoff
.mask
|= W_SWAPWEP
;
2278 else if (otmp
== uquiver
)
2279 context
.takeoff
.mask
|= W_QUIVER
;
2282 impossible("select_off: %s???", doname(otmp
));
2287 STATIC_OVL
struct obj
*
2290 struct obj
*otmp
= (struct obj
*) 0;
2291 struct takeoff_info
*doff
= &context
.takeoff
;
2293 if (doff
->what
== W_WEP
) {
2294 if (!cursed(uwep
)) {
2295 setuwep((struct obj
*) 0);
2296 You("are empty %s.", body_part(HANDED
));
2299 } else if (doff
->what
== W_SWAPWEP
) {
2300 setuswapwep((struct obj
*) 0);
2301 You("no longer have a second weapon readied.");
2303 } else if (doff
->what
== W_QUIVER
) {
2304 setuqwep((struct obj
*) 0);
2305 You("no longer have ammunition readied.");
2306 } else if (doff
->what
== WORN_ARMOR
) {
2310 } else if (doff
->what
== WORN_CLOAK
) {
2314 } else if (doff
->what
== WORN_BOOTS
) {
2318 } else if (doff
->what
== WORN_GLOVES
) {
2321 (void) Gloves_off();
2322 } else if (doff
->what
== WORN_HELMET
) {
2325 (void) Helmet_off();
2326 } else if (doff
->what
== WORN_SHIELD
) {
2329 (void) Shield_off();
2330 } else if (doff
->what
== WORN_SHIRT
) {
2334 } else if (doff
->what
== WORN_AMUL
) {
2338 } else if (doff
->what
== LEFT_RING
) {
2342 } else if (doff
->what
== RIGHT_RING
) {
2346 } else if (doff
->what
== WORN_BLINDF
) {
2347 if (!cursed(ublindf
))
2348 Blindf_off(ublindf
);
2350 impossible("do_takeoff: taking off %lx", doff
->what
);
2356 /* occupation callback for 'A' */
2362 register struct obj
*otmp
;
2363 struct takeoff_info
*doff
= &context
.takeoff
;
2366 if (doff
->delay
> 0) {
2368 return 1; /* still busy */
2370 if ((otmp
= do_takeoff()))
2373 doff
->mask
&= ~doff
->what
;
2377 for (i
= 0; takeoff_order
[i
]; i
++)
2378 if (doff
->mask
& takeoff_order
[i
]) {
2379 doff
->what
= takeoff_order
[i
];
2383 otmp
= (struct obj
*) 0;
2386 if (doff
->what
== 0L) {
2387 You("finish %s.", doff
->disrobing
);
2389 } else if (doff
->what
== W_WEP
) {
2391 } else if (doff
->what
== W_SWAPWEP
) {
2393 } else if (doff
->what
== W_QUIVER
) {
2395 } else if (doff
->what
== WORN_ARMOR
) {
2397 /* If a cloak is being worn, add the time to take it off and put
2398 * it back on again. Kludge alert! since that time is 0 for all
2399 * known cloaks, add 1 so that it actually matters...
2402 doff
->delay
+= 2 * objects
[uarmc
->otyp
].oc_delay
+ 1;
2403 } else if (doff
->what
== WORN_CLOAK
) {
2405 } else if (doff
->what
== WORN_BOOTS
) {
2407 } else if (doff
->what
== WORN_GLOVES
) {
2409 } else if (doff
->what
== WORN_HELMET
) {
2411 } else if (doff
->what
== WORN_SHIELD
) {
2413 } else if (doff
->what
== WORN_SHIRT
) {
2415 /* add the time to take off and put back on armor and/or cloak */
2417 doff
->delay
+= 2 * objects
[uarm
->otyp
].oc_delay
;
2419 doff
->delay
+= 2 * objects
[uarmc
->otyp
].oc_delay
+ 1;
2420 } else if (doff
->what
== WORN_AMUL
) {
2422 } else if (doff
->what
== LEFT_RING
) {
2424 } else if (doff
->what
== RIGHT_RING
) {
2426 } else if (doff
->what
== WORN_BLINDF
) {
2429 impossible("take_off: taking off %lx", doff
->what
);
2430 return 0; /* force done */
2434 doff
->delay
+= objects
[otmp
->otyp
].oc_delay
;
2436 /* Since setting the occupation now starts the counter next move, that
2437 * would always produce a delay 1 too big per item unless we subtract
2438 * 1 here to account for it.
2440 if (doff
->delay
> 0)
2443 set_occupation(take_off
, doff
->disrobing
, 0);
2444 return 1; /* get busy */
2447 /* clear saved context to avoid inappropriate resumption of interrupted 'A' */
2451 context
.takeoff
.what
= context
.takeoff
.mask
= 0L;
2452 context
.takeoff
.disrobing
[0] = '\0';
2455 /* the 'A' command -- remove multiple worn items */
2461 if (context
.takeoff
.what
|| context
.takeoff
.mask
) {
2462 You("continue %s.", context
.takeoff
.disrobing
);
2463 set_occupation(take_off
, context
.takeoff
.disrobing
, 0);
2465 } else if (!uwep
&& !uswapwep
&& !uquiver
&& !uamul
&& !ublindf
&& !uleft
2466 && !uright
&& !wearing_armor()) {
2467 You("are not wearing anything.");
2471 add_valid_menu_class(0); /* reset */
2472 if (flags
.menu_style
!= MENU_TRADITIONAL
2473 || (result
= ggetobj("take off", select_off
, 0, FALSE
,
2474 (unsigned *) 0)) < -1)
2475 result
= menu_remarm(result
);
2477 if (context
.takeoff
.mask
) {
2478 /* default activity for armor and/or accessories,
2479 possibly combined with weapons */
2480 (void) strncpy(context
.takeoff
.disrobing
, "disrobing", CONTEXTVERBSZ
);
2481 /* specific activity when handling weapons only */
2482 if (!(context
.takeoff
.mask
& ~W_WEAPON
))
2483 (void) strncpy(context
.takeoff
.disrobing
, "disarming",
2487 /* The time to perform the command is already completely accounted for
2488 * in take_off(); if we return 1, that would add an extra turn to each
2499 menu_item
*pick_list
;
2500 boolean all_worn_categories
= TRUE
;
2503 all_worn_categories
= (retry
== -2);
2504 } else if (flags
.menu_style
== MENU_FULL
) {
2505 all_worn_categories
= FALSE
;
2506 n
= query_category("What type of things do you want to take off?",
2507 invent
, WORN_TYPES
| ALL_TYPES
, &pick_list
,
2511 for (i
= 0; i
< n
; i
++) {
2512 if (pick_list
[i
].item
.a_int
== ALL_TYPES_SELECTED
)
2513 all_worn_categories
= TRUE
;
2515 add_valid_menu_class(pick_list
[i
].item
.a_int
);
2517 free((genericptr_t
) pick_list
);
2518 } else if (flags
.menu_style
== MENU_COMBINATION
) {
2519 all_worn_categories
= FALSE
;
2520 if (ggetobj("take off", select_off
, 0, TRUE
, (unsigned *) 0) == -2)
2521 all_worn_categories
= TRUE
;
2524 n
= query_objlist("What do you want to take off?", &invent
,
2525 (SIGNAL_NOMENU
| USE_INVLET
| INVORDER_SORT
),
2526 &pick_list
, PICK_ANY
,
2527 all_worn_categories
? is_worn
: is_worn_by_type
);
2529 for (i
= 0; i
< n
; i
++)
2530 (void) select_off(pick_list
[i
].item
.a_obj
);
2531 free((genericptr_t
) pick_list
);
2532 } else if (n
< 0 && flags
.menu_style
!= MENU_COMBINATION
) {
2533 There("is nothing else you can remove or unwield.");
2538 /* hit by destroy armor scroll/black dragon breath/monster spell */
2541 register struct obj
*atmp
;
2543 register struct obj
*otmp
;
2544 #define DESTROY_ARM(o) \
2545 ((otmp = (o)) != 0 && (!atmp || atmp == otmp) \
2546 && (!obj_resists(otmp, 0, 90)) \
2547 ? (otmp->in_use = TRUE) \
2550 if (DESTROY_ARM(uarmc
)) {
2553 Your("%s crumbles and turns to dust!", cloak_simple_name(uarmc
));
2556 } else if (DESTROY_ARM(uarm
)) {
2559 Your("armor turns to dust and falls to the %s!", surface(u
.ux
, u
.uy
));
2560 (void) Armor_gone();
2562 } else if (DESTROY_ARM(uarmu
)) {
2565 Your("shirt crumbles into tiny threads and falls apart!");
2568 } else if (DESTROY_ARM(uarmh
)) {
2571 Your("%s turns to dust and is blown away!", helm_simple_name(uarmh
));
2572 (void) Helmet_off();
2574 } else if (DESTROY_ARM(uarmg
)) {
2577 Your("gloves vanish!");
2578 (void) Gloves_off();
2581 } else if (DESTROY_ARM(uarmf
)) {
2584 Your("boots disintegrate!");
2587 } else if (DESTROY_ARM(uarms
)) {
2590 Your("shield crumbles away!");
2591 (void) Shield_off();
2594 return 0; /* could not destroy anything */
2603 adj_abon(otmp
, delta
)
2604 register struct obj
*otmp
;
2605 register schar delta
;
2607 if (uarmg
&& uarmg
== otmp
&& otmp
->otyp
== GAUNTLETS_OF_DEXTERITY
) {
2609 makeknown(uarmg
->otyp
);
2610 ABON(A_DEX
) += (delta
);
2614 if (uarmh
&& uarmh
== otmp
&& otmp
->otyp
== HELM_OF_BRILLIANCE
) {
2616 makeknown(uarmh
->otyp
);
2617 ABON(A_INT
) += (delta
);
2618 ABON(A_WIS
) += (delta
);
2624 /* decide whether a worn item is covered up by some other worn item,
2625 used for dipping into liquid and applying grease;
2626 some criteria are different than select_off()'s */
2628 inaccessible_equipment(obj
, verb
, only_if_known_cursed
)
2630 const char *verb
; /* "dip" or "grease", or null to avoid messages */
2631 boolean only_if_known_cursed
; /* ignore covering unless known to be cursed */
2633 static NEARDATA
const char need_to_take_off_outer_armor
[] =
2634 "need to take off %s to %s %s.";
2636 boolean anycovering
= !only_if_known_cursed
; /* more comprehensible... */
2637 #define BLOCKSACCESS(x) (anycovering || ((x)->cursed && (x)->bknown))
2639 if (!obj
|| !obj
->owornmask
)
2640 return FALSE
; /* not inaccessible */
2642 /* check for suit covered by cloak */
2643 if (obj
== uarm
&& uarmc
&& BLOCKSACCESS(uarmc
)) {
2645 Strcpy(buf
, yname(uarmc
));
2646 You(need_to_take_off_outer_armor
, buf
, verb
, yname(obj
));
2650 /* check for shirt covered by suit and/or cloak */
2652 && ((uarm
&& BLOCKSACCESS(uarm
)) || (uarmc
&& BLOCKSACCESS(uarmc
)))) {
2654 char cloaktmp
[QBUFSZ
], suittmp
[QBUFSZ
];
2655 /* if sameprefix, use yname and xname to get "your cloak and suit"
2656 or "Manlobbi's cloak and suit"; otherwise, use yname and yname
2657 to get "your cloak and Manlobbi's suit" or vice versa */
2658 boolean sameprefix
= (uarm
&& uarmc
2659 && !strcmp(shk_your(cloaktmp
, uarmc
),
2660 shk_your(suittmp
, uarm
)));
2664 Strcat(buf
, yname(uarmc
));
2666 Strcat(buf
, " and ");
2668 Strcat(buf
, sameprefix
? xname(uarm
) : yname(uarm
));
2669 You(need_to_take_off_outer_armor
, buf
, verb
, yname(obj
));
2673 /* check for ring covered by gloves */
2674 if ((obj
== uleft
|| obj
== uright
) && uarmg
&& BLOCKSACCESS(uarmg
)) {
2676 Strcpy(buf
, yname(uarmg
));
2677 You(need_to_take_off_outer_armor
, buf
, verb
, yname(obj
));
2681 /* item is not inaccessible */