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