add and use new APIs, Tobjnam, otense and vtense, is_plural to determine tense/form of verbs and a few pronouns as well
2012 lines
50 KiB
C
2012 lines
50 KiB
C
/* SCCS Id: @(#)do_wear.c 3.4 2001/12/06 */
|
|
/* 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 boolean cancelled_don = FALSE;
|
|
|
|
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) {
|
|
char how[BUFSZ];
|
|
|
|
how[0] = '\0';
|
|
if (otmp->otyp == TOWEL)
|
|
Sprintf(how, " around your %s", body_part(HEAD));
|
|
You("are now wearing %s%s.",
|
|
obj_is_pname(otmp) ? the(xname(otmp)) : an(xname(otmp)),
|
|
how);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* 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();
|
|
spoteffects(FALSE);
|
|
}
|
|
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 && !cancelled_don) {
|
|
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) && !cancelled_don) {
|
|
makeknown(otyp);
|
|
/* make boots known in case you survive the drowning */
|
|
spoteffects(TRUE);
|
|
}
|
|
break;
|
|
case ELVEN_BOOTS:
|
|
if (!oldprop && !HStealth && !BStealth && !cancelled_don) {
|
|
makeknown(otyp);
|
|
You("sure are noisy.");
|
|
}
|
|
break;
|
|
case FUMBLE_BOOTS:
|
|
if (!oldprop && !(HFumbling & ~TIMEOUT))
|
|
HFumbling = EFumbling = 0;
|
|
break;
|
|
case LEVITATION_BOOTS:
|
|
if (!oldprop && !HLevitation && !cancelled_don) {
|
|
(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);
|
|
}
|
|
cancelled_don = FALSE;
|
|
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:
|
|
case LEATHER_CLOAK:
|
|
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 very tightly.", Tobjnam(uarmc, "fit"));
|
|
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:
|
|
case LEATHER_CLOAK:
|
|
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) {
|
|
if (Blind)
|
|
pline("%s for a moment.", Tobjnam(uarmh, "vibrate"));
|
|
else
|
|
pline("%s %s for a moment.",
|
|
Tobjnam(uarmh, "glow"), 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:
|
|
if (!cancelled_don) {
|
|
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:
|
|
if (!cancelled_don) 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);
|
|
cancelled_don = FALSE;
|
|
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:
|
|
if (!cancelled_don) adj_abon(uarmg, -uarmg->spe);
|
|
break;
|
|
default: impossible(unknown_type, c_gloves, uarmg->otyp);
|
|
}
|
|
setworn((struct obj *)0, W_ARMG);
|
|
cancelled_don = FALSE;
|
|
|
|
/* Prevent wielding cockatrice when not wearing gloves */
|
|
if (uwep && uwep->otyp == CORPSE &&
|
|
touch_petrifies(&mons[uwep->corpsenm])) {
|
|
char kbuf[BUFSZ];
|
|
|
|
You("wield the %s in your bare %s.",
|
|
corpse_xname(uwep, TRUE), makeplural(body_part(HAND)));
|
|
Strcpy(kbuf, an(corpse_xname(uwep, TRUE)));
|
|
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 in your bare %s.",
|
|
corpse_xname(uswapwep, TRUE), body_part(HAND));
|
|
|
|
Strcpy(kbuf, an(corpse_xname(uswapwep, TRUE)));
|
|
instapetrify(kbuf);
|
|
uswapwepgone(); /* lifesaved 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);
|
|
cancelled_don = FALSE;
|
|
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);
|
|
cancelled_don = FALSE;
|
|
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!");
|
|
if (orig_sex == poly_gender() && uamul->dknown &&
|
|
!objects[AMULET_OF_CHANGE].oc_name_known &&
|
|
!objects[AMULET_OF_CHANGE].oc_uname)
|
|
docall(uamul);
|
|
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) {
|
|
/* HMagical_breathing must be set off
|
|
before calling drown() */
|
|
setworn((struct obj *)0, W_AMUL);
|
|
if (!breathless(youmonst.data) && !amphibious(youmonst.data)
|
|
&& !Swimming) {
|
|
You("suddenly inhale an unhealthy amount of water!");
|
|
(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;
|
|
spoteffects(FALSE); /* for sinks */
|
|
}
|
|
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;
|
|
update_inventory();
|
|
}
|
|
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;
|
|
{
|
|
boolean already_blind = Blind, changed = FALSE;
|
|
|
|
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);
|
|
on_msg(otmp);
|
|
|
|
if (Blind && !already_blind) {
|
|
changed = TRUE;
|
|
if (flags.verbose) You_cant("see any more.");
|
|
/* set ball&chain variables before the hero goes blind */
|
|
if (Punished) set_bc(0);
|
|
} else if (already_blind && !Blind) {
|
|
changed = TRUE;
|
|
/* "You are now wearing the Eyes of the Overworld." */
|
|
You("can see!");
|
|
}
|
|
if (changed) {
|
|
/* blindness has just been toggled */
|
|
if (Blind_telepat || Infravision) see_monsters();
|
|
vision_full_recalc = 1; /* recalc vision limits */
|
|
flags.botl = 1;
|
|
}
|
|
}
|
|
|
|
void
|
|
Blindf_off(otmp)
|
|
register struct obj *otmp;
|
|
{
|
|
boolean was_blind = Blind, changed = FALSE;
|
|
|
|
setworn((struct obj *)0, otmp->owornmask);
|
|
off_msg(otmp);
|
|
|
|
if (Blind) {
|
|
if (was_blind) {
|
|
/* "still cannot see" makes no sense when removing lenses
|
|
since they can't have been the cause of your blindness */
|
|
if (otmp->otyp != LENSES)
|
|
You("still cannot see.");
|
|
} else {
|
|
changed = TRUE; /* !was_blind */
|
|
/* "You were wearing the Eyes of the Overworld." */
|
|
You_cant("see anything now!");
|
|
/* set ball&chain variables before the hero goes blind */
|
|
if (Punished) set_bc(0);
|
|
}
|
|
} else if (was_blind) {
|
|
changed = TRUE; /* !Blind */
|
|
You("can see again.");
|
|
}
|
|
if (changed) {
|
|
/* blindness has just been toggled */
|
|
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)
|
|
*/
|
|
cancelled_don = (afternmv == Boots_on || afternmv == Helmet_on ||
|
|
afternmv == Gloves_on || afternmv == Armor_on);
|
|
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;
|
|
} else if (welded(uwep) && bimanual(uwep) &&
|
|
(otmp == uarm
|
|
#ifdef TOURIST
|
|
|| otmp == uarmu
|
|
#endif
|
|
)) {
|
|
You("seem unable to take off %s while holding your %s.",
|
|
the(xname(otmp)), 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 (welded(uwep) && bimanual(uwep) &&
|
|
(otmp == uarm
|
|
#ifdef TOURIST
|
|
|| otmp == uarmu
|
|
#endif
|
|
)) {
|
|
if (noisy)
|
|
You("cannot do that while holding your %s.",
|
|
is_sword(uwep) ? c_sword : c_weapon);
|
|
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 : cloak_simple_name(uarmc));
|
|
}
|
|
err++;
|
|
} else
|
|
*mask = W_ARMU;
|
|
#endif
|
|
} else if (is_cloak(otmp)) {
|
|
if (uarmc) {
|
|
if (noisy) already_wearing(an(cloak_simple_name(uarmc)));
|
|
err++;
|
|
} else
|
|
*mask = W_ARMC;
|
|
} else if (is_suit(otmp)) {
|
|
if (uarmc) {
|
|
if (noisy) You("cannot wear armor over a %s.", cloak_simple_name(uarmc));
|
|
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 == uswapwep)
|
|
setuswapwep((struct obj *) 0);
|
|
if(otmp == uquiver)
|
|
setuqwep((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);
|
|
}
|
|
if (is_worn(otmp))
|
|
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 < -128) uac = -128; /* u.uac is an schar */
|
|
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);
|
|
}
|
|
|
|
/* erode some arbitrary armor worn by the victim */
|
|
void
|
|
erode_armor(victim, acid_dmg)
|
|
struct monst *victim;
|
|
boolean acid_dmg;
|
|
{
|
|
struct obj *otmph = some_armor(victim);
|
|
|
|
if (otmph && (otmph != uarmf)) {
|
|
erode_obj(otmph, acid_dmg, FALSE);
|
|
}
|
|
}
|
|
|
|
STATIC_PTR
|
|
int
|
|
select_off(otmp)
|
|
register struct obj *otmp;
|
|
{
|
|
char buf[BUFSZ];
|
|
|
|
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)))) {
|
|
You("cannot free a weapon hand to take off the ring.");
|
|
return(0);
|
|
}
|
|
if(uarmg && uarmg->cursed && (otmp==uright || otmp==uleft)) {
|
|
uarmg->bknown = TRUE;
|
|
You("cannot remove your gloves to take off the ring.");
|
|
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) {
|
|
Strcpy(buf, the(xname(uarmc)));
|
|
You("cannot remove %s to take off %s.", buf, the(xname(otmp)));
|
|
uarmc->bknown = TRUE;
|
|
return(0);
|
|
}
|
|
#ifdef TOURIST
|
|
if(otmp==uarmu && uarm && uarm->cursed) {
|
|
Strcpy(buf, the(xname(uarm)));
|
|
You("cannot remove %s to take off %s.", buf, the(xname(otmp)));
|
|
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)) Blindf_off(ublindf);
|
|
} 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, (unsigned *)0)) < -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, (unsigned *)0) == -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 && flags.menu_style != MENU_COMBINATION) {
|
|
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("%s crumbles and turns to dust!", cloak_simple_name(uarmc));
|
|
(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*/
|