1 /* SCCS Id: @(#)do_wear.c 3.4 2003/11/14 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
9 STATIC_DCL long takeoff_mask, taking_off;
13 STATIC_OVL NEARDATA long takeoff_mask = 0L;
14 static NEARDATA long taking_off = 0L;
16 static NEARDATA int todelay;
17 static boolean cancelled_don = FALSE;
19 static NEARDATA const char see_yourself[] = "see yourself";
20 static NEARDATA const char unknown_type[] = "Unknown type of %s (%d)";
21 static NEARDATA const char c_armor[] = "armor",
27 c_gloves[] = "gloves",
29 c_helmet[] = "helmet",
30 c_shield[] = "shield",
31 c_weapon[] = "weapon",
36 static NEARDATA const long takeoff_order[] = { WORN_BLINDF, W_WEP,
37 WORN_SHIELD, WORN_GLOVES, LEFT_RING, RIGHT_RING, WORN_CLOAK,
38 WORN_HELMET, WORN_AMUL, WORN_ARMOR,
42 WORN_BOOTS, W_SWAPWEP, W_QUIVER, 0L };
44 STATIC_DCL void FDECL(on_msg, (struct obj *));
45 STATIC_PTR int NDECL(Armor_on);
46 STATIC_PTR int NDECL(Boots_on);
47 STATIC_DCL int NDECL(Cloak_on);
48 STATIC_PTR int NDECL(Helmet_on);
49 STATIC_PTR int NDECL(Gloves_on);
50 STATIC_PTR int NDECL(Shield_on);
52 STATIC_PTR int NDECL(Shirt_on);
54 STATIC_DCL void NDECL(Amulet_on);
55 STATIC_DCL void FDECL(Ring_off_or_gone, (struct obj *, BOOLEAN_P));
56 STATIC_PTR int FDECL(select_off, (struct obj *));
57 STATIC_DCL struct obj *NDECL(do_takeoff);
58 STATIC_PTR int NDECL(take_off);
59 STATIC_DCL int FDECL(menu_remarm, (int));
60 STATIC_DCL void FDECL(already_wearing, (const char*));
61 STATIC_DCL void FDECL(already_wearing2, (const char*, const char*));
65 register struct obj *otmp;
68 You("were wearing %s.", doname(otmp));
71 /* for items that involve no delay */
74 register struct obj *otmp;
80 if (otmp->otyp == TOWEL)
81 Sprintf(how, " around your %s", body_part(HEAD));
82 You("are now wearing %s%s.",
83 obj_is_pname(otmp) ? the(xname(otmp)) : an(xname(otmp)),
89 * The Type_on() functions should be called *after* setworn().
90 * The Type_off() functions call setworn() themselves.
98 u.uprops[objects[uarmf->otyp].oc_oprop].extrinsic & ~WORN_BOOTS;
100 switch(uarmf->otyp) {
107 case WATER_WALKING_BOOTS:
108 if (u.uinwater) spoteffects(TRUE);
111 /* Speed boots are still better than intrinsic speed, */
112 /* though not better than potion speed */
113 if (!oldprop && !(HFast & TIMEOUT)) {
114 makeknown(uarmf->otyp);
115 You_feel("yourself speed up%s.",
116 (oldprop || HFast) ? " a bit more" : "");
120 if (!oldprop && !HStealth && !BStealth) {
121 makeknown(uarmf->otyp);
122 You("walk very quietly.");
126 if (!oldprop && !(HFumbling & ~TIMEOUT))
127 incr_itimeout(&HFumbling, rnd(20));
129 case LEVITATION_BOOTS:
130 if (!oldprop && !HLevitation) {
131 makeknown(uarmf->otyp);
136 default: impossible(unknown_type, c_boots, uarmf->otyp);
144 int otyp = uarmf->otyp;
145 long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_BOOTS;
147 takeoff_mask &= ~W_ARMF;
148 /* For levitation, float_down() returns if Levitation, so we
149 * must do a setworn() _before_ the levitation case.
151 setworn((struct obj *)0, W_ARMF);
154 if (!Very_fast && !cancelled_don) {
156 You_feel("yourself slow down%s.",
157 Fast ? " a bit" : "");
160 case WATER_WALKING_BOOTS:
161 if (is_pool(u.ux,u.uy) && !Levitation && !Flying &&
162 !is_clinger(youmonst.data) && !cancelled_don) {
164 /* make boots known in case you survive the drowning */
169 if (!oldprop && !HStealth && !BStealth && !cancelled_don) {
171 You("sure are noisy.");
175 if (!oldprop && !(HFumbling & ~TIMEOUT))
176 HFumbling = EFumbling = 0;
178 case LEVITATION_BOOTS:
179 if (!oldprop && !HLevitation && !cancelled_don) {
180 (void) float_down(0L, 0L);
190 default: impossible(unknown_type, c_boots, otyp);
192 cancelled_don = FALSE;
200 u.uprops[objects[uarmc->otyp].oc_oprop].extrinsic & ~WORN_CLOAK;
202 switch(uarmc->otyp) {
204 case CLOAK_OF_PROTECTION:
205 case CLOAK_OF_DISPLACEMENT:
206 makeknown(uarmc->otyp);
210 case CLOAK_OF_MAGIC_RESISTANCE:
215 /* Note: it's already being worn, so we have to cheat here. */
216 if ((HInvis || EInvis || pm_invisible(youmonst.data)) && !Blind) {
219 See_invisible ? "no longer see through yourself"
223 case CLOAK_OF_INVISIBILITY:
224 /* since cloak of invisibility was worn, we know mummy wrapping
225 wasn't, so no need to check `oldprop' against blocked */
226 if (!oldprop && !HInvis && !Blind) {
227 makeknown(uarmc->otyp);
229 pline("Suddenly you can%s yourself.",
230 See_invisible ? " see through" : "not see");
234 pline("%s very tightly.", Tobjnam(uarmc, "fit"));
236 /* Alchemy smock gives poison _and_ acid resistance */
238 EAcid_resistance |= WORN_CLOAK;
240 default: impossible(unknown_type, c_cloak, uarmc->otyp);
248 int otyp = uarmc->otyp;
249 long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_CLOAK;
251 takeoff_mask &= ~W_ARMC;
252 /* For mummy wrapping, taking it off first resets `Invisible'. */
253 setworn((struct obj *)0, W_ARMC);
258 case CLOAK_OF_PROTECTION:
259 case CLOAK_OF_MAGIC_RESISTANCE:
260 case CLOAK_OF_DISPLACEMENT:
266 if (Invis && !Blind) {
269 See_invisible ? "see through yourself"
270 : "no longer see yourself");
273 case CLOAK_OF_INVISIBILITY:
274 if (!oldprop && !HInvis && !Blind) {
275 makeknown(CLOAK_OF_INVISIBILITY);
277 pline("Suddenly you can %s.",
278 See_invisible ? "no longer see through yourself"
282 /* Alchemy smock gives poison _and_ acid resistance */
284 EAcid_resistance &= ~WORN_CLOAK;
286 default: impossible(unknown_type, c_cloak, otyp);
295 switch(uarmh->otyp) {
299 case ELVEN_LEATHER_HELM:
300 case DWARVISH_IRON_HELM:
302 case HELM_OF_TELEPATHY:
304 case HELM_OF_BRILLIANCE:
305 adj_abon(uarmh, uarmh->spe);
308 /* people think marked wizards know what they're talking
309 * about, but it takes trained arrogance to pull it off,
310 * and the actual enchantment of the hat is irrelevant.
312 ABON(A_CHA) += (Role_if(PM_WIZARD) ? 1 : -1);
314 makeknown(uarmh->otyp);
316 case HELM_OF_OPPOSITE_ALIGNMENT:
317 if (u.ualign.type == A_NEUTRAL)
318 u.ualign.type = rn2(2) ? A_CHAOTIC : A_LAWFUL;
319 else u.ualign.type = -(u.ualign.type);
320 u.ublessed = 0; /* lose your god's protection */
321 /* makeknown(uarmh->otyp); -- moved below, after xname() */
324 if (!uarmh->cursed) {
326 pline("%s for a moment.", Tobjnam(uarmh, "vibrate"));
328 pline("%s %s for a moment.",
329 Tobjnam(uarmh, "glow"), hcolor(NH_BLACK));
332 flags.botl = 1; /* reveal new alignment or INT & WIS */
334 pline("My brain hurts!"); /* Monty Python's Flying Circus */
335 } else if (uarmh->otyp == DUNCE_CAP) {
336 You_feel("%s.", /* track INT change; ignore WIS */
337 ACURR(A_INT) <= (ABASE(A_INT) + ABON(A_INT) + ATEMP(A_INT)) ?
338 "like sitting in a corner" : "giddy");
340 Your("mind oscillates briefly.");
341 makeknown(HELM_OF_OPPOSITE_ALIGNMENT);
344 default: impossible(unknown_type, c_helmet, uarmh->otyp);
352 takeoff_mask &= ~W_ARMH;
354 switch(uarmh->otyp) {
358 case ELVEN_LEATHER_HELM:
359 case DWARVISH_IRON_HELM:
366 if (!cancelled_don) {
367 ABON(A_CHA) += (Role_if(PM_WIZARD) ? -1 : 1);
371 case HELM_OF_TELEPATHY:
372 /* need to update ability before calling see_monsters() */
373 setworn((struct obj *)0, W_ARMH);
376 case HELM_OF_BRILLIANCE:
377 if (!cancelled_don) adj_abon(uarmh, -uarmh->spe);
379 case HELM_OF_OPPOSITE_ALIGNMENT:
380 u.ualign.type = u.ualignbase[A_CURRENT];
381 u.ublessed = 0; /* lose the other god's protection */
384 default: impossible(unknown_type, c_helmet, uarmh->otyp);
386 setworn((struct obj *)0, W_ARMH);
387 cancelled_don = FALSE;
396 u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
398 switch(uarmg->otyp) {
401 case GAUNTLETS_OF_FUMBLING:
402 if (!oldprop && !(HFumbling & ~TIMEOUT))
403 incr_itimeout(&HFumbling, rnd(20));
405 case GAUNTLETS_OF_POWER:
406 makeknown(uarmg->otyp);
407 flags.botl = 1; /* taken care of in attrib.c */
409 case GAUNTLETS_OF_DEXTERITY:
410 adj_abon(uarmg, uarmg->spe);
412 default: impossible(unknown_type, c_gloves, uarmg->otyp);
421 u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
423 takeoff_mask &= ~W_ARMG;
425 switch(uarmg->otyp) {
428 case GAUNTLETS_OF_FUMBLING:
429 if (!oldprop && !(HFumbling & ~TIMEOUT))
430 HFumbling = EFumbling = 0;
432 case GAUNTLETS_OF_POWER:
433 makeknown(uarmg->otyp);
434 flags.botl = 1; /* taken care of in attrib.c */
436 case GAUNTLETS_OF_DEXTERITY:
437 if (!cancelled_don) adj_abon(uarmg, -uarmg->spe);
439 default: impossible(unknown_type, c_gloves, uarmg->otyp);
441 setworn((struct obj *)0, W_ARMG);
442 cancelled_don = FALSE;
443 (void) encumber_msg(); /* immediate feedback for GoP */
445 /* Prevent wielding cockatrice when not wearing gloves */
446 if (uwep && uwep->otyp == CORPSE &&
447 touch_petrifies(&mons[uwep->corpsenm])) {
450 You("wield the %s in your bare %s.",
451 corpse_xname(uwep, TRUE), makeplural(body_part(HAND)));
452 Strcpy(kbuf, an(corpse_xname(uwep, TRUE)));
454 uwepgone(); /* life-saved still doesn't allow touching cockatrice */
457 /* KMH -- ...or your secondary weapon when you're wielding it */
458 if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE &&
459 touch_petrifies(&mons[uswapwep->corpsenm])) {
462 You("wield the %s in your bare %s.",
463 corpse_xname(uswapwep, TRUE), body_part(HAND));
465 Strcpy(kbuf, an(corpse_xname(uswapwep, TRUE)));
467 uswapwepgone(); /* lifesaved still doesn't allow touching cockatrice */
477 switch (uarms->otyp) {
480 case URUK_HAI_SHIELD:
482 case DWARVISH_ROUNDSHIELD:
484 case SHIELD_OF_REFLECTION:
486 default: impossible(unknown_type, c_shield, uarms->otyp);
495 takeoff_mask &= ~W_ARMS;
497 switch (uarms->otyp) {
500 case URUK_HAI_SHIELD:
502 case DWARVISH_ROUNDSHIELD:
504 case SHIELD_OF_REFLECTION:
506 default: impossible(unknown_type, c_shield, uarms->otyp);
509 setworn((struct obj *)0, W_ARMS);
518 switch (uarmu->otyp) {
522 default: impossible(unknown_type, c_shirt, uarmu->otyp);
531 takeoff_mask &= ~W_ARMU;
533 switch (uarmu->otyp) {
537 default: impossible(unknown_type, c_shirt, uarmu->otyp);
540 setworn((struct obj *)0, W_ARMU);
545 /* This must be done in worn.c, because one of the possible intrinsics conferred
546 * is fire resistance, and we have to immediately set HFire_resistance in worn.c
547 * since worn.c will check it before returning.
559 takeoff_mask &= ~W_ARM;
560 setworn((struct obj *)0, W_ARM);
561 cancelled_don = FALSE;
565 /* The gone functions differ from the off functions in that if you die from
566 * taking it off and have life saving, you still die.
571 takeoff_mask &= ~W_ARM;
573 cancelled_don = FALSE;
580 switch(uamul->otyp) {
582 case AMULET_OF_LIFE_SAVING:
583 case AMULET_VERSUS_POISON:
584 case AMULET_OF_REFLECTION:
585 case AMULET_OF_MAGICAL_BREATHING:
586 case FAKE_AMULET_OF_YENDOR:
588 case AMULET_OF_UNCHANGING:
594 case AMULET_OF_CHANGE:
596 int orig_sex = poly_gender();
598 if (Unchanging) break;
600 /* Don't use same message as polymorph */
601 if (orig_sex != poly_gender()) {
602 makeknown(AMULET_OF_CHANGE);
603 You("are suddenly very %s!", flags.female ? "feminine"
607 /* already polymorphed into single-gender monster; only
608 changed the character's base sex */
609 You("don't feel like yourself.");
610 pline_The("amulet disintegrates!");
611 if (orig_sex == poly_gender() && uamul->dknown &&
612 !objects[AMULET_OF_CHANGE].oc_name_known &&
613 !objects[AMULET_OF_CHANGE].oc_uname)
618 case AMULET_OF_STRANGULATION:
619 makeknown(AMULET_OF_STRANGULATION);
620 pline("It constricts your throat!");
623 case AMULET_OF_RESTFUL_SLEEP:
624 HSleeping = rnd(100);
626 case AMULET_OF_YENDOR:
634 takeoff_mask &= ~W_AMUL;
636 switch(uamul->otyp) {
638 /* need to update ability before calling see_monsters() */
639 setworn((struct obj *)0, W_AMUL);
642 case AMULET_OF_LIFE_SAVING:
643 case AMULET_VERSUS_POISON:
644 case AMULET_OF_REFLECTION:
645 case AMULET_OF_CHANGE:
646 case AMULET_OF_UNCHANGING:
647 case FAKE_AMULET_OF_YENDOR:
649 case AMULET_OF_MAGICAL_BREATHING:
651 /* HMagical_breathing must be set off
652 before calling drown() */
653 setworn((struct obj *)0, W_AMUL);
654 if (!breathless(youmonst.data) && !amphibious(youmonst.data)
656 You("suddenly inhale an unhealthy amount of water!");
662 case AMULET_OF_STRANGULATION:
664 You("can breathe more easily!");
668 case AMULET_OF_RESTFUL_SLEEP:
669 setworn((struct obj *)0, W_AMUL);
673 case AMULET_OF_YENDOR:
676 setworn((struct obj *)0, W_AMUL);
682 register struct obj *obj;
684 long oldprop = u.uprops[objects[obj->otyp].oc_oprop].extrinsic;
685 int old_attrib, which;
687 if (obj == uwep) setuwep((struct obj *) 0);
688 if (obj == uswapwep) setuswapwep((struct obj *) 0);
689 if (obj == uquiver) setuqwep((struct obj *) 0);
691 /* only mask out W_RING when we don't have both
692 left and right rings of the same type */
693 if ((oldprop & W_RING) != W_RING) oldprop &= ~W_RING;
696 case RIN_TELEPORTATION:
697 case RIN_REGENERATION:
701 case RIN_AGGRAVATE_MONSTER:
702 case RIN_POISON_RESISTANCE:
703 case RIN_FIRE_RESISTANCE:
704 case RIN_COLD_RESISTANCE:
705 case RIN_SHOCK_RESISTANCE:
707 case RIN_TELEPORT_CONTROL:
709 case RIN_POLYMORPH_CONTROL:
710 case RIN_FREE_ACTION:
711 case RIN_SLOW_DIGESTION:
712 case RIN_SUSTAIN_ABILITY:
718 case RIN_SEE_INVISIBLE:
719 /* can now see invisible monsters */
720 set_mimic_blocking(); /* do special mimic handling */
722 #ifdef INVISIBLE_OBJECTS
726 if (Invis && !oldprop && !HSee_invisible &&
727 !perceives(youmonst.data) && !Blind) {
729 pline("Suddenly you are transparent, but there!");
730 makeknown(RIN_SEE_INVISIBLE);
733 case RIN_INVISIBILITY:
734 if (!oldprop && !HInvis && !BInvis && !Blind) {
735 makeknown(RIN_INVISIBILITY);
737 self_invis_message();
741 if (!oldprop && !HLevitation) {
743 makeknown(RIN_LEVITATION);
744 spoteffects(FALSE); /* for sinks */
747 case RIN_GAIN_STRENGTH:
750 case RIN_GAIN_CONSTITUTION:
756 old_attrib = ACURR(which);
757 ABON(which) += obj->spe;
758 if (ACURR(which) != old_attrib ||
759 (objects[obj->otyp].oc_name_known &&
760 old_attrib != 25 && old_attrib != 3)) {
762 makeknown(obj->otyp);
767 case RIN_INCREASE_ACCURACY: /* KMH */
768 u.uhitinc += obj->spe;
770 case RIN_INCREASE_DAMAGE:
771 u.udaminc += obj->spe;
773 case RIN_PROTECTION_FROM_SHAPE_CHAN:
777 if (obj->spe || objects[RIN_PROTECTION].oc_name_known) {
779 makeknown(RIN_PROTECTION);
788 Ring_off_or_gone(obj,gone)
789 register struct obj *obj;
792 long mask = (obj->owornmask & W_RING);
793 int old_attrib, which;
795 takeoff_mask &= ~mask;
796 if(!(u.uprops[objects[obj->otyp].oc_oprop].extrinsic & mask))
797 impossible("Strange... I didn't know you had that ring.");
798 if(gone) setnotworn(obj);
799 else setworn((struct obj *)0, obj->owornmask);
802 case RIN_TELEPORTATION:
803 case RIN_REGENERATION:
807 case RIN_AGGRAVATE_MONSTER:
808 case RIN_POISON_RESISTANCE:
809 case RIN_FIRE_RESISTANCE:
810 case RIN_COLD_RESISTANCE:
811 case RIN_SHOCK_RESISTANCE:
813 case RIN_TELEPORT_CONTROL:
815 case RIN_POLYMORPH_CONTROL:
816 case RIN_FREE_ACTION:
817 case RIN_SLOW_DIGESTION:
818 case RIN_SUSTAIN_ABILITY:
824 case RIN_SEE_INVISIBLE:
825 /* Make invisible monsters go away */
826 if (!See_invisible) {
827 set_mimic_blocking(); /* do special mimic handling */
829 #ifdef INVISIBLE_OBJECTS
834 if (Invisible && !Blind) {
836 pline("Suddenly you cannot see yourself.");
837 makeknown(RIN_SEE_INVISIBLE);
840 case RIN_INVISIBILITY:
841 if (!Invis && !BInvis && !Blind) {
843 Your("body seems to unfade%s.",
844 See_invisible ? " completely" : "..");
845 makeknown(RIN_INVISIBILITY);
849 (void) float_down(0L, 0L);
850 if (!Levitation) makeknown(RIN_LEVITATION);
852 case RIN_GAIN_STRENGTH:
855 case RIN_GAIN_CONSTITUTION:
861 old_attrib = ACURR(which);
862 ABON(which) -= obj->spe;
863 if (ACURR(which) != old_attrib) {
865 makeknown(obj->otyp);
870 case RIN_INCREASE_ACCURACY: /* KMH */
871 u.uhitinc -= obj->spe;
873 case RIN_INCREASE_DAMAGE:
874 u.udaminc -= obj->spe;
877 /* might have forgotten it due to amnesia */
880 makeknown(RIN_PROTECTION);
884 case RIN_PROTECTION_FROM_SHAPE_CHAN:
885 /* If you're no longer protected, let the chameleons
886 * change shape again -dgk
897 Ring_off_or_gone(obj,FALSE);
904 Ring_off_or_gone(obj,TRUE);
909 register struct obj *otmp;
911 boolean already_blind = Blind, changed = FALSE;
914 setuwep((struct obj *) 0);
915 if (otmp == uswapwep)
916 setuswapwep((struct obj *) 0);
918 setuqwep((struct obj *) 0);
919 setworn(otmp, W_TOOL);
922 if (Blind && !already_blind) {
924 if (flags.verbose) You_cant("see any more.");
925 /* set ball&chain variables before the hero goes blind */
926 if (Punished) set_bc(0);
927 } else if (already_blind && !Blind) {
929 /* "You are now wearing the Eyes of the Overworld." */
933 /* blindness has just been toggled */
934 if (Blind_telepat || Infravision) see_monsters();
935 vision_full_recalc = 1; /* recalc vision limits */
942 register struct obj *otmp;
944 boolean was_blind = Blind, changed = FALSE;
946 takeoff_mask &= ~W_TOOL;
947 setworn((struct obj *)0, otmp->owornmask);
952 /* "still cannot see" makes no sense when removing lenses
953 since they can't have been the cause of your blindness */
954 if (otmp->otyp != LENSES)
955 You("still cannot see.");
957 changed = TRUE; /* !was_blind */
958 /* "You were wearing the Eyes of the Overworld." */
959 You_cant("see anything now!");
960 /* set ball&chain variables before the hero goes blind */
961 if (Punished) set_bc(0);
963 } else if (was_blind) {
964 changed = TRUE; /* !Blind */
965 You("can see again.");
968 /* blindness has just been toggled */
969 if (Blind_telepat || Infravision) see_monsters();
970 vision_full_recalc = 1; /* recalc vision limits */
975 /* called in main to set intrinsics of worn start-up items */
980 if (uarmu) (void) Shirt_on();
982 if (uarm) (void) Armor_on();
983 if (uarmc) (void) Cloak_on();
984 if (uarmf) (void) Boots_on();
985 if (uarmg) (void) Gloves_on();
986 if (uarmh) (void) Helmet_on();
987 if (uarms) (void) Shield_on();
990 /* check whether the target object is currently being put on (or taken off) */
992 donning(otmp) /* also checks for doffing */
993 register struct obj *otmp;
995 /* long what = (occupation == take_off) ? taking_off : 0L; */
996 long what = taking_off; /* if nonzero, occupation is implied */
997 boolean result = FALSE;
1000 result = (afternmv == Armor_on || afternmv == Armor_off ||
1001 what == WORN_ARMOR);
1003 else if (otmp == uarmu)
1004 result = (afternmv == Shirt_on || afternmv == Shirt_off ||
1005 what == WORN_SHIRT);
1007 else if (otmp == uarmc)
1008 result = (afternmv == Cloak_on || afternmv == Cloak_off ||
1009 what == WORN_CLOAK);
1010 else if (otmp == uarmf)
1011 result = (afternmv == Boots_on || afternmv == Boots_off ||
1012 what == WORN_BOOTS);
1013 else if (otmp == uarmh)
1014 result = (afternmv == Helmet_on || afternmv == Helmet_off ||
1015 what == WORN_HELMET);
1016 else if (otmp == uarmg)
1017 result = (afternmv == Gloves_on || afternmv == Gloves_off ||
1018 what == WORN_GLOVES);
1019 else if (otmp == uarms)
1020 result = (afternmv == Shield_on || afternmv == Shield_off ||
1021 what == WORN_SHIELD);
1029 /* the piece of armor we were donning/doffing has vanished, so stop
1030 * wasting time on it (and don't dereference it when donning would
1033 cancelled_don = (afternmv == Boots_on || afternmv == Helmet_on ||
1034 afternmv == Gloves_on || afternmv == Armor_on);
1036 nomovemsg = (char *)0;
1042 static NEARDATA const char clothes[] = {ARMOR_CLASS, 0};
1043 static NEARDATA const char accessories[] = {RING_CLASS, AMULET_CLASS, TOOL_CLASS, FOOD_CLASS, 0};
1045 /* the 'T' command */
1049 register struct obj *otmp = (struct obj *)0;
1050 int armorpieces = 0;
1052 #define MOREARM(x) if (x) { armorpieces++; otmp = x; }
1070 /* assert( GRAY_DRAGON_SCALES > YELLOW_DRAGON_SCALE_MAIL ); */
1072 pline_The("%s merged with your skin!",
1073 uskin->otyp >= GRAY_DRAGON_SCALES ?
1074 "dragon scales are" : "dragon scale mail is");
1076 pline("Not wearing any armor.%s", (iflags.cmdassist &&
1077 (uleft || uright || uamul || ublindf)) ?
1078 " Use 'R' command to remove accessories." : "");
1081 if (armorpieces > 1)
1082 otmp = getobj(clothes, "take off");
1083 if (otmp == 0) return(0);
1084 if (!(otmp->owornmask & W_ARMOR)) {
1085 You("are not wearing that.");
1088 /* note: the `uskin' case shouldn't be able to happen here; dragons
1089 can't wear any armor so will end up with `armorpieces == 0' above */
1090 if (otmp == uskin || ((otmp == uarm) && uarmc)
1092 || ((otmp == uarmu) && (uarmc || uarm))
1095 You_cant("take that off.");
1099 reset_remarm(); /* clear takeoff_mask and taking_off */
1100 (void) select_off(otmp);
1101 if (!takeoff_mask) return 0;
1102 reset_remarm(); /* armoroff() doesn't use takeoff_mask */
1104 (void) armoroff(otmp);
1108 /* the 'R' command */
1112 register struct obj *otmp = 0;
1113 int Accessories = 0;
1115 #define MOREACC(x) if (x) { Accessories++; otmp = x; }
1122 pline("Not wearing any accessories.%s", (iflags.cmdassist &&
1127 uarms || uarmh || uarmg || uarmf)) ?
1128 " Use 'T' command to take off armor." : "");
1131 if (Accessories != 1) otmp = getobj(accessories, "remove");
1132 if(!otmp) return(0);
1133 if(!(otmp->owornmask & (W_RING | W_AMUL | W_TOOL))) {
1134 You("are not wearing that.");
1138 reset_remarm(); /* clear takeoff_mask and taking_off */
1139 (void) select_off(otmp);
1140 if (!takeoff_mask) return 0;
1141 reset_remarm(); /* not used by Ring_/Amulet_/Blindf_off() */
1143 if (otmp == uright || otmp == uleft) {
1144 /* Sometimes we want to give the off_msg before removing and
1145 * sometimes after; for instance, "you were wearing a moonstone
1146 * ring (on right hand)" is desired but "you were wearing a
1147 * square amulet (being worn)" is not because of the redundant
1152 } else if (otmp == uamul) {
1155 } else if (otmp == ublindf) {
1156 Blindf_off(otmp); /* does its own off_msg */
1158 impossible("removing strange accessory?");
1163 /* Check if something worn is cursed _and_ unremovable. */
1166 register struct obj *otmp;
1168 /* Curses, like chickens, come home to roost. */
1169 if((otmp == uwep) ? welded(otmp) : (int)otmp->cursed) {
1170 You("can't. %s cursed.",
1171 (is_boots(otmp) || is_gloves(otmp) || otmp->quan > 1L)
1172 ? "They are" : "It is");
1173 otmp->bknown = TRUE;
1181 register struct obj *otmp;
1183 register int delay = -objects[otmp->otyp].oc_delay;
1185 if(cursed(otmp)) return(0);
1188 if (is_helmet(otmp)) {
1189 nomovemsg = "You finish taking off your helmet.";
1190 afternmv = Helmet_off;
1192 else if (is_gloves(otmp)) {
1193 nomovemsg = "You finish taking off your gloves.";
1194 afternmv = Gloves_off;
1196 else if (is_boots(otmp)) {
1197 nomovemsg = "You finish taking off your boots.";
1198 afternmv = Boots_off;
1201 nomovemsg = "You finish taking off your suit.";
1202 afternmv = Armor_off;
1205 /* Be warned! We want off_msg after removing the item to
1206 * avoid "You were wearing ____ (being worn)." However, an
1207 * item which grants fire resistance might cause some trouble
1208 * if removed in Hell and lifesaving puts it back on; in this
1209 * case the message will be printed at the wrong time (after
1210 * the messages saying you died and were lifesaved). Luckily,
1211 * no cloak, shield, or fast-removable armor grants fire
1212 * resistance, so we can safely do the off_msg afterwards.
1213 * Rings do grant fire resistance, but for rings we want the
1214 * off_msg before removal anyway so there's no problem. Take
1215 * care in adding armors granting fire resistance; this code
1216 * might need modification.
1217 * 3.2 (actually 3.1 even): this comment is obsolete since
1218 * fire resistance is not needed for Gehennom.
1222 else if(is_shield(otmp))
1223 (void) Shield_off();
1224 else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
1227 takeoff_mask = taking_off = 0L;
1235 You("are already wearing %s%c", cc, (cc == c_that_) ? '!' : '.');
1239 already_wearing2(cc1, cc2)
1240 const char *cc1, *cc2;
1242 You_cant("wear %s because you're wearing %s there already.", cc1, cc2);
1246 * canwearobj checks to see whether the player can wear a piece of armor
1248 * inputs: otmp (the piece of armor)
1249 * noisy (if TRUE give error messages, otherwise be quiet about it)
1250 * output: mask (otmp's armor type)
1253 canwearobj(otmp,mask,noisy)
1261 which = is_cloak(otmp) ? c_cloak :
1263 is_shirt(otmp) ? c_shirt :
1265 is_suit(otmp) ? c_suit : 0;
1266 if (which && cantweararm(youmonst.data) &&
1267 /* same exception for cloaks as used in m_dowear() */
1268 (which != c_cloak || youmonst.data->msize != MZ_SMALL) &&
1269 (racial_exception(&youmonst, otmp) < 1)) {
1270 if (noisy) pline_The("%s will not fit on your body.", which);
1272 } else if (otmp->owornmask & W_ARMOR) {
1273 if (noisy) already_wearing(c_that_);
1277 if (welded(uwep) && bimanual(uwep) &&
1284 You("cannot do that while holding your %s.",
1285 is_sword(uwep) ? c_sword : c_weapon);
1289 if (is_helmet(otmp)) {
1291 if (noisy) already_wearing(an(c_helmet));
1293 } else if (Upolyd && has_horns(youmonst.data) && !is_flimsy(otmp)) {
1294 /* (flimsy exception matches polyself handling) */
1296 pline_The("%s won't fit over your horn%s.",
1297 c_helmet, plur(num_horns(youmonst.data)));
1301 } else if (is_shield(otmp)) {
1303 if (noisy) already_wearing(an(c_shield));
1305 } else if (uwep && bimanual(uwep)) {
1307 You("cannot wear a shield while wielding a two-handed %s.",
1308 is_sword(uwep) ? c_sword :
1309 (uwep->otyp == BATTLE_AXE) ? c_axe : c_weapon);
1311 } else if (u.twoweap) {
1313 You("cannot wear a shield while wielding two weapons.");
1317 } else if (is_boots(otmp)) {
1319 if (noisy) already_wearing(c_boots);
1321 } else if (Upolyd && slithy(youmonst.data)) {
1322 if (noisy) You("have no feet..."); /* not body_part(FOOT) */
1324 } else if (Upolyd && youmonst.data->mlet == S_CENTAUR) {
1325 /* break_armor() pushes boots off for centaurs,
1326 so don't let dowear() put them back on... */
1327 if (noisy) pline("You have too many hooves to wear %s.",
1328 c_boots); /* makeplural(body_part(FOOT)) yields
1329 "rear hooves" which sounds odd */
1331 } else if (u.utrap && (u.utraptype == TT_BEARTRAP ||
1332 u.utraptype == TT_INFLOOR)) {
1333 if (u.utraptype == TT_BEARTRAP) {
1334 if (noisy) Your("%s is trapped!", body_part(FOOT));
1336 if (noisy) Your("%s are stuck in the %s!",
1337 makeplural(body_part(FOOT)),
1338 surface(u.ux, u.uy));
1343 } else if (is_gloves(otmp)) {
1345 if (noisy) already_wearing(c_gloves);
1347 } else if (welded(uwep)) {
1348 if (noisy) You("cannot wear gloves over your %s.",
1349 is_sword(uwep) ? c_sword : c_weapon);
1354 } else if (is_shirt(otmp)) {
1355 if (uarm || uarmc || uarmu) {
1357 if (noisy) already_wearing(an(c_shirt));
1359 if (noisy) You_cant("wear that over your %s.",
1360 (uarm && !uarmc) ? c_armor : cloak_simple_name(uarmc));
1366 } else if (is_cloak(otmp)) {
1368 if (noisy) already_wearing(an(cloak_simple_name(uarmc)));
1372 } else if (is_suit(otmp)) {
1374 if (noisy) You("cannot wear armor over a %s.", cloak_simple_name(uarmc));
1377 if (noisy) already_wearing("some armor");
1382 /* getobj can't do this after setting its allow_all flag; that
1383 happens if you have armor for slots that are covered up or
1384 extra armor for slots that are filled */
1385 if (noisy) silly_thing("wear", otmp);
1388 /* Unnecessary since now only weapons and special items like pick-axes get
1389 * welded to your hand, not armor
1392 if (noisy) weldmsg(otmp);
1399 /* the 'W' command */
1407 /* cantweararm checks for suits of armor */
1408 /* verysmall or nohands checks for shields, gloves, etc... */
1409 if ((verysmall(youmonst.data) || nohands(youmonst.data))) {
1410 pline("Don't even bother.");
1414 otmp = getobj(clothes, "wear");
1415 if(!otmp) return(0);
1417 if (!canwearobj(otmp,&mask,TRUE)) return(0);
1419 if (otmp->oartifact && !touch_artifact(otmp, &youmonst))
1420 return 1; /* costs a turn even though it didn't get worn */
1422 if (otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT &&
1423 qstart_level.dnum == u.uz.dnum) { /* in quest */
1424 if (u.ualignbase[A_CURRENT] == u.ualignbase[A_ORIGINAL])
1425 You("narrowly avoid losing all chance at your goal.");
1426 else /* converted */
1427 You("are suddenly overcome with shame and change your mind.");
1428 u.ublessed = 0; /* lose your god's protection */
1429 makeknown(otmp->otyp);
1436 setuwep((struct obj *)0);
1437 if (otmp == uswapwep)
1438 setuswapwep((struct obj *) 0);
1439 if (otmp == uquiver)
1440 setuqwep((struct obj *) 0);
1441 setworn(otmp, mask);
1442 delay = -objects[otmp->otyp].oc_delay;
1445 if(is_boots(otmp)) afternmv = Boots_on;
1446 if(is_helmet(otmp)) afternmv = Helmet_on;
1447 if(is_gloves(otmp)) afternmv = Gloves_on;
1448 if(otmp == uarm) afternmv = Armor_on;
1449 nomovemsg = "You finish your dressing maneuver.";
1451 if(is_cloak(otmp)) (void) Cloak_on();
1452 if (is_shield(otmp)) (void) Shield_on();
1454 if (is_shirt(otmp)) (void) Shirt_on();
1458 takeoff_mask = taking_off = 0L;
1465 register struct obj *otmp;
1468 if(uleft && uright && uamul && ublindf) {
1469 Your("%s%s are full, and you're already wearing an amulet and %s.",
1470 humanoid(youmonst.data) ? "ring-" : "",
1471 makeplural(body_part(FINGER)),
1472 ublindf->otyp==LENSES ? "some lenses" : "a blindfold");
1475 otmp = getobj(accessories, "put on");
1476 if(!otmp) return(0);
1477 if(otmp->owornmask & (W_RING | W_AMUL | W_TOOL)) {
1478 already_wearing(c_that_);
1486 setuwep((struct obj *)0);
1487 if(otmp == uswapwep)
1488 setuswapwep((struct obj *) 0);
1490 setuqwep((struct obj *) 0);
1491 if(otmp->oclass == RING_CLASS || otmp->otyp == MEAT_RING) {
1492 if(nolimbs(youmonst.data)) {
1493 You("cannot make the ring stick to your body.");
1496 if(uleft && uright){
1497 There("are no more %s%s to fill.",
1498 humanoid(youmonst.data) ? "ring-" : "",
1499 makeplural(body_part(FINGER)));
1502 if(uleft) mask = RIGHT_RING;
1503 else if(uright) mask = LEFT_RING;
1508 Sprintf(qbuf, "Which %s%s, Right or Left?",
1509 humanoid(youmonst.data) ? "ring-" : "",
1511 if(!(answer = yn_function(qbuf, "rl", '\0')))
1524 if (uarmg && uarmg->cursed) {
1525 uarmg->bknown = TRUE;
1526 You("cannot remove your gloves to put on the ring.");
1529 if (welded(uwep) && bimanual(uwep)) {
1530 /* welded will set bknown */
1531 You("cannot free your weapon hands to put on the ring.");
1534 if (welded(uwep) && mask==RIGHT_RING) {
1535 /* welded will set bknown */
1536 You("cannot free your weapon hand to put on the ring.");
1539 if (otmp->oartifact && !touch_artifact(otmp, &youmonst))
1540 return 1; /* costs a turn even though it didn't get worn */
1541 setworn(otmp, mask);
1543 } else if (otmp->oclass == AMULET_CLASS) {
1545 already_wearing("an amulet");
1548 if (otmp->oartifact && !touch_artifact(otmp, &youmonst))
1550 setworn(otmp, W_AMUL);
1551 if (otmp->otyp == AMULET_OF_CHANGE) {
1553 /* Don't do a prinv() since the amulet is now gone */
1557 } else { /* it's a blindfold, towel, or lenses */
1559 if (ublindf->otyp == TOWEL)
1560 Your("%s is already covered by a towel.",
1562 else if (ublindf->otyp == BLINDFOLD) {
1563 if (otmp->otyp == LENSES)
1564 already_wearing2("lenses", "a blindfold");
1566 already_wearing("a blindfold");
1567 } else if (ublindf->otyp == LENSES) {
1568 if (otmp->otyp == BLINDFOLD)
1569 already_wearing2("a blindfold", "some lenses");
1571 already_wearing("some lenses");
1573 already_wearing(something); /* ??? */
1576 if (otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL && otmp->otyp != LENSES) {
1577 You_cant("wear that!");
1580 if (otmp->oartifact && !touch_artifact(otmp, &youmonst))
1586 prinv((char *)0, otmp, 0L);
1597 int uac = mons[u.umonnum].ac;
1599 if(uarm) uac -= ARM_BONUS(uarm);
1600 if(uarmc) uac -= ARM_BONUS(uarmc);
1601 if(uarmh) uac -= ARM_BONUS(uarmh);
1602 if(uarmf) uac -= ARM_BONUS(uarmf);
1603 if(uarms) uac -= ARM_BONUS(uarms);
1604 if(uarmg) uac -= ARM_BONUS(uarmg);
1606 if(uarmu) uac -= ARM_BONUS(uarmu);
1608 if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe;
1609 if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe;
1610 if (HProtection & INTRINSIC) uac -= u.ublessed;
1611 uac -= u.uspellprot;
1612 if (uac < -128) uac = -128; /* u.uac is an schar */
1625 register struct obj *otmp;
1627 boolean leftfall, rightfall;
1628 const char *otherwep = 0;
1630 leftfall = (uleft && !uleft->cursed &&
1631 (!uwep || !welded(uwep) || !bimanual(uwep)));
1632 rightfall = (uright && !uright->cursed && (!welded(uwep)));
1633 if (!uarmg && (leftfall || rightfall) && !nolimbs(youmonst.data)) {
1634 /* changed so cursed rings don't fall off, GAN 10/30/86 */
1635 Your("%s off your %s.",
1636 (leftfall && rightfall) ? "rings slip" : "ring slips",
1637 (leftfall && rightfall) ? makeplural(body_part(FINGER)) :
1653 if (u.twoweap && otmp) {
1654 otherwep = is_sword(otmp) ? c_sword :
1655 makesingular(oclass_names[(int)otmp->oclass]);
1656 Your("%s %sslips from your %s.",
1659 makeplural(body_part(HAND)));
1660 setuswapwep((struct obj *)0);
1662 if (otmp->otyp != LOADSTONE || !otmp->cursed)
1666 if (otmp && !welded(otmp)) {
1667 const char *thiswep;
1669 /* nice wording if both weapons are the same type */
1670 thiswep = is_sword(otmp) ? c_sword :
1671 makesingular(oclass_names[(int)otmp->oclass]);
1672 if (otherwep && strcmp(thiswep, otherwep)) otherwep = 0;
1674 /* changed so cursed weapons don't fall, GAN 10/30/86 */
1675 Your("%s%s %sslips from your %s.",
1676 otherwep ? "other " : "", thiswep,
1678 makeplural(body_part(HAND)));
1679 setuwep((struct obj *)0);
1680 if (otmp->otyp != LOADSTONE || !otmp->cursed)
1687 struct monst *victim;
1689 register struct obj *otmph, *otmp;
1691 otmph = (victim == &youmonst) ? uarmc : which_armor(victim, W_ARMC);
1693 otmph = (victim == &youmonst) ? uarm : which_armor(victim, W_ARM);
1696 otmph = (victim == &youmonst) ? uarmu : which_armor(victim, W_ARMU);
1699 otmp = (victim == &youmonst) ? uarmh : which_armor(victim, W_ARMH);
1700 if(otmp && (!otmph || !rn2(4))) otmph = otmp;
1701 otmp = (victim == &youmonst) ? uarmg : which_armor(victim, W_ARMG);
1702 if(otmp && (!otmph || !rn2(4))) otmph = otmp;
1703 otmp = (victim == &youmonst) ? uarmf : which_armor(victim, W_ARMF);
1704 if(otmp && (!otmph || !rn2(4))) otmph = otmp;
1705 otmp = (victim == &youmonst) ? uarms : which_armor(victim, W_ARMS);
1706 if(otmp && (!otmph || !rn2(4))) otmph = otmp;
1710 /* erode some arbitrary armor worn by the victim */
1712 erode_armor(victim, acid_dmg)
1713 struct monst *victim;
1716 struct obj *otmph = some_armor(victim);
1718 if (otmph && (otmph != uarmf)) {
1719 erode_obj(otmph, acid_dmg, FALSE);
1720 if (carried(otmph)) update_inventory();
1724 /* used for praying to check and fix levitation trouble */
1726 stuck_ring(ring, otyp)
1730 if (ring != uleft && ring != uright) {
1731 impossible("stuck_ring: neither left nor right?");
1732 return (struct obj *)0;
1735 if (ring && ring->otyp == otyp) {
1736 /* reasons ring can't be removed match those checked by select_off();
1737 limbless case has extra checks because ordinarily it's temporary */
1738 if (nolimbs(youmonst.data) &&
1739 uamul && uamul->otyp == AMULET_OF_UNCHANGING && uamul->cursed)
1741 if (welded(uwep) && (ring == uright || bimanual(uwep))) return uwep;
1742 if (uarmg && uarmg->cursed) return uarmg;
1743 if (ring->cursed) return ring;
1745 /* either no ring or not right type or nothing prevents its removal */
1746 return (struct obj *)0;
1749 /* also for praying; find worn item that confers "Unchanging" attribute */
1753 if (uamul && uamul->otyp == AMULET_OF_UNCHANGING) return uamul;
1757 /* occupation callback for 'A' */
1761 register struct obj *otmp;
1766 if (!otmp) return 0;
1767 *buf = '\0'; /* lint suppresion */
1769 /* special ring checks */
1770 if (otmp == uright || otmp == uleft) {
1771 if (nolimbs(youmonst.data)) {
1772 pline_The("ring is stuck.");
1775 why = 0; /* the item which prevents ring removal */
1776 if (welded(uwep) && (otmp == uright || bimanual(uwep))) {
1777 Sprintf(buf, "free a weapon %s", body_part(HAND));
1779 } else if (uarmg && uarmg->cursed) {
1780 Sprintf(buf, "take off your %s", c_gloves);
1784 You("cannot %s to remove the ring.", buf);
1789 /* special glove checks */
1790 if (otmp == uarmg) {
1792 You("are unable to take off your %s while wielding that %s.",
1793 c_gloves, is_sword(uwep) ? c_sword : c_weapon);
1794 uwep->bknown = TRUE;
1797 You_cant("take off the slippery %s with your slippery %s.",
1798 c_gloves, makeplural(body_part(FINGER)));
1802 /* special boot checks */
1803 if (otmp == uarmf) {
1804 if (u.utrap && u.utraptype == TT_BEARTRAP) {
1805 pline_The("bear trap prevents you from pulling your %s out.",
1808 } else if (u.utrap && u.utraptype == TT_INFLOOR) {
1809 You("are stuck in the %s, and cannot pull your %s out.",
1810 surface(u.ux, u.uy), makeplural(body_part(FOOT)));
1814 /* special suit and shirt checks */
1820 why = 0; /* the item which prevents disrobing */
1821 if (uarmc && uarmc->cursed) {
1822 Sprintf(buf, "remove your %s", cloak_simple_name(uarmc));
1825 } else if (otmp == uarmu && uarm && uarm->cursed) {
1826 Sprintf(buf, "remove your %s", c_suit);
1829 } else if (welded(uwep) && bimanual(uwep)) {
1830 Sprintf(buf, "release your %s",
1831 is_sword(uwep) ? c_sword :
1832 (uwep->otyp == BATTLE_AXE) ? c_axe : c_weapon);
1836 You("cannot %s to take off %s.", buf, the(xname(otmp)));
1841 /* basic curse check */
1842 if (otmp == uquiver || (otmp == uswapwep && !u.twoweap)) {
1843 ; /* some items can be removed even when cursed */
1845 /* otherwise, this is fundamental */
1846 if (cursed(otmp)) return 0;
1849 if(otmp == uarm) takeoff_mask |= WORN_ARMOR;
1850 else if(otmp == uarmc) takeoff_mask |= WORN_CLOAK;
1851 else if(otmp == uarmf) takeoff_mask |= WORN_BOOTS;
1852 else if(otmp == uarmg) takeoff_mask |= WORN_GLOVES;
1853 else if(otmp == uarmh) takeoff_mask |= WORN_HELMET;
1854 else if(otmp == uarms) takeoff_mask |= WORN_SHIELD;
1856 else if(otmp == uarmu) takeoff_mask |= WORN_SHIRT;
1858 else if(otmp == uleft) takeoff_mask |= LEFT_RING;
1859 else if(otmp == uright) takeoff_mask |= RIGHT_RING;
1860 else if(otmp == uamul) takeoff_mask |= WORN_AMUL;
1861 else if(otmp == ublindf) takeoff_mask |= WORN_BLINDF;
1862 else if(otmp == uwep) takeoff_mask |= W_WEP;
1863 else if(otmp == uswapwep) takeoff_mask |= W_SWAPWEP;
1864 else if(otmp == uquiver) takeoff_mask |= W_QUIVER;
1866 else impossible("select_off: %s???", doname(otmp));
1871 STATIC_OVL struct obj *
1874 register struct obj *otmp = (struct obj *)0;
1876 if (taking_off == W_WEP) {
1878 setuwep((struct obj *) 0);
1879 You("are empty %s.", body_part(HANDED));
1882 } else if (taking_off == W_SWAPWEP) {
1883 setuswapwep((struct obj *) 0);
1884 You("no longer have a second weapon readied.");
1886 } else if (taking_off == W_QUIVER) {
1887 setuqwep((struct obj *) 0);
1888 You("no longer have ammunition readied.");
1889 } else if (taking_off == WORN_ARMOR) {
1891 if(!cursed(otmp)) (void) Armor_off();
1892 } else if (taking_off == WORN_CLOAK) {
1894 if(!cursed(otmp)) (void) Cloak_off();
1895 } else if (taking_off == WORN_BOOTS) {
1897 if(!cursed(otmp)) (void) Boots_off();
1898 } else if (taking_off == WORN_GLOVES) {
1900 if(!cursed(otmp)) (void) Gloves_off();
1901 } else if (taking_off == WORN_HELMET) {
1903 if(!cursed(otmp)) (void) Helmet_off();
1904 } else if (taking_off == WORN_SHIELD) {
1906 if(!cursed(otmp)) (void) Shield_off();
1908 } else if (taking_off == WORN_SHIRT) {
1910 if (!cursed(otmp)) (void) Shirt_off();
1912 } else if (taking_off == WORN_AMUL) {
1914 if(!cursed(otmp)) Amulet_off();
1915 } else if (taking_off == LEFT_RING) {
1917 if(!cursed(otmp)) Ring_off(uleft);
1918 } else if (taking_off == RIGHT_RING) {
1920 if(!cursed(otmp)) Ring_off(uright);
1921 } else if (taking_off == WORN_BLINDF) {
1922 if (!cursed(ublindf)) Blindf_off(ublindf);
1923 } else impossible("do_takeoff: taking off %lx", taking_off);
1928 static const char *disrobing = "";
1935 register struct obj *otmp;
1940 return(1); /* still busy */
1942 if ((otmp = do_takeoff())) off_msg(otmp);
1944 takeoff_mask &= ~taking_off;
1948 for(i = 0; takeoff_order[i]; i++)
1949 if(takeoff_mask & takeoff_order[i]) {
1950 taking_off = takeoff_order[i];
1954 otmp = (struct obj *) 0;
1957 if (taking_off == 0L) {
1958 You("finish %s.", disrobing);
1960 } else if (taking_off == W_WEP) {
1962 } else if (taking_off == W_SWAPWEP) {
1964 } else if (taking_off == W_QUIVER) {
1966 } else if (taking_off == WORN_ARMOR) {
1968 /* If a cloak is being worn, add the time to take it off and put
1969 * it back on again. Kludge alert! since that time is 0 for all
1970 * known cloaks, add 1 so that it actually matters...
1972 if (uarmc) todelay += 2 * objects[uarmc->otyp].oc_delay + 1;
1973 } else if (taking_off == WORN_CLOAK) {
1975 } else if (taking_off == WORN_BOOTS) {
1977 } else if (taking_off == WORN_GLOVES) {
1979 } else if (taking_off == WORN_HELMET) {
1981 } else if (taking_off == WORN_SHIELD) {
1984 } else if (taking_off == WORN_SHIRT) {
1986 /* add the time to take off and put back on armor and/or cloak */
1987 if (uarm) todelay += 2 * objects[uarm->otyp].oc_delay;
1988 if (uarmc) todelay += 2 * objects[uarmc->otyp].oc_delay + 1;
1990 } else if (taking_off == WORN_AMUL) {
1992 } else if (taking_off == LEFT_RING) {
1994 } else if (taking_off == RIGHT_RING) {
1996 } else if (taking_off == WORN_BLINDF) {
1999 impossible("take_off: taking off %lx", taking_off);
2000 return 0; /* force done */
2003 if (otmp) todelay += objects[otmp->otyp].oc_delay;
2005 /* Since setting the occupation now starts the counter next move, that
2006 * would always produce a delay 1 too big per item unless we subtract
2007 * 1 here to account for it.
2009 if (todelay > 0) todelay--;
2011 set_occupation(take_off, disrobing, 0);
2012 return(1); /* get busy */
2015 /* clear saved context to avoid inappropriate resumption of interrupted 'A' */
2019 taking_off = takeoff_mask = 0L;
2023 /* the 'A' command -- remove multiple worn items */
2029 if (taking_off || takeoff_mask) {
2030 You("continue %s.", disrobing);
2031 set_occupation(take_off, disrobing, 0);
2033 } else if (!uwep && !uswapwep && !uquiver && !uamul && !ublindf &&
2034 !uleft && !uright && !wearing_armor()) {
2035 You("are not wearing anything.");
2039 add_valid_menu_class(0); /* reset */
2040 if (flags.menu_style != MENU_TRADITIONAL ||
2041 (result = ggetobj("take off", select_off, 0, FALSE, (unsigned *)0)) < -1)
2042 result = menu_remarm(result);
2045 /* default activity for armor and/or accessories,
2046 possibly combined with weapons */
2047 disrobing = "disrobing";
2048 /* specific activity when handling weapons only */
2049 if (!(takeoff_mask & ~(W_WEP|W_SWAPWEP|W_QUIVER)))
2050 disrobing = "disarming";
2053 /* The time to perform the command is already completely accounted for
2054 * in take_off(); if we return 1, that would add an extra turn to each
2065 menu_item *pick_list;
2066 boolean all_worn_categories = TRUE;
2069 all_worn_categories = (retry == -2);
2070 } else if (flags.menu_style == MENU_FULL) {
2071 all_worn_categories = FALSE;
2072 n = query_category("What type of things do you want to take off?",
2073 invent, WORN_TYPES|ALL_TYPES, &pick_list, PICK_ANY);
2075 for (i = 0; i < n; i++) {
2076 if (pick_list[i].item.a_int == ALL_TYPES_SELECTED)
2077 all_worn_categories = TRUE;
2079 add_valid_menu_class(pick_list[i].item.a_int);
2081 free((genericptr_t) pick_list);
2082 } else if (flags.menu_style == MENU_COMBINATION) {
2083 all_worn_categories = FALSE;
2084 if (ggetobj("take off", select_off, 0, TRUE, (unsigned *)0) == -2)
2085 all_worn_categories = TRUE;
2088 n = query_objlist("What do you want to take off?", invent,
2089 SIGNAL_NOMENU|USE_INVLET|INVORDER_SORT,
2090 &pick_list, PICK_ANY,
2091 all_worn_categories ? is_worn : is_worn_by_type);
2093 for (i = 0; i < n; i++)
2094 (void) select_off(pick_list[i].item.a_obj);
2095 free((genericptr_t) pick_list);
2096 } else if (n < 0 && flags.menu_style != MENU_COMBINATION) {
2097 There("is nothing else you can remove or unwield.");
2102 /* hit by destroy armor scroll/black dragon breath/monster spell */
2105 register struct obj *atmp;
2107 register struct obj *otmp;
2108 #define DESTROY_ARM(o) ((otmp = (o)) != 0 && \
2109 (!atmp || atmp == otmp) && \
2110 (!obj_resists(otmp, 0, 90)))
2112 if (DESTROY_ARM(uarmc)) {
2113 if (donning(otmp)) cancel_don();
2114 Your("%s crumbles and turns to dust!",
2115 cloak_simple_name(uarmc));
2118 } else if (DESTROY_ARM(uarm)) {
2119 if (donning(otmp)) cancel_don();
2120 Your("armor turns to dust and falls to the %s!",
2121 surface(u.ux,u.uy));
2122 (void) Armor_gone();
2125 } else if (DESTROY_ARM(uarmu)) {
2126 if (donning(otmp)) cancel_don();
2127 Your("shirt crumbles into tiny threads and falls apart!");
2131 } else if (DESTROY_ARM(uarmh)) {
2132 if (donning(otmp)) cancel_don();
2133 Your("helmet turns to dust and is blown away!");
2134 (void) Helmet_off();
2136 } else if (DESTROY_ARM(uarmg)) {
2137 if (donning(otmp)) cancel_don();
2138 Your("gloves vanish!");
2139 (void) Gloves_off();
2142 } else if (DESTROY_ARM(uarmf)) {
2143 if (donning(otmp)) cancel_don();
2144 Your("boots disintegrate!");
2147 } else if (DESTROY_ARM(uarms)) {
2148 if (donning(otmp)) cancel_don();
2149 Your("shield crumbles away!");
2150 (void) Shield_off();
2153 return 0; /* could not destroy anything */
2162 adj_abon(otmp, delta)
2163 register struct obj *otmp;
2164 register schar delta;
2166 if (uarmg && uarmg == otmp && otmp->otyp == GAUNTLETS_OF_DEXTERITY) {
2168 makeknown(uarmg->otyp);
2169 ABON(A_DEX) += (delta);
2173 if (uarmh && uarmh == otmp && otmp->otyp == HELM_OF_BRILLIANCE) {
2175 makeknown(uarmh->otyp);
2176 ABON(A_INT) += (delta);
2177 ABON(A_WIS) += (delta);