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
;
1488 impossible("cursed without otmp");
1491 /* Curses, like chickens, come home to roost. */
1492 if ((otmp
== uwep
) ? welded(otmp
) : (int) otmp
->cursed
) {
1493 boolean use_plural
= (is_boots(otmp
) || is_gloves(otmp
)
1494 || otmp
->otyp
== LENSES
|| otmp
->quan
> 1L);
1496 You("can't. %s cursed.", use_plural
? "They are" : "It is");
1497 otmp
->bknown
= TRUE
;
1505 register struct obj
*otmp
;
1507 register int delay
= -objects
[otmp
->otyp
].oc_delay
;
1513 multi_reason
= "disrobing";
1514 if (is_helmet(otmp
)) {
1516 nomovemsg
= !strcmp(helm_simple_name(otmp
), "hat")
1517 ? "You finish taking off your hat."
1518 : "You finish taking off your helmet.";
1519 afternmv
= Helmet_off
;
1520 } else if (is_gloves(otmp
)) {
1521 nomovemsg
= "You finish taking off your gloves.";
1522 afternmv
= Gloves_off
;
1523 } else if (is_boots(otmp
)) {
1524 nomovemsg
= "You finish taking off your boots.";
1525 afternmv
= Boots_off
;
1527 nomovemsg
= "You finish taking off your suit.";
1528 afternmv
= Armor_off
;
1531 /* Be warned! We want off_msg after removing the item to
1532 * avoid "You were wearing ____ (being worn)." However, an
1533 * item which grants fire resistance might cause some trouble
1534 * if removed in Hell and lifesaving puts it back on; in this
1535 * case the message will be printed at the wrong time (after
1536 * the messages saying you died and were lifesaved). Luckily,
1537 * no cloak, shield, or fast-removable armor grants fire
1538 * resistance, so we can safely do the off_msg afterwards.
1539 * Rings do grant fire resistance, but for rings we want the
1540 * off_msg before removal anyway so there's no problem. Take
1541 * care in adding armors granting fire resistance; this code
1542 * might need modification.
1543 * 3.2 (actually 3.1 even): that comment is obsolete since
1544 * fire resistance is not required for Gehennom so setworn()
1545 * doesn't force the resistance granting item to be re-worn
1546 * after being lifesaved anymore.
1550 else if (is_shield(otmp
))
1551 (void) Shield_off();
1553 setworn((struct obj
*) 0, otmp
->owornmask
& W_ARMOR
);
1556 context
.takeoff
.mask
= context
.takeoff
.what
= 0L;
1564 You("are already wearing %s%c", cc
, (cc
== c_that_
) ? '!' : '.');
1568 already_wearing2(cc1
, cc2
)
1569 const char *cc1
, *cc2
;
1571 You_cant("wear %s because you're wearing %s there already.", cc1
, cc2
);
1575 * canwearobj checks to see whether the player can wear a piece of armor
1577 * inputs: otmp (the piece of armor)
1578 * noisy (if TRUE give error messages, otherwise be quiet about it)
1579 * output: mask (otmp's armor type)
1582 canwearobj(otmp
, mask
, noisy
)
1590 which
= is_cloak(otmp
)
1597 if (which
&& cantweararm(youmonst
.data
)
1598 /* same exception for cloaks as used in m_dowear() */
1599 && (which
!= c_cloak
|| youmonst
.data
->msize
!= MZ_SMALL
)
1600 && (racial_exception(&youmonst
, otmp
) < 1)) {
1602 pline_The("%s will not fit on your body.", which
);
1604 } else if (otmp
->owornmask
& W_ARMOR
) {
1606 already_wearing(c_that_
);
1610 if (welded(uwep
) && bimanual(uwep
) && (is_suit(otmp
) || is_shirt(otmp
))) {
1612 You("cannot do that while holding your %s.",
1613 is_sword(uwep
) ? c_sword
: c_weapon
);
1617 if (is_helmet(otmp
)) {
1620 already_wearing(an(helm_simple_name(uarmh
)));
1622 } else if (Upolyd
&& has_horns(youmonst
.data
) && !is_flimsy(otmp
)) {
1623 /* (flimsy exception matches polyself handling) */
1625 pline_The("%s won't fit over your horn%s.",
1626 helm_simple_name(otmp
),
1627 plur(num_horns(youmonst
.data
)));
1631 } else if (is_shield(otmp
)) {
1634 already_wearing(an(c_shield
));
1636 } else if (uwep
&& bimanual(uwep
)) {
1638 You("cannot wear a shield while wielding a two-handed %s.",
1639 is_sword(uwep
) ? c_sword
: (uwep
->otyp
== BATTLE_AXE
)
1643 } else if (u
.twoweap
) {
1645 You("cannot wear a shield while wielding two weapons.");
1649 } else if (is_boots(otmp
)) {
1652 already_wearing(c_boots
);
1654 } else if (Upolyd
&& slithy(youmonst
.data
)) {
1656 You("have no feet..."); /* not body_part(FOOT) */
1658 } else if (Upolyd
&& youmonst
.data
->mlet
== S_CENTAUR
) {
1659 /* break_armor() pushes boots off for centaurs,
1660 so don't let dowear() put them back on... */
1662 pline("You have too many hooves to wear %s.",
1663 c_boots
); /* makeplural(body_part(FOOT)) yields
1664 "rear hooves" which sounds odd */
1667 && (u
.utraptype
== TT_BEARTRAP
|| u
.utraptype
== TT_INFLOOR
1668 || u
.utraptype
== TT_LAVA
1669 || u
.utraptype
== TT_BURIEDBALL
)) {
1670 if (u
.utraptype
== TT_BEARTRAP
) {
1672 Your("%s is trapped!", body_part(FOOT
));
1673 } else if (u
.utraptype
== TT_INFLOOR
|| u
.utraptype
== TT_LAVA
) {
1675 Your("%s are stuck in the %s!",
1676 makeplural(body_part(FOOT
)), surface(u
.ux
, u
.uy
));
1677 } else { /*TT_BURIEDBALL*/
1679 Your("%s is attached to the buried ball!",
1685 } else if (is_gloves(otmp
)) {
1688 already_wearing(c_gloves
);
1690 } else if (welded(uwep
)) {
1692 You("cannot wear gloves over your %s.",
1693 is_sword(uwep
) ? c_sword
: c_weapon
);
1697 } else if (is_shirt(otmp
)) {
1698 if (uarm
|| uarmc
|| uarmu
) {
1701 already_wearing(an(c_shirt
));
1704 You_cant("wear that over your %s.",
1705 (uarm
&& !uarmc
) ? c_armor
1706 : cloak_simple_name(uarmc
));
1711 } else if (is_cloak(otmp
)) {
1714 already_wearing(an(cloak_simple_name(uarmc
)));
1718 } else if (is_suit(otmp
)) {
1721 You("cannot wear armor over a %s.", cloak_simple_name(uarmc
));
1725 already_wearing("some armor");
1730 /* getobj can't do this after setting its allow_all flag; that
1731 happens if you have armor for slots that are covered up or
1732 extra armor for slots that are filled */
1734 silly_thing("wear", otmp
);
1737 /* Unnecessary since now only weapons and special items like pick-axes get
1738 * welded to your hand, not armor
1741 if (noisy) weldmsg(otmp);
1749 accessory_or_armor_on(obj
)
1753 boolean armor
, ring
, eyewear
;
1755 if (obj
->owornmask
& (W_ACCESSORY
| W_ARMOR
)) {
1756 already_wearing(c_that_
);
1759 armor
= (obj
->oclass
== ARMOR_CLASS
);
1760 ring
= (obj
->oclass
== RING_CLASS
|| obj
->otyp
== MEAT_RING
);
1761 eyewear
= (obj
->otyp
== BLINDFOLD
|| obj
->otyp
== TOWEL
1762 || obj
->otyp
== LENSES
);
1763 /* checks which are performed prior to actually touching the item */
1765 if (!canwearobj(obj
, &mask
, TRUE
))
1768 if (obj
->otyp
== HELM_OF_OPPOSITE_ALIGNMENT
1769 && qstart_level
.dnum
== u
.uz
.dnum
) { /* in quest */
1770 if (u
.ualignbase
[A_CURRENT
] == u
.ualignbase
[A_ORIGINAL
])
1771 You("narrowly avoid losing all chance at your goal.");
1772 else /* converted */
1773 You("are suddenly overcome with shame and change your mind.");
1774 u
.ublessed
= 0; /* lose your god's protection */
1775 makeknown(obj
->otyp
);
1776 context
.botl
= 1; /*for AC after zeroing u.ublessed */
1782 char answer
, qbuf
[QBUFSZ
];
1785 if (nolimbs(youmonst
.data
)) {
1786 You("cannot make the ring stick to your body.");
1789 if (uleft
&& uright
) {
1790 There("are no more %s%s to fill.",
1791 humanoid(youmonst
.data
) ? "ring-" : "",
1792 makeplural(body_part(FINGER
)));
1797 } else if (uright
) {
1801 Sprintf(qbuf
, "Which %s%s, Right or Left?",
1802 humanoid(youmonst
.data
) ? "ring-" : "",
1804 answer
= yn_function(qbuf
, "rl", '\0');
1819 if (uarmg
&& uarmg
->cursed
) {
1820 res
= !uarmg
->bknown
;
1822 You("cannot remove your gloves to put on the ring.");
1823 return res
; /* uses move iff we learned gloves are cursed */
1826 res
= !uwep
->bknown
; /* check this before calling welded() */
1827 if ((mask
== RIGHT_RING
|| bimanual(uwep
)) && welded(uwep
)) {
1828 const char *hand
= body_part(HAND
);
1830 /* welded will set bknown */
1832 hand
= makeplural(hand
);
1833 You("cannot free your weapon %s to put on the ring.",
1835 return res
; /* uses move iff we learned weapon is cursed */
1838 } else if (obj
->oclass
== AMULET_CLASS
) {
1840 already_wearing("an amulet");
1843 } else if (eyewear
) {
1845 if (ublindf
->otyp
== TOWEL
)
1846 Your("%s is already covered by a towel.",
1848 else if (ublindf
->otyp
== BLINDFOLD
) {
1849 if (obj
->otyp
== LENSES
)
1850 already_wearing2("lenses", "a blindfold");
1852 already_wearing("a blindfold");
1853 } else if (ublindf
->otyp
== LENSES
) {
1854 if (obj
->otyp
== BLINDFOLD
)
1855 already_wearing2("a blindfold", "some lenses");
1857 already_wearing("some lenses");
1859 already_wearing(something
); /* ??? */
1864 /* neither armor nor accessory */
1865 You_cant("wear that!");
1870 if (!retouch_object(&obj
, FALSE
))
1871 return 1; /* costs a turn even though it didn't get worn */
1876 obj
->known
= 1; /* since AC is shown on the status line */
1877 /* if the armor is wielded, release it for wearing */
1878 if (obj
->owornmask
& W_WEAPON
)
1879 remove_worn_item(obj
, FALSE
);
1881 delay
= -objects
[obj
->otyp
].oc_delay
;
1884 multi_reason
= "dressing up";
1886 afternmv
= Boots_on
;
1888 afternmv
= Helmet_on
;
1890 afternmv
= Gloves_on
;
1892 afternmv
= Armor_on
;
1893 nomovemsg
= "You finish your dressing maneuver.";
1903 context
.takeoff
.mask
= context
.takeoff
.what
= 0L;
1904 } else { /* not armor */
1905 boolean give_feedback
= FALSE
;
1907 /* [releasing wielded accessory handled in Xxx_on()] */
1911 give_feedback
= TRUE
;
1912 } else if (obj
->oclass
== AMULET_CLASS
) {
1913 setworn(obj
, W_AMUL
);
1915 /* no feedback here if amulet of change got used up */
1916 give_feedback
= (uamul
!= 0);
1917 } else if (eyewear
) {
1918 /* setworn() handled by Blindf_on() */
1920 /* message handled by Blindf_on(); leave give_feedback False */
1922 /* feedback for ring or for amulet other than 'change' */
1923 if (give_feedback
&& is_worn(obj
))
1924 prinv((char *) 0, obj
, 0L);
1929 /* the 'W' command */
1935 /* cantweararm() checks for suits of armor, not what we want here;
1936 verysmall() or nohands() checks for shields, gloves, etc... */
1937 if ((verysmall(youmonst
.data
) || nohands(youmonst
.data
))) {
1938 pline("Don't even bother.");
1941 if (uarm
&& uarmu
&& uarmc
&& uarmh
&& uarms
&& uarmg
&& uarmf
1942 && uleft
&& uright
&& uamul
&& ublindf
) {
1943 /* 'W' message doesn't mention accessories */
1944 You("are already wearing a full complement of armor.");
1947 otmp
= getobj(clothes
, "wear");
1948 return otmp
? accessory_or_armor_on(otmp
) : 0;
1951 /* the 'P' command */
1957 if (uleft
&& uright
&& uamul
&& ublindf
1958 && uarm
&& uarmu
&& uarmc
&& uarmh
&& uarms
&& uarmg
&& uarmf
) {
1959 /* 'P' message doesn't mention armor */
1960 Your("%s%s are full, and you're already wearing an amulet and %s.",
1961 humanoid(youmonst
.data
) ? "ring-" : "",
1962 makeplural(body_part(FINGER
)),
1963 (ublindf
->otyp
== LENSES
) ? "some lenses" : "a blindfold");
1966 otmp
= getobj(accessories
, "put on");
1967 return otmp
? accessory_or_armor_on(otmp
) : 0;
1970 /* calculate current armor class */
1974 int uac
= mons
[u
.umonnum
].ac
; /* base armor class for current form */
1976 /* armor class from worn gear */
1978 uac
-= ARM_BONUS(uarm
);
1980 uac
-= ARM_BONUS(uarmc
);
1982 uac
-= ARM_BONUS(uarmh
);
1984 uac
-= ARM_BONUS(uarmf
);
1986 uac
-= ARM_BONUS(uarms
);
1988 uac
-= ARM_BONUS(uarmg
);
1990 uac
-= ARM_BONUS(uarmu
);
1991 if (uleft
&& uleft
->otyp
== RIN_PROTECTION
)
1993 if (uright
&& uright
->otyp
== RIN_PROTECTION
)
1996 /* armor class from other sources */
1997 if (HProtection
& INTRINSIC
)
1999 uac
-= u
.uspellprot
;
2001 /* [The magic binary numbers 127 and -128 should be replaced with the
2002 * mystic decimal numbers 99 and -99 which require no explanation to
2003 * the uninitiated and would cap the width of a status line value at
2004 * one less character.]
2007 uac
= -128; /* u.uac is an schar */
2009 uac
= 127; /* for completeness */
2020 register struct obj
*otmp
;
2022 boolean leftfall
, rightfall
, wastwoweap
= FALSE
;
2023 const char *otherwep
= 0, *thiswep
, *which
, *hand
;
2025 leftfall
= (uleft
&& !uleft
->cursed
2026 && (!uwep
|| !welded(uwep
) || !bimanual(uwep
)));
2027 rightfall
= (uright
&& !uright
->cursed
&& (!welded(uwep
)));
2028 if (!uarmg
&& (leftfall
|| rightfall
) && !nolimbs(youmonst
.data
)) {
2029 /* changed so cursed rings don't fall off, GAN 10/30/86 */
2030 Your("%s off your %s.",
2031 (leftfall
&& rightfall
) ? "rings slip" : "ring slips",
2032 (leftfall
&& rightfall
) ? makeplural(body_part(FINGER
))
2033 : body_part(FINGER
));
2048 if (u
.twoweap
&& otmp
) {
2049 /* secondary weapon doesn't need nearly as much handling as
2050 primary; when in two-weapon mode, we know it's one-handed
2051 with something else in the other hand and also that it's
2052 a weapon or weptool rather than something unusual, plus
2053 we don't need to compare its type with the primary */
2054 otherwep
= is_sword(otmp
) ? c_sword
: weapon_descr(otmp
);
2055 if (otmp
->quan
> 1L)
2056 otherwep
= makeplural(otherwep
);
2057 hand
= body_part(HAND
);
2059 Your("%s %s%s from your %s%s.", otherwep
, xfl
? "also " : "",
2060 otense(otmp
, "slip"), which
, hand
);
2063 setuswapwep((struct obj
*) 0); /* clears u.twoweap */
2064 if (canletgo(otmp
, ""))
2068 if (otmp
&& !welded(otmp
)) {
2069 long savequan
= otmp
->quan
;
2071 /* nice wording if both weapons are the same type */
2072 thiswep
= is_sword(otmp
) ? c_sword
: weapon_descr(otmp
);
2073 if (otherwep
&& strcmp(thiswep
, makesingular(otherwep
)))
2075 if (otmp
->quan
> 1L) {
2076 /* most class names for unconventional wielded items
2077 are ok, but if wielding multiple apples or rations
2078 we don't want "your foods slip", so force non-corpse
2079 food to be singular; skipping makeplural() isn't
2080 enough--we need to fool otense() too */
2081 if (!strcmp(thiswep
, "food"))
2084 thiswep
= makeplural(thiswep
);
2086 hand
= body_part(HAND
);
2089 hand
= makeplural(hand
);
2090 else if (wastwoweap
)
2091 which
= "right "; /* preceding msg was about left */
2092 pline("%s %s%s %s%s from your %s%s.",
2093 !strncmp(thiswep
, "corpse", 6) ? "The" : "Your",
2094 otherwep
? "other " : "", thiswep
, xfl
? "also " : "",
2095 otense(otmp
, "slip"), which
, hand
);
2097 otmp
->quan
= savequan
;
2098 setuwep((struct obj
*) 0);
2099 if (canletgo(otmp
, ""))
2106 struct monst
*victim
;
2108 register struct obj
*otmph
, *otmp
;
2110 otmph
= (victim
== &youmonst
) ? uarmc
: which_armor(victim
, W_ARMC
);
2112 otmph
= (victim
== &youmonst
) ? uarm
: which_armor(victim
, W_ARM
);
2114 otmph
= (victim
== &youmonst
) ? uarmu
: which_armor(victim
, W_ARMU
);
2116 otmp
= (victim
== &youmonst
) ? uarmh
: which_armor(victim
, W_ARMH
);
2117 if (otmp
&& (!otmph
|| !rn2(4)))
2119 otmp
= (victim
== &youmonst
) ? uarmg
: which_armor(victim
, W_ARMG
);
2120 if (otmp
&& (!otmph
|| !rn2(4)))
2122 otmp
= (victim
== &youmonst
) ? uarmf
: which_armor(victim
, W_ARMF
);
2123 if (otmp
&& (!otmph
|| !rn2(4)))
2125 otmp
= (victim
== &youmonst
) ? uarms
: which_armor(victim
, W_ARMS
);
2126 if (otmp
&& (!otmph
|| !rn2(4)))
2131 /* used for praying to check and fix levitation trouble */
2133 stuck_ring(ring
, otyp
)
2137 if (ring
!= uleft
&& ring
!= uright
) {
2138 impossible("stuck_ring: neither left nor right?");
2139 return (struct obj
*) 0;
2142 if (ring
&& ring
->otyp
== otyp
) {
2143 /* reasons ring can't be removed match those checked by select_off();
2144 limbless case has extra checks because ordinarily it's temporary */
2145 if (nolimbs(youmonst
.data
) && uamul
2146 && uamul
->otyp
== AMULET_OF_UNCHANGING
&& uamul
->cursed
)
2148 if (welded(uwep
) && (ring
== uright
|| bimanual(uwep
)))
2150 if (uarmg
&& uarmg
->cursed
)
2155 /* either no ring or not right type or nothing prevents its removal */
2156 return (struct obj
*) 0;
2159 /* also for praying; find worn item that confers "Unchanging" attribute */
2163 if (uamul
&& uamul
->otyp
== AMULET_OF_UNCHANGING
)
2171 register struct obj
*otmp
;
2178 *buf
= '\0'; /* lint suppression */
2180 /* special ring checks */
2181 if (otmp
== uright
|| otmp
== uleft
) {
2182 if (nolimbs(youmonst
.data
)) {
2183 pline_The("ring is stuck.");
2186 why
= 0; /* the item which prevents ring removal */
2187 if (welded(uwep
) && (otmp
== uright
|| bimanual(uwep
))) {
2188 Sprintf(buf
, "free a weapon %s", body_part(HAND
));
2190 } else if (uarmg
&& uarmg
->cursed
) {
2191 Sprintf(buf
, "take off your %s", c_gloves
);
2195 You("cannot %s to remove the ring.", buf
);
2200 /* special glove checks */
2201 if (otmp
== uarmg
) {
2203 You("are unable to take off your %s while wielding that %s.",
2204 c_gloves
, is_sword(uwep
) ? c_sword
: c_weapon
);
2205 uwep
->bknown
= TRUE
;
2208 You_cant("take off the slippery %s with your slippery %s.",
2209 c_gloves
, makeplural(body_part(FINGER
)));
2213 /* special boot checks */
2214 if (otmp
== uarmf
) {
2215 if (u
.utrap
&& u
.utraptype
== TT_BEARTRAP
) {
2216 pline_The("bear trap prevents you from pulling your %s out.",
2219 } else if (u
.utrap
&& u
.utraptype
== TT_INFLOOR
) {
2220 You("are stuck in the %s, and cannot pull your %s out.",
2221 surface(u
.ux
, u
.uy
), makeplural(body_part(FOOT
)));
2225 /* special suit and shirt checks */
2226 if (otmp
== uarm
|| otmp
== uarmu
) {
2227 why
= 0; /* the item which prevents disrobing */
2228 if (uarmc
&& uarmc
->cursed
) {
2229 Sprintf(buf
, "remove your %s", cloak_simple_name(uarmc
));
2231 } else if (otmp
== uarmu
&& uarm
&& uarm
->cursed
) {
2232 Sprintf(buf
, "remove your %s", c_suit
);
2234 } else if (welded(uwep
) && bimanual(uwep
)) {
2235 Sprintf(buf
, "release your %s",
2236 is_sword(uwep
) ? c_sword
: (uwep
->otyp
== BATTLE_AXE
)
2242 You("cannot %s to take off %s.", buf
, the(xname(otmp
)));
2247 /* basic curse check */
2248 if (otmp
== uquiver
|| (otmp
== uswapwep
&& !u
.twoweap
)) {
2249 ; /* some items can be removed even when cursed */
2251 /* otherwise, this is fundamental */
2257 context
.takeoff
.mask
|= WORN_ARMOR
;
2258 else if (otmp
== uarmc
)
2259 context
.takeoff
.mask
|= WORN_CLOAK
;
2260 else if (otmp
== uarmf
)
2261 context
.takeoff
.mask
|= WORN_BOOTS
;
2262 else if (otmp
== uarmg
)
2263 context
.takeoff
.mask
|= WORN_GLOVES
;
2264 else if (otmp
== uarmh
)
2265 context
.takeoff
.mask
|= WORN_HELMET
;
2266 else if (otmp
== uarms
)
2267 context
.takeoff
.mask
|= WORN_SHIELD
;
2268 else if (otmp
== uarmu
)
2269 context
.takeoff
.mask
|= WORN_SHIRT
;
2270 else if (otmp
== uleft
)
2271 context
.takeoff
.mask
|= LEFT_RING
;
2272 else if (otmp
== uright
)
2273 context
.takeoff
.mask
|= RIGHT_RING
;
2274 else if (otmp
== uamul
)
2275 context
.takeoff
.mask
|= WORN_AMUL
;
2276 else if (otmp
== ublindf
)
2277 context
.takeoff
.mask
|= WORN_BLINDF
;
2278 else if (otmp
== uwep
)
2279 context
.takeoff
.mask
|= W_WEP
;
2280 else if (otmp
== uswapwep
)
2281 context
.takeoff
.mask
|= W_SWAPWEP
;
2282 else if (otmp
== uquiver
)
2283 context
.takeoff
.mask
|= W_QUIVER
;
2286 impossible("select_off: %s???", doname(otmp
));
2291 STATIC_OVL
struct obj
*
2294 struct obj
*otmp
= (struct obj
*) 0;
2295 struct takeoff_info
*doff
= &context
.takeoff
;
2297 if (doff
->what
== W_WEP
) {
2298 if (!cursed(uwep
)) {
2299 setuwep((struct obj
*) 0);
2300 You("are empty %s.", body_part(HANDED
));
2303 } else if (doff
->what
== W_SWAPWEP
) {
2304 setuswapwep((struct obj
*) 0);
2305 You("no longer have a second weapon readied.");
2307 } else if (doff
->what
== W_QUIVER
) {
2308 setuqwep((struct obj
*) 0);
2309 You("no longer have ammunition readied.");
2310 } else if (doff
->what
== WORN_ARMOR
) {
2314 } else if (doff
->what
== WORN_CLOAK
) {
2318 } else if (doff
->what
== WORN_BOOTS
) {
2322 } else if (doff
->what
== WORN_GLOVES
) {
2325 (void) Gloves_off();
2326 } else if (doff
->what
== WORN_HELMET
) {
2329 (void) Helmet_off();
2330 } else if (doff
->what
== WORN_SHIELD
) {
2333 (void) Shield_off();
2334 } else if (doff
->what
== WORN_SHIRT
) {
2338 } else if (doff
->what
== WORN_AMUL
) {
2342 } else if (doff
->what
== LEFT_RING
) {
2346 } else if (doff
->what
== RIGHT_RING
) {
2350 } else if (doff
->what
== WORN_BLINDF
) {
2351 if (!cursed(ublindf
))
2352 Blindf_off(ublindf
);
2354 impossible("do_takeoff: taking off %lx", doff
->what
);
2360 /* occupation callback for 'A' */
2366 register struct obj
*otmp
;
2367 struct takeoff_info
*doff
= &context
.takeoff
;
2370 if (doff
->delay
> 0) {
2372 return 1; /* still busy */
2374 if ((otmp
= do_takeoff()))
2377 doff
->mask
&= ~doff
->what
;
2381 for (i
= 0; takeoff_order
[i
]; i
++)
2382 if (doff
->mask
& takeoff_order
[i
]) {
2383 doff
->what
= takeoff_order
[i
];
2387 otmp
= (struct obj
*) 0;
2390 if (doff
->what
== 0L) {
2391 You("finish %s.", doff
->disrobing
);
2393 } else if (doff
->what
== W_WEP
) {
2395 } else if (doff
->what
== W_SWAPWEP
) {
2397 } else if (doff
->what
== W_QUIVER
) {
2399 } else if (doff
->what
== WORN_ARMOR
) {
2401 /* If a cloak is being worn, add the time to take it off and put
2402 * it back on again. Kludge alert! since that time is 0 for all
2403 * known cloaks, add 1 so that it actually matters...
2406 doff
->delay
+= 2 * objects
[uarmc
->otyp
].oc_delay
+ 1;
2407 } else if (doff
->what
== WORN_CLOAK
) {
2409 } else if (doff
->what
== WORN_BOOTS
) {
2411 } else if (doff
->what
== WORN_GLOVES
) {
2413 } else if (doff
->what
== WORN_HELMET
) {
2415 } else if (doff
->what
== WORN_SHIELD
) {
2417 } else if (doff
->what
== WORN_SHIRT
) {
2419 /* add the time to take off and put back on armor and/or cloak */
2421 doff
->delay
+= 2 * objects
[uarm
->otyp
].oc_delay
;
2423 doff
->delay
+= 2 * objects
[uarmc
->otyp
].oc_delay
+ 1;
2424 } else if (doff
->what
== WORN_AMUL
) {
2426 } else if (doff
->what
== LEFT_RING
) {
2428 } else if (doff
->what
== RIGHT_RING
) {
2430 } else if (doff
->what
== WORN_BLINDF
) {
2433 impossible("take_off: taking off %lx", doff
->what
);
2434 return 0; /* force done */
2438 doff
->delay
+= objects
[otmp
->otyp
].oc_delay
;
2440 /* Since setting the occupation now starts the counter next move, that
2441 * would always produce a delay 1 too big per item unless we subtract
2442 * 1 here to account for it.
2444 if (doff
->delay
> 0)
2447 set_occupation(take_off
, doff
->disrobing
, 0);
2448 return 1; /* get busy */
2451 /* clear saved context to avoid inappropriate resumption of interrupted 'A' */
2455 context
.takeoff
.what
= context
.takeoff
.mask
= 0L;
2456 context
.takeoff
.disrobing
[0] = '\0';
2459 /* the 'A' command -- remove multiple worn items */
2465 if (context
.takeoff
.what
|| context
.takeoff
.mask
) {
2466 You("continue %s.", context
.takeoff
.disrobing
);
2467 set_occupation(take_off
, context
.takeoff
.disrobing
, 0);
2469 } else if (!uwep
&& !uswapwep
&& !uquiver
&& !uamul
&& !ublindf
&& !uleft
2470 && !uright
&& !wearing_armor()) {
2471 You("are not wearing anything.");
2475 add_valid_menu_class(0); /* reset */
2476 if (flags
.menu_style
!= MENU_TRADITIONAL
2477 || (result
= ggetobj("take off", select_off
, 0, FALSE
,
2478 (unsigned *) 0)) < -1)
2479 result
= menu_remarm(result
);
2481 if (context
.takeoff
.mask
) {
2482 /* default activity for armor and/or accessories,
2483 possibly combined with weapons */
2484 (void) strncpy(context
.takeoff
.disrobing
, "disrobing", CONTEXTVERBSZ
);
2485 /* specific activity when handling weapons only */
2486 if (!(context
.takeoff
.mask
& ~W_WEAPON
))
2487 (void) strncpy(context
.takeoff
.disrobing
, "disarming",
2491 /* The time to perform the command is already completely accounted for
2492 * in take_off(); if we return 1, that would add an extra turn to each
2503 menu_item
*pick_list
;
2504 boolean all_worn_categories
= TRUE
;
2507 all_worn_categories
= (retry
== -2);
2508 } else if (flags
.menu_style
== MENU_FULL
) {
2509 all_worn_categories
= FALSE
;
2510 n
= query_category("What type of things do you want to take off?",
2511 invent
, WORN_TYPES
| ALL_TYPES
, &pick_list
,
2515 for (i
= 0; i
< n
; i
++) {
2516 if (pick_list
[i
].item
.a_int
== ALL_TYPES_SELECTED
)
2517 all_worn_categories
= TRUE
;
2519 add_valid_menu_class(pick_list
[i
].item
.a_int
);
2521 free((genericptr_t
) pick_list
);
2522 } else if (flags
.menu_style
== MENU_COMBINATION
) {
2523 all_worn_categories
= FALSE
;
2524 if (ggetobj("take off", select_off
, 0, TRUE
, (unsigned *) 0) == -2)
2525 all_worn_categories
= TRUE
;
2528 n
= query_objlist("What do you want to take off?", &invent
,
2529 (SIGNAL_NOMENU
| USE_INVLET
| INVORDER_SORT
),
2530 &pick_list
, PICK_ANY
,
2531 all_worn_categories
? is_worn
: is_worn_by_type
);
2533 for (i
= 0; i
< n
; i
++)
2534 (void) select_off(pick_list
[i
].item
.a_obj
);
2535 free((genericptr_t
) pick_list
);
2536 } else if (n
< 0 && flags
.menu_style
!= MENU_COMBINATION
) {
2537 There("is nothing else you can remove or unwield.");
2542 /* hit by destroy armor scroll/black dragon breath/monster spell */
2545 register struct obj
*atmp
;
2547 register struct obj
*otmp
;
2548 #define DESTROY_ARM(o) \
2549 ((otmp = (o)) != 0 && (!atmp || atmp == otmp) \
2550 && (!obj_resists(otmp, 0, 90)) \
2551 ? (otmp->in_use = TRUE) \
2554 if (DESTROY_ARM(uarmc
)) {
2557 Your("%s crumbles and turns to dust!", cloak_simple_name(uarmc
));
2560 } else if (DESTROY_ARM(uarm
)) {
2563 Your("armor turns to dust and falls to the %s!", surface(u
.ux
, u
.uy
));
2564 (void) Armor_gone();
2566 } else if (DESTROY_ARM(uarmu
)) {
2569 Your("shirt crumbles into tiny threads and falls apart!");
2572 } else if (DESTROY_ARM(uarmh
)) {
2575 Your("%s turns to dust and is blown away!", helm_simple_name(uarmh
));
2576 (void) Helmet_off();
2578 } else if (DESTROY_ARM(uarmg
)) {
2581 Your("gloves vanish!");
2582 (void) Gloves_off();
2585 } else if (DESTROY_ARM(uarmf
)) {
2588 Your("boots disintegrate!");
2591 } else if (DESTROY_ARM(uarms
)) {
2594 Your("shield crumbles away!");
2595 (void) Shield_off();
2598 return 0; /* could not destroy anything */
2607 adj_abon(otmp
, delta
)
2608 register struct obj
*otmp
;
2609 register schar delta
;
2611 if (uarmg
&& uarmg
== otmp
&& otmp
->otyp
== GAUNTLETS_OF_DEXTERITY
) {
2613 makeknown(uarmg
->otyp
);
2614 ABON(A_DEX
) += (delta
);
2618 if (uarmh
&& uarmh
== otmp
&& otmp
->otyp
== HELM_OF_BRILLIANCE
) {
2620 makeknown(uarmh
->otyp
);
2621 ABON(A_INT
) += (delta
);
2622 ABON(A_WIS
) += (delta
);
2628 /* decide whether a worn item is covered up by some other worn item,
2629 used for dipping into liquid and applying grease;
2630 some criteria are different than select_off()'s */
2632 inaccessible_equipment(obj
, verb
, only_if_known_cursed
)
2634 const char *verb
; /* "dip" or "grease", or null to avoid messages */
2635 boolean only_if_known_cursed
; /* ignore covering unless known to be cursed */
2637 static NEARDATA
const char need_to_take_off_outer_armor
[] =
2638 "need to take off %s to %s %s.";
2640 boolean anycovering
= !only_if_known_cursed
; /* more comprehensible... */
2641 #define BLOCKSACCESS(x) (anycovering || ((x)->cursed && (x)->bknown))
2643 if (!obj
|| !obj
->owornmask
)
2644 return FALSE
; /* not inaccessible */
2646 /* check for suit covered by cloak */
2647 if (obj
== uarm
&& uarmc
&& BLOCKSACCESS(uarmc
)) {
2649 Strcpy(buf
, yname(uarmc
));
2650 You(need_to_take_off_outer_armor
, buf
, verb
, yname(obj
));
2654 /* check for shirt covered by suit and/or cloak */
2656 && ((uarm
&& BLOCKSACCESS(uarm
)) || (uarmc
&& BLOCKSACCESS(uarmc
)))) {
2658 char cloaktmp
[QBUFSZ
], suittmp
[QBUFSZ
];
2659 /* if sameprefix, use yname and xname to get "your cloak and suit"
2660 or "Manlobbi's cloak and suit"; otherwise, use yname and yname
2661 to get "your cloak and Manlobbi's suit" or vice versa */
2662 boolean sameprefix
= (uarm
&& uarmc
2663 && !strcmp(shk_your(cloaktmp
, uarmc
),
2664 shk_your(suittmp
, uarm
)));
2668 Strcat(buf
, yname(uarmc
));
2670 Strcat(buf
, " and ");
2672 Strcat(buf
, sameprefix
? xname(uarm
) : yname(uarm
));
2673 You(need_to_take_off_outer_armor
, buf
, verb
, yname(obj
));
2677 /* check for ring covered by gloves */
2678 if ((obj
== uleft
|| obj
== uright
) && uarmg
&& BLOCKSACCESS(uarmg
)) {
2680 Strcpy(buf
, yname(uarmg
));
2681 You(need_to_take_off_outer_armor
, buf
, verb
, yname(obj
));
2685 /* item is not inaccessible */