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*/