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
off_msg(otmp)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
on_msg(otmp)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
Boots_on()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
Boots_off()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
Cloak_on()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
Cloak_off()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
Helmet_on()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
Helmet_off()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
Gloves_on()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
Gloves_off()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
Shield_on()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
Shield_off()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
Shirt_on()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
Shirt_off()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
Armor_on()551 Armor_on()
552 {
553     return 0;
554 }
555 
556 int
Armor_off()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
Armor_gone()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
Amulet_on()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
Amulet_off()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
Ring_on(obj)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
Ring_off_or_gone(obj,gone)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
Ring_off(obj)894 Ring_off(obj)
895 struct obj *obj;
896 {
897 	Ring_off_or_gone(obj,FALSE);
898 }
899 
900 void
Ring_gone(obj)901 Ring_gone(obj)
902 struct obj *obj;
903 {
904 	Ring_off_or_gone(obj,TRUE);
905 }
906 
907 void
Blindf_on(otmp)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
Blindf_off(otmp)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
set_wear()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
donning(otmp)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
cancel_don()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
dotakeoff()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
doremring()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
cursed(otmp)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
armoroff(otmp)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
already_wearing(cc)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
already_wearing2(cc1,cc2)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
canwearobj(otmp,mask,noisy)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
dowear()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
doputon()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
find_ac()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
glibr()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 *
some_armor(victim)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
erode_armor(victim,acid_dmg)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 *
stuck_ring(ring,otyp)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 *
unchanger()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
select_off(otmp)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 *
do_takeoff()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
take_off()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
reset_remarm()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
doddoremarm()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
menu_remarm(retry)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
destroy_arm(atmp)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
adj_abon(otmp,delta)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*/
2186