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