1    | /*	SCCS Id: @(#)do_wear.c	3.3	2000/05/05	*/
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, taking_off = 0L;
14   | 
15   | static NEARDATA int todelay;
16   | 
17   | static NEARDATA const char see_yourself[] = "see yourself";
18   | static NEARDATA const char unknown_type[] = "Unknown type of %s (%d)";
19   | static NEARDATA const char *c_armor  = "armor",
20   | 			   *c_suit   = "suit",
21   | #ifdef TOURIST
22   | 			   *c_shirt  = "shirt",
23   | #endif
24   | 			   *c_cloak  = "cloak",
25   | 			   *c_gloves = "gloves",
26   | 			   *c_boots  = "boots",
27   | 			   *c_helmet = "helmet",
28   | 			   *c_shield = "shield",
29   | 			   *c_weapon = "weapon",
30   | 			   *c_sword  = "sword",
31   | 			   *c_axe    = "axe",
32   | 			   *c_that_  = "that";
33   | 
34   | static NEARDATA const long takeoff_order[] = { WORN_BLINDF, W_WEP,
35   | 	WORN_SHIELD, WORN_GLOVES, LEFT_RING, RIGHT_RING, WORN_CLOAK,
36   | 	WORN_HELMET, WORN_AMUL, WORN_ARMOR,
37   | #ifdef TOURIST
38   | 	WORN_SHIRT,
39   | #endif
40   | 	WORN_BOOTS, W_SWAPWEP, W_QUIVER, 0L };
41   | 
42   | STATIC_DCL void FDECL(on_msg, (struct obj *));
43   | STATIC_PTR int NDECL(Armor_on);
44   | STATIC_PTR int NDECL(Boots_on);
45   | STATIC_DCL int NDECL(Cloak_on);
46   | STATIC_PTR int NDECL(Helmet_on);
47   | STATIC_PTR int NDECL(Gloves_on);
48   | STATIC_DCL void NDECL(Amulet_on);
49   | STATIC_DCL void FDECL(Ring_off_or_gone, (struct obj *, BOOLEAN_P));
50   | STATIC_PTR int FDECL(select_off, (struct obj *));
51   | STATIC_DCL struct obj *NDECL(do_takeoff);
52   | STATIC_PTR int NDECL(take_off);
53   | STATIC_DCL int FDECL(menu_remarm, (int));
54   | STATIC_DCL void FDECL(already_wearing, (const char*));
55   | STATIC_DCL void FDECL(already_wearing2, (const char*, const char*));
56   | 
57   | void
58   | off_msg(otmp)
59   | register struct obj *otmp;
60   | {
61   | 	if(flags.verbose)
62   | 	    You("were wearing %s.", doname(otmp));
63   | }
64   | 
65   | /* for items that involve no delay */
66   | STATIC_OVL void
67   | on_msg(otmp)
68   | register struct obj *otmp;
69   | {
70   | 	if(flags.verbose)
71   | 	    You("are now wearing %s.",
72   | 		obj_is_pname(otmp) ? the(xname(otmp)) : an(xname(otmp)));
73   | }
74   | 
75   | /*
76   |  * The Type_on() functions should be called *after* setworn().
77   |  * The Type_off() functions call setworn() themselves.
78   |  */
79   | 
80   | STATIC_PTR
81   | int
82   | Boots_on()
83   | {
84   | 	long oldprop = u.uprops[objects[uarmf->otyp].oc_oprop].extrinsic & ~WORN_BOOTS;
85   | 
86   | 
87   |     switch(uarmf->otyp) {
88   | 	case LOW_BOOTS:
89   | 	case IRON_SHOES:
90   | 	case HIGH_BOOTS:
91   | 	case JUMPING_BOOTS:
92   | 	case KICKING_BOOTS:
93   | 		break;
94   | 	case WATER_WALKING_BOOTS:
95   | 		if (u.uinwater) spoteffects(TRUE);
96   | 		break;
97   | 	case SPEED_BOOTS:
98   | 		/* Speed boots are still better than intrinsic speed, */
99   | 		/* though not better than potion speed */
100  | 		if (!oldprop && !(HFast & TIMEOUT)) {
101  | 			makeknown(uarmf->otyp);
102  | 			You_feel("yourself speed up%s.",
103  | 				(oldprop || HFast) ? " a bit more" : "");
104  | 		}
105  | 		break;
106  | 	case ELVEN_BOOTS:
107  | 		if (!oldprop && !HStealth && !BStealth) {
108  | 			makeknown(uarmf->otyp);
109  | 			You("walk very quietly.");
110  | 		}
111  | 		break;
112  | 	case FUMBLE_BOOTS:
113  | 		if (!oldprop && !(HFumbling & ~TIMEOUT))
114  | 			incr_itimeout(&HFumbling, rnd(20));
115  | 		break;
116  | 	case LEVITATION_BOOTS:
117  | 		if (!oldprop && !HLevitation) {
118  | 			makeknown(uarmf->otyp);
119  | 			float_up();
120  | 		}
121  | 		break;
122  | 	default: impossible(unknown_type, c_boots, uarmf->otyp);
123  |     }
124  |     return 0;
125  | }
126  | 
127  | int
128  | Boots_off()
129  | {
130  |     int otyp = uarmf->otyp;
131  | 	long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_BOOTS;
132  | 
133  | 
134  | 	/* For levitation, float_down() returns if Levitation, so we
135  | 	 * must do a setworn() _before_ the levitation case.
136  | 	 */
137  |     setworn((struct obj *)0, W_ARMF);
138  |     switch (otyp) {
139  | 	case SPEED_BOOTS:
140  | 		if (!Very_fast) {
141  | 			makeknown(otyp);
142  | 			You_feel("yourself slow down%s.",
143  | 				Fast ? " a bit" : "");
144  | 		}
145  | 		break;
146  | 	case WATER_WALKING_BOOTS:
147  | 		if (is_pool(u.ux,u.uy) && !Levitation
148  | 			    && !Flying && !is_clinger(youmonst.data)) {
149  | 			makeknown(otyp);
150  | 			/* make boots known in case you survive the drowning */
151  | 			spoteffects(TRUE);
152  | 		}
153  | 		break;
154  | 	case ELVEN_BOOTS:
155  | 		if (!oldprop && !HStealth && !BStealth) {
156  | 			makeknown(otyp);
157  | 			You("sure are noisy.");
158  | 		}
159  | 		break;
160  | 	case FUMBLE_BOOTS:
161  | 		if (!oldprop && !(HFumbling & ~TIMEOUT))
162  | 			HFumbling = EFumbling = 0;
163  | 		break;
164  | 	case LEVITATION_BOOTS:
165  | 		if (!oldprop && !HLevitation) {
166  | 			(void) float_down(0L, 0L);
167  | 			makeknown(otyp);
168  | 		}
169  | 		break;
170  | 	case LOW_BOOTS:
171  | 	case IRON_SHOES:
172  | 	case HIGH_BOOTS:
173  | 	case JUMPING_BOOTS:
174  | 	case KICKING_BOOTS:
175  | 		break;
176  | 	default: impossible(unknown_type, c_boots, otyp);
177  |     }
178  |     return 0;
179  | }
180  | 
181  | STATIC_OVL int
182  | Cloak_on()
183  | {
184  |     long oldprop = u.uprops[objects[uarmc->otyp].oc_oprop].extrinsic & ~WORN_CLOAK;
185  | 
186  | 
187  |     switch(uarmc->otyp) {
188  | 	case ELVEN_CLOAK:
189  | 	case CLOAK_OF_PROTECTION:
190  | 	case CLOAK_OF_DISPLACEMENT:
191  | 		makeknown(uarmc->otyp);
192  | 		break;
193  | 	case ORCISH_CLOAK:
194  | 	case DWARVISH_CLOAK:
195  | 	case CLOAK_OF_MAGIC_RESISTANCE:
196  | 	case ROBE:
197  | 		break;
198  | 	case MUMMY_WRAPPING:
199  | 		/* Note: it's already being worn, so we have to cheat here. */
200  | 		if ((HInvis || EInvis || pm_invisible(youmonst.data)) && !Blind) {
201  | 		    newsym(u.ux,u.uy);
202  | 		    You("can %s!",
203  | 			See_invisible ? "no longer see through yourself"
204  | 			: see_yourself);
205  | 		}
206  | 		break;
207  | 	case CLOAK_OF_INVISIBILITY:
208  | 		/* since cloak of invisibility was worn, we know mummy wrapping
209  | 		   wasn't, so no need to check `oldprop' against blocked */
210  | 		if (!oldprop && !HInvis && !Blind) {
211  | 		    makeknown(uarmc->otyp);
212  | 		    newsym(u.ux,u.uy);
213  | 		    pline("Suddenly you can%s yourself.",
214  | 			See_invisible ? " see through" : "not see");
215  | 		}
216  | 		break;
217  | 	case OILSKIN_CLOAK:
218  | 		pline("%s fits very tightly.",The(xname(uarmc)));
219  | 		break;
220  | 	/* Alchemy smock gives poison _and_ acid resistance */
221  | 	case ALCHEMY_SMOCK:
222  | 		EAcid_resistance |= WORN_CLOAK;
223  |   		break;
224  | 	default: impossible(unknown_type, c_cloak, uarmc->otyp);
225  |     }
226  |     return 0;
227  | }
228  | 
229  | int
230  | Cloak_off()
231  | {
232  |     int otyp = uarmc->otyp;
233  |     long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_CLOAK;
234  | 
235  | 
236  | 	/* For mummy wrapping, taking it off first resets `Invisible'. */
237  |     setworn((struct obj *)0, W_ARMC);
238  |     switch (otyp) {
239  | 	case ELVEN_CLOAK:
240  | 	case ORCISH_CLOAK:
241  | 	case DWARVISH_CLOAK:
242  | 	case CLOAK_OF_PROTECTION:
243  | 	case CLOAK_OF_MAGIC_RESISTANCE:
244  | 	case CLOAK_OF_DISPLACEMENT:
245  | 	case OILSKIN_CLOAK:
246  | 	case ROBE:
247  | 		break;
248  | 	case MUMMY_WRAPPING:
249  | 		if (Invis && !Blind) {
250  | 		    newsym(u.ux,u.uy);
251  | 		    You("can %s.",
252  | 			See_invisible ? "see through yourself"
253  | 			: "no longer see yourself");
254  | 		}
255  | 		break;
256  | 	case CLOAK_OF_INVISIBILITY:
257  | 		if (!oldprop && !HInvis && !Blind) {
258  | 		    makeknown(CLOAK_OF_INVISIBILITY);
259  | 		    newsym(u.ux,u.uy);
260  | 		    pline("Suddenly you can %s.",
261  | 			See_invisible ? "no longer see through yourself"
262  | 			: see_yourself);
263  | 		}
264  | 		break;
265  | 	/* Alchemy smock gives poison _and_ acid resistance */
266  | 	case ALCHEMY_SMOCK:
267  | 		EAcid_resistance &= ~WORN_CLOAK;
268  |   		break;
269  | 	default: impossible(unknown_type, c_cloak, otyp);
270  |     }
271  |     return 0;
272  | }
273  | 
274  | STATIC_PTR
275  | int
276  | Helmet_on()
277  | {
278  |     switch(uarmh->otyp) {
279  | 	case FEDORA:
280  | 	case HELMET:
281  | 	case DENTED_POT:
282  | 	case ELVEN_LEATHER_HELM:
283  | 	case DWARVISH_IRON_HELM:
284  | 	case ORCISH_HELM:
285  | 	case HELM_OF_TELEPATHY:
286  | 		break;
287  | 	case HELM_OF_BRILLIANCE:
288  | 		adj_abon(uarmh, uarmh->spe);
289  | 		break;
290  | 	case CORNUTHAUM:
291  | 		/* people think marked wizards know what they're talking
292  | 		 * about, but it takes trained arrogance to pull it off,
293  | 		 * and the actual enchantment of the hat is irrelevant.
294  | 		 */
295  | 		ABON(A_CHA) += (Role_if(PM_WIZARD) ? 1 : -1);
296  | 		flags.botl = 1;
297  | 		makeknown(uarmh->otyp);
298  | 		break;
299  | 	case HELM_OF_OPPOSITE_ALIGNMENT:
300  | 		if (u.ualign.type == A_NEUTRAL)
301  | 		    u.ualign.type = rn2(2) ? A_CHAOTIC : A_LAWFUL;
302  | 		else u.ualign.type = -(u.ualign.type);
303  | 		u.ublessed = 0; /* lose your god's protection */
304  | 	     /* makeknown(uarmh->otyp);   -- moved below, after xname() */
305  | 		/*FALLTHRU*/
306  | 	case DUNCE_CAP:
307  | 		if (!uarmh->cursed) {
308  | 		    pline("%s %s%s for a moment.", The(xname(uarmh)),
309  | 			  Blind ? "vibrates" : "glows ",
310  | 			  Blind ? (const char *)"" : hcolor(Black));
311  | 		    curse(uarmh);
312  | 		}
313  | 		flags.botl = 1;		/* reveal new alignment or INT & WIS */
314  | 		if (Hallucination) {
315  | 		    pline("My brain hurts!"); /* Monty Python's Flying Circus */
316  | 		} else if (uarmh->otyp == DUNCE_CAP) {
317  | 		    You_feel("%s.",	/* track INT change; ignore WIS */
318  | 		  ACURR(A_INT) <= (ABASE(A_INT) + ABON(A_INT) + ATEMP(A_INT)) ?
319  | 			     "like sitting in a corner" : "giddy");
320  | 		} else {
321  | 		    Your("mind oscillates briefly.");
322  | 		    makeknown(HELM_OF_OPPOSITE_ALIGNMENT);
323  | 		}
324  | 		break;
325  | 	default: impossible(unknown_type, c_helmet, uarmh->otyp);
326  |     }
327  |     return 0;
328  | }
329  | 
330  | int
331  | Helmet_off()
332  | {
333  |     switch(uarmh->otyp) {
334  | 	case FEDORA:
335  | 	case HELMET:
336  | 	case DENTED_POT:
337  | 	case ELVEN_LEATHER_HELM:
338  | 	case DWARVISH_IRON_HELM:
339  | 	case ORCISH_HELM:
340  | 		break;
341  | 	case DUNCE_CAP:
342  | 		flags.botl = 1;
343  | 		break;
344  | 	case CORNUTHAUM:
345  | 		ABON(A_CHA) += (Role_if(PM_WIZARD) ? -1 : 1);
346  | 		flags.botl = 1;
347  | 		break;
348  | 	case HELM_OF_TELEPATHY:
349  | 		/* need to update ability before calling see_monsters() */
350  | 		setworn((struct obj *)0, W_ARMH);
351  | 		see_monsters();
352  | 		return 0;
353  | 	case HELM_OF_BRILLIANCE:
354  | 		adj_abon(uarmh, -uarmh->spe);
355  | 		break;
356  | 	case HELM_OF_OPPOSITE_ALIGNMENT:
357  | 		u.ualign.type = u.ualignbase[A_CURRENT];
358  | 		u.ublessed = 0; /* lose the other god's protection */
359  | 		flags.botl = 1;
360  | 		break;
361  | 	default: impossible(unknown_type, c_helmet, uarmh->otyp);
362  |     }
363  |     setworn((struct obj *)0, W_ARMH);
364  |     return 0;
365  | }
366  | 
367  | STATIC_PTR
368  | int
369  | Gloves_on()
370  | {
371  |     long oldprop =
372  | 		u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
373  | 
374  | 
375  |     switch(uarmg->otyp) {
376  | 	case LEATHER_GLOVES:
377  | 		break;
378  | 	case GAUNTLETS_OF_FUMBLING:
379  | 		if (!oldprop && !(HFumbling & ~TIMEOUT))
380  | 			incr_itimeout(&HFumbling, rnd(20));
381  | 		break;
382  | 	case GAUNTLETS_OF_POWER:
383  | 		makeknown(uarmg->otyp);
384  | 		flags.botl = 1; /* taken care of in attrib.c */
385  | 		break;
386  | 	case GAUNTLETS_OF_DEXTERITY:
387  | 		adj_abon(uarmg, uarmg->spe);
388  | 		break;
389  | 	default: impossible(unknown_type, c_gloves, uarmg->otyp);
390  |     }
391  |     return 0;
392  | }
393  | 
394  | int
395  | Gloves_off()
396  | {
397  |     long oldprop =
398  | 		u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
399  | 
400  | 
401  |     switch(uarmg->otyp) {
402  | 	case LEATHER_GLOVES:
403  | 		break;
404  | 	case GAUNTLETS_OF_FUMBLING:
405  | 		if (!oldprop && !(HFumbling & ~TIMEOUT))
406  | 			HFumbling = EFumbling = 0;
407  | 		break;
408  | 	case GAUNTLETS_OF_POWER:
409  | 		makeknown(uarmg->otyp);
410  | 		flags.botl = 1; /* taken care of in attrib.c */
411  | 		break;
412  | 	case GAUNTLETS_OF_DEXTERITY:
413  | 		adj_abon(uarmg, -uarmg->spe);
414  | 		break;
415  | 	default: impossible(unknown_type, c_gloves, uarmg->otyp);
416  |     }
417  |     setworn((struct obj *)0, W_ARMG);
418  | 
419  |     /* Prevent wielding cockatrice when not wearing gloves */
420  |     if (uwep && uwep->otyp == CORPSE &&
421  | 		touch_petrifies(&mons[uwep->corpsenm])) {
422  | 	char kbuf[BUFSZ];
423  | 
424  | 	You("wield the %s corpse in your bare %s.",
425  | 	    mons[uwep->corpsenm].mname, makeplural(body_part(HAND)));
426  | 	Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
427  | 	instapetrify(kbuf);
428  | 	uwepgone();  /* life-saved still doesn't allow touching cockatrice */
429  |     }
430  | 	/* KMH -- ...or your secondary weapon when you're wielding it */
431  | 	if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE &&
432  | 			touch_petrifies(&mons[uswapwep->corpsenm])) {
433  | 	char kbuf[BUFSZ];
434  | 
435  | 	You("wield the %s corpse in your bare %s.",
436  | 		mons[uswapwep->corpsenm].mname, body_part(HAND));
437  | 
438  | 	Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
439  | 	instapetrify(kbuf);
440  | 	uswapwepgone();  /* life-saved still doesn't allow touching cockatrice */
441  | 	}
442  | 
443  |     return 0;
444  | }
445  | 
446  | /*
447  | STATIC_OVL int
448  | Shield_on()
449  | {
450  |     switch(uarms->otyp) {
451  | 	case SMALL_SHIELD:
452  | 	case ELVEN_SHIELD:
453  | 	case URUK_HAI_SHIELD:
454  | 	case ORCISH_SHIELD:
455  | 	case DWARVISH_ROUNDSHIELD:
456  | 	case LARGE_SHIELD:
457  | 	case SHIELD_OF_REFLECTION:
458  | 		break;
459  | 	default: impossible(unknown_type, c_shield, uarms->otyp);
460  |     }
461  |     return 0;
462  | }
463  | */
464  | 
465  | int
466  | Shield_off()
467  | {
468  | /*
469  |     switch(uarms->otyp) {
470  | 	case SMALL_SHIELD:
471  | 	case ELVEN_SHIELD:
472  | 	case URUK_HAI_SHIELD:
473  | 	case ORCISH_SHIELD:
474  | 	case DWARVISH_ROUNDSHIELD:
475  | 	case LARGE_SHIELD:
476  | 	case SHIELD_OF_REFLECTION:
477  | 		break;
478  | 	default: impossible(unknown_type, c_shield, uarms->otyp);
479  |     }
480  | */
481  |     setworn((struct obj *)0, W_ARMS);
482  |     return 0;
483  | }
484  | 
485  | /* This must be done in worn.c, because one of the possible intrinsics conferred
486  |  * is fire resistance, and we have to immediately set HFire_resistance in worn.c
487  |  * since worn.c will check it before returning.
488  |  */
489  | STATIC_PTR
490  | int
491  | Armor_on()
492  | {
493  |     return 0;
494  | }
495  | 
496  | int
497  | Armor_off()
498  | {
499  |     setworn((struct obj *)0, W_ARM);
500  |     return 0;
501  | }
502  | 
503  | /* The gone functions differ from the off functions in that if you die from
504  |  * taking it off and have life saving, you still die.
505  |  */
506  | int
507  | Armor_gone()
508  | {
509  |     setnotworn(uarm);
510  |     return 0;
511  | }
512  | 
513  | STATIC_OVL void
514  | Amulet_on()
515  | {
516  |     switch(uamul->otyp) {
517  | 	case AMULET_OF_ESP:
518  | 	case AMULET_OF_LIFE_SAVING:
519  | 	case AMULET_VERSUS_POISON:
520  | 	case AMULET_OF_REFLECTION:
521  | 	case AMULET_OF_MAGICAL_BREATHING:
522  | 	case FAKE_AMULET_OF_YENDOR:
523  | 		break;
524  | 	case AMULET_OF_UNCHANGING:
525  | 		if (Slimed) {
526  | 		    Slimed = 0;
527  | 		    flags.botl = 1;
528  | 		}
529  | 		break;
530  | 	case AMULET_OF_CHANGE:
531  | 	    {
532  | 		int orig_sex = poly_gender();
533  | 
534  | 		if (Unchanging) break;
535  | 		change_sex();
536  | 		/* Don't use same message as polymorph */
537  | 		if (orig_sex != poly_gender()) {
538  | 		    makeknown(AMULET_OF_CHANGE);
539  | 		    You("are suddenly very %s!", flags.female ? "feminine"
540  | 			: "masculine");
541  | 		    flags.botl = 1;
542  | 		} else
543  | 		    /* already polymorphed into single-gender monster; only
544  | 		       changed the character's base sex */
545  | 		    You("don't feel like yourself.");
546  | 		pline_The("amulet disintegrates!");
547  | 		useup(uamul);
548  | 		break;
549  | 	    }
550  | 	case AMULET_OF_STRANGULATION:
551  | 		makeknown(AMULET_OF_STRANGULATION);
552  | 		pline("It constricts your throat!");
553  | 		Strangled = 6;
554  | 		break;
555  | 	case AMULET_OF_RESTFUL_SLEEP:
556  | 		HSleeping = rnd(100);
557  | 		break;
558  | 	case AMULET_OF_YENDOR:
559  | 		break;
560  |     }
561  | }
562  | 
563  | void
564  | Amulet_off()
565  | {
566  |     switch(uamul->otyp) {
567  | 	case AMULET_OF_ESP:
568  | 		/* need to update ability before calling see_monsters() */
569  | 		setworn((struct obj *)0, W_AMUL);
570  | 		see_monsters();
571  | 		return;
572  | 	case AMULET_OF_LIFE_SAVING:
573  | 	case AMULET_VERSUS_POISON:
574  | 	case AMULET_OF_REFLECTION:
575  | 	case AMULET_OF_CHANGE:
576  | 	case AMULET_OF_UNCHANGING:
577  | 	case FAKE_AMULET_OF_YENDOR:
578  | 		break;
579  | 	case AMULET_OF_MAGICAL_BREATHING:
580  | 		if (Underwater) {
581  | 		    if (!breathless(youmonst.data) && !amphibious(youmonst.data)
582  | 						&& !Swimming)
583  | 			You("suddenly inhale an unhealthy amount of water!");
584  | 		    /* HMagical_breathing must be set off
585  | 		       before calling drown() */
586  | 		    setworn((struct obj *)0, W_AMUL);
587  | 		    (void) drown();
588  | 		    return;
589  | 		}
590  | 		break;
591  | 	case AMULET_OF_STRANGULATION:
592  | 		if (Strangled) {
593  | 			You("can breathe more easily!");
594  | 			Strangled = 0;
595  | 		}
596  | 		break;
597  | 	case AMULET_OF_RESTFUL_SLEEP:
598  | 		setworn((struct obj *)0, W_AMUL);
599  | 		if (!ESleeping)
600  | 			HSleeping = 0;
601  | 		return;
602  | 	case AMULET_OF_YENDOR:
603  | 		break;
604  |     }
605  |     setworn((struct obj *)0, W_AMUL);
606  |     return;
607  | }
608  | 
609  | void
610  | Ring_on(obj)
611  | register struct obj *obj;
612  | {
613  |     long oldprop = u.uprops[objects[obj->otyp].oc_oprop].extrinsic;
614  |     int old_attrib;
615  | 
616  | 
617  | 	if (obj == uwep) setuwep((struct obj *) 0);
618  | 	if (obj == uswapwep) setuswapwep((struct obj *) 0);
619  | 	if (obj == uquiver) setuqwep((struct obj *) 0);
620  | 
621  |     /* only mask out W_RING when we don't have both
622  |        left and right rings of the same type */
623  |     if ((oldprop & W_RING) != W_RING) oldprop &= ~W_RING;
624  | 
625  |     switch(obj->otyp){
626  | 	case RIN_TELEPORTATION:
627  | 	case RIN_REGENERATION:
628  | 	case RIN_SEARCHING:
629  | 	case RIN_STEALTH:
630  | 	case RIN_HUNGER:
631  | 	case RIN_AGGRAVATE_MONSTER:
632  | 	case RIN_POISON_RESISTANCE:
633  | 	case RIN_FIRE_RESISTANCE:
634  | 	case RIN_COLD_RESISTANCE:
635  | 	case RIN_SHOCK_RESISTANCE:
636  | 	case RIN_CONFLICT:
637  | 	case RIN_TELEPORT_CONTROL:
638  | 	case RIN_POLYMORPH:
639  | 	case RIN_POLYMORPH_CONTROL:
640  | 	case RIN_FREE_ACTION:                
641  | 	case RIN_SLOW_DIGESTION:
642  | 	case RIN_SUSTAIN_ABILITY:
643  | 	case MEAT_RING:
644  | 		break;
645  | 	case RIN_WARNING:
646  | 		see_monsters();
647  | 		break;
648  | 	case RIN_SEE_INVISIBLE:
649  | 		/* can now see invisible monsters */
650  | 		set_mimic_blocking(); /* do special mimic handling */
651  | 		see_monsters();
652  | #ifdef INVISIBLE_OBJECTS
653  | 		see_objects();
654  | #endif
655  | 
656  | 		if (Invis && !oldprop && !HSee_invisible &&
657  | 				!perceives(youmonst.data) && !Blind) {
658  | 		    newsym(u.ux,u.uy);
659  | 		    pline("Suddenly you are transparent, but there!");
660  | 		    makeknown(RIN_SEE_INVISIBLE);
661  | 		}
662  | 		break;
663  | 	case RIN_INVISIBILITY:
664  | 		if (!oldprop && !HInvis && !BInvis && !Blind) {
665  | 		    makeknown(RIN_INVISIBILITY);
666  | 		    newsym(u.ux,u.uy);
667  | 		    self_invis_message();
668  | 		}
669  | 		break;
670  | 	case RIN_ADORNMENT:
671  | 		old_attrib = ACURR(A_CHA);
672  | 		ABON(A_CHA) += obj->spe;
673  | 		flags.botl = 1;
674  | 		if (ACURR(A_CHA) != old_attrib ||
675  | 		    (objects[RIN_ADORNMENT].oc_name_known &&
676  | 		     old_attrib != 25 && old_attrib != 3)) {
677  | 			makeknown(RIN_ADORNMENT);
678  | 			obj->known = TRUE;
679  | 		}
680  | 		break;
681  | 	case RIN_LEVITATION:
682  | 		if(!oldprop && !HLevitation) {
683  | 			float_up();
684  | 			makeknown(RIN_LEVITATION);
685  | 			obj->known = TRUE;
686  | 		}
687  | 		break;
688  | 	case RIN_GAIN_STRENGTH:
689  | 		old_attrib = ACURR(A_STR);
690  | 		ABON(A_STR) += obj->spe;
691  | 		flags.botl = 1;
692  | 		if (ACURR(A_STR) != old_attrib ||
693  | 		    (objects[RIN_GAIN_STRENGTH].oc_name_known &&
694  | 		     old_attrib != STR19(25) && old_attrib != 3)) {
695  | 			makeknown(RIN_GAIN_STRENGTH);
696  | 			obj->known = TRUE;
697  | 		}
698  | 		break;
699  | 	case RIN_GAIN_CONSTITUTION:
700  | 		old_attrib = ACURR(A_CON);
701  | 		ABON(A_CON) += obj->spe;
702  | 		flags.botl = 1;
703  | 		if (ACURR(A_CON) != old_attrib ||
704  | 		    objects[RIN_GAIN_CONSTITUTION].oc_name_known) {
705  | 			makeknown(RIN_GAIN_CONSTITUTION);
706  | 			obj->known = TRUE;
707  | 		}
708  | 		break;
709  | 	case RIN_INCREASE_ACCURACY:	/* KMH */
710  | 		u.uhitinc += obj->spe;
711  | 		break;
712  | 	case RIN_INCREASE_DAMAGE:
713  | 		u.udaminc += obj->spe;
714  | 		break;
715  | 	case RIN_PROTECTION_FROM_SHAPE_CHAN:
716  | 		rescham();
717  | 		break;
718  | 	case RIN_PROTECTION:
719  | 		flags.botl = 1;
720  | 		if (obj->spe || objects[RIN_PROTECTION].oc_name_known) {
721  | 			makeknown(RIN_PROTECTION);
722  | 			obj->known = TRUE;
723  | 		}
724  | 		break;
725  |     }
726  | }
727  | 
728  | STATIC_OVL void
729  | Ring_off_or_gone(obj,gone)
730  | register struct obj *obj;
731  | boolean gone;
732  | {
733  |     register long mask = obj->owornmask & W_RING;
734  |     int old_attrib;
735  | 
736  |     if(!(u.uprops[objects[obj->otyp].oc_oprop].extrinsic & mask))
737  | 	impossible("Strange... I didn't know you had that ring.");
738  |     if(gone) setnotworn(obj);
739  |     else setworn((struct obj *)0, obj->owornmask);
740  |     switch(obj->otyp) {
741  | 	case RIN_TELEPORTATION:
742  | 	case RIN_REGENERATION:
743  | 	case RIN_SEARCHING:
744  | 	case RIN_STEALTH:
745  | 	case RIN_HUNGER:
746  | 	case RIN_AGGRAVATE_MONSTER:
747  | 	case RIN_POISON_RESISTANCE:
748  | 	case RIN_FIRE_RESISTANCE:
749  | 	case RIN_COLD_RESISTANCE:
750  | 	case RIN_SHOCK_RESISTANCE:
751  | 	case RIN_CONFLICT:
752  | 	case RIN_TELEPORT_CONTROL:
753  | 	case RIN_POLYMORPH:
754  | 	case RIN_POLYMORPH_CONTROL:
755  | 	case RIN_FREE_ACTION:                
756  | 	case RIN_SLOW_DIGESTION:
757  | 	case RIN_SUSTAIN_ABILITY:
758  | 	case MEAT_RING:
759  | 		break;
760  | 	case RIN_WARNING:
761  | 		see_monsters();
762  | 		break;
763  | 	case RIN_SEE_INVISIBLE:
764  | 		/* Make invisible monsters go away */
765  | 		if (!See_invisible) {
766  | 		    set_mimic_blocking(); /* do special mimic handling */
767  | 		    see_monsters();
768  | #ifdef INVISIBLE_OBJECTS                
769  | 		    see_objects();
770  | #endif
771  | 		}
772  | 
773  | 		if (Invisible && !Blind) {
774  | 			newsym(u.ux,u.uy);
775  | 			pline("Suddenly you cannot see yourself.");
776  | 			makeknown(RIN_SEE_INVISIBLE);
777  | 		}
778  | 		break;
779  | 	case RIN_INVISIBILITY:
780  | 		if (!Invis && !BInvis && !Blind) {
781  | 			newsym(u.ux,u.uy);
782  | 			Your("body seems to unfade%s.",
783  | 			    See_invisible ? " completely" : "..");
784  | 			makeknown(RIN_INVISIBILITY);
785  | 		}
786  | 		break;
787  | 	case RIN_ADORNMENT:
788  | 		old_attrib = ACURR(A_CHA);
789  | 		ABON(A_CHA) -= obj->spe;
790  | 		if (ACURR(A_CHA) != old_attrib) makeknown(RIN_ADORNMENT);
791  | 		flags.botl = 1;
792  | 		break;
793  | 	case RIN_LEVITATION:
794  | 		(void) float_down(0L, 0L);
795  | 		if (!Levitation) makeknown(RIN_LEVITATION);
796  | 		break;
797  | 	case RIN_GAIN_STRENGTH:
798  | 		old_attrib = ACURR(A_STR);
799  | 		ABON(A_STR) -= obj->spe;
800  | 		if (ACURR(A_STR) != old_attrib) makeknown(RIN_GAIN_STRENGTH);
801  | 		flags.botl = 1;
802  | 		break;
803  | 	case RIN_GAIN_CONSTITUTION:
804  | 		old_attrib = ACURR(A_CON);
805  | 		ABON(A_CON) -= obj->spe;
806  | 		flags.botl = 1;
807  | 		if (ACURR(A_CON) != old_attrib) makeknown(RIN_GAIN_CONSTITUTION);
808  | 		break;
809  | 	case RIN_INCREASE_ACCURACY:	/* KMH */
810  | 		u.uhitinc -= obj->spe;
811  | 		break;
812  | 	case RIN_INCREASE_DAMAGE:
813  | 		u.udaminc -= obj->spe;
814  | 		break;
815  | 	case RIN_PROTECTION_FROM_SHAPE_CHAN:
816  | 		/* If you're no longer protected, let the chameleons
817  | 		 * change shape again -dgk
818  | 		 */
819  | 		restartcham();
820  | 		break;
821  |     }
822  | }
823  | 
824  | void
825  | Ring_off(obj)
826  | struct obj *obj;
827  | {
828  | 	Ring_off_or_gone(obj,FALSE);
829  | }
830  | 
831  | void
832  | Ring_gone(obj)
833  | struct obj *obj;
834  | {
835  | 	Ring_off_or_gone(obj,TRUE);
836  | }
837  | 
838  | void
839  | Blindf_on(otmp)
840  | register struct obj *otmp;
841  | {
842  | 	long already_blinded = Blinded;
843  | 
844  | 	if (otmp == uwep)
845  | 	    setuwep((struct obj *) 0);
846  | 	if (otmp == uswapwep)
847  | 		setuswapwep((struct obj *) 0);
848  | 	if (otmp == uquiver)
849  | 		setuqwep((struct obj *) 0);
850  | 	setworn(otmp, W_TOOL);
851  | 	if (otmp->otyp == TOWEL && flags.verbose)
852  | 	    You("wrap %s around your %s.", an(xname(otmp)), body_part(HEAD));
853  | 	on_msg(otmp);
854  | 	if (!already_blinded) {
855  | 	    if (Punished) set_bc(0);	/* Set ball&chain variables before */
856  | 					/* the hero goes blind.		   */
857  | 	    if (Blind_telepat || Infravision) see_monsters(); /* sense monsters */
858  | 	    vision_full_recalc = 1;	/* recalc vision limits */
859  | 	    flags.botl = 1;
860  | 	}
861  | }
862  | 
863  | void
864  | Blindf_off(otmp)
865  | register struct obj *otmp;
866  | {
867  | 	long was_blind = Blind;	/* may still be able to see */
868  | 
869  | 	setworn((struct obj *)0, otmp->owornmask);
870  | 	off_msg(otmp);
871  | 
872  | 	if (Blind) {
873  | 	    if (otmp->otyp == LENSES)
874  | 		; /* "still cannot see" makes no sense for lenses; do nothing */
875  | 	    else if (was_blind)
876  | 		You("still cannot see.");
877  | 	    else
878  | 		You("cannot see anything now!");
879  | 	} else if (!Blinded) {
880  | 	    if (Blind_telepat || Infravision) see_monsters();
881  | 	}
882  | 	vision_full_recalc = 1;	/* recalc vision limits */
883  | 	flags.botl = 1;
884  | }
885  | 
886  | /* called in main to set intrinsics of worn start-up items */
887  | void
888  | set_wear()
889  | {
890  | 	if (uarm)  (void) Armor_on();
891  | 	if (uarmc) (void) Cloak_on();
892  | 	if (uarmf) (void) Boots_on();
893  | 	if (uarmg) (void) Gloves_on();
894  | 	if (uarmh) (void) Helmet_on();
895  | /*	if (uarms) (void) Shield_on(); */
896  | }
897  | 
898  | boolean
899  | donning(otmp)
900  | register struct obj *otmp;
901  | {
902  |     return((boolean)((otmp == uarmf && (afternmv == Boots_on || afternmv == Boots_off))
903  | 	|| (otmp == uarmh && (afternmv == Helmet_on || afternmv == Helmet_off))
904  | 	|| (otmp == uarmg && (afternmv == Gloves_on || afternmv == Gloves_off))
905  | 	|| (otmp == uarm && (afternmv == Armor_on || afternmv == Armor_off))));
906  | }
907  | 
908  | void
909  | cancel_don()
910  | {
911  | 	/* the piece of armor we were donning/doffing has vanished, so stop
912  | 	 * wasting time on it (and don't dereference it when donning would
913  | 	 * otherwise finish)
914  | 	 */
915  | 	afternmv = 0;
916  | 	nomovemsg = (char *)0;
917  | 	multi = 0;
918  | }
919  | 
920  | static NEARDATA const char clothes[] = {ARMOR_CLASS, 0};
921  | static NEARDATA const char accessories[] = {RING_CLASS, AMULET_CLASS, TOOL_CLASS, FOOD_CLASS, 0};
922  | 
923  | int
924  | dotakeoff()
925  | {
926  | 	register struct obj *otmp = (struct obj *)0;
927  | 	int armorpieces = 0;
928  | 
929  | #define MOREARM(x) if (x) { armorpieces++; otmp = x; }
930  | 	MOREARM(uarmh);
931  | 	MOREARM(uarms);
932  | 	MOREARM(uarmg);
933  | 	MOREARM(uarmf);
934  | 	if (uarmc) {
935  | 		armorpieces++;
936  | 		otmp = uarmc;
937  | 	} else if (uarm) {
938  | 		armorpieces++;
939  | 		otmp = uarm;
940  | #ifdef TOURIST
941  | 	} else if (uarmu) {
942  | 		armorpieces++;
943  | 		otmp = uarmu;
944  | #endif
945  | 	}
946  | 	if (!armorpieces) {
947  | 	     /* assert( GRAY_DRAGON_SCALES > YELLOW_DRAGON_SCALE_MAIL ); */
948  | 		if (uskin)
949  | 		    pline_The("%s merged with your skin!",
950  | 			      uskin->otyp >= GRAY_DRAGON_SCALES ?
951  | 				"dragon scales are" : "dragon scale mail is");
952  | 		else
953  | 		    pline("Not wearing any armor.");
954  | 		return 0;
955  | 	}
956  | 	if (armorpieces > 1)
957  | 		otmp = getobj(clothes, "take off");
958  | 	if (otmp == 0) return(0);
959  | 	if (!(otmp->owornmask & W_ARMOR)) {
960  | 		You("are not wearing that.");
961  | 		return(0);
962  | 	}
963  | 	/* note: the `uskin' case shouldn't be able to happen here; dragons
964  | 	   can't wear any armor so will end up with `armorpieces == 0' above */
965  | 	if (otmp == uskin || ((otmp == uarm) && uarmc)
966  | #ifdef TOURIST
967  | 			  || ((otmp == uarmu) && (uarmc || uarm))
968  | #endif
969  | 		) {
970  | 	    You_cant("take that off.");
971  | 	    return 0;
972  | 	}
973  | 	if (otmp == uarmg && welded(uwep)) {
974  | 	    You("seem unable to take off the gloves while holding your %s.",
975  | 		is_sword(uwep) ? c_sword : c_weapon);
976  | 	    uwep->bknown = TRUE;
977  | 	    return 0;
978  | 	}
979  | 	if (otmp == uarmg && Glib) {
980  | 	    You_cant("remove the slippery gloves with your slippery fingers.");
981  | 	    return 0;
982  | 	}
983  | 	if (otmp == uarmf && u.utrap && (u.utraptype == TT_BEARTRAP ||
984  | 					u.utraptype == TT_INFLOOR)) { /* -3. */
985  | 	    if(u.utraptype == TT_BEARTRAP)
986  | 		pline_The("bear trap prevents you from pulling your %s out.",
987  | 		      body_part(FOOT));
988  | 	    else
989  | 		You("are stuck in the %s, and cannot pull your %s out.",
990  | 		    surface(u.ux, u.uy), makeplural(body_part(FOOT)));
991  | 		return(0);
992  | 	}
993  | 	reset_remarm();			/* since you may change ordering */
994  | 	(void) armoroff(otmp);
995  | 	return(1);
996  | }
997  | 
998  | int
999  | doremring()
1000 | {
1001 | 	register struct obj *otmp = 0;
1002 | 	int Accessories = 0;
1003 | 
1004 | #define MOREACC(x) if (x) { Accessories++; otmp = x; }
1005 | 	MOREACC(uleft);
1006 | 	MOREACC(uright);
1007 | 	MOREACC(uamul);
1008 | 	MOREACC(ublindf);
1009 | 
1010 | 	if(!Accessories) {
1011 | 		pline("Not wearing any accessories.");
1012 | 		return(0);
1013 | 	}
1014 | 	if (Accessories != 1) otmp = getobj(accessories, "take off");
1015 | 	if(!otmp) return(0);
1016 | 	if(!(otmp->owornmask & (W_RING | W_AMUL | W_TOOL))) {
1017 | 		You("are not wearing that.");
1018 | 		return(0);
1019 | 	}
1020 | 	if(cursed(otmp)) return(0);
1021 | 	if(otmp->oclass == RING_CLASS || otmp->otyp == MEAT_RING) {
1022 | 		if (nolimbs(youmonst.data)) {
1023 | 			pline("It seems to be stuck.");
1024 | 			return(0);
1025 | 		}
1026 | 		if (uarmg && uarmg->cursed) {
1027 | 			uarmg->bknown = TRUE;
1028 | 			You(
1029 | 	    "seem unable to remove your ring without taking off your gloves.");
1030 | 			return(0);
1031 | 		}
1032 | 		if (welded(uwep) && bimanual(uwep)) {
1033 | 			uwep->bknown = TRUE;
1034 | 			You(
1035 | 	       "seem unable to remove the ring while your hands hold your %s.",
1036 | 			    is_sword(uwep) ? c_sword : c_weapon);
1037 | 			return(0);
1038 | 		}
1039 | 		if (welded(uwep) && otmp==uright) {
1040 | 			uwep->bknown = TRUE;
1041 | 			You(
1042 | 	 "seem unable to remove the ring while your right hand holds your %s.",
1043 | 			    is_sword(uwep) ? c_sword : c_weapon);
1044 | 			return(0);
1045 | 		}
1046 | 		/* Sometimes we want to give the off_msg before removing and
1047 | 		 * sometimes after; for instance, "you were wearing a moonstone
1048 | 		 * ring (on right hand)" is desired but "you were wearing a
1049 | 		 * square amulet (being worn)" is not because of the redundant
1050 | 		 * "being worn".
1051 | 		 */
1052 | 		off_msg(otmp);
1053 | 		Ring_off(otmp);
1054 | 	} else if(otmp->oclass == AMULET_CLASS) {
1055 | 		Amulet_off();
1056 | 		off_msg(otmp);
1057 | 	} else Blindf_off(otmp); /* does its own off_msg */
1058 | 	return(1);
1059 | }
1060 | 
1061 | /* Check if something worn is cursed _and_ unremovable. */
1062 | int
1063 | cursed(otmp)
1064 | register struct obj *otmp;
1065 | {
1066 | 	/* Curses, like chickens, come home to roost. */
1067 | 	if((otmp == uwep) ? welded(otmp) : (int)otmp->cursed) {
1068 | 		You("can't.  %s to be cursed.",
1069 | 			(is_boots(otmp) || is_gloves(otmp) || otmp->quan > 1L)
1070 | 			? "They seem" : "It seems");
1071 | 		otmp->bknown = TRUE;
1072 | 		return(1);
1073 | 	}
1074 | 	return(0);
1075 | }
1076 | 
1077 | int
1078 | armoroff(otmp)
1079 | register struct obj *otmp;
1080 | {
1081 | 	register int delay = -objects[otmp->otyp].oc_delay;
1082 | 
1083 | 	if(cursed(otmp)) return(0);
1084 | 	if(delay) {
1085 | 		nomul(delay);
1086 | 		if (is_helmet(otmp)) {
1087 | 			nomovemsg = "You finish taking off your helmet.";
1088 | 			afternmv = Helmet_off;
1089 | 		     }
1090 | 		else if (is_gloves(otmp)) {
1091 | 			nomovemsg = "You finish taking off your gloves.";
1092 | 			afternmv = Gloves_off;
1093 | 		     }
1094 | 		else if (is_boots(otmp)) {
1095 | 			nomovemsg = "You finish taking off your boots.";
1096 | 			afternmv = Boots_off;
1097 | 		     }
1098 | 		else {
1099 | 			nomovemsg = "You finish taking off your suit.";
1100 | 			afternmv = Armor_off;
1101 | 		}
1102 | 	} else {
1103 | 		/* Be warned!  We want off_msg after removing the item to
1104 | 		 * avoid "You were wearing ____ (being worn)."  However, an
1105 | 		 * item which grants fire resistance might cause some trouble
1106 | 		 * if removed in Hell and lifesaving puts it back on; in this
1107 | 		 * case the message will be printed at the wrong time (after
1108 | 		 * the messages saying you died and were lifesaved).  Luckily,
1109 | 		 * no cloak, shield, or fast-removable armor grants fire
1110 | 		 * resistance, so we can safely do the off_msg afterwards.
1111 | 		 * Rings do grant fire resistance, but for rings we want the
1112 | 		 * off_msg before removal anyway so there's no problem.  Take
1113 | 		 * care in adding armors granting fire resistance; this code
1114 | 		 * might need modification.
1115 | 		 * 3.2 (actually 3.1 even): this comment is obsolete since
1116 | 		 * fire resistance is not needed for Gehennom.
1117 | 		 */
1118 | 		if(is_cloak(otmp))
1119 | 			(void) Cloak_off();
1120 | 		else if(is_shield(otmp))
1121 | 			(void) Shield_off();
1122 | 		else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
1123 | 		off_msg(otmp);
1124 | 	}
1125 | 	takeoff_mask = taking_off = 0L;
1126 | 	return(1);
1127 | }
1128 | 
1129 | STATIC_OVL void
1130 | already_wearing(cc)
1131 | const char *cc;
1132 | {
1133 | 	You("are already wearing %s%c", cc, (cc == c_that_) ? '!' : '.');
1134 | }
1135 | 
1136 | STATIC_OVL void
1137 | already_wearing2(cc1, cc2)
1138 | const char *cc1, *cc2;
1139 | {
1140 | 	You_cant("wear %s because you're wearing %s there already.", cc1, cc2);
1141 | }
1142 | 
1143 | /*
1144 |  * canwearobj checks to see whether the player can wear a piece of armor
1145 |  *
1146 |  * inputs: otmp (the piece of armor)
1147 |  *         noisy (if TRUE give error messages, otherwise be quiet about it)
1148 |  * output: mask (otmp's armor type)
1149 |  */
1150 | int
1151 | canwearobj(otmp,mask,noisy)
1152 | struct obj *otmp;
1153 | long *mask;
1154 | boolean noisy;
1155 | {
1156 |     int err = 0;
1157 |     const char *which;
1158 | 
1159 |     which = is_cloak(otmp) ? c_cloak :
1160 | #ifdef TOURIST
1161 | 	    is_shirt(otmp) ? c_shirt :
1162 | #endif
1163 | 	    is_suit(otmp) ? c_suit : 0;
1164 |     if (which && cantweararm(youmonst.data) &&
1165 | 	    /* same exception for cloaks as used in m_dowear() */
1166 | 	    (which != c_cloak || youmonst.data->msize != MZ_SMALL)) {
1167 | 	if (noisy) pline_The("%s will not fit on your body.", which);
1168 | 	return 0;
1169 |     } else if (otmp->owornmask & W_ARMOR) {
1170 | 	if (noisy) already_wearing(c_that_);
1171 | 	return 0;
1172 |     }
1173 | 
1174 |     if (is_helmet(otmp)) {
1175 | 	if (uarmh) {
1176 | 	    if (noisy) already_wearing(an(c_helmet));
1177 | 	    err++;
1178 | 	} else
1179 | 	    *mask = W_ARMH;
1180 |     } else if (is_shield(otmp)) {
1181 | 	if (uarms) {
1182 | 	    if (noisy) already_wearing(an(c_shield));
1183 | 	    err++;
1184 | 	} else if (uwep && bimanual(uwep)) {
1185 | 	    if (noisy) 
1186 | 		You("cannot wear a shield while wielding a two-handed %s.",
1187 | 		    is_sword(uwep) ? c_sword :
1188 | 		    (uwep->otyp == BATTLE_AXE) ? c_axe : c_weapon);
1189 | 	    err++;
1190 | 	} else if (u.twoweap) {
1191 | 	    if (noisy)
1192 | 		You("cannot wear a shield while wielding two weapons.");
1193 | 	    err++;
1194 | 	} else
1195 | 	    *mask = W_ARMS;
1196 |     } else if (is_boots(otmp)) {
1197 | 	if (uarmf) {
1198 | 	    if (noisy) already_wearing(c_boots);
1199 | 	    err++;
1200 | 	} else if (Upolyd && slithy(youmonst.data)) {
1201 | 	    if (noisy) You("have no feet...");	/* not body_part(FOOT) */
1202 | 	    err++;
1203 | 	} else if (u.utrap && (u.utraptype == TT_BEARTRAP ||
1204 | 				u.utraptype == TT_INFLOOR)) {
1205 | 	    if (u.utraptype == TT_BEARTRAP) {
1206 | 		if (noisy) Your("%s is trapped!", body_part(FOOT));
1207 | 	    } else {
1208 | 		if (noisy) Your("%s are stuck in the %s!",
1209 | 				makeplural(body_part(FOOT)),
1210 | 				surface(u.ux, u.uy));
1211 | 	    }
1212 | 	    err++;
1213 | 	} else
1214 | 	    *mask = W_ARMF;
1215 |     } else if (is_gloves(otmp)) {
1216 | 	if (uarmg) {
1217 | 	    if (noisy) already_wearing(c_gloves);
1218 | 	    err++;
1219 | 	} else if (welded(uwep)) {
1220 | 	    if (noisy) You("cannot wear gloves over your %s.",
1221 | 			   is_sword(uwep) ? c_sword : c_weapon);
1222 | 	    err++;
1223 | 	} else
1224 | 	    *mask = W_ARMG;
1225 | #ifdef TOURIST
1226 |     } else if (is_shirt(otmp)) {
1227 | 	if (uarm || uarmc || uarmu) {
1228 | 	    if (uarmu) {
1229 | 		if (noisy) already_wearing(an(c_shirt));
1230 | 	    } else {
1231 | 		if (noisy) You_cant("wear that over your %s.",
1232 | 				    (uarm && !uarmc) ? c_armor : c_cloak);
1233 | 	    }
1234 | 	    err++;
1235 | 	} else
1236 | 	    *mask = W_ARMU;
1237 | #endif
1238 |     } else if (is_cloak(otmp)) {
1239 | 	if (uarmc) {
1240 | 	    if (noisy) already_wearing(an(c_cloak));
1241 | 	    err++;
1242 | 	} else
1243 | 	    *mask = W_ARMC;
1244 |     } else if (is_suit(otmp)) {
1245 | 	if (uarmc) {
1246 | 	    if (noisy) You("cannot wear armor over a cloak.");
1247 | 	    err++;
1248 | 	} else if (uarm) {
1249 | 	    if (noisy) already_wearing("some armor");
1250 | 	    err++;
1251 | 	} else
1252 | 	    *mask = W_ARM;
1253 |     } else {
1254 | 	/* getobj can't do this after setting its allow_all flag; that
1255 | 	   happens if you have armor for slots that are covered up or
1256 | 	   extra armor for slots that are filled */
1257 | 	if (noisy) pline(silly_thing_to, "wear");
1258 | 	err++;
1259 |     }
1260 | /* Unnecessary since now only weapons and special items like pick-axes get
1261 |  * welded to your hand, not armor
1262 |     if (welded(otmp)) {
1263 | 	if (!err++) {
1264 | 	    if (noisy) weldmsg(otmp);
1265 | 	}
1266 |     }
1267 |  */
1268 |     return !err;
1269 | }
1270 | 
1271 | /* the 'W' command */
1272 | int
1273 | dowear()
1274 | {
1275 | 	struct obj *otmp;
1276 | 	int delay;
1277 | 	long mask = 0;
1278 | 
1279 | 	/* cantweararm checks for suits of armor */
1280 | 	/* verysmall or nohands checks for shields, gloves, etc... */
1281 | 	if ((verysmall(youmonst.data) || nohands(youmonst.data))) {
1282 | 		pline("Don't even bother.");
1283 | 		return(0);
1284 | 	}
1285 | 
1286 | 	otmp = getobj(clothes, "wear");
1287 | 	if(!otmp) return(0);
1288 | 
1289 | 	if (!canwearobj(otmp,&mask,TRUE)) return(0);
1290 | 
1291 | 	if (otmp->oartifact && !touch_artifact(otmp, &youmonst))
1292 | 	    return 1;	/* costs a turn even though it didn't get worn */
1293 | 
1294 | 	if (otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT &&
1295 | 			qstart_level.dnum == u.uz.dnum) {	/* in quest */
1296 | 		You("narrowly avoid losing all chance at your goal.");
1297 | 		u.ublessed = 0; /* lose your god's protection */
1298 | 		makeknown(otmp->otyp);
1299 | 		flags.botl = 1;
1300 | 		return 1;
1301 | 	}
1302 | 
1303 | 	otmp->known = TRUE;
1304 | 	if(otmp == uwep)
1305 | 		setuwep((struct obj *)0);
1306 | 	if (otmp == uswapwep)
1307 | 		setuswapwep((struct obj *) 0);
1308 | 	if (otmp == uquiver)
1309 | 		setuqwep((struct obj *) 0);
1310 | 	setworn(otmp, mask);
1311 | 	delay = -objects[otmp->otyp].oc_delay;
1312 | 	if(delay){
1313 | 		nomul(delay);
1314 | 		if(is_boots(otmp)) afternmv = Boots_on;
1315 | 		if(is_helmet(otmp)) afternmv = Helmet_on;
1316 | 		if(is_gloves(otmp)) afternmv = Gloves_on;
1317 | 		if(otmp == uarm) afternmv = Armor_on;
1318 | 		nomovemsg = "You finish your dressing maneuver.";
1319 | 	} else {
1320 | 		if(is_cloak(otmp)) (void) Cloak_on();
1321 | /*		if(is_shield(otmp)) (void) Shield_on(); */
1322 | 		on_msg(otmp);
1323 | 	}
1324 | 	takeoff_mask = taking_off = 0L;
1325 | 	return(1);
1326 | }
1327 | 
1328 | int
1329 | doputon()
1330 | {
1331 | 	register struct obj *otmp;
1332 | 	long mask = 0L;
1333 | 
1334 | 	if(uleft && uright && uamul && ublindf) {
1335 | 		Your("%s%s are full, and you're already wearing an amulet and %s.",
1336 | 			humanoid(youmonst.data) ? "ring-" : "",
1337 | 			makeplural(body_part(FINGER)),
1338 | 			ublindf->otyp==LENSES ? "some lenses" : "a blindfold");
1339 | 		return(0);
1340 | 	}
1341 | 	otmp = getobj(accessories, "wear");
1342 | 	if(!otmp) return(0);
1343 | 	if(otmp->owornmask & (W_RING | W_AMUL | W_TOOL)) {
1344 | 		already_wearing(c_that_);
1345 | 		return(0);
1346 | 	}
1347 | 	if(welded(otmp)) {
1348 | 		weldmsg(otmp);
1349 | 		return(0);
1350 | 	}
1351 | 	if(otmp == uwep)
1352 | 		setuwep((struct obj *)0);
1353 | 	if(otmp->oclass == RING_CLASS || otmp->otyp == MEAT_RING) {
1354 | 		if(nolimbs(youmonst.data)) {
1355 | 			You("cannot make the ring stick to your body.");
1356 | 			return(0);
1357 | 		}
1358 | 		if(uleft && uright){
1359 | 			There("are no more %s%s to fill.",
1360 | 				humanoid(youmonst.data) ? "ring-" : "",
1361 | 				makeplural(body_part(FINGER)));
1362 | 			return(0);
1363 | 		}
1364 | 		if(uleft) mask = RIGHT_RING;
1365 | 		else if(uright) mask = LEFT_RING;
1366 | 		else do {
1367 | 			char qbuf[QBUFSZ];
1368 | 			char answer;
1369 | 
1370 | 			Sprintf(qbuf, "Which %s%s, Right or Left?",
1371 | 				humanoid(youmonst.data) ? "ring-" : "",
1372 | 				body_part(FINGER));
1373 | 			if(!(answer = yn_function(qbuf, "rl", '\0')))
1374 | 				return(0);
1375 | 			switch(answer){
1376 | 			case 'l':
1377 | 			case 'L':
1378 | 				mask = LEFT_RING;
1379 | 				break;
1380 | 			case 'r':
1381 | 			case 'R':
1382 | 				mask = RIGHT_RING;
1383 | 				break;
1384 | 			}
1385 | 		} while(!mask);
1386 | 		if (uarmg && uarmg->cursed) {
1387 | 			uarmg->bknown = TRUE;
1388 | 		    You("cannot remove your gloves to put on the ring.");
1389 | 			return(0);
1390 | 		}
1391 | 		if (welded(uwep) && bimanual(uwep)) {
1392 | 			/* welded will set bknown */
1393 | 	    You("cannot free your weapon hands to put on the ring.");
1394 | 			return(0);
1395 | 		}
1396 | 		if (welded(uwep) && mask==RIGHT_RING) {
1397 | 			/* welded will set bknown */
1398 | 	    You("cannot free your weapon hand to put on the ring.");
1399 | 			return(0);
1400 | 		}
1401 | 		setworn(otmp, mask);
1402 | 		Ring_on(otmp);
1403 | 	} else if (otmp->oclass == AMULET_CLASS) {
1404 | 		if(uamul) {
1405 | 			already_wearing("an amulet");
1406 | 			return(0);
1407 | 		}
1408 | 		setworn(otmp, W_AMUL);
1409 | 		if (otmp->otyp == AMULET_OF_CHANGE) {
1410 | 			Amulet_on();
1411 | 			/* Don't do a prinv() since the amulet is now gone */
1412 | 			return(1);
1413 | 		}
1414 | 		Amulet_on();
1415 | 	} else {	/* it's a blindfold, towel, or lenses */
1416 | 		if (ublindf) {
1417 | 			if (ublindf->otyp == TOWEL)
1418 | 				Your("%s is already covered by a towel.",
1419 | 					body_part(FACE));
1420 | 			else if (ublindf->otyp == BLINDFOLD) {
1421 | 				if (otmp->otyp == LENSES)
1422 | 					already_wearing2("lenses", "a blindfold");
1423 | 				else
1424 | 					already_wearing("a blindfold");
1425 | 			} else if (ublindf->otyp == LENSES) {
1426 | 				if (otmp->otyp == BLINDFOLD)
1427 | 					already_wearing2("a blindfold", "some lenses");
1428 | 				else
1429 | 					already_wearing("some lenses");
1430 | 			} else
1431 | 				already_wearing(something); /* ??? */
1432 | 			return(0);
1433 | 		}
1434 | 		if (otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL && otmp->otyp != LENSES) {
1435 | 			You_cant("wear that!");
1436 | 			return(0);
1437 | 		}
1438 | 		Blindf_on(otmp);
1439 | 		return(1);
1440 | 	}
1441 | 	prinv((char *)0, otmp, 0L);
1442 | 	return(1);
1443 | }
1444 | 
1445 | #endif /* OVLB */
1446 | 
1447 | #ifdef OVL0
1448 | 
1449 | void
1450 | find_ac()
1451 | {
1452 | 	int uac = mons[u.umonnum].ac;
1453 | 
1454 | 	if(uarm) uac -= ARM_BONUS(uarm);
1455 | 	if(uarmc) uac -= ARM_BONUS(uarmc);
1456 | 	if(uarmh) uac -= ARM_BONUS(uarmh);
1457 | 	if(uarmf) uac -= ARM_BONUS(uarmf);
1458 | 	if(uarms) uac -= ARM_BONUS(uarms);
1459 | 	if(uarmg) uac -= ARM_BONUS(uarmg);
1460 | #ifdef TOURIST
1461 | 	if(uarmu) uac -= ARM_BONUS(uarmu);
1462 | #endif
1463 | 	if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe;
1464 | 	if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe;
1465 | 	if (HProtection & INTRINSIC) uac -= u.ublessed;
1466 | 	uac -= u.uspellprot;
1467 | 	if(uac != u.uac){
1468 | 		u.uac = uac;
1469 | 		flags.botl = 1;
1470 | 	}
1471 | }
1472 | 
1473 | #endif /* OVL0 */
1474 | #ifdef OVLB
1475 | 
1476 | void
1477 | glibr()
1478 | {
1479 | 	register struct obj *otmp;
1480 | 	int xfl = 0;
1481 | 	boolean leftfall, rightfall;
1482 | 
1483 | 	leftfall = (uleft && !uleft->cursed &&
1484 | 		    (!uwep || !welded(uwep) || !bimanual(uwep)));
1485 | 	rightfall = (uright && !uright->cursed && (!welded(uwep)));
1486 | 	if (!uarmg && (leftfall || rightfall) && !nolimbs(youmonst.data)) {
1487 | 		/* changed so cursed rings don't fall off, GAN 10/30/86 */
1488 | 		Your("%s off your %s.",
1489 | 			(leftfall && rightfall) ? "rings slip" : "ring slips",
1490 | 			makeplural(body_part(FINGER)));
1491 | 		xfl++;
1492 | 		if (leftfall) {
1493 | 			otmp = uleft;
1494 | 			Ring_off(uleft);
1495 | 			dropx(otmp);
1496 | 		}
1497 | 		if (rightfall) {
1498 | 			otmp = uright;
1499 | 			Ring_off(uright);
1500 | 			dropx(otmp);
1501 | 		}
1502 | 	}
1503 | 
1504 | 	otmp = uswapwep;
1505 | 	if (u.twoweap && otmp) {
1506 | 		Your("%s %sslips from your %s.",
1507 | 			is_sword(otmp) ? c_sword :
1508 | 				makesingular(oclass_names[(int)otmp->oclass]),
1509 | 			xfl ? "also " : "",
1510 | 			makeplural(body_part(HAND)));
1511 | 		setuswapwep((struct obj *)0);
1512 | 		xfl++;
1513 | 		if (otmp->otyp != LOADSTONE || !otmp->cursed)
1514 | 			dropx(otmp);
1515 | 	}
1516 | 	otmp = uwep;
1517 | 	if (otmp && !welded(otmp)) {
1518 | 		/* changed so cursed weapons don't fall, GAN 10/30/86 */
1519 | 		Your("%s %sslips from your %s.",
1520 | 			is_sword(otmp) ? c_sword :
1521 | 				makesingular(oclass_names[(int)otmp->oclass]),
1522 | 			xfl ? "also " : "",
1523 | 			makeplural(body_part(HAND)));
1524 | 		setuwep((struct obj *)0);
1525 | 		if (otmp->otyp != LOADSTONE || !otmp->cursed)
1526 | 			dropx(otmp);
1527 | 	}
1528 | }
1529 | 
1530 | struct obj *
1531 | some_armor(victim)
1532 | struct monst *victim;
1533 | {
1534 | 	register struct obj *otmph, *otmp;
1535 | 
1536 | 	otmph = (victim == &youmonst) ? uarmc : which_armor(victim, W_ARMC);
1537 | 	if (!otmph)
1538 | 	    otmph = (victim == &youmonst) ? uarm : which_armor(victim, W_ARM);
1539 | #ifdef TOURIST
1540 | 	if (!otmph)
1541 | 	    otmph = (victim == &youmonst) ? uarmu : which_armor(victim, W_ARMU);
1542 | #endif
1543 | 	
1544 | 	otmp = (victim == &youmonst) ? uarmh : which_armor(victim, W_ARMH);
1545 | 	if(otmp && (!otmph || !rn2(4))) otmph = otmp;
1546 | 	otmp = (victim == &youmonst) ? uarmg : which_armor(victim, W_ARMG);
1547 | 	if(otmp && (!otmph || !rn2(4))) otmph = otmp;
1548 | 	otmp = (victim == &youmonst) ? uarmf : which_armor(victim, W_ARMF);
1549 | 	if(otmp && (!otmph || !rn2(4))) otmph = otmp;
1550 | 	otmp = (victim == &youmonst) ? uarms : which_armor(victim, W_ARMS);
1551 | 	if(otmp && (!otmph || !rn2(4))) otmph = otmp;
1552 | 	return(otmph);
1553 | }
1554 | 
1555 | void
1556 | erode_armor(victim,acid_dmg)
1557 | struct monst *victim;
1558 | boolean acid_dmg;
1559 | {
1560 | 	register struct obj *otmph = some_armor(victim);
1561 | 	int erosion;
1562 | 	boolean vismon = (victim != &youmonst) && canseemon(victim);
1563 | 
1564 | 	if (!otmph) return;
1565 | 	erosion = acid_dmg  ? otmph->oeroded2 : otmph->oeroded;
1566 | 	if (otmph != uarmf) {
1567 | 	    if (otmph->greased) {
1568 | 		grease_protect(otmph,(char *)0,FALSE,victim);
1569 | 		return;
1570 | 	    }
1571 | 	    if (otmph->oerodeproof ||
1572 | 		(acid_dmg ? !is_corrodeable(otmph) : !is_rustprone(otmph))) {
1573 | 		if (flags.verbose || !(otmph->oerodeproof && otmph->rknown)) {
1574 | 		    if (victim == &youmonst)
1575 | 			Your("%s not affected.", aobjnam(otmph, "are"));
1576 | 		    else if (vismon)
1577 | 			pline("%s's %s not affected.", Monnam(victim),
1578 | 			    aobjnam(otmph, "are"));
1579 | 		}
1580 | 		if (otmph->oerodeproof) otmph->rknown = TRUE;
1581 | 		return;
1582 | 	    }
1583 | 	    if (erosion < MAX_ERODE) {
1584 | 		if (victim == &youmonst)
1585 | 		    Your("%s%s!", aobjnam(otmph, acid_dmg ? "corrode" : "rust"),
1586 | 			erosion+1 == MAX_ERODE ? " completely" :
1587 | 			erosion ? " further" : "");
1588 | 		else if (vismon)
1589 | 		    pline("%s's %s%s!", Monnam(victim),
1590 | 			aobjnam(otmph, acid_dmg ? "corrode" : "rust"),
1591 | 			erosion+1 == MAX_ERODE ? " completely" :
1592 | 			erosion ? " further" : "");
1593 | 		if (acid_dmg)
1594 | 		    otmph->oeroded2++;
1595 | 		else
1596 | 		    otmph->oeroded++;
1597 | 		return;
1598 | 	    }
1599 | 	    if (flags.verbose) {
1600 | 		if (victim == &youmonst)
1601 | 		    Your("%s completely %s.",
1602 | 			 aobjnam(otmph, Blind ? "feel" : "look"),
1603 | 			 acid_dmg ? "corroded" : "rusty");
1604 | 		else if (vismon)
1605 | 		    pline("%s's %s completely %s.", Monnam(victim),
1606 | 			 aobjnam(otmph, "look"),
1607 | 			 acid_dmg ? "corroded" : "rusty");
1608 | 	    }
1609 | 	}
1610 | }
1611 | 
1612 | STATIC_PTR
1613 | int
1614 | select_off(otmp)
1615 | register struct obj *otmp;
1616 | {
1617 | 	if(!otmp) return(0);
1618 | 	if(cursed(otmp)) return(0);
1619 | 	if((otmp->oclass==RING_CLASS || otmp->otyp == MEAT_RING)
1620 | 				&& nolimbs(youmonst.data))
1621 | 		return(0);
1622 | 	if(welded(uwep) && (otmp==uarmg || otmp==uright || (otmp==uleft
1623 | 			&& bimanual(uwep))))
1624 | 		return(0);
1625 | 	if(uarmg && uarmg->cursed && (otmp==uright || otmp==uleft)) {
1626 | 		uarmg->bknown = TRUE;
1627 | 		return(0);
1628 | 	}
1629 | 	if(otmp == uarmf && u.utrap && (u.utraptype == TT_BEARTRAP ||
1630 | 					u.utraptype == TT_INFLOOR)) {
1631 | 		return (0);
1632 | 	}
1633 | 	if((otmp==uarm
1634 | #ifdef TOURIST
1635 | 			|| otmp==uarmu
1636 | #endif
1637 | 					) && uarmc && uarmc->cursed) {
1638 | 		uarmc->bknown = TRUE;
1639 | 		return(0);
1640 | 	}
1641 | #ifdef TOURIST
1642 | 	if(otmp==uarmu && uarm && uarm->cursed) {
1643 | 		uarm->bknown = TRUE;
1644 | 		return(0);
1645 | 	}
1646 | #endif
1647 | 
1648 | 	if(otmp == uarm) takeoff_mask |= WORN_ARMOR;
1649 | 	else if(otmp == uarmc) takeoff_mask |= WORN_CLOAK;
1650 | 	else if(otmp == uarmf) takeoff_mask |= WORN_BOOTS;
1651 | 	else if(otmp == uarmg) takeoff_mask |= WORN_GLOVES;
1652 | 	else if(otmp == uarmh) takeoff_mask |= WORN_HELMET;
1653 | 	else if(otmp == uarms) takeoff_mask |= WORN_SHIELD;
1654 | #ifdef TOURIST
1655 | 	else if(otmp == uarmu) takeoff_mask |= WORN_SHIRT;
1656 | #endif
1657 | 	else if(otmp == uleft) takeoff_mask |= LEFT_RING;
1658 | 	else if(otmp == uright) takeoff_mask |= RIGHT_RING;
1659 | 	else if(otmp == uamul) takeoff_mask |= WORN_AMUL;
1660 | 	else if(otmp == ublindf) takeoff_mask |= WORN_BLINDF;
1661 | 	else if(otmp == uwep) takeoff_mask |= W_WEP;
1662 | 	else if(otmp == uswapwep) takeoff_mask |= W_SWAPWEP;
1663 | 	else if(otmp == uquiver) takeoff_mask |= W_QUIVER;
1664 | 
1665 | 	else impossible("select_off: %s???", doname(otmp));
1666 | 
1667 | 	return(0);
1668 | }
1669 | 
1670 | STATIC_OVL struct obj *
1671 | do_takeoff()
1672 | {
1673 | 	register struct obj *otmp = (struct obj *)0;
1674 | 
1675 | 	if (taking_off == W_WEP) {
1676 | 	  if(!cursed(uwep)) {
1677 | 	    setuwep((struct obj *) 0);
1678 | 	    You("are empty %s.", body_part(HANDED));
1679 | 	    u.twoweap = FALSE;
1680 | 	  }
1681 | 	} else if (taking_off == W_SWAPWEP) {
1682 | 	  setuswapwep((struct obj *) 0);
1683 | 	  You("no longer have a second weapon readied.");
1684 | 	  u.twoweap = FALSE;
1685 | 	} else if (taking_off == W_QUIVER) {
1686 | 	  setuqwep((struct obj *) 0);
1687 | 	  You("no longer have ammunition readied.");
1688 | 	} else if (taking_off == WORN_ARMOR) {
1689 | 	  otmp = uarm;
1690 | 	  if(!cursed(otmp)) (void) Armor_off();
1691 | 	} else if (taking_off == WORN_CLOAK) {
1692 | 	  otmp = uarmc;
1693 | 	  if(!cursed(otmp)) (void) Cloak_off();
1694 | 	} else if (taking_off == WORN_BOOTS) {
1695 | 	  otmp = uarmf;
1696 | 	  if(!cursed(otmp)) (void) Boots_off();
1697 | 	} else if (taking_off == WORN_GLOVES) {
1698 | 	  otmp = uarmg;
1699 | 	  if(!cursed(otmp)) (void) Gloves_off();
1700 | 	} else if (taking_off == WORN_HELMET) {
1701 | 	  otmp = uarmh;
1702 | 	  if(!cursed(otmp)) (void) Helmet_off();
1703 | 	} else if (taking_off == WORN_SHIELD) {
1704 | 	  otmp = uarms;
1705 | 	  if(!cursed(otmp)) (void) Shield_off();
1706 | #ifdef TOURIST
1707 | 	} else if (taking_off == WORN_SHIRT) {
1708 | 	  otmp = uarmu;
1709 | 	  if(!cursed(otmp))
1710 | 	    setworn((struct obj *)0, uarmu->owornmask & W_ARMOR);
1711 | #endif
1712 | 	} else if (taking_off == WORN_AMUL) {
1713 | 	  otmp = uamul;
1714 | 	  if(!cursed(otmp)) Amulet_off();
1715 | 	} else if (taking_off == LEFT_RING) {
1716 | 	  otmp = uleft;
1717 | 	  if(!cursed(otmp)) Ring_off(uleft);
1718 | 	} else if (taking_off == RIGHT_RING) {
1719 | 	  otmp = uright;
1720 | 	  if(!cursed(otmp)) Ring_off(uright);
1721 | 	} else if (taking_off == WORN_BLINDF) {
1722 | 	  if(!cursed(ublindf)) {
1723 | 	    setworn((struct obj *)0, ublindf->owornmask);
1724 | 	    if(!Blinded) make_blinded(1L,FALSE); /* See on next move */
1725 | 	    else	 You("still cannot see.");
1726 | 	  }
1727 | 	} else impossible("do_takeoff: taking off %lx", taking_off);
1728 | 
1729 | 	return(otmp);
1730 | }
1731 | 
1732 | STATIC_PTR
1733 | int
1734 | take_off()
1735 | {
1736 | 	register int i;
1737 | 	register struct obj *otmp;
1738 | 
1739 | 	if(taking_off) {
1740 | 	    if(todelay > 0) {
1741 | 
1742 | 		todelay--;
1743 | 		return(1);	/* still busy */
1744 | 	    } else if((otmp = do_takeoff())) off_msg(otmp);
1745 | 
1746 | 	    takeoff_mask &= ~taking_off;
1747 | 	    taking_off = 0L;
1748 | 	}
1749 | 
1750 | 	for(i = 0; takeoff_order[i]; i++)
1751 | 	    if(takeoff_mask & takeoff_order[i]) {
1752 | 		taking_off = takeoff_order[i];
1753 | 		break;
1754 | 	    }
1755 | 
1756 | 	otmp = (struct obj *) 0;
1757 | 	todelay = 0;
1758 | 
1759 | 	if (taking_off == 0L) {
1760 | 	  You("finish disrobing.");
1761 | 	  return 0;
1762 | 	} else if (taking_off == W_WEP) {
1763 | 	  todelay = 1;
1764 | 	} else if (taking_off == W_SWAPWEP) {
1765 | 	  todelay = 1;
1766 | 	} else if (taking_off == W_QUIVER) {
1767 | 	  todelay = 1;
1768 | 	} else if (taking_off == WORN_ARMOR) {
1769 | 	  otmp = uarm;
1770 | 	  /* If a cloak is being worn, add the time to take it off and put
1771 | 	   * it back on again.  Kludge alert! since that time is 0 for all
1772 | 	   * known cloaks, add 1 so that it actually matters...
1773 | 	   */
1774 | 	  if (uarmc) todelay += 2 * objects[uarmc->otyp].oc_delay + 1;
1775 | 	} else if (taking_off == WORN_CLOAK) {
1776 | 	  otmp = uarmc;
1777 | 	} else if (taking_off == WORN_BOOTS) {
1778 | 	  otmp = uarmf;
1779 | 	} else if (taking_off == WORN_GLOVES) {
1780 | 	  otmp = uarmg;
1781 | 	} else if (taking_off == WORN_HELMET) {
1782 | 	  otmp = uarmh;
1783 | 	} else if (taking_off == WORN_SHIELD) {
1784 | 	  otmp = uarms;
1785 | #ifdef TOURIST
1786 | 	} else if (taking_off == WORN_SHIRT) {
1787 | 	  otmp = uarmu;
1788 | 	  /* add the time to take off and put back on armor and/or cloak */
1789 | 	  if (uarm)  todelay += 2 * objects[uarm->otyp].oc_delay;
1790 | 	  if (uarmc) todelay += 2 * objects[uarmc->otyp].oc_delay + 1;
1791 | #endif
1792 | 	} else if (taking_off == WORN_AMUL) {
1793 | 	  todelay = 1;
1794 | 	} else if (taking_off == LEFT_RING) {
1795 | 	  todelay = 1;
1796 | 	} else if (taking_off == RIGHT_RING) {
1797 | 	  todelay = 1;
1798 | 	} else if (taking_off == WORN_BLINDF) {
1799 | 	  todelay = 2;
1800 | 	} else {
1801 | 	  impossible("take_off: taking off %lx", taking_off);
1802 | 	  return 0;	/* force done */
1803 | 	}
1804 | 
1805 | 	if (otmp) todelay += objects[otmp->otyp].oc_delay;
1806 | 
1807 | 	/* Since setting the occupation now starts the counter next move, that
1808 |          * would always produce a delay 1 too big per item unless we subtract
1809 | 	 * 1 here to account for it.
1810 | 	 */
1811 | 	if (todelay>0) todelay--;
1812 | 
1813 | 	set_occupation(take_off, "disrobing", 0);
1814 | 	return(1);		/* get busy */
1815 | }
1816 | 
1817 | #endif /* OVLB */
1818 | #ifdef OVL1
1819 | 
1820 | void
1821 | reset_remarm()
1822 | {
1823 | 	taking_off = takeoff_mask = 0L;
1824 | }
1825 | 
1826 | #endif /* OVL1 */
1827 | #ifdef OVLB
1828 | 
1829 | int
1830 | doddoremarm()
1831 | {
1832 |     int result = 0;
1833 | 
1834 |     if (taking_off || takeoff_mask) {
1835 | 	You("continue disrobing.");
1836 | 	set_occupation(take_off, "disrobing", 0);
1837 | 	(void) take_off();
1838 | 	return 0;
1839 |     } else if (!uwep && !uswapwep && !uquiver && !uamul && !ublindf &&
1840 | 		!uleft && !uright && !wearing_armor()) {
1841 | 	You("are not wearing anything.");
1842 | 	return 0;
1843 |     }
1844 | 
1845 |     add_valid_menu_class(0); /* reset */
1846 |     if (flags.menu_style != MENU_TRADITIONAL ||
1847 | 	    (result = ggetobj("take off", select_off, 0, FALSE)) < -1)
1848 | 	result = menu_remarm(result);
1849 | 
1850 |     if (takeoff_mask)
1851 | 	(void) take_off();
1852 |     /* The time to perform the command is already completely accounted for
1853 |      * in take_off(); if we return 1, that would add an extra turn to each
1854 |      * disrobe.
1855 |      */
1856 |     return 0;
1857 | }
1858 | 
1859 | STATIC_OVL int
1860 | menu_remarm(retry)
1861 | int retry;
1862 | {
1863 |     int n, i = 0;
1864 |     menu_item *pick_list;
1865 |     boolean all_worn_categories = TRUE;
1866 | 
1867 |     if (retry) {
1868 | 	all_worn_categories = (retry == -2);
1869 |     } else if (flags.menu_style == MENU_FULL) {
1870 | 	all_worn_categories = FALSE;
1871 | 	n = query_category("What type of things do you want to take off?",
1872 | 			   invent, WORN_TYPES|ALL_TYPES, &pick_list, PICK_ANY);
1873 | 	if (!n) return 0;
1874 | 	for (i = 0; i < n; i++) {
1875 | 	    if (pick_list[i].item.a_int == ALL_TYPES_SELECTED)
1876 | 		all_worn_categories = TRUE;
1877 | 	    else
1878 | 		add_valid_menu_class(pick_list[i].item.a_int);
1879 | 	}
1880 | 	free((genericptr_t) pick_list);
1881 |     } else if (flags.menu_style == MENU_COMBINATION) {
1882 | 	all_worn_categories = FALSE;
1883 | 	if (ggetobj("take off", select_off, 0, TRUE) == -2)
1884 | 	    all_worn_categories = TRUE;
1885 |     }
1886 | 
1887 |     n = query_objlist("What do you want to take off?", invent,
1888 | 			SIGNAL_NOMENU|USE_INVLET|INVORDER_SORT,
1889 | 			&pick_list, PICK_ANY,
1890 | 			all_worn_categories ? is_worn : is_worn_by_type);
1891 |     if (n > 0) {
1892 | 	for (i = 0; i < n; i++)
1893 | 	    (void) select_off(pick_list[i].item.a_obj);
1894 | 	free((genericptr_t) pick_list);
1895 |     } else if (n < 0) {
1896 | 	There("is nothing else you can remove or unwield.");
1897 |     }
1898 |     return 0;
1899 | }
1900 | 
1901 | int
1902 | destroy_arm(atmp)
1903 | register struct obj *atmp;
1904 | {
1905 | 	register struct obj *otmp;
1906 | #define DESTROY_ARM(o) ((otmp = (o)) != 0 && \
1907 | 			(!atmp || atmp == otmp) && \
1908 | 			(!obj_resists(otmp, 0, 90)))
1909 | 
1910 | 	if (DESTROY_ARM(uarmc)) {
1911 | 		Your("cloak crumbles and turns to dust!");
1912 | 		(void) Cloak_off();
1913 | 		useup(otmp);
1914 | 	} else if (DESTROY_ARM(uarm)) {
1915 | 		/* may be disintegrated by spell or dragon breath... */
1916 | 		if (donning(otmp)) cancel_don();
1917 | 		Your("armor turns to dust and falls to the %s!",
1918 | 			surface(u.ux,u.uy));
1919 | 		(void) Armor_gone();
1920 | 		useup(otmp);
1921 | #ifdef TOURIST
1922 | 	} else if (DESTROY_ARM(uarmu)) {
1923 | 		Your("shirt crumbles into tiny threads and falls apart!");
1924 | 		useup(otmp);
1925 | #endif
1926 | 	} else if (DESTROY_ARM(uarmh)) {
1927 | 		if (donning(otmp)) cancel_don();
1928 | 		Your("helmet turns to dust and is blown away!");
1929 | 		(void) Helmet_off();
1930 | 		useup(otmp);
1931 | 	} else if (DESTROY_ARM(uarmg)) {
1932 | 		if (donning(otmp)) cancel_don();
1933 | 		Your("gloves vanish!");
1934 | 		(void) Gloves_off();
1935 | 		useup(otmp);
1936 | 		selftouch("You");
1937 | 	} else if (DESTROY_ARM(uarmf)) {
1938 | 		if (donning(otmp)) cancel_don();
1939 | 		Your("boots disintegrate!");
1940 | 		(void) Boots_off();
1941 | 		useup(otmp);
1942 | 	} else if (DESTROY_ARM(uarms)) {
1943 | 		Your("shield crumbles away!");
1944 | 		(void) Shield_off();
1945 | 		useup(otmp);
1946 | 	} else	return(0);		/* could not destroy anything */
1947 | 
1948 | #undef DESTROY_ARM
1949 | 	return(1);
1950 | }
1951 | 
1952 | void
1953 | adj_abon(otmp, delta)
1954 | register struct obj *otmp;
1955 | register schar delta;
1956 | {
1957 | 	if (uarmg && uarmg == otmp && otmp->otyp == GAUNTLETS_OF_DEXTERITY) {
1958 | 		if (delta) {
1959 | 			makeknown(uarmg->otyp);
1960 | 			ABON(A_DEX) += (delta);
1961 | 		}
1962 | 		flags.botl = 1;
1963 | 	}
1964 | 	if (uarmh && uarmh == otmp && otmp->otyp == HELM_OF_BRILLIANCE) {
1965 | 		if (delta) {
1966 | 			makeknown(uarmh->otyp);
1967 | 			ABON(A_INT) += (delta);
1968 | 			ABON(A_WIS) += (delta);
1969 | 		}
1970 | 		flags.botl = 1;
1971 | 	}
1972 | }
1973 | 
1974 | #endif /* OVLB */
1975 | 
1976 | /*do_wear.c*/