/* SCCS Id: @(#)do_wear.c 3.3 2000/05/05 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" #ifndef OVLB STATIC_DCL long takeoff_mask, taking_off; #else /* OVLB */ STATIC_OVL NEARDATA long takeoff_mask = 0L, taking_off = 0L; static NEARDATA int todelay; static NEARDATA const char see_yourself[] = "see yourself"; static NEARDATA const char unknown_type[] = "Unknown type of %s (%d)"; static NEARDATA const char *c_armor = "armor", *c_suit = "suit", #ifdef TOURIST *c_shirt = "shirt", #endif *c_cloak = "cloak", *c_gloves = "gloves", *c_boots = "boots", *c_helmet = "helmet", *c_shield = "shield", *c_weapon = "weapon", *c_sword = "sword", *c_axe = "axe", *c_that_ = "that"; static NEARDATA const long takeoff_order[] = { WORN_BLINDF, W_WEP, WORN_SHIELD, WORN_GLOVES, LEFT_RING, RIGHT_RING, WORN_CLOAK, WORN_HELMET, WORN_AMUL, WORN_ARMOR, #ifdef TOURIST WORN_SHIRT, #endif WORN_BOOTS, W_SWAPWEP, W_QUIVER, 0L }; STATIC_DCL void FDECL(on_msg, (struct obj *)); STATIC_PTR int NDECL(Armor_on); STATIC_PTR int NDECL(Boots_on); STATIC_DCL int NDECL(Cloak_on); STATIC_PTR int NDECL(Helmet_on); STATIC_PTR int NDECL(Gloves_on); STATIC_DCL void NDECL(Amulet_on); STATIC_DCL void FDECL(Ring_off_or_gone, (struct obj *, BOOLEAN_P)); STATIC_PTR int FDECL(select_off, (struct obj *)); STATIC_DCL struct obj *NDECL(do_takeoff); STATIC_PTR int NDECL(take_off); STATIC_DCL int FDECL(menu_remarm, (int)); STATIC_DCL void FDECL(already_wearing, (const char*)); STATIC_DCL void FDECL(already_wearing2, (const char*, const char*)); void off_msg(otmp) register struct obj *otmp; { if(flags.verbose) You("were wearing %s.", doname(otmp)); } /* for items that involve no delay */ STATIC_OVL void on_msg(otmp) register struct obj *otmp; { if(flags.verbose) You("are now wearing %s.", obj_is_pname(otmp) ? the(xname(otmp)) : an(xname(otmp))); } /* * The Type_on() functions should be called *after* setworn(). * The Type_off() functions call setworn() themselves. */ STATIC_PTR int Boots_on() { long oldprop = u.uprops[objects[uarmf->otyp].oc_oprop].extrinsic & ~WORN_BOOTS; switch(uarmf->otyp) { case LOW_BOOTS: case IRON_SHOES: case HIGH_BOOTS: case JUMPING_BOOTS: case KICKING_BOOTS: break; case WATER_WALKING_BOOTS: if (u.uinwater) spoteffects(TRUE); break; case SPEED_BOOTS: /* Speed boots are still better than intrinsic speed, */ /* though not better than potion speed */ if (!oldprop && !(HFast & TIMEOUT)) { makeknown(uarmf->otyp); You_feel("yourself speed up%s.", (oldprop || HFast) ? " a bit more" : ""); } break; case ELVEN_BOOTS: if (!oldprop && !HStealth && !BStealth) { makeknown(uarmf->otyp); You("walk very quietly."); } break; case FUMBLE_BOOTS: if (!oldprop && !(HFumbling & ~TIMEOUT)) incr_itimeout(&HFumbling, rnd(20)); break; case LEVITATION_BOOTS: if (!oldprop && !HLevitation) { makeknown(uarmf->otyp); float_up(); } break; default: impossible(unknown_type, c_boots, uarmf->otyp); } return 0; } int Boots_off() { int otyp = uarmf->otyp; long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_BOOTS; /* For levitation, float_down() returns if Levitation, so we * must do a setworn() _before_ the levitation case. */ setworn((struct obj *)0, W_ARMF); switch (otyp) { case SPEED_BOOTS: if (!Very_fast) { makeknown(otyp); You_feel("yourself slow down%s.", Fast ? " a bit" : ""); } break; case WATER_WALKING_BOOTS: if (is_pool(u.ux,u.uy) && !Levitation && !Flying && !is_clinger(youmonst.data)) { makeknown(otyp); /* make boots known in case you survive the drowning */ spoteffects(TRUE); } break; case ELVEN_BOOTS: if (!oldprop && !HStealth && !BStealth) { makeknown(otyp); You("sure are noisy."); } break; case FUMBLE_BOOTS: if (!oldprop && !(HFumbling & ~TIMEOUT)) HFumbling = EFumbling = 0; break; case LEVITATION_BOOTS: if (!oldprop && !HLevitation) { (void) float_down(0L, 0L); makeknown(otyp); } break; case LOW_BOOTS: case IRON_SHOES: case HIGH_BOOTS: case JUMPING_BOOTS: case KICKING_BOOTS: break; default: impossible(unknown_type, c_boots, otyp); } return 0; } STATIC_OVL int Cloak_on() { long oldprop = u.uprops[objects[uarmc->otyp].oc_oprop].extrinsic & ~WORN_CLOAK; switch(uarmc->otyp) { case ELVEN_CLOAK: case CLOAK_OF_PROTECTION: case CLOAK_OF_DISPLACEMENT: makeknown(uarmc->otyp); break; case ORCISH_CLOAK: case DWARVISH_CLOAK: case CLOAK_OF_MAGIC_RESISTANCE: case ROBE: break; case MUMMY_WRAPPING: /* Note: it's already being worn, so we have to cheat here. */ if ((HInvis || EInvis || pm_invisible(youmonst.data)) && !Blind) { newsym(u.ux,u.uy); You("can %s!", See_invisible ? "no longer see through yourself" : see_yourself); } break; case CLOAK_OF_INVISIBILITY: /* since cloak of invisibility was worn, we know mummy wrapping wasn't, so no need to check `oldprop' against blocked */ if (!oldprop && !HInvis && !Blind) { makeknown(uarmc->otyp); newsym(u.ux,u.uy); pline("Suddenly you can%s yourself.", See_invisible ? " see through" : "not see"); } break; case OILSKIN_CLOAK: pline("%s fits very tightly.",The(xname(uarmc))); break; /* Alchemy smock gives poison _and_ acid resistance */ case ALCHEMY_SMOCK: EAcid_resistance |= WORN_CLOAK; break; default: impossible(unknown_type, c_cloak, uarmc->otyp); } return 0; } int Cloak_off() { int otyp = uarmc->otyp; long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_CLOAK; /* For mummy wrapping, taking it off first resets `Invisible'. */ setworn((struct obj *)0, W_ARMC); switch (otyp) { case ELVEN_CLOAK: case ORCISH_CLOAK: case DWARVISH_CLOAK: case CLOAK_OF_PROTECTION: case CLOAK_OF_MAGIC_RESISTANCE: case CLOAK_OF_DISPLACEMENT: case OILSKIN_CLOAK: case ROBE: break; case MUMMY_WRAPPING: if (Invis && !Blind) { newsym(u.ux,u.uy); You("can %s.", See_invisible ? "see through yourself" : "no longer see yourself"); } break; case CLOAK_OF_INVISIBILITY: if (!oldprop && !HInvis && !Blind) { makeknown(CLOAK_OF_INVISIBILITY); newsym(u.ux,u.uy); pline("Suddenly you can %s.", See_invisible ? "no longer see through yourself" : see_yourself); } break; /* Alchemy smock gives poison _and_ acid resistance */ case ALCHEMY_SMOCK: EAcid_resistance &= ~WORN_CLOAK; break; default: impossible(unknown_type, c_cloak, otyp); } return 0; } STATIC_PTR int Helmet_on() { switch(uarmh->otyp) { case FEDORA: case HELMET: case DENTED_POT: case ELVEN_LEATHER_HELM: case DWARVISH_IRON_HELM: case ORCISH_HELM: case HELM_OF_TELEPATHY: break; case HELM_OF_BRILLIANCE: adj_abon(uarmh, uarmh->spe); break; case CORNUTHAUM: /* people think marked wizards know what they're talking * about, but it takes trained arrogance to pull it off, * and the actual enchantment of the hat is irrelevant. */ ABON(A_CHA) += (Role_if(PM_WIZARD) ? 1 : -1); flags.botl = 1; makeknown(uarmh->otyp); break; case HELM_OF_OPPOSITE_ALIGNMENT: if (u.ualign.type == A_NEUTRAL) u.ualign.type = rn2(2) ? A_CHAOTIC : A_LAWFUL; else u.ualign.type = -(u.ualign.type); u.ublessed = 0; /* lose your god's protection */ /* makeknown(uarmh->otyp); -- moved below, after xname() */ /*FALLTHRU*/ case DUNCE_CAP: if (!uarmh->cursed) { pline("%s %s%s for a moment.", The(xname(uarmh)), Blind ? "vibrates" : "glows ", Blind ? (const char *)"" : hcolor(Black)); curse(uarmh); } flags.botl = 1; /* reveal new alignment or INT & WIS */ if (Hallucination) { pline("My brain hurts!"); /* Monty Python's Flying Circus */ } else if (uarmh->otyp == DUNCE_CAP) { You_feel("%s.", /* track INT change; ignore WIS */ ACURR(A_INT) <= (ABASE(A_INT) + ABON(A_INT) + ATEMP(A_INT)) ? "like sitting in a corner" : "giddy"); } else { Your("mind oscillates briefly."); makeknown(HELM_OF_OPPOSITE_ALIGNMENT); } break; default: impossible(unknown_type, c_helmet, uarmh->otyp); } return 0; } int Helmet_off() { switch(uarmh->otyp) { case FEDORA: case HELMET: case DENTED_POT: case ELVEN_LEATHER_HELM: case DWARVISH_IRON_HELM: case ORCISH_HELM: break; case DUNCE_CAP: flags.botl = 1; break; case CORNUTHAUM: ABON(A_CHA) += (Role_if(PM_WIZARD) ? -1 : 1); flags.botl = 1; break; case HELM_OF_TELEPATHY: /* need to update ability before calling see_monsters() */ setworn((struct obj *)0, W_ARMH); see_monsters(); return 0; case HELM_OF_BRILLIANCE: adj_abon(uarmh, -uarmh->spe); break; case HELM_OF_OPPOSITE_ALIGNMENT: u.ualign.type = u.ualignbase[A_CURRENT]; u.ublessed = 0; /* lose the other god's protection */ flags.botl = 1; break; default: impossible(unknown_type, c_helmet, uarmh->otyp); } setworn((struct obj *)0, W_ARMH); return 0; } STATIC_PTR int Gloves_on() { long oldprop = u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES; switch(uarmg->otyp) { case LEATHER_GLOVES: break; case GAUNTLETS_OF_FUMBLING: if (!oldprop && !(HFumbling & ~TIMEOUT)) incr_itimeout(&HFumbling, rnd(20)); break; case GAUNTLETS_OF_POWER: makeknown(uarmg->otyp); flags.botl = 1; /* taken care of in attrib.c */ break; case GAUNTLETS_OF_DEXTERITY: adj_abon(uarmg, uarmg->spe); break; default: impossible(unknown_type, c_gloves, uarmg->otyp); } return 0; } int Gloves_off() { long oldprop = u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES; switch(uarmg->otyp) { case LEATHER_GLOVES: break; case GAUNTLETS_OF_FUMBLING: if (!oldprop && !(HFumbling & ~TIMEOUT)) HFumbling = EFumbling = 0; break; case GAUNTLETS_OF_POWER: makeknown(uarmg->otyp); flags.botl = 1; /* taken care of in attrib.c */ break; case GAUNTLETS_OF_DEXTERITY: adj_abon(uarmg, -uarmg->spe); break; default: impossible(unknown_type, c_gloves, uarmg->otyp); } setworn((struct obj *)0, W_ARMG); /* Prevent wielding cockatrice when not wearing gloves */ if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])) { char kbuf[BUFSZ]; You("wield the %s corpse in your bare %s.", mons[uwep->corpsenm].mname, makeplural(body_part(HAND))); Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname)); instapetrify(kbuf); uwepgone(); /* life-saved still doesn't allow touching cockatrice */ } /* KMH -- ...or your secondary weapon when you're wielding it */ if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE && touch_petrifies(&mons[uswapwep->corpsenm])) { char kbuf[BUFSZ]; You("wield the %s corpse in your bare %s.", mons[uswapwep->corpsenm].mname, body_part(HAND)); Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname)); instapetrify(kbuf); uswapwepgone(); /* life-saved still doesn't allow touching cockatrice */ } return 0; } /* STATIC_OVL int Shield_on() { switch(uarms->otyp) { case SMALL_SHIELD: case ELVEN_SHIELD: case URUK_HAI_SHIELD: case ORCISH_SHIELD: case DWARVISH_ROUNDSHIELD: case LARGE_SHIELD: case SHIELD_OF_REFLECTION: break; default: impossible(unknown_type, c_shield, uarms->otyp); } return 0; } */ int Shield_off() { /* switch(uarms->otyp) { case SMALL_SHIELD: case ELVEN_SHIELD: case URUK_HAI_SHIELD: case ORCISH_SHIELD: case DWARVISH_ROUNDSHIELD: case LARGE_SHIELD: case SHIELD_OF_REFLECTION: break; default: impossible(unknown_type, c_shield, uarms->otyp); } */ setworn((struct obj *)0, W_ARMS); return 0; } /* This must be done in worn.c, because one of the possible intrinsics conferred * is fire resistance, and we have to immediately set HFire_resistance in worn.c * since worn.c will check it before returning. */ STATIC_PTR int Armor_on() { return 0; } int Armor_off() { setworn((struct obj *)0, W_ARM); return 0; } /* The gone functions differ from the off functions in that if you die from * taking it off and have life saving, you still die. */ int Armor_gone() { setnotworn(uarm); return 0; } STATIC_OVL void Amulet_on() { switch(uamul->otyp) { case AMULET_OF_ESP: case AMULET_OF_LIFE_SAVING: case AMULET_VERSUS_POISON: case AMULET_OF_REFLECTION: case AMULET_OF_MAGICAL_BREATHING: case FAKE_AMULET_OF_YENDOR: break; case AMULET_OF_UNCHANGING: if (Slimed) { Slimed = 0; flags.botl = 1; } break; case AMULET_OF_CHANGE: { int orig_sex = poly_gender(); if (Unchanging) break; change_sex(); /* Don't use same message as polymorph */ if (orig_sex != poly_gender()) { makeknown(AMULET_OF_CHANGE); You("are suddenly very %s!", flags.female ? "feminine" : "masculine"); flags.botl = 1; } else /* already polymorphed into single-gender monster; only changed the character's base sex */ You("don't feel like yourself."); pline_The("amulet disintegrates!"); useup(uamul); break; } case AMULET_OF_STRANGULATION: makeknown(AMULET_OF_STRANGULATION); pline("It constricts your throat!"); Strangled = 6; break; case AMULET_OF_RESTFUL_SLEEP: HSleeping = rnd(100); break; case AMULET_OF_YENDOR: break; } } void Amulet_off() { switch(uamul->otyp) { case AMULET_OF_ESP: /* need to update ability before calling see_monsters() */ setworn((struct obj *)0, W_AMUL); see_monsters(); return; case AMULET_OF_LIFE_SAVING: case AMULET_VERSUS_POISON: case AMULET_OF_REFLECTION: case AMULET_OF_CHANGE: case AMULET_OF_UNCHANGING: case FAKE_AMULET_OF_YENDOR: break; case AMULET_OF_MAGICAL_BREATHING: if (Underwater) { if (!breathless(youmonst.data) && !amphibious(youmonst.data) && !Swimming) You("suddenly inhale an unhealthy amount of water!"); /* HMagical_breathing must be set off before calling drown() */ setworn((struct obj *)0, W_AMUL); (void) drown(); return; } break; case AMULET_OF_STRANGULATION: if (Strangled) { You("can breathe more easily!"); Strangled = 0; } break; case AMULET_OF_RESTFUL_SLEEP: setworn((struct obj *)0, W_AMUL); if (!ESleeping) HSleeping = 0; return; case AMULET_OF_YENDOR: break; } setworn((struct obj *)0, W_AMUL); return; } void Ring_on(obj) register struct obj *obj; { long oldprop = u.uprops[objects[obj->otyp].oc_oprop].extrinsic; int old_attrib; if (obj == uwep) setuwep((struct obj *) 0); if (obj == uswapwep) setuswapwep((struct obj *) 0); if (obj == uquiver) setuqwep((struct obj *) 0); /* only mask out W_RING when we don't have both left and right rings of the same type */ if ((oldprop & W_RING) != W_RING) oldprop &= ~W_RING; switch(obj->otyp){ case RIN_TELEPORTATION: case RIN_REGENERATION: case RIN_SEARCHING: case RIN_STEALTH: case RIN_HUNGER: case RIN_AGGRAVATE_MONSTER: case RIN_POISON_RESISTANCE: case RIN_FIRE_RESISTANCE: case RIN_COLD_RESISTANCE: case RIN_SHOCK_RESISTANCE: case RIN_CONFLICT: case RIN_TELEPORT_CONTROL: case RIN_POLYMORPH: case RIN_POLYMORPH_CONTROL: case RIN_FREE_ACTION: case RIN_SLOW_DIGESTION: case RIN_SUSTAIN_ABILITY: case MEAT_RING: break; case RIN_WARNING: see_monsters(); break; case RIN_SEE_INVISIBLE: /* can now see invisible monsters */ set_mimic_blocking(); /* do special mimic handling */ see_monsters(); #ifdef INVISIBLE_OBJECTS see_objects(); #endif if (Invis && !oldprop && !HSee_invisible && !perceives(youmonst.data) && !Blind) { newsym(u.ux,u.uy); pline("Suddenly you are transparent, but there!"); makeknown(RIN_SEE_INVISIBLE); } break; case RIN_INVISIBILITY: if (!oldprop && !HInvis && !BInvis && !Blind) { makeknown(RIN_INVISIBILITY); newsym(u.ux,u.uy); self_invis_message(); } break; case RIN_ADORNMENT: old_attrib = ACURR(A_CHA); ABON(A_CHA) += obj->spe; flags.botl = 1; if (ACURR(A_CHA) != old_attrib || (objects[RIN_ADORNMENT].oc_name_known && old_attrib != 25 && old_attrib != 3)) { makeknown(RIN_ADORNMENT); obj->known = TRUE; } break; case RIN_LEVITATION: if(!oldprop && !HLevitation) { float_up(); makeknown(RIN_LEVITATION); obj->known = TRUE; } break; case RIN_GAIN_STRENGTH: old_attrib = ACURR(A_STR); ABON(A_STR) += obj->spe; flags.botl = 1; if (ACURR(A_STR) != old_attrib || (objects[RIN_GAIN_STRENGTH].oc_name_known && old_attrib != STR19(25) && old_attrib != 3)) { makeknown(RIN_GAIN_STRENGTH); obj->known = TRUE; } break; case RIN_GAIN_CONSTITUTION: old_attrib = ACURR(A_CON); ABON(A_CON) += obj->spe; flags.botl = 1; if (ACURR(A_CON) != old_attrib || objects[RIN_GAIN_CONSTITUTION].oc_name_known) { makeknown(RIN_GAIN_CONSTITUTION); obj->known = TRUE; } break; case RIN_INCREASE_ACCURACY: /* KMH */ u.uhitinc += obj->spe; break; case RIN_INCREASE_DAMAGE: u.udaminc += obj->spe; break; case RIN_PROTECTION_FROM_SHAPE_CHAN: rescham(); break; case RIN_PROTECTION: flags.botl = 1; if (obj->spe || objects[RIN_PROTECTION].oc_name_known) { makeknown(RIN_PROTECTION); obj->known = TRUE; } break; } } STATIC_OVL void Ring_off_or_gone(obj,gone) register struct obj *obj; boolean gone; { register long mask = obj->owornmask & W_RING; int old_attrib; if(!(u.uprops[objects[obj->otyp].oc_oprop].extrinsic & mask)) impossible("Strange... I didn't know you had that ring."); if(gone) setnotworn(obj); else setworn((struct obj *)0, obj->owornmask); switch(obj->otyp) { case RIN_TELEPORTATION: case RIN_REGENERATION: case RIN_SEARCHING: case RIN_STEALTH: case RIN_HUNGER: case RIN_AGGRAVATE_MONSTER: case RIN_POISON_RESISTANCE: case RIN_FIRE_RESISTANCE: case RIN_COLD_RESISTANCE: case RIN_SHOCK_RESISTANCE: case RIN_CONFLICT: case RIN_TELEPORT_CONTROL: case RIN_POLYMORPH: case RIN_POLYMORPH_CONTROL: case RIN_FREE_ACTION: case RIN_SLOW_DIGESTION: case RIN_SUSTAIN_ABILITY: case MEAT_RING: break; case RIN_WARNING: see_monsters(); break; case RIN_SEE_INVISIBLE: /* Make invisible monsters go away */ if (!See_invisible) { set_mimic_blocking(); /* do special mimic handling */ see_monsters(); #ifdef INVISIBLE_OBJECTS see_objects(); #endif } if (Invisible && !Blind) { newsym(u.ux,u.uy); pline("Suddenly you cannot see yourself."); makeknown(RIN_SEE_INVISIBLE); } break; case RIN_INVISIBILITY: if (!Invis && !BInvis && !Blind) { newsym(u.ux,u.uy); Your("body seems to unfade%s.", See_invisible ? " completely" : ".."); makeknown(RIN_INVISIBILITY); } break; case RIN_ADORNMENT: old_attrib = ACURR(A_CHA); ABON(A_CHA) -= obj->spe; if (ACURR(A_CHA) != old_attrib) makeknown(RIN_ADORNMENT); flags.botl = 1; break; case RIN_LEVITATION: (void) float_down(0L, 0L); if (!Levitation) makeknown(RIN_LEVITATION); break; case RIN_GAIN_STRENGTH: old_attrib = ACURR(A_STR); ABON(A_STR) -= obj->spe; if (ACURR(A_STR) != old_attrib) makeknown(RIN_GAIN_STRENGTH); flags.botl = 1; break; case RIN_GAIN_CONSTITUTION: old_attrib = ACURR(A_CON); ABON(A_CON) -= obj->spe; flags.botl = 1; if (ACURR(A_CON) != old_attrib) makeknown(RIN_GAIN_CONSTITUTION); break; case RIN_INCREASE_ACCURACY: /* KMH */ u.uhitinc -= obj->spe; break; case RIN_INCREASE_DAMAGE: u.udaminc -= obj->spe; break; case RIN_PROTECTION_FROM_SHAPE_CHAN: /* If you're no longer protected, let the chameleons * change shape again -dgk */ restartcham(); break; } } void Ring_off(obj) struct obj *obj; { Ring_off_or_gone(obj,FALSE); } void Ring_gone(obj) struct obj *obj; { Ring_off_or_gone(obj,TRUE); } void Blindf_on(otmp) register struct obj *otmp; { long already_blinded = Blinded; if (otmp == uwep) setuwep((struct obj *) 0); if (otmp == uswapwep) setuswapwep((struct obj *) 0); if (otmp == uquiver) setuqwep((struct obj *) 0); setworn(otmp, W_TOOL); if (otmp->otyp == TOWEL && flags.verbose) You("wrap %s around your %s.", an(xname(otmp)), body_part(HEAD)); on_msg(otmp); if (!already_blinded) { if (Punished) set_bc(0); /* Set ball&chain variables before */ /* the hero goes blind. */ if (Blind_telepat || Infravision) see_monsters(); /* sense monsters */ vision_full_recalc = 1; /* recalc vision limits */ flags.botl = 1; } } void Blindf_off(otmp) register struct obj *otmp; { long was_blind = Blind; /* may still be able to see */ setworn((struct obj *)0, otmp->owornmask); off_msg(otmp); if (Blind) { if (otmp->otyp == LENSES) ; /* "still cannot see" makes no sense for lenses; do nothing */ else if (was_blind) You("still cannot see."); else You("cannot see anything now!"); } else if (!Blinded) { if (Blind_telepat || Infravision) see_monsters(); } vision_full_recalc = 1; /* recalc vision limits */ flags.botl = 1; } /* called in main to set intrinsics of worn start-up items */ void set_wear() { if (uarm) (void) Armor_on(); if (uarmc) (void) Cloak_on(); if (uarmf) (void) Boots_on(); if (uarmg) (void) Gloves_on(); if (uarmh) (void) Helmet_on(); /* if (uarms) (void) Shield_on(); */ } boolean donning(otmp) register struct obj *otmp; { return((boolean)((otmp == uarmf && (afternmv == Boots_on || afternmv == Boots_off)) || (otmp == uarmh && (afternmv == Helmet_on || afternmv == Helmet_off)) || (otmp == uarmg && (afternmv == Gloves_on || afternmv == Gloves_off)) || (otmp == uarm && (afternmv == Armor_on || afternmv == Armor_off)))); } void cancel_don() { /* the piece of armor we were donning/doffing has vanished, so stop * wasting time on it (and don't dereference it when donning would * otherwise finish) */ afternmv = 0; nomovemsg = (char *)0; multi = 0; } static NEARDATA const char clothes[] = {ARMOR_CLASS, 0}; static NEARDATA const char accessories[] = {RING_CLASS, AMULET_CLASS, TOOL_CLASS, FOOD_CLASS, 0}; int dotakeoff() { register struct obj *otmp = (struct obj *)0; int armorpieces = 0; #define MOREARM(x) if (x) { armorpieces++; otmp = x; } MOREARM(uarmh); MOREARM(uarms); MOREARM(uarmg); MOREARM(uarmf); if (uarmc) { armorpieces++; otmp = uarmc; } else if (uarm) { armorpieces++; otmp = uarm; #ifdef TOURIST } else if (uarmu) { armorpieces++; otmp = uarmu; #endif } if (!armorpieces) { /* assert( GRAY_DRAGON_SCALES > YELLOW_DRAGON_SCALE_MAIL ); */ if (uskin) pline_The("%s merged with your skin!", uskin->otyp >= GRAY_DRAGON_SCALES ? "dragon scales are" : "dragon scale mail is"); else pline("Not wearing any armor."); return 0; } if (armorpieces > 1) otmp = getobj(clothes, "take off"); if (otmp == 0) return(0); if (!(otmp->owornmask & W_ARMOR)) { You("are not wearing that."); return(0); } /* note: the `uskin' case shouldn't be able to happen here; dragons can't wear any armor so will end up with `armorpieces == 0' above */ if (otmp == uskin || ((otmp == uarm) && uarmc) #ifdef TOURIST || ((otmp == uarmu) && (uarmc || uarm)) #endif ) { You_cant("take that off."); return 0; } if (otmp == uarmg && welded(uwep)) { You("seem unable to take off the gloves while holding your %s.", is_sword(uwep) ? c_sword : c_weapon); uwep->bknown = TRUE; return 0; } if (otmp == uarmg && Glib) { You_cant("remove the slippery gloves with your slippery fingers."); return 0; } if (otmp == uarmf && u.utrap && (u.utraptype == TT_BEARTRAP || u.utraptype == TT_INFLOOR)) { /* -3. */ if(u.utraptype == TT_BEARTRAP) pline_The("bear trap prevents you from pulling your %s out.", body_part(FOOT)); else You("are stuck in the %s, and cannot pull your %s out.", surface(u.ux, u.uy), makeplural(body_part(FOOT))); return(0); } reset_remarm(); /* since you may change ordering */ (void) armoroff(otmp); return(1); } int doremring() { register struct obj *otmp = 0; int Accessories = 0; #define MOREACC(x) if (x) { Accessories++; otmp = x; } MOREACC(uleft); MOREACC(uright); MOREACC(uamul); MOREACC(ublindf); if(!Accessories) { pline("Not wearing any accessories."); return(0); } if (Accessories != 1) otmp = getobj(accessories, "take off"); if(!otmp) return(0); if(!(otmp->owornmask & (W_RING | W_AMUL | W_TOOL))) { You("are not wearing that."); return(0); } if(cursed(otmp)) return(0); if(otmp->oclass == RING_CLASS || otmp->otyp == MEAT_RING) { if (nolimbs(youmonst.data)) { pline("It seems to be stuck."); return(0); } if (uarmg && uarmg->cursed) { uarmg->bknown = TRUE; You( "seem unable to remove your ring without taking off your gloves."); return(0); } if (welded(uwep) && bimanual(uwep)) { uwep->bknown = TRUE; You( "seem unable to remove the ring while your hands hold your %s.", is_sword(uwep) ? c_sword : c_weapon); return(0); } if (welded(uwep) && otmp==uright) { uwep->bknown = TRUE; You( "seem unable to remove the ring while your right hand holds your %s.", is_sword(uwep) ? c_sword : c_weapon); return(0); } /* Sometimes we want to give the off_msg before removing and * sometimes after; for instance, "you were wearing a moonstone * ring (on right hand)" is desired but "you were wearing a * square amulet (being worn)" is not because of the redundant * "being worn". */ off_msg(otmp); Ring_off(otmp); } else if(otmp->oclass == AMULET_CLASS) { Amulet_off(); off_msg(otmp); } else Blindf_off(otmp); /* does its own off_msg */ return(1); } /* Check if something worn is cursed _and_ unremovable. */ int cursed(otmp) register struct obj *otmp; { /* Curses, like chickens, come home to roost. */ if((otmp == uwep) ? welded(otmp) : (int)otmp->cursed) { You("can't. %s to be cursed.", (is_boots(otmp) || is_gloves(otmp) || otmp->quan > 1L) ? "They seem" : "It seems"); otmp->bknown = TRUE; return(1); } return(0); } int armoroff(otmp) register struct obj *otmp; { register int delay = -objects[otmp->otyp].oc_delay; if(cursed(otmp)) return(0); if(delay) { nomul(delay); if (is_helmet(otmp)) { nomovemsg = "You finish taking off your helmet."; afternmv = Helmet_off; } else if (is_gloves(otmp)) { nomovemsg = "You finish taking off your gloves."; afternmv = Gloves_off; } else if (is_boots(otmp)) { nomovemsg = "You finish taking off your boots."; afternmv = Boots_off; } else { nomovemsg = "You finish taking off your suit."; afternmv = Armor_off; } } else { /* Be warned! We want off_msg after removing the item to * avoid "You were wearing ____ (being worn)." However, an * item which grants fire resistance might cause some trouble * if removed in Hell and lifesaving puts it back on; in this * case the message will be printed at the wrong time (after * the messages saying you died and were lifesaved). Luckily, * no cloak, shield, or fast-removable armor grants fire * resistance, so we can safely do the off_msg afterwards. * Rings do grant fire resistance, but for rings we want the * off_msg before removal anyway so there's no problem. Take * care in adding armors granting fire resistance; this code * might need modification. * 3.2 (actually 3.1 even): this comment is obsolete since * fire resistance is not needed for Gehennom. */ if(is_cloak(otmp)) (void) Cloak_off(); else if(is_shield(otmp)) (void) Shield_off(); else setworn((struct obj *)0, otmp->owornmask & W_ARMOR); off_msg(otmp); } takeoff_mask = taking_off = 0L; return(1); } STATIC_OVL void already_wearing(cc) const char *cc; { You("are already wearing %s%c", cc, (cc == c_that_) ? '!' : '.'); } STATIC_OVL void already_wearing2(cc1, cc2) const char *cc1, *cc2; { You_cant("wear %s because you're wearing %s there already.", cc1, cc2); } /* * canwearobj checks to see whether the player can wear a piece of armor * * inputs: otmp (the piece of armor) * noisy (if TRUE give error messages, otherwise be quiet about it) * output: mask (otmp's armor type) */ int canwearobj(otmp,mask,noisy) struct obj *otmp; long *mask; boolean noisy; { int err = 0; const char *which; which = is_cloak(otmp) ? c_cloak : #ifdef TOURIST is_shirt(otmp) ? c_shirt : #endif is_suit(otmp) ? c_suit : 0; if (which && cantweararm(youmonst.data) && /* same exception for cloaks as used in m_dowear() */ (which != c_cloak || youmonst.data->msize != MZ_SMALL)) { if (noisy) pline_The("%s will not fit on your body.", which); return 0; } else if (otmp->owornmask & W_ARMOR) { if (noisy) already_wearing(c_that_); return 0; } if (is_helmet(otmp)) { if (uarmh) { if (noisy) already_wearing(an(c_helmet)); err++; } else *mask = W_ARMH; } else if (is_shield(otmp)) { if (uarms) { if (noisy) already_wearing(an(c_shield)); err++; } else if (uwep && bimanual(uwep)) { if (noisy) You("cannot wear a shield while wielding a two-handed %s.", is_sword(uwep) ? c_sword : (uwep->otyp == BATTLE_AXE) ? c_axe : c_weapon); err++; } else if (u.twoweap) { if (noisy) You("cannot wear a shield while wielding two weapons."); err++; } else *mask = W_ARMS; } else if (is_boots(otmp)) { if (uarmf) { if (noisy) already_wearing(c_boots); err++; } else if (Upolyd && slithy(youmonst.data)) { if (noisy) You("have no feet..."); /* not body_part(FOOT) */ err++; } else if (u.utrap && (u.utraptype == TT_BEARTRAP || u.utraptype == TT_INFLOOR)) { if (u.utraptype == TT_BEARTRAP) { if (noisy) Your("%s is trapped!", body_part(FOOT)); } else { if (noisy) Your("%s are stuck in the %s!", makeplural(body_part(FOOT)), surface(u.ux, u.uy)); } err++; } else *mask = W_ARMF; } else if (is_gloves(otmp)) { if (uarmg) { if (noisy) already_wearing(c_gloves); err++; } else if (welded(uwep)) { if (noisy) You("cannot wear gloves over your %s.", is_sword(uwep) ? c_sword : c_weapon); err++; } else *mask = W_ARMG; #ifdef TOURIST } else if (is_shirt(otmp)) { if (uarm || uarmc || uarmu) { if (uarmu) { if (noisy) already_wearing(an(c_shirt)); } else { if (noisy) You_cant("wear that over your %s.", (uarm && !uarmc) ? c_armor : c_cloak); } err++; } else *mask = W_ARMU; #endif } else if (is_cloak(otmp)) { if (uarmc) { if (noisy) already_wearing(an(c_cloak)); err++; } else *mask = W_ARMC; } else if (is_suit(otmp)) { if (uarmc) { if (noisy) You("cannot wear armor over a cloak."); err++; } else if (uarm) { if (noisy) already_wearing("some armor"); err++; } else *mask = W_ARM; } else { /* getobj can't do this after setting its allow_all flag; that happens if you have armor for slots that are covered up or extra armor for slots that are filled */ if (noisy) pline(silly_thing_to, "wear"); err++; } /* Unnecessary since now only weapons and special items like pick-axes get * welded to your hand, not armor if (welded(otmp)) { if (!err++) { if (noisy) weldmsg(otmp); } } */ return !err; } /* the 'W' command */ int dowear() { struct obj *otmp; int delay; long mask = 0; /* cantweararm checks for suits of armor */ /* verysmall or nohands checks for shields, gloves, etc... */ if ((verysmall(youmonst.data) || nohands(youmonst.data))) { pline("Don't even bother."); return(0); } otmp = getobj(clothes, "wear"); if(!otmp) return(0); if (!canwearobj(otmp,&mask,TRUE)) return(0); if (otmp->oartifact && !touch_artifact(otmp, &youmonst)) return 1; /* costs a turn even though it didn't get worn */ if (otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT && qstart_level.dnum == u.uz.dnum) { /* in quest */ You("narrowly avoid losing all chance at your goal."); u.ublessed = 0; /* lose your god's protection */ makeknown(otmp->otyp); flags.botl = 1; return 1; } otmp->known = TRUE; if(otmp == uwep) setuwep((struct obj *)0); if (otmp == uswapwep) setuswapwep((struct obj *) 0); if (otmp == uquiver) setuqwep((struct obj *) 0); setworn(otmp, mask); delay = -objects[otmp->otyp].oc_delay; if(delay){ nomul(delay); if(is_boots(otmp)) afternmv = Boots_on; if(is_helmet(otmp)) afternmv = Helmet_on; if(is_gloves(otmp)) afternmv = Gloves_on; if(otmp == uarm) afternmv = Armor_on; nomovemsg = "You finish your dressing maneuver."; } else { if(is_cloak(otmp)) (void) Cloak_on(); /* if(is_shield(otmp)) (void) Shield_on(); */ on_msg(otmp); } takeoff_mask = taking_off = 0L; return(1); } int doputon() { register struct obj *otmp; long mask = 0L; if(uleft && uright && uamul && ublindf) { Your("%s%s are full, and you're already wearing an amulet and %s.", humanoid(youmonst.data) ? "ring-" : "", makeplural(body_part(FINGER)), ublindf->otyp==LENSES ? "some lenses" : "a blindfold"); return(0); } otmp = getobj(accessories, "wear"); if(!otmp) return(0); if(otmp->owornmask & (W_RING | W_AMUL | W_TOOL)) { already_wearing(c_that_); return(0); } if(welded(otmp)) { weldmsg(otmp); return(0); } if(otmp == uwep) setuwep((struct obj *)0); if(otmp->oclass == RING_CLASS || otmp->otyp == MEAT_RING) { if(nolimbs(youmonst.data)) { You("cannot make the ring stick to your body."); return(0); } if(uleft && uright){ There("are no more %s%s to fill.", humanoid(youmonst.data) ? "ring-" : "", makeplural(body_part(FINGER))); return(0); } if(uleft) mask = RIGHT_RING; else if(uright) mask = LEFT_RING; else do { char qbuf[QBUFSZ]; char answer; Sprintf(qbuf, "Which %s%s, Right or Left?", humanoid(youmonst.data) ? "ring-" : "", body_part(FINGER)); if(!(answer = yn_function(qbuf, "rl", '\0'))) return(0); switch(answer){ case 'l': case 'L': mask = LEFT_RING; break; case 'r': case 'R': mask = RIGHT_RING; break; } } while(!mask); if (uarmg && uarmg->cursed) { uarmg->bknown = TRUE; You("cannot remove your gloves to put on the ring."); return(0); } if (welded(uwep) && bimanual(uwep)) { /* welded will set bknown */ You("cannot free your weapon hands to put on the ring."); return(0); } if (welded(uwep) && mask==RIGHT_RING) { /* welded will set bknown */ You("cannot free your weapon hand to put on the ring."); return(0); } setworn(otmp, mask); Ring_on(otmp); } else if (otmp->oclass == AMULET_CLASS) { if(uamul) { already_wearing("an amulet"); return(0); } setworn(otmp, W_AMUL); if (otmp->otyp == AMULET_OF_CHANGE) { Amulet_on(); /* Don't do a prinv() since the amulet is now gone */ return(1); } Amulet_on(); } else { /* it's a blindfold, towel, or lenses */ if (ublindf) { if (ublindf->otyp == TOWEL) Your("%s is already covered by a towel.", body_part(FACE)); else if (ublindf->otyp == BLINDFOLD) { if (otmp->otyp == LENSES) already_wearing2("lenses", "a blindfold"); else already_wearing("a blindfold"); } else if (ublindf->otyp == LENSES) { if (otmp->otyp == BLINDFOLD) already_wearing2("a blindfold", "some lenses"); else already_wearing("some lenses"); } else already_wearing(something); /* ??? */ return(0); } if (otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL && otmp->otyp != LENSES) { You_cant("wear that!"); return(0); } Blindf_on(otmp); return(1); } prinv((char *)0, otmp, 0L); return(1); } #endif /* OVLB */ #ifdef OVL0 void find_ac() { int uac = mons[u.umonnum].ac; if(uarm) uac -= ARM_BONUS(uarm); if(uarmc) uac -= ARM_BONUS(uarmc); if(uarmh) uac -= ARM_BONUS(uarmh); if(uarmf) uac -= ARM_BONUS(uarmf); if(uarms) uac -= ARM_BONUS(uarms); if(uarmg) uac -= ARM_BONUS(uarmg); #ifdef TOURIST if(uarmu) uac -= ARM_BONUS(uarmu); #endif if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe; if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe; if (HProtection & INTRINSIC) uac -= u.ublessed; uac -= u.uspellprot; if(uac != u.uac){ u.uac = uac; flags.botl = 1; } } #endif /* OVL0 */ #ifdef OVLB void glibr() { register struct obj *otmp; int xfl = 0; boolean leftfall, rightfall; leftfall = (uleft && !uleft->cursed && (!uwep || !welded(uwep) || !bimanual(uwep))); rightfall = (uright && !uright->cursed && (!welded(uwep))); if (!uarmg && (leftfall || rightfall) && !nolimbs(youmonst.data)) { /* changed so cursed rings don't fall off, GAN 10/30/86 */ Your("%s off your %s.", (leftfall && rightfall) ? "rings slip" : "ring slips", makeplural(body_part(FINGER))); xfl++; if (leftfall) { otmp = uleft; Ring_off(uleft); dropx(otmp); } if (rightfall) { otmp = uright; Ring_off(uright); dropx(otmp); } } otmp = uswapwep; if (u.twoweap && otmp) { Your("%s %sslips from your %s.", is_sword(otmp) ? c_sword : makesingular(oclass_names[(int)otmp->oclass]), xfl ? "also " : "", makeplural(body_part(HAND))); setuswapwep((struct obj *)0); xfl++; if (otmp->otyp != LOADSTONE || !otmp->cursed) dropx(otmp); } otmp = uwep; if (otmp && !welded(otmp)) { /* changed so cursed weapons don't fall, GAN 10/30/86 */ Your("%s %sslips from your %s.", is_sword(otmp) ? c_sword : makesingular(oclass_names[(int)otmp->oclass]), xfl ? "also " : "", makeplural(body_part(HAND))); setuwep((struct obj *)0); if (otmp->otyp != LOADSTONE || !otmp->cursed) dropx(otmp); } } struct obj * some_armor(victim) struct monst *victim; { register struct obj *otmph, *otmp; otmph = (victim == &youmonst) ? uarmc : which_armor(victim, W_ARMC); if (!otmph) otmph = (victim == &youmonst) ? uarm : which_armor(victim, W_ARM); #ifdef TOURIST if (!otmph) otmph = (victim == &youmonst) ? uarmu : which_armor(victim, W_ARMU); #endif otmp = (victim == &youmonst) ? uarmh : which_armor(victim, W_ARMH); if(otmp && (!otmph || !rn2(4))) otmph = otmp; otmp = (victim == &youmonst) ? uarmg : which_armor(victim, W_ARMG); if(otmp && (!otmph || !rn2(4))) otmph = otmp; otmp = (victim == &youmonst) ? uarmf : which_armor(victim, W_ARMF); if(otmp && (!otmph || !rn2(4))) otmph = otmp; otmp = (victim == &youmonst) ? uarms : which_armor(victim, W_ARMS); if(otmp && (!otmph || !rn2(4))) otmph = otmp; return(otmph); } void erode_armor(victim,acid_dmg) struct monst *victim; boolean acid_dmg; { register struct obj *otmph = some_armor(victim); int erosion; boolean vismon = (victim != &youmonst) && canseemon(victim); if (!otmph) return; erosion = acid_dmg ? otmph->oeroded2 : otmph->oeroded; if (otmph != uarmf) { if (otmph->greased) { grease_protect(otmph,(char *)0,FALSE,victim); return; } if (otmph->oerodeproof || (acid_dmg ? !is_corrodeable(otmph) : !is_rustprone(otmph))) { if (flags.verbose || !(otmph->oerodeproof && otmph->rknown)) { if (victim == &youmonst) Your("%s not affected.", aobjnam(otmph, "are")); else if (vismon) pline("%s's %s not affected.", Monnam(victim), aobjnam(otmph, "are")); } if (otmph->oerodeproof) otmph->rknown = TRUE; return; } if (erosion < MAX_ERODE) { if (victim == &youmonst) Your("%s%s!", aobjnam(otmph, acid_dmg ? "corrode" : "rust"), erosion+1 == MAX_ERODE ? " completely" : erosion ? " further" : ""); else if (vismon) pline("%s's %s%s!", Monnam(victim), aobjnam(otmph, acid_dmg ? "corrode" : "rust"), erosion+1 == MAX_ERODE ? " completely" : erosion ? " further" : ""); if (acid_dmg) otmph->oeroded2++; else otmph->oeroded++; return; } if (flags.verbose) { if (victim == &youmonst) Your("%s completely %s.", aobjnam(otmph, Blind ? "feel" : "look"), acid_dmg ? "corroded" : "rusty"); else if (vismon) pline("%s's %s completely %s.", Monnam(victim), aobjnam(otmph, "look"), acid_dmg ? "corroded" : "rusty"); } } } STATIC_PTR int select_off(otmp) register struct obj *otmp; { if(!otmp) return(0); if(cursed(otmp)) return(0); if((otmp->oclass==RING_CLASS || otmp->otyp == MEAT_RING) && nolimbs(youmonst.data)) return(0); if(welded(uwep) && (otmp==uarmg || otmp==uright || (otmp==uleft && bimanual(uwep)))) return(0); if(uarmg && uarmg->cursed && (otmp==uright || otmp==uleft)) { uarmg->bknown = TRUE; return(0); } if(otmp == uarmf && u.utrap && (u.utraptype == TT_BEARTRAP || u.utraptype == TT_INFLOOR)) { return (0); } if((otmp==uarm #ifdef TOURIST || otmp==uarmu #endif ) && uarmc && uarmc->cursed) { uarmc->bknown = TRUE; return(0); } #ifdef TOURIST if(otmp==uarmu && uarm && uarm->cursed) { uarm->bknown = TRUE; return(0); } #endif if(otmp == uarm) takeoff_mask |= WORN_ARMOR; else if(otmp == uarmc) takeoff_mask |= WORN_CLOAK; else if(otmp == uarmf) takeoff_mask |= WORN_BOOTS; else if(otmp == uarmg) takeoff_mask |= WORN_GLOVES; else if(otmp == uarmh) takeoff_mask |= WORN_HELMET; else if(otmp == uarms) takeoff_mask |= WORN_SHIELD; #ifdef TOURIST else if(otmp == uarmu) takeoff_mask |= WORN_SHIRT; #endif else if(otmp == uleft) takeoff_mask |= LEFT_RING; else if(otmp == uright) takeoff_mask |= RIGHT_RING; else if(otmp == uamul) takeoff_mask |= WORN_AMUL; else if(otmp == ublindf) takeoff_mask |= WORN_BLINDF; else if(otmp == uwep) takeoff_mask |= W_WEP; else if(otmp == uswapwep) takeoff_mask |= W_SWAPWEP; else if(otmp == uquiver) takeoff_mask |= W_QUIVER; else impossible("select_off: %s???", doname(otmp)); return(0); } STATIC_OVL struct obj * do_takeoff() { register struct obj *otmp = (struct obj *)0; if (taking_off == W_WEP) { if(!cursed(uwep)) { setuwep((struct obj *) 0); You("are empty %s.", body_part(HANDED)); u.twoweap = FALSE; } } else if (taking_off == W_SWAPWEP) { setuswapwep((struct obj *) 0); You("no longer have a second weapon readied."); u.twoweap = FALSE; } else if (taking_off == W_QUIVER) { setuqwep((struct obj *) 0); You("no longer have ammunition readied."); } else if (taking_off == WORN_ARMOR) { otmp = uarm; if(!cursed(otmp)) (void) Armor_off(); } else if (taking_off == WORN_CLOAK) { otmp = uarmc; if(!cursed(otmp)) (void) Cloak_off(); } else if (taking_off == WORN_BOOTS) { otmp = uarmf; if(!cursed(otmp)) (void) Boots_off(); } else if (taking_off == WORN_GLOVES) { otmp = uarmg; if(!cursed(otmp)) (void) Gloves_off(); } else if (taking_off == WORN_HELMET) { otmp = uarmh; if(!cursed(otmp)) (void) Helmet_off(); } else if (taking_off == WORN_SHIELD) { otmp = uarms; if(!cursed(otmp)) (void) Shield_off(); #ifdef TOURIST } else if (taking_off == WORN_SHIRT) { otmp = uarmu; if(!cursed(otmp)) setworn((struct obj *)0, uarmu->owornmask & W_ARMOR); #endif } else if (taking_off == WORN_AMUL) { otmp = uamul; if(!cursed(otmp)) Amulet_off(); } else if (taking_off == LEFT_RING) { otmp = uleft; if(!cursed(otmp)) Ring_off(uleft); } else if (taking_off == RIGHT_RING) { otmp = uright; if(!cursed(otmp)) Ring_off(uright); } else if (taking_off == WORN_BLINDF) { if(!cursed(ublindf)) { setworn((struct obj *)0, ublindf->owornmask); if(!Blinded) make_blinded(1L,FALSE); /* See on next move */ else You("still cannot see."); } } else impossible("do_takeoff: taking off %lx", taking_off); return(otmp); } STATIC_PTR int take_off() { register int i; register struct obj *otmp; if(taking_off) { if(todelay > 0) { todelay--; return(1); /* still busy */ } else if((otmp = do_takeoff())) off_msg(otmp); takeoff_mask &= ~taking_off; taking_off = 0L; } for(i = 0; takeoff_order[i]; i++) if(takeoff_mask & takeoff_order[i]) { taking_off = takeoff_order[i]; break; } otmp = (struct obj *) 0; todelay = 0; if (taking_off == 0L) { You("finish disrobing."); return 0; } else if (taking_off == W_WEP) { todelay = 1; } else if (taking_off == W_SWAPWEP) { todelay = 1; } else if (taking_off == W_QUIVER) { todelay = 1; } else if (taking_off == WORN_ARMOR) { otmp = uarm; /* If a cloak is being worn, add the time to take it off and put * it back on again. Kludge alert! since that time is 0 for all * known cloaks, add 1 so that it actually matters... */ if (uarmc) todelay += 2 * objects[uarmc->otyp].oc_delay + 1; } else if (taking_off == WORN_CLOAK) { otmp = uarmc; } else if (taking_off == WORN_BOOTS) { otmp = uarmf; } else if (taking_off == WORN_GLOVES) { otmp = uarmg; } else if (taking_off == WORN_HELMET) { otmp = uarmh; } else if (taking_off == WORN_SHIELD) { otmp = uarms; #ifdef TOURIST } else if (taking_off == WORN_SHIRT) { otmp = uarmu; /* add the time to take off and put back on armor and/or cloak */ if (uarm) todelay += 2 * objects[uarm->otyp].oc_delay; if (uarmc) todelay += 2 * objects[uarmc->otyp].oc_delay + 1; #endif } else if (taking_off == WORN_AMUL) { todelay = 1; } else if (taking_off == LEFT_RING) { todelay = 1; } else if (taking_off == RIGHT_RING) { todelay = 1; } else if (taking_off == WORN_BLINDF) { todelay = 2; } else { impossible("take_off: taking off %lx", taking_off); return 0; /* force done */ } if (otmp) todelay += objects[otmp->otyp].oc_delay; /* Since setting the occupation now starts the counter next move, that * would always produce a delay 1 too big per item unless we subtract * 1 here to account for it. */ if (todelay>0) todelay--; set_occupation(take_off, "disrobing", 0); return(1); /* get busy */ } #endif /* OVLB */ #ifdef OVL1 void reset_remarm() { taking_off = takeoff_mask = 0L; } #endif /* OVL1 */ #ifdef OVLB int doddoremarm() { int result = 0; if (taking_off || takeoff_mask) { You("continue disrobing."); set_occupation(take_off, "disrobing", 0); (void) take_off(); return 0; } else if (!uwep && !uswapwep && !uquiver && !uamul && !ublindf && !uleft && !uright && !wearing_armor()) { You("are not wearing anything."); return 0; } add_valid_menu_class(0); /* reset */ if (flags.menu_style != MENU_TRADITIONAL || (result = ggetobj("take off", select_off, 0, FALSE)) < -1) result = menu_remarm(result); if (takeoff_mask) (void) take_off(); /* The time to perform the command is already completely accounted for * in take_off(); if we return 1, that would add an extra turn to each * disrobe. */ return 0; } STATIC_OVL int menu_remarm(retry) int retry; { int n, i = 0; menu_item *pick_list; boolean all_worn_categories = TRUE; if (retry) { all_worn_categories = (retry == -2); } else if (flags.menu_style == MENU_FULL) { all_worn_categories = FALSE; n = query_category("What type of things do you want to take off?", invent, WORN_TYPES|ALL_TYPES, &pick_list, PICK_ANY); if (!n) return 0; for (i = 0; i < n; i++) { if (pick_list[i].item.a_int == ALL_TYPES_SELECTED) all_worn_categories = TRUE; else add_valid_menu_class(pick_list[i].item.a_int); } free((genericptr_t) pick_list); } else if (flags.menu_style == MENU_COMBINATION) { all_worn_categories = FALSE; if (ggetobj("take off", select_off, 0, TRUE) == -2) all_worn_categories = TRUE; } n = query_objlist("What do you want to take off?", invent, SIGNAL_NOMENU|USE_INVLET|INVORDER_SORT, &pick_list, PICK_ANY, all_worn_categories ? is_worn : is_worn_by_type); if (n > 0) { for (i = 0; i < n; i++) (void) select_off(pick_list[i].item.a_obj); free((genericptr_t) pick_list); } else if (n < 0) { There("is nothing else you can remove or unwield."); } return 0; } int destroy_arm(atmp) register struct obj *atmp; { register struct obj *otmp; #define DESTROY_ARM(o) ((otmp = (o)) != 0 && \ (!atmp || atmp == otmp) && \ (!obj_resists(otmp, 0, 90))) if (DESTROY_ARM(uarmc)) { Your("cloak crumbles and turns to dust!"); (void) Cloak_off(); useup(otmp); } else if (DESTROY_ARM(uarm)) { /* may be disintegrated by spell or dragon breath... */ if (donning(otmp)) cancel_don(); Your("armor turns to dust and falls to the %s!", surface(u.ux,u.uy)); (void) Armor_gone(); useup(otmp); #ifdef TOURIST } else if (DESTROY_ARM(uarmu)) { Your("shirt crumbles into tiny threads and falls apart!"); useup(otmp); #endif } else if (DESTROY_ARM(uarmh)) { if (donning(otmp)) cancel_don(); Your("helmet turns to dust and is blown away!"); (void) Helmet_off(); useup(otmp); } else if (DESTROY_ARM(uarmg)) { if (donning(otmp)) cancel_don(); Your("gloves vanish!"); (void) Gloves_off(); useup(otmp); selftouch("You"); } else if (DESTROY_ARM(uarmf)) { if (donning(otmp)) cancel_don(); Your("boots disintegrate!"); (void) Boots_off(); useup(otmp); } else if (DESTROY_ARM(uarms)) { Your("shield crumbles away!"); (void) Shield_off(); useup(otmp); } else return(0); /* could not destroy anything */ #undef DESTROY_ARM return(1); } void adj_abon(otmp, delta) register struct obj *otmp; register schar delta; { if (uarmg && uarmg == otmp && otmp->otyp == GAUNTLETS_OF_DEXTERITY) { if (delta) { makeknown(uarmg->otyp); ABON(A_DEX) += (delta); } flags.botl = 1; } if (uarmh && uarmh == otmp && otmp->otyp == HELM_OF_BRILLIANCE) { if (delta) { makeknown(uarmh->otyp); ABON(A_INT) += (delta); ABON(A_WIS) += (delta); } flags.botl = 1; } } #endif /* OVLB */ /*do_wear.c*/