OSDN Git Service

shrink mine
[nethackexpress/trunk.git] / src / do_wear.c
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. */
4
5 #include "hack.h"
6
7 #ifndef OVLB
8
9 STATIC_DCL long takeoff_mask, taking_off;
10
11 #else /* OVLB */
12
13 STATIC_OVL NEARDATA long takeoff_mask = 0L;
14 static NEARDATA long taking_off = 0L;
15
16 static NEARDATA int todelay;
17 static boolean cancelled_don = FALSE;
18
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",
22                            c_suit[]   = "suit",
23 #ifdef TOURIST
24                            c_shirt[]  = "shirt",
25 #endif
26                            c_cloak[]  = "cloak",
27                            c_gloves[] = "gloves",
28                            c_boots[]  = "boots",
29                            c_helmet[] = "helmet",
30                            c_shield[] = "shield",
31                            c_weapon[] = "weapon",
32                            c_sword[]  = "sword",
33                            c_axe[]    = "axe",
34                            c_that_[]  = "that";
35
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,
39 #ifdef TOURIST
40         WORN_SHIRT,
41 #endif
42         WORN_BOOTS, W_SWAPWEP, W_QUIVER, 0L };
43
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);
51 #ifdef TOURIST
52 STATIC_PTR int NDECL(Shirt_on);
53 #endif
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*));
62
63 void
64 off_msg(otmp)
65 register struct obj *otmp;
66 {
67         if(flags.verbose)
68             You("were wearing %s.", doname(otmp));
69 }
70
71 /* for items that involve no delay */
72 STATIC_OVL void
73 on_msg(otmp)
74 register struct obj *otmp;
75 {
76         if (flags.verbose) {
77             char how[BUFSZ];
78
79             how[0] = '\0';
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)),
84                 how);
85         }
86 }
87
88 /*
89  * The Type_on() functions should be called *after* setworn().
90  * The Type_off() functions call setworn() themselves.
91  */
92
93 STATIC_PTR
94 int
95 Boots_on()
96 {
97     long oldprop =
98         u.uprops[objects[uarmf->otyp].oc_oprop].extrinsic & ~WORN_BOOTS;
99
100     switch(uarmf->otyp) {
101         case LOW_BOOTS:
102         case IRON_SHOES:
103         case HIGH_BOOTS:
104         case JUMPING_BOOTS:
105         case KICKING_BOOTS:
106                 break;
107         case WATER_WALKING_BOOTS:
108                 if (u.uinwater) spoteffects(TRUE);
109                 break;
110         case SPEED_BOOTS:
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" : "");
117                 }
118                 break;
119         case ELVEN_BOOTS:
120                 if (!oldprop && !HStealth && !BStealth) {
121                         makeknown(uarmf->otyp);
122                         You("walk very quietly.");
123                 }
124                 break;
125         case FUMBLE_BOOTS:
126                 if (!oldprop && !(HFumbling & ~TIMEOUT))
127                         incr_itimeout(&HFumbling, rnd(20));
128                 break;
129         case LEVITATION_BOOTS:
130                 if (!oldprop && !HLevitation) {
131                         makeknown(uarmf->otyp);
132                         float_up();
133                         spoteffects(FALSE);
134                 }
135                 break;
136         default: impossible(unknown_type, c_boots, uarmf->otyp);
137     }
138     return 0;
139 }
140
141 int
142 Boots_off()
143 {
144     int otyp = uarmf->otyp;
145     long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_BOOTS;
146
147     takeoff_mask &= ~W_ARMF;
148         /* For levitation, float_down() returns if Levitation, so we
149          * must do a setworn() _before_ the levitation case.
150          */
151     setworn((struct obj *)0, W_ARMF);
152     switch (otyp) {
153         case SPEED_BOOTS:
154                 if (!Very_fast && !cancelled_don) {
155                         makeknown(otyp);
156                         You_feel("yourself slow down%s.",
157                                 Fast ? " a bit" : "");
158                 }
159                 break;
160         case WATER_WALKING_BOOTS:
161                 if (is_pool(u.ux,u.uy) && !Levitation && !Flying &&
162                     !is_clinger(youmonst.data) && !cancelled_don) {
163                         makeknown(otyp);
164                         /* make boots known in case you survive the drowning */
165                         spoteffects(TRUE);
166                 }
167                 break;
168         case ELVEN_BOOTS:
169                 if (!oldprop && !HStealth && !BStealth && !cancelled_don) {
170                         makeknown(otyp);
171                         You("sure are noisy.");
172                 }
173                 break;
174         case FUMBLE_BOOTS:
175                 if (!oldprop && !(HFumbling & ~TIMEOUT))
176                         HFumbling = EFumbling = 0;
177                 break;
178         case LEVITATION_BOOTS:
179                 if (!oldprop && !HLevitation && !cancelled_don) {
180                         (void) float_down(0L, 0L);
181                         makeknown(otyp);
182                 }
183                 break;
184         case LOW_BOOTS:
185         case IRON_SHOES:
186         case HIGH_BOOTS:
187         case JUMPING_BOOTS:
188         case KICKING_BOOTS:
189                 break;
190         default: impossible(unknown_type, c_boots, otyp);
191     }
192     cancelled_don = FALSE;
193     return 0;
194 }
195
196 STATIC_OVL int
197 Cloak_on()
198 {
199     long oldprop =
200         u.uprops[objects[uarmc->otyp].oc_oprop].extrinsic & ~WORN_CLOAK;
201
202     switch(uarmc->otyp) {
203         case ELVEN_CLOAK:
204         case CLOAK_OF_PROTECTION:
205         case CLOAK_OF_DISPLACEMENT:
206                 makeknown(uarmc->otyp);
207                 break;
208         case ORCISH_CLOAK:
209         case DWARVISH_CLOAK:
210         case CLOAK_OF_MAGIC_RESISTANCE:
211         case ROBE:
212         case LEATHER_CLOAK:
213                 break;
214         case MUMMY_WRAPPING:
215                 /* Note: it's already being worn, so we have to cheat here. */
216                 if ((HInvis || EInvis || pm_invisible(youmonst.data)) && !Blind) {
217                     newsym(u.ux,u.uy);
218                     You("can %s!",
219                         See_invisible ? "no longer see through yourself"
220                         : see_yourself);
221                 }
222                 break;
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);
228                     newsym(u.ux,u.uy);
229                     pline("Suddenly you can%s yourself.",
230                         See_invisible ? " see through" : "not see");
231                 }
232                 break;
233         case OILSKIN_CLOAK:
234                 pline("%s very tightly.", Tobjnam(uarmc, "fit"));
235                 break;
236         /* Alchemy smock gives poison _and_ acid resistance */
237         case ALCHEMY_SMOCK:
238                 EAcid_resistance |= WORN_CLOAK;
239                 break;
240         default: impossible(unknown_type, c_cloak, uarmc->otyp);
241     }
242     return 0;
243 }
244
245 int
246 Cloak_off()
247 {
248     int otyp = uarmc->otyp;
249     long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_CLOAK;
250
251     takeoff_mask &= ~W_ARMC;
252         /* For mummy wrapping, taking it off first resets `Invisible'. */
253     setworn((struct obj *)0, W_ARMC);
254     switch (otyp) {
255         case ELVEN_CLOAK:
256         case ORCISH_CLOAK:
257         case DWARVISH_CLOAK:
258         case CLOAK_OF_PROTECTION:
259         case CLOAK_OF_MAGIC_RESISTANCE:
260         case CLOAK_OF_DISPLACEMENT:
261         case OILSKIN_CLOAK:
262         case ROBE:
263         case LEATHER_CLOAK:
264                 break;
265         case MUMMY_WRAPPING:
266                 if (Invis && !Blind) {
267                     newsym(u.ux,u.uy);
268                     You("can %s.",
269                         See_invisible ? "see through yourself"
270                         : "no longer see yourself");
271                 }
272                 break;
273         case CLOAK_OF_INVISIBILITY:
274                 if (!oldprop && !HInvis && !Blind) {
275                     makeknown(CLOAK_OF_INVISIBILITY);
276                     newsym(u.ux,u.uy);
277                     pline("Suddenly you can %s.",
278                         See_invisible ? "no longer see through yourself"
279                         : see_yourself);
280                 }
281                 break;
282         /* Alchemy smock gives poison _and_ acid resistance */
283         case ALCHEMY_SMOCK:
284                 EAcid_resistance &= ~WORN_CLOAK;
285                 break;
286         default: impossible(unknown_type, c_cloak, otyp);
287     }
288     return 0;
289 }
290
291 STATIC_PTR
292 int
293 Helmet_on()
294 {
295     switch(uarmh->otyp) {
296         case FEDORA:
297         case HELMET:
298         case DENTED_POT:
299         case ELVEN_LEATHER_HELM:
300         case DWARVISH_IRON_HELM:
301         case ORCISH_HELM:
302         case HELM_OF_TELEPATHY:
303                 break;
304         case HELM_OF_BRILLIANCE:
305                 adj_abon(uarmh, uarmh->spe);
306                 break;
307         case CORNUTHAUM:
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.
311                  */
312                 ABON(A_CHA) += (Role_if(PM_WIZARD) ? 1 : -1);
313                 flags.botl = 1;
314                 makeknown(uarmh->otyp);
315                 break;
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() */
322                 /*FALLTHRU*/
323         case DUNCE_CAP:
324                 if (!uarmh->cursed) {
325                     if (Blind)
326                         pline("%s for a moment.", Tobjnam(uarmh, "vibrate"));
327                     else
328                         pline("%s %s for a moment.",
329                               Tobjnam(uarmh, "glow"), hcolor(NH_BLACK));
330                     curse(uarmh);
331                 }
332                 flags.botl = 1;         /* reveal new alignment or INT & WIS */
333                 if (Hallucination) {
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");
339                 } else {
340                     Your("mind oscillates briefly.");
341                     makeknown(HELM_OF_OPPOSITE_ALIGNMENT);
342                 }
343                 break;
344         default: impossible(unknown_type, c_helmet, uarmh->otyp);
345     }
346     return 0;
347 }
348
349 int
350 Helmet_off()
351 {
352     takeoff_mask &= ~W_ARMH;
353
354     switch(uarmh->otyp) {
355         case FEDORA:
356         case HELMET:
357         case DENTED_POT:
358         case ELVEN_LEATHER_HELM:
359         case DWARVISH_IRON_HELM:
360         case ORCISH_HELM:
361             break;
362         case DUNCE_CAP:
363             flags.botl = 1;
364             break;
365         case CORNUTHAUM:
366             if (!cancelled_don) {
367                 ABON(A_CHA) += (Role_if(PM_WIZARD) ? -1 : 1);
368                 flags.botl = 1;
369             }
370             break;
371         case HELM_OF_TELEPATHY:
372             /* need to update ability before calling see_monsters() */
373             setworn((struct obj *)0, W_ARMH);
374             see_monsters();
375             return 0;
376         case HELM_OF_BRILLIANCE:
377             if (!cancelled_don) adj_abon(uarmh, -uarmh->spe);
378             break;
379         case HELM_OF_OPPOSITE_ALIGNMENT:
380             u.ualign.type = u.ualignbase[A_CURRENT];
381             u.ublessed = 0; /* lose the other god's protection */
382             flags.botl = 1;
383             break;
384         default: impossible(unknown_type, c_helmet, uarmh->otyp);
385     }
386     setworn((struct obj *)0, W_ARMH);
387     cancelled_don = FALSE;
388     return 0;
389 }
390
391 STATIC_PTR
392 int
393 Gloves_on()
394 {
395     long oldprop =
396         u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
397
398     switch(uarmg->otyp) {
399         case LEATHER_GLOVES:
400                 break;
401         case GAUNTLETS_OF_FUMBLING:
402                 if (!oldprop && !(HFumbling & ~TIMEOUT))
403                         incr_itimeout(&HFumbling, rnd(20));
404                 break;
405         case GAUNTLETS_OF_POWER:
406                 makeknown(uarmg->otyp);
407                 flags.botl = 1; /* taken care of in attrib.c */
408                 break;
409         case GAUNTLETS_OF_DEXTERITY:
410                 adj_abon(uarmg, uarmg->spe);
411                 break;
412         default: impossible(unknown_type, c_gloves, uarmg->otyp);
413     }
414     return 0;
415 }
416
417 int
418 Gloves_off()
419 {
420     long oldprop =
421         u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
422
423     takeoff_mask &= ~W_ARMG;
424
425     switch(uarmg->otyp) {
426         case LEATHER_GLOVES:
427             break;
428         case GAUNTLETS_OF_FUMBLING:
429             if (!oldprop && !(HFumbling & ~TIMEOUT))
430                 HFumbling = EFumbling = 0;
431             break;
432         case GAUNTLETS_OF_POWER:
433             makeknown(uarmg->otyp);
434             flags.botl = 1; /* taken care of in attrib.c */
435             break;
436         case GAUNTLETS_OF_DEXTERITY:
437             if (!cancelled_don) adj_abon(uarmg, -uarmg->spe);
438             break;
439         default: impossible(unknown_type, c_gloves, uarmg->otyp);
440     }
441     setworn((struct obj *)0, W_ARMG);
442     cancelled_don = FALSE;
443     (void) encumber_msg();              /* immediate feedback for GoP */
444
445     /* Prevent wielding cockatrice when not wearing gloves */
446     if (uwep && uwep->otyp == CORPSE &&
447                 touch_petrifies(&mons[uwep->corpsenm])) {
448         char kbuf[BUFSZ];
449
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)));
453         instapetrify(kbuf);
454         uwepgone();  /* life-saved still doesn't allow touching cockatrice */
455     }
456
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])) {
460         char kbuf[BUFSZ];
461
462         You("wield the %s in your bare %s.",
463             corpse_xname(uswapwep, TRUE), body_part(HAND));
464
465         Strcpy(kbuf, an(corpse_xname(uswapwep, TRUE)));
466         instapetrify(kbuf);
467         uswapwepgone(); /* lifesaved still doesn't allow touching cockatrice */
468     }
469
470     return 0;
471 }
472
473 STATIC_OVL int
474 Shield_on()
475 {
476 /*
477     switch (uarms->otyp) {
478         case SMALL_SHIELD:
479         case ELVEN_SHIELD:
480         case URUK_HAI_SHIELD:
481         case ORCISH_SHIELD:
482         case DWARVISH_ROUNDSHIELD:
483         case LARGE_SHIELD:
484         case SHIELD_OF_REFLECTION:
485                 break;
486         default: impossible(unknown_type, c_shield, uarms->otyp);
487     }
488 */
489     return 0;
490 }
491
492 int
493 Shield_off()
494 {
495     takeoff_mask &= ~W_ARMS;
496 /*
497     switch (uarms->otyp) {
498         case SMALL_SHIELD:
499         case ELVEN_SHIELD:
500         case URUK_HAI_SHIELD:
501         case ORCISH_SHIELD:
502         case DWARVISH_ROUNDSHIELD:
503         case LARGE_SHIELD:
504         case SHIELD_OF_REFLECTION:
505                 break;
506         default: impossible(unknown_type, c_shield, uarms->otyp);
507     }
508 */
509     setworn((struct obj *)0, W_ARMS);
510     return 0;
511 }
512
513 #ifdef TOURIST
514 STATIC_OVL int
515 Shirt_on()
516 {
517 /*
518     switch (uarmu->otyp) {
519         case HAWAIIAN_SHIRT:
520         case T_SHIRT:
521                 break;
522         default: impossible(unknown_type, c_shirt, uarmu->otyp);
523     }
524 */
525     return 0;
526 }
527
528 int
529 Shirt_off()
530 {
531     takeoff_mask &= ~W_ARMU;
532 /*
533     switch (uarmu->otyp) {
534         case HAWAIIAN_SHIRT:
535         case T_SHIRT:
536                 break;
537         default: impossible(unknown_type, c_shirt, uarmu->otyp);
538     }
539 */
540     setworn((struct obj *)0, W_ARMU);
541     return 0;
542 }
543 #endif  /*TOURIST*/
544
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.
548  */
549 STATIC_PTR
550 int
551 Armor_on()
552 {
553     return 0;
554 }
555
556 int
557 Armor_off()
558 {
559     takeoff_mask &= ~W_ARM;
560     setworn((struct obj *)0, W_ARM);
561     cancelled_don = FALSE;
562     return 0;
563 }
564
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.
567  */
568 int
569 Armor_gone()
570 {
571     takeoff_mask &= ~W_ARM;
572     setnotworn(uarm);
573     cancelled_don = FALSE;
574     return 0;
575 }
576
577 STATIC_OVL void
578 Amulet_on()
579 {
580     switch(uamul->otyp) {
581         case AMULET_OF_ESP:
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:
587                 break;
588         case AMULET_OF_UNCHANGING:
589                 if (Slimed) {
590                     Slimed = 0;
591                     flags.botl = 1;
592                 }
593                 break;
594         case AMULET_OF_CHANGE:
595             {
596                 int orig_sex = poly_gender();
597
598                 if (Unchanging) break;
599                 change_sex();
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"
604                         : "masculine");
605                     flags.botl = 1;
606                 } else
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)
614                     docall(uamul);
615                 useup(uamul);
616                 break;
617             }
618         case AMULET_OF_STRANGULATION:
619                 makeknown(AMULET_OF_STRANGULATION);
620                 pline("It constricts your throat!");
621                 Strangled = 6;
622                 break;
623         case AMULET_OF_RESTFUL_SLEEP:
624                 HSleeping = rnd(100);
625                 break;
626         case AMULET_OF_YENDOR:
627                 break;
628     }
629 }
630
631 void
632 Amulet_off()
633 {
634     takeoff_mask &= ~W_AMUL;
635
636     switch(uamul->otyp) {
637         case AMULET_OF_ESP:
638                 /* need to update ability before calling see_monsters() */
639                 setworn((struct obj *)0, W_AMUL);
640                 see_monsters();
641                 return;
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:
648                 break;
649         case AMULET_OF_MAGICAL_BREATHING:
650                 if (Underwater) {
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)
655                                                 && !Swimming) {
656                         You("suddenly inhale an unhealthy amount of water!");
657                         (void) drown();
658                     }
659                     return;
660                 }
661                 break;
662         case AMULET_OF_STRANGULATION:
663                 if (Strangled) {
664                         You("can breathe more easily!");
665                         Strangled = 0;
666                 }
667                 break;
668         case AMULET_OF_RESTFUL_SLEEP:
669                 setworn((struct obj *)0, W_AMUL);
670                 if (!ESleeping)
671                         HSleeping = 0;
672                 return;
673         case AMULET_OF_YENDOR:
674                 break;
675     }
676     setworn((struct obj *)0, W_AMUL);
677     return;
678 }
679
680 void
681 Ring_on(obj)
682 register struct obj *obj;
683 {
684     long oldprop = u.uprops[objects[obj->otyp].oc_oprop].extrinsic;
685     int old_attrib, which;
686
687     if (obj == uwep) setuwep((struct obj *) 0);
688     if (obj == uswapwep) setuswapwep((struct obj *) 0);
689     if (obj == uquiver) setuqwep((struct obj *) 0);
690
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;
694
695     switch(obj->otyp){
696         case RIN_TELEPORTATION:
697         case RIN_REGENERATION:
698         case RIN_SEARCHING:
699         case RIN_STEALTH:
700         case RIN_HUNGER:
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:
706         case RIN_CONFLICT:
707         case RIN_TELEPORT_CONTROL:
708         case RIN_POLYMORPH:
709         case RIN_POLYMORPH_CONTROL:
710         case RIN_FREE_ACTION:                
711         case RIN_SLOW_DIGESTION:
712         case RIN_SUSTAIN_ABILITY:
713         case MEAT_RING:
714                 break;
715         case RIN_WARNING:
716                 see_monsters();
717                 break;
718         case RIN_SEE_INVISIBLE:
719                 /* can now see invisible monsters */
720                 set_mimic_blocking(); /* do special mimic handling */
721                 see_monsters();
722 #ifdef INVISIBLE_OBJECTS
723                 see_objects();
724 #endif
725
726                 if (Invis && !oldprop && !HSee_invisible &&
727                                 !perceives(youmonst.data) && !Blind) {
728                     newsym(u.ux,u.uy);
729                     pline("Suddenly you are transparent, but there!");
730                     makeknown(RIN_SEE_INVISIBLE);
731                 }
732                 break;
733         case RIN_INVISIBILITY:
734                 if (!oldprop && !HInvis && !BInvis && !Blind) {
735                     makeknown(RIN_INVISIBILITY);
736                     newsym(u.ux,u.uy);
737                     self_invis_message();
738                 }
739                 break;
740         case RIN_LEVITATION:
741                 if (!oldprop && !HLevitation) {
742                     float_up();
743                     makeknown(RIN_LEVITATION);
744                     spoteffects(FALSE); /* for sinks */
745                 }
746                 break;
747         case RIN_GAIN_STRENGTH:
748                 which = A_STR;
749                 goto adjust_attrib;
750         case RIN_GAIN_CONSTITUTION:
751                 which = A_CON;
752                 goto adjust_attrib;
753         case RIN_ADORNMENT:
754                 which = A_CHA;
755  adjust_attrib:
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)) {
761                     flags.botl = 1;
762                     makeknown(obj->otyp);
763                     obj->known = 1;
764                     update_inventory();
765                 }
766                 break;
767         case RIN_INCREASE_ACCURACY:     /* KMH */
768                 u.uhitinc += obj->spe;
769                 break;
770         case RIN_INCREASE_DAMAGE:
771                 u.udaminc += obj->spe;
772                 break;
773         case RIN_PROTECTION_FROM_SHAPE_CHAN:
774                 rescham();
775                 break;
776         case RIN_PROTECTION:
777                 if (obj->spe || objects[RIN_PROTECTION].oc_name_known) {
778                     flags.botl = 1;
779                     makeknown(RIN_PROTECTION);
780                     obj->known = 1;
781                     update_inventory();
782                 }
783                 break;
784     }
785 }
786
787 STATIC_OVL void
788 Ring_off_or_gone(obj,gone)
789 register struct obj *obj;
790 boolean gone;
791 {
792     long mask = (obj->owornmask & W_RING);
793     int old_attrib, which;
794
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);
800
801     switch(obj->otyp) {
802         case RIN_TELEPORTATION:
803         case RIN_REGENERATION:
804         case RIN_SEARCHING:
805         case RIN_STEALTH:
806         case RIN_HUNGER:
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:
812         case RIN_CONFLICT:
813         case RIN_TELEPORT_CONTROL:
814         case RIN_POLYMORPH:
815         case RIN_POLYMORPH_CONTROL:
816         case RIN_FREE_ACTION:                
817         case RIN_SLOW_DIGESTION:
818         case RIN_SUSTAIN_ABILITY:
819         case MEAT_RING:
820                 break;
821         case RIN_WARNING:
822                 see_monsters();
823                 break;
824         case RIN_SEE_INVISIBLE:
825                 /* Make invisible monsters go away */
826                 if (!See_invisible) {
827                     set_mimic_blocking(); /* do special mimic handling */
828                     see_monsters();
829 #ifdef INVISIBLE_OBJECTS                
830                     see_objects();
831 #endif
832                 }
833
834                 if (Invisible && !Blind) {
835                     newsym(u.ux,u.uy);
836                     pline("Suddenly you cannot see yourself.");
837                     makeknown(RIN_SEE_INVISIBLE);
838                 }
839                 break;
840         case RIN_INVISIBILITY:
841                 if (!Invis && !BInvis && !Blind) {
842                     newsym(u.ux,u.uy);
843                     Your("body seems to unfade%s.",
844                          See_invisible ? " completely" : "..");
845                     makeknown(RIN_INVISIBILITY);
846                 }
847                 break;
848         case RIN_LEVITATION:
849                 (void) float_down(0L, 0L);
850                 if (!Levitation) makeknown(RIN_LEVITATION);
851                 break;
852         case RIN_GAIN_STRENGTH:
853                 which = A_STR;
854                 goto adjust_attrib;
855         case RIN_GAIN_CONSTITUTION:
856                 which = A_CON;
857                 goto adjust_attrib;
858         case RIN_ADORNMENT:
859                 which = A_CHA;
860  adjust_attrib:
861                 old_attrib = ACURR(which);
862                 ABON(which) -= obj->spe;
863                 if (ACURR(which) != old_attrib) {
864                     flags.botl = 1;
865                     makeknown(obj->otyp);
866                     obj->known = 1;
867                     update_inventory();
868                 }
869                 break;
870         case RIN_INCREASE_ACCURACY:     /* KMH */
871                 u.uhitinc -= obj->spe;
872                 break;
873         case RIN_INCREASE_DAMAGE:
874                 u.udaminc -= obj->spe;
875                 break;
876         case RIN_PROTECTION:
877                 /* might have forgotten it due to amnesia */
878                 if (obj->spe) {
879                     flags.botl = 1;
880                     makeknown(RIN_PROTECTION);
881                     obj->known = 1;
882                     update_inventory();
883                 }
884         case RIN_PROTECTION_FROM_SHAPE_CHAN:
885                 /* If you're no longer protected, let the chameleons
886                  * change shape again -dgk
887                  */
888                 restartcham();
889                 break;
890     }
891 }
892
893 void
894 Ring_off(obj)
895 struct obj *obj;
896 {
897         Ring_off_or_gone(obj,FALSE);
898 }
899
900 void
901 Ring_gone(obj)
902 struct obj *obj;
903 {
904         Ring_off_or_gone(obj,TRUE);
905 }
906
907 void
908 Blindf_on(otmp)
909 register struct obj *otmp;
910 {
911         boolean already_blind = Blind, changed = FALSE;
912
913         if (otmp == uwep)
914             setuwep((struct obj *) 0);
915         if (otmp == uswapwep)
916             setuswapwep((struct obj *) 0);
917         if (otmp == uquiver)
918             setuqwep((struct obj *) 0);
919         setworn(otmp, W_TOOL);
920         on_msg(otmp);
921
922         if (Blind && !already_blind) {
923             changed = TRUE;
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) {
928             changed = TRUE;
929             /* "You are now wearing the Eyes of the Overworld." */
930             You("can see!");
931         }
932         if (changed) {
933             /* blindness has just been toggled */
934             if (Blind_telepat || Infravision) see_monsters();
935             vision_full_recalc = 1;     /* recalc vision limits */
936             flags.botl = 1;
937         }
938 }
939
940 void
941 Blindf_off(otmp)
942 register struct obj *otmp;
943 {
944         boolean was_blind = Blind, changed = FALSE;
945
946         takeoff_mask &= ~W_TOOL;
947         setworn((struct obj *)0, otmp->owornmask);
948         off_msg(otmp);
949
950         if (Blind) {
951             if (was_blind) {
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.");
956             } else {
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);
962             }
963         } else if (was_blind) {
964             changed = TRUE;     /* !Blind */
965             You("can see again.");
966         }
967         if (changed) {
968             /* blindness has just been toggled */
969             if (Blind_telepat || Infravision) see_monsters();
970             vision_full_recalc = 1;     /* recalc vision limits */
971             flags.botl = 1;
972         }
973 }
974
975 /* called in main to set intrinsics of worn start-up items */
976 void
977 set_wear()
978 {
979 #ifdef TOURIST
980         if (uarmu) (void) Shirt_on();
981 #endif
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();
988 }
989
990 /* check whether the target object is currently being put on (or taken off) */
991 boolean
992 donning(otmp)           /* also checks for doffing */
993 register struct obj *otmp;
994 {
995  /* long what = (occupation == take_off) ? taking_off : 0L; */
996     long what = taking_off;     /* if nonzero, occupation is implied */
997     boolean result = FALSE;
998
999     if (otmp == uarm)
1000         result = (afternmv == Armor_on || afternmv == Armor_off ||
1001                   what == WORN_ARMOR);
1002 #ifdef TOURIST
1003     else if (otmp == uarmu)
1004         result = (afternmv == Shirt_on || afternmv == Shirt_off ||
1005                   what == WORN_SHIRT);
1006 #endif
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);
1022
1023     return result;
1024 }
1025
1026 void
1027 cancel_don()
1028 {
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
1031          * otherwise finish)
1032          */
1033         cancelled_don = (afternmv == Boots_on || afternmv == Helmet_on ||
1034                          afternmv == Gloves_on || afternmv == Armor_on);
1035         afternmv = 0;
1036         nomovemsg = (char *)0;
1037         multi = 0;
1038         todelay = 0;
1039         taking_off = 0L;
1040 }
1041
1042 static NEARDATA const char clothes[] = {ARMOR_CLASS, 0};
1043 static NEARDATA const char accessories[] = {RING_CLASS, AMULET_CLASS, TOOL_CLASS, FOOD_CLASS, 0};
1044
1045 /* the 'T' command */
1046 int
1047 dotakeoff()
1048 {
1049         register struct obj *otmp = (struct obj *)0;
1050         int armorpieces = 0;
1051
1052 #define MOREARM(x) if (x) { armorpieces++; otmp = x; }
1053         MOREARM(uarmh);
1054         MOREARM(uarms);
1055         MOREARM(uarmg);
1056         MOREARM(uarmf);
1057         if (uarmc) {
1058                 armorpieces++;
1059                 otmp = uarmc;
1060         } else if (uarm) {
1061                 armorpieces++;
1062                 otmp = uarm;
1063 #ifdef TOURIST
1064         } else if (uarmu) {
1065                 armorpieces++;
1066                 otmp = uarmu;
1067 #endif
1068         }
1069         if (!armorpieces) {
1070              /* assert( GRAY_DRAGON_SCALES > YELLOW_DRAGON_SCALE_MAIL ); */
1071                 if (uskin)
1072                     pline_The("%s merged with your skin!",
1073                               uskin->otyp >= GRAY_DRAGON_SCALES ?
1074                                 "dragon scales are" : "dragon scale mail is");
1075                 else
1076                     pline("Not wearing any armor.%s", (iflags.cmdassist && 
1077                                 (uleft || uright || uamul || ublindf)) ?
1078                           "  Use 'R' command to remove accessories." : "");
1079                 return 0;
1080         }
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.");
1086                 return(0);
1087         }
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)
1091 #ifdef TOURIST
1092                           || ((otmp == uarmu) && (uarmc || uarm))
1093 #endif
1094                 ) {
1095             You_cant("take that off.");
1096             return 0;
1097         }
1098
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 */
1103
1104         (void) armoroff(otmp);
1105         return(1);
1106 }
1107
1108 /* the 'R' command */
1109 int
1110 doremring()
1111 {
1112         register struct obj *otmp = 0;
1113         int Accessories = 0;
1114
1115 #define MOREACC(x) if (x) { Accessories++; otmp = x; }
1116         MOREACC(uleft);
1117         MOREACC(uright);
1118         MOREACC(uamul);
1119         MOREACC(ublindf);
1120
1121         if(!Accessories) {
1122                 pline("Not wearing any accessories.%s", (iflags.cmdassist &&
1123                             (uarm || uarmc ||
1124 #ifdef TOURIST
1125                              uarmu ||
1126 #endif
1127                              uarms || uarmh || uarmg || uarmf)) ?
1128                       "  Use 'T' command to take off armor." : "");
1129                 return(0);
1130         }
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.");
1135                 return(0);
1136         }
1137
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() */
1142
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
1148                  * "being worn".
1149                  */
1150                 off_msg(otmp);
1151                 Ring_off(otmp);
1152         } else if (otmp == uamul) {
1153                 Amulet_off();
1154                 off_msg(otmp);
1155         } else if (otmp == ublindf) {
1156                 Blindf_off(otmp);       /* does its own off_msg */
1157         } else {
1158                 impossible("removing strange accessory?");
1159         }
1160         return(1);
1161 }
1162
1163 /* Check if something worn is cursed _and_ unremovable. */
1164 int
1165 cursed(otmp)
1166 register struct obj *otmp;
1167 {
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;
1174                 return(1);
1175         }
1176         return(0);
1177 }
1178
1179 int
1180 armoroff(otmp)
1181 register struct obj *otmp;
1182 {
1183         register int delay = -objects[otmp->otyp].oc_delay;
1184
1185         if(cursed(otmp)) return(0);
1186         if(delay) {
1187                 nomul(delay);
1188                 if (is_helmet(otmp)) {
1189                         nomovemsg = "You finish taking off your helmet.";
1190                         afternmv = Helmet_off;
1191                      }
1192                 else if (is_gloves(otmp)) {
1193                         nomovemsg = "You finish taking off your gloves.";
1194                         afternmv = Gloves_off;
1195                      }
1196                 else if (is_boots(otmp)) {
1197                         nomovemsg = "You finish taking off your boots.";
1198                         afternmv = Boots_off;
1199                      }
1200                 else {
1201                         nomovemsg = "You finish taking off your suit.";
1202                         afternmv = Armor_off;
1203                 }
1204         } else {
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.
1219                  */
1220                 if(is_cloak(otmp))
1221                         (void) Cloak_off();
1222                 else if(is_shield(otmp))
1223                         (void) Shield_off();
1224                 else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
1225                 off_msg(otmp);
1226         }
1227         takeoff_mask = taking_off = 0L;
1228         return(1);
1229 }
1230
1231 STATIC_OVL void
1232 already_wearing(cc)
1233 const char *cc;
1234 {
1235         You("are already wearing %s%c", cc, (cc == c_that_) ? '!' : '.');
1236 }
1237
1238 STATIC_OVL void
1239 already_wearing2(cc1, cc2)
1240 const char *cc1, *cc2;
1241 {
1242         You_cant("wear %s because you're wearing %s there already.", cc1, cc2);
1243 }
1244
1245 /*
1246  * canwearobj checks to see whether the player can wear a piece of armor
1247  *
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)
1251  */
1252 int
1253 canwearobj(otmp,mask,noisy)
1254 struct obj *otmp;
1255 long *mask;
1256 boolean noisy;
1257 {
1258     int err = 0;
1259     const char *which;
1260
1261     which = is_cloak(otmp) ? c_cloak :
1262 #ifdef TOURIST
1263             is_shirt(otmp) ? c_shirt :
1264 #endif
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);
1271         return 0;
1272     } else if (otmp->owornmask & W_ARMOR) {
1273         if (noisy) already_wearing(c_that_);
1274         return 0;
1275     }
1276
1277     if (welded(uwep) && bimanual(uwep) &&
1278             (is_suit(otmp)
1279 #ifdef TOURIST
1280                         || is_shirt(otmp)
1281 #endif
1282             )) {
1283         if (noisy)
1284             You("cannot do that while holding your %s.",
1285                 is_sword(uwep) ? c_sword : c_weapon);
1286         return 0;
1287     }
1288
1289     if (is_helmet(otmp)) {
1290         if (uarmh) {
1291             if (noisy) already_wearing(an(c_helmet));
1292             err++;
1293         } else if (Upolyd && has_horns(youmonst.data) && !is_flimsy(otmp)) {
1294             /* (flimsy exception matches polyself handling) */
1295             if (noisy)
1296                 pline_The("%s won't fit over your horn%s.",
1297                           c_helmet, plur(num_horns(youmonst.data)));
1298             err++;
1299         } else
1300             *mask = W_ARMH;
1301     } else if (is_shield(otmp)) {
1302         if (uarms) {
1303             if (noisy) already_wearing(an(c_shield));
1304             err++;
1305         } else if (uwep && bimanual(uwep)) {
1306             if (noisy) 
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);
1310             err++;
1311         } else if (u.twoweap) {
1312             if (noisy)
1313                 You("cannot wear a shield while wielding two weapons.");
1314             err++;
1315         } else
1316             *mask = W_ARMS;
1317     } else if (is_boots(otmp)) {
1318         if (uarmf) {
1319             if (noisy) already_wearing(c_boots);
1320             err++;
1321         } else if (Upolyd && slithy(youmonst.data)) {
1322             if (noisy) You("have no feet...");  /* not body_part(FOOT) */
1323             err++;
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 */
1330             err++;
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));
1335             } else {
1336                 if (noisy) Your("%s are stuck in the %s!",
1337                                 makeplural(body_part(FOOT)),
1338                                 surface(u.ux, u.uy));
1339             }
1340             err++;
1341         } else
1342             *mask = W_ARMF;
1343     } else if (is_gloves(otmp)) {
1344         if (uarmg) {
1345             if (noisy) already_wearing(c_gloves);
1346             err++;
1347         } else if (welded(uwep)) {
1348             if (noisy) You("cannot wear gloves over your %s.",
1349                            is_sword(uwep) ? c_sword : c_weapon);
1350             err++;
1351         } else
1352             *mask = W_ARMG;
1353 #ifdef TOURIST
1354     } else if (is_shirt(otmp)) {
1355         if (uarm || uarmc || uarmu) {
1356             if (uarmu) {
1357                 if (noisy) already_wearing(an(c_shirt));
1358             } else {
1359                 if (noisy) You_cant("wear that over your %s.",
1360                                    (uarm && !uarmc) ? c_armor : cloak_simple_name(uarmc));
1361             }
1362             err++;
1363         } else
1364             *mask = W_ARMU;
1365 #endif
1366     } else if (is_cloak(otmp)) {
1367         if (uarmc) {
1368             if (noisy) already_wearing(an(cloak_simple_name(uarmc)));
1369             err++;
1370         } else
1371             *mask = W_ARMC;
1372     } else if (is_suit(otmp)) {
1373         if (uarmc) {
1374             if (noisy) You("cannot wear armor over a %s.", cloak_simple_name(uarmc));
1375             err++;
1376         } else if (uarm) {
1377             if (noisy) already_wearing("some armor");
1378             err++;
1379         } else
1380             *mask = W_ARM;
1381     } else {
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);
1386         err++;
1387     }
1388 /* Unnecessary since now only weapons and special items like pick-axes get
1389  * welded to your hand, not armor
1390     if (welded(otmp)) {
1391         if (!err++) {
1392             if (noisy) weldmsg(otmp);
1393         }
1394     }
1395  */
1396     return !err;
1397 }
1398
1399 /* the 'W' command */
1400 int
1401 dowear()
1402 {
1403         struct obj *otmp;
1404         int delay;
1405         long mask = 0;
1406
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.");
1411                 return(0);
1412         }
1413
1414         otmp = getobj(clothes, "wear");
1415         if(!otmp) return(0);
1416
1417         if (!canwearobj(otmp,&mask,TRUE)) return(0);
1418
1419         if (otmp->oartifact && !touch_artifact(otmp, &youmonst))
1420             return 1;   /* costs a turn even though it didn't get worn */
1421
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);
1430                 flags.botl = 1;
1431                 return 1;
1432         }
1433
1434         otmp->known = TRUE;
1435         if(otmp == uwep)
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;
1443         if(delay){
1444                 nomul(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.";
1450         } else {
1451                 if(is_cloak(otmp)) (void) Cloak_on();
1452                 if (is_shield(otmp)) (void) Shield_on();
1453 #ifdef TOURIST
1454                 if (is_shirt(otmp)) (void) Shirt_on();
1455 #endif
1456                 on_msg(otmp);
1457         }
1458         takeoff_mask = taking_off = 0L;
1459         return(1);
1460 }
1461
1462 int
1463 doputon()
1464 {
1465         register struct obj *otmp;
1466         long mask = 0L;
1467
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");
1473                 return(0);
1474         }
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_);
1479                 return(0);
1480         }
1481         if(welded(otmp)) {
1482                 weldmsg(otmp);
1483                 return(0);
1484         }
1485         if(otmp == uwep)
1486                 setuwep((struct obj *)0);
1487         if(otmp == uswapwep)
1488                 setuswapwep((struct obj *) 0);
1489         if(otmp == uquiver)
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.");
1494                         return(0);
1495                 }
1496                 if(uleft && uright){
1497                         There("are no more %s%s to fill.",
1498                                 humanoid(youmonst.data) ? "ring-" : "",
1499                                 makeplural(body_part(FINGER)));
1500                         return(0);
1501                 }
1502                 if(uleft) mask = RIGHT_RING;
1503                 else if(uright) mask = LEFT_RING;
1504                 else do {
1505                         char qbuf[QBUFSZ];
1506                         char answer;
1507
1508                         Sprintf(qbuf, "Which %s%s, Right or Left?",
1509                                 humanoid(youmonst.data) ? "ring-" : "",
1510                                 body_part(FINGER));
1511                         if(!(answer = yn_function(qbuf, "rl", '\0')))
1512                                 return(0);
1513                         switch(answer){
1514                         case 'l':
1515                         case 'L':
1516                                 mask = LEFT_RING;
1517                                 break;
1518                         case 'r':
1519                         case 'R':
1520                                 mask = RIGHT_RING;
1521                                 break;
1522                         }
1523                 } while(!mask);
1524                 if (uarmg && uarmg->cursed) {
1525                         uarmg->bknown = TRUE;
1526                     You("cannot remove your gloves to put on the ring.");
1527                         return(0);
1528                 }
1529                 if (welded(uwep) && bimanual(uwep)) {
1530                         /* welded will set bknown */
1531             You("cannot free your weapon hands to put on the ring.");
1532                         return(0);
1533                 }
1534                 if (welded(uwep) && mask==RIGHT_RING) {
1535                         /* welded will set bknown */
1536             You("cannot free your weapon hand to put on the ring.");
1537                         return(0);
1538                 }
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);
1542                 Ring_on(otmp);
1543         } else if (otmp->oclass == AMULET_CLASS) {
1544                 if(uamul) {
1545                         already_wearing("an amulet");
1546                         return(0);
1547                 }
1548                 if (otmp->oartifact && !touch_artifact(otmp, &youmonst))
1549                     return 1;
1550                 setworn(otmp, W_AMUL);
1551                 if (otmp->otyp == AMULET_OF_CHANGE) {
1552                         Amulet_on();
1553                         /* Don't do a prinv() since the amulet is now gone */
1554                         return(1);
1555                 }
1556                 Amulet_on();
1557         } else {        /* it's a blindfold, towel, or lenses */
1558                 if (ublindf) {
1559                         if (ublindf->otyp == TOWEL)
1560                                 Your("%s is already covered by a towel.",
1561                                         body_part(FACE));
1562                         else if (ublindf->otyp == BLINDFOLD) {
1563                                 if (otmp->otyp == LENSES)
1564                                         already_wearing2("lenses", "a blindfold");
1565                                 else
1566                                         already_wearing("a blindfold");
1567                         } else if (ublindf->otyp == LENSES) {
1568                                 if (otmp->otyp == BLINDFOLD)
1569                                         already_wearing2("a blindfold", "some lenses");
1570                                 else
1571                                         already_wearing("some lenses");
1572                         } else
1573                                 already_wearing(something); /* ??? */
1574                         return(0);
1575                 }
1576                 if (otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL && otmp->otyp != LENSES) {
1577                         You_cant("wear that!");
1578                         return(0);
1579                 }
1580                 if (otmp->oartifact && !touch_artifact(otmp, &youmonst))
1581                     return 1;
1582                 Blindf_on(otmp);
1583                 return(1);
1584         }
1585         if (is_worn(otmp))
1586             prinv((char *)0, otmp, 0L);
1587         return(1);
1588 }
1589
1590 #endif /* OVLB */
1591
1592 #ifdef OVL0
1593
1594 void
1595 find_ac()
1596 {
1597         int uac = mons[u.umonnum].ac;
1598
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);
1605 #ifdef TOURIST
1606         if(uarmu) uac -= ARM_BONUS(uarmu);
1607 #endif
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 */
1613         if(uac != u.uac){
1614                 u.uac = uac;
1615                 flags.botl = 1;
1616         }
1617 }
1618
1619 #endif /* OVL0 */
1620 #ifdef OVLB
1621
1622 void
1623 glibr()
1624 {
1625         register struct obj *otmp;
1626         int xfl = 0;
1627         boolean leftfall, rightfall;
1628         const char *otherwep = 0;
1629
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)) :
1638                         body_part(FINGER));
1639                 xfl++;
1640                 if (leftfall) {
1641                         otmp = uleft;
1642                         Ring_off(uleft);
1643                         dropx(otmp);
1644                 }
1645                 if (rightfall) {
1646                         otmp = uright;
1647                         Ring_off(uright);
1648                         dropx(otmp);
1649                 }
1650         }
1651
1652         otmp = uswapwep;
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.",
1657                         otherwep,
1658                         xfl ? "also " : "",
1659                         makeplural(body_part(HAND)));
1660                 setuswapwep((struct obj *)0);
1661                 xfl++;
1662                 if (otmp->otyp != LOADSTONE || !otmp->cursed)
1663                         dropx(otmp);
1664         }
1665         otmp = uwep;
1666         if (otmp && !welded(otmp)) {
1667                 const char *thiswep;
1668
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;
1673
1674                 /* changed so cursed weapons don't fall, GAN 10/30/86 */
1675                 Your("%s%s %sslips from your %s.",
1676                         otherwep ? "other " : "", thiswep,
1677                         xfl ? "also " : "",
1678                         makeplural(body_part(HAND)));
1679                 setuwep((struct obj *)0);
1680                 if (otmp->otyp != LOADSTONE || !otmp->cursed)
1681                         dropx(otmp);
1682         }
1683 }
1684
1685 struct obj *
1686 some_armor(victim)
1687 struct monst *victim;
1688 {
1689         register struct obj *otmph, *otmp;
1690
1691         otmph = (victim == &youmonst) ? uarmc : which_armor(victim, W_ARMC);
1692         if (!otmph)
1693             otmph = (victim == &youmonst) ? uarm : which_armor(victim, W_ARM);
1694 #ifdef TOURIST
1695         if (!otmph)
1696             otmph = (victim == &youmonst) ? uarmu : which_armor(victim, W_ARMU);
1697 #endif
1698         
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;
1707         return(otmph);
1708 }
1709
1710 /* erode some arbitrary armor worn by the victim */
1711 void
1712 erode_armor(victim, acid_dmg)
1713 struct monst *victim;
1714 boolean acid_dmg;
1715 {
1716         struct obj *otmph = some_armor(victim);
1717
1718         if (otmph && (otmph != uarmf)) {
1719             erode_obj(otmph, acid_dmg, FALSE);
1720             if (carried(otmph)) update_inventory();
1721         }
1722 }
1723
1724 /* used for praying to check and fix levitation trouble */
1725 struct obj *
1726 stuck_ring(ring, otyp)
1727 struct obj *ring;
1728 int otyp;
1729 {
1730     if (ring != uleft && ring != uright) {
1731         impossible("stuck_ring: neither left nor right?");
1732         return (struct obj *)0;
1733     }
1734
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)
1740             return uamul;
1741         if (welded(uwep) && (ring == uright || bimanual(uwep))) return uwep;
1742         if (uarmg && uarmg->cursed) return uarmg;
1743         if (ring->cursed) return ring;
1744     }
1745     /* either no ring or not right type or nothing prevents its removal */
1746     return (struct obj *)0;
1747 }
1748
1749 /* also for praying; find worn item that confers "Unchanging" attribute */
1750 struct obj *
1751 unchanger()
1752 {
1753     if (uamul && uamul->otyp == AMULET_OF_UNCHANGING) return uamul;
1754     return 0;
1755 }
1756
1757 /* occupation callback for 'A' */
1758 STATIC_PTR
1759 int
1760 select_off(otmp)
1761 register struct obj *otmp;
1762 {
1763         struct obj *why;
1764         char buf[BUFSZ];
1765
1766         if (!otmp) return 0;
1767         *buf = '\0';                    /* lint suppresion */
1768
1769         /* special ring checks */
1770         if (otmp == uright || otmp == uleft) {
1771             if (nolimbs(youmonst.data)) {
1772                 pline_The("ring is stuck.");
1773                 return 0;
1774             }
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));
1778                 why = uwep;
1779             } else if (uarmg && uarmg->cursed) {
1780                 Sprintf(buf, "take off your %s", c_gloves);
1781                 why = uarmg;
1782             }
1783             if (why) {
1784                 You("cannot %s to remove the ring.", buf);
1785                 why->bknown = TRUE;
1786                 return 0;
1787             }
1788         }
1789         /* special glove checks */
1790         if (otmp == uarmg) {
1791             if (welded(uwep)) {
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;
1795                 return 0;
1796             } else if (Glib) {
1797                 You_cant("take off the slippery %s with your slippery %s.",
1798                          c_gloves, makeplural(body_part(FINGER)));
1799                 return 0;
1800             }
1801         }
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.",
1806                           body_part(FOOT));
1807                 return 0;
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)));
1811                 return 0;
1812             }
1813         }
1814         /* special suit and shirt checks */
1815         if (otmp == uarm
1816 #ifdef TOURIST
1817                         || otmp == uarmu
1818 #endif
1819                 ) {
1820             why = 0;    /* the item which prevents disrobing */
1821             if (uarmc && uarmc->cursed) {
1822                 Sprintf(buf, "remove your %s", cloak_simple_name(uarmc));
1823                 why = uarmc;
1824 #ifdef TOURIST
1825             } else if (otmp == uarmu && uarm && uarm->cursed) {
1826                 Sprintf(buf, "remove your %s", c_suit);
1827                 why = uarm;
1828 #endif
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);
1833                 why = uwep;
1834             }
1835             if (why) {
1836                 You("cannot %s to take off %s.", buf, the(xname(otmp)));
1837                 why->bknown = TRUE;
1838                 return 0;
1839             }
1840         }
1841         /* basic curse check */
1842         if (otmp == uquiver || (otmp == uswapwep && !u.twoweap)) {
1843             ;   /* some items can be removed even when cursed */
1844         } else {
1845             /* otherwise, this is fundamental */
1846             if (cursed(otmp)) return 0;
1847         }
1848
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;
1855 #ifdef TOURIST
1856         else if(otmp == uarmu) takeoff_mask |= WORN_SHIRT;
1857 #endif
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;
1865
1866         else impossible("select_off: %s???", doname(otmp));
1867
1868         return(0);
1869 }
1870
1871 STATIC_OVL struct obj *
1872 do_takeoff()
1873 {
1874         register struct obj *otmp = (struct obj *)0;
1875
1876         if (taking_off == W_WEP) {
1877           if(!cursed(uwep)) {
1878             setuwep((struct obj *) 0);
1879             You("are empty %s.", body_part(HANDED));
1880             u.twoweap = FALSE;
1881           }
1882         } else if (taking_off == W_SWAPWEP) {
1883           setuswapwep((struct obj *) 0);
1884           You("no longer have a second weapon readied.");
1885           u.twoweap = FALSE;
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) {
1890           otmp = uarm;
1891           if(!cursed(otmp)) (void) Armor_off();
1892         } else if (taking_off == WORN_CLOAK) {
1893           otmp = uarmc;
1894           if(!cursed(otmp)) (void) Cloak_off();
1895         } else if (taking_off == WORN_BOOTS) {
1896           otmp = uarmf;
1897           if(!cursed(otmp)) (void) Boots_off();
1898         } else if (taking_off == WORN_GLOVES) {
1899           otmp = uarmg;
1900           if(!cursed(otmp)) (void) Gloves_off();
1901         } else if (taking_off == WORN_HELMET) {
1902           otmp = uarmh;
1903           if(!cursed(otmp)) (void) Helmet_off();
1904         } else if (taking_off == WORN_SHIELD) {
1905           otmp = uarms;
1906           if(!cursed(otmp)) (void) Shield_off();
1907 #ifdef TOURIST
1908         } else if (taking_off == WORN_SHIRT) {
1909           otmp = uarmu;
1910           if (!cursed(otmp)) (void) Shirt_off();
1911 #endif
1912         } else if (taking_off == WORN_AMUL) {
1913           otmp = uamul;
1914           if(!cursed(otmp)) Amulet_off();
1915         } else if (taking_off == LEFT_RING) {
1916           otmp = uleft;
1917           if(!cursed(otmp)) Ring_off(uleft);
1918         } else if (taking_off == RIGHT_RING) {
1919           otmp = uright;
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);
1924
1925         return(otmp);
1926 }
1927
1928 static const char *disrobing = "";
1929
1930 STATIC_PTR
1931 int
1932 take_off()
1933 {
1934         register int i;
1935         register struct obj *otmp;
1936
1937         if (taking_off) {
1938             if (todelay > 0) {
1939                 todelay--;
1940                 return(1);      /* still busy */
1941             } else {
1942                 if ((otmp = do_takeoff())) off_msg(otmp);
1943             }
1944             takeoff_mask &= ~taking_off;
1945             taking_off = 0L;
1946         }
1947
1948         for(i = 0; takeoff_order[i]; i++)
1949             if(takeoff_mask & takeoff_order[i]) {
1950                 taking_off = takeoff_order[i];
1951                 break;
1952             }
1953
1954         otmp = (struct obj *) 0;
1955         todelay = 0;
1956
1957         if (taking_off == 0L) {
1958           You("finish %s.", disrobing);
1959           return 0;
1960         } else if (taking_off == W_WEP) {
1961           todelay = 1;
1962         } else if (taking_off == W_SWAPWEP) {
1963           todelay = 1;
1964         } else if (taking_off == W_QUIVER) {
1965           todelay = 1;
1966         } else if (taking_off == WORN_ARMOR) {
1967           otmp = uarm;
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...
1971            */
1972           if (uarmc) todelay += 2 * objects[uarmc->otyp].oc_delay + 1;
1973         } else if (taking_off == WORN_CLOAK) {
1974           otmp = uarmc;
1975         } else if (taking_off == WORN_BOOTS) {
1976           otmp = uarmf;
1977         } else if (taking_off == WORN_GLOVES) {
1978           otmp = uarmg;
1979         } else if (taking_off == WORN_HELMET) {
1980           otmp = uarmh;
1981         } else if (taking_off == WORN_SHIELD) {
1982           otmp = uarms;
1983 #ifdef TOURIST
1984         } else if (taking_off == WORN_SHIRT) {
1985           otmp = uarmu;
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;
1989 #endif
1990         } else if (taking_off == WORN_AMUL) {
1991           todelay = 1;
1992         } else if (taking_off == LEFT_RING) {
1993           todelay = 1;
1994         } else if (taking_off == RIGHT_RING) {
1995           todelay = 1;
1996         } else if (taking_off == WORN_BLINDF) {
1997           todelay = 2;
1998         } else {
1999           impossible("take_off: taking off %lx", taking_off);
2000           return 0;     /* force done */
2001         }
2002
2003         if (otmp) todelay += objects[otmp->otyp].oc_delay;
2004
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.
2008          */
2009         if (todelay > 0) todelay--;
2010
2011         set_occupation(take_off, disrobing, 0);
2012         return(1);              /* get busy */
2013 }
2014
2015 /* clear saved context to avoid inappropriate resumption of interrupted 'A' */
2016 void
2017 reset_remarm()
2018 {
2019         taking_off = takeoff_mask = 0L;
2020         disrobing = nul;
2021 }
2022
2023 /* the 'A' command -- remove multiple worn items */
2024 int
2025 doddoremarm()
2026 {
2027     int result = 0;
2028
2029     if (taking_off || takeoff_mask) {
2030         You("continue %s.", disrobing);
2031         set_occupation(take_off, disrobing, 0);
2032         return 0;
2033     } else if (!uwep && !uswapwep && !uquiver && !uamul && !ublindf &&
2034                 !uleft && !uright && !wearing_armor()) {
2035         You("are not wearing anything.");
2036         return 0;
2037     }
2038
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);
2043
2044     if (takeoff_mask) {
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";
2051         (void) take_off();
2052     }
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
2055      * disrobe.
2056      */
2057     return 0;
2058 }
2059
2060 STATIC_OVL int
2061 menu_remarm(retry)
2062 int retry;
2063 {
2064     int n, i = 0;
2065     menu_item *pick_list;
2066     boolean all_worn_categories = TRUE;
2067
2068     if (retry) {
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);
2074         if (!n) return 0;
2075         for (i = 0; i < n; i++) {
2076             if (pick_list[i].item.a_int == ALL_TYPES_SELECTED)
2077                 all_worn_categories = TRUE;
2078             else
2079                 add_valid_menu_class(pick_list[i].item.a_int);
2080         }
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;
2086     }
2087
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);
2092     if (n > 0) {
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.");
2098     }
2099     return 0;
2100 }
2101
2102 /* hit by destroy armor scroll/black dragon breath/monster spell */
2103 int
2104 destroy_arm(atmp)
2105 register struct obj *atmp;
2106 {
2107         register struct obj *otmp;
2108 #define DESTROY_ARM(o) ((otmp = (o)) != 0 && \
2109                         (!atmp || atmp == otmp) && \
2110                         (!obj_resists(otmp, 0, 90)))
2111
2112         if (DESTROY_ARM(uarmc)) {
2113                 if (donning(otmp)) cancel_don();
2114                 Your("%s crumbles and turns to dust!",
2115                      cloak_simple_name(uarmc));
2116                 (void) Cloak_off();
2117                 useup(otmp);
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();
2123                 useup(otmp);
2124 #ifdef TOURIST
2125         } else if (DESTROY_ARM(uarmu)) {
2126                 if (donning(otmp)) cancel_don();
2127                 Your("shirt crumbles into tiny threads and falls apart!");
2128                 (void) Shirt_off();
2129                 useup(otmp);
2130 #endif
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();
2135                 useup(otmp);
2136         } else if (DESTROY_ARM(uarmg)) {
2137                 if (donning(otmp)) cancel_don();
2138                 Your("gloves vanish!");
2139                 (void) Gloves_off();
2140                 useup(otmp);
2141                 selftouch("You");
2142         } else if (DESTROY_ARM(uarmf)) {
2143                 if (donning(otmp)) cancel_don();
2144                 Your("boots disintegrate!");
2145                 (void) Boots_off();
2146                 useup(otmp);
2147         } else if (DESTROY_ARM(uarms)) {
2148                 if (donning(otmp)) cancel_don();
2149                 Your("shield crumbles away!");
2150                 (void) Shield_off();
2151                 useup(otmp);
2152         } else {
2153                 return 0;               /* could not destroy anything */
2154         }
2155
2156 #undef DESTROY_ARM
2157         stop_occupation();
2158         return(1);
2159 }
2160
2161 void
2162 adj_abon(otmp, delta)
2163 register struct obj *otmp;
2164 register schar delta;
2165 {
2166         if (uarmg && uarmg == otmp && otmp->otyp == GAUNTLETS_OF_DEXTERITY) {
2167                 if (delta) {
2168                         makeknown(uarmg->otyp);
2169                         ABON(A_DEX) += (delta);
2170                 }
2171                 flags.botl = 1;
2172         }
2173         if (uarmh && uarmh == otmp && otmp->otyp == HELM_OF_BRILLIANCE) {
2174                 if (delta) {
2175                         makeknown(uarmh->otyp);
2176                         ABON(A_INT) += (delta);
2177                         ABON(A_WIS) += (delta);
2178                 }
2179                 flags.botl = 1;
2180         }
2181 }
2182
2183 #endif /* OVLB */
2184
2185 /*do_wear.c*/