-/* NetHack 3.6 extern.h $NHDT-Date: 1440120640 2015/08/21 01:30:40 $ $NHDT-Branch: master $:$NHDT-Revision: 1.506 $ */
+/* NetHack 3.6 extern.h $NHDT-Date: 1445126411 2015/10/18 00:00:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.508 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
E int FDECL(mon_wield_item, (struct monst *));
E int NDECL(abon);
E int NDECL(dbon);
+E void FDECL(wet_a_towel, (struct obj *, int, BOOLEAN_P));
+E void FDECL(dry_a_towel, (struct obj *, int, BOOLEAN_P));
E int NDECL(enhance_weapon_skill);
E void FDECL(unrestrict_weapon_skill, (int));
E void FDECL(use_skill, (int, int));
-/* NetHack 3.6 obj.h $NHDT-Date: 1432512782 2015/05/25 00:13:02 $ $NHDT-Branch: master $:$NHDT-Revision: 1.49 $ */
+/* NetHack 3.6 obj.h $NHDT-Date: 1445126423 2015/10/18 00:00:23 $ $NHDT-Branch: master $:$NHDT-Revision: 1.50 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
&& objects[otmp->otyp].oc_skill <= -P_DART)
#define is_weptool(o) \
((o)->oclass == TOOL_CLASS && objects[(o)->otyp].oc_skill != P_NONE)
+ /* towel is not a weptool: spe isn't an enchantment, cursed towel
+ doesn't weld to hand, and twoweapon won't work with one */
+#define is_wet_towel(o) ((o)->otyp == TOWEL && (o)->spe > 0)
#define bimanual(otmp) \
((otmp->oclass == WEAPON_CLASS || otmp->oclass == TOOL_CLASS) \
&& objects[otmp->otyp].oc_bimanual)
-/* NetHack 3.6 apply.c $NHDT-Date: 1440120650 2015/08/21 01:30:50 $ $NHDT-Branch: master $:$NHDT-Revision: 1.201 $ */
+/* NetHack 3.6 apply.c $NHDT-Date: 1445126424 2015/10/18 00:00:24 $ $NHDT-Branch: master $:$NHDT-Revision: 1.206 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
use_towel(obj)
struct obj *obj;
{
+ boolean drying_feedback = (obj == uwep);
+
if (!freehand()) {
You("have no free %s!", body_part(HAND));
return 0;
incr_itimeout(&Glib, rn1(10, 3));
Your("%s %s!", makeplural(body_part(HAND)),
(old ? "are filthier than ever" : "get slimy"));
- if (obj->spe > 0) obj->spe--;
+ if (is_wet_towel(obj))
+ dry_a_towel(obj, -1, drying_feedback);
return 1;
case 1:
if (!ublindf) {
dropx(saved_ublindf);
}
}
- if (obj->spe > 0) obj->spe--;
+ if (is_wet_towel(obj))
+ dry_a_towel(obj, -1, drying_feedback);
return 1;
case 0:
break;
if (Glib) {
Glib = 0;
You("wipe off your %s.", makeplural(body_part(HAND)));
- if (obj->spe > 0) obj->spe--;
+ if (is_wet_towel(obj))
+ dry_a_towel(obj, -1, drying_feedback);
return 1;
} else if (u.ucreamed) {
Blinded -= u.ucreamed;
u.ucreamed = 0;
- if (obj->spe > 0) obj->spe--;
-
if (!Blinded) {
pline("You've got the glop off.");
if (!gulp_blnd_check()) {
} else {
Your("%s feels clean now.", body_part(FACE));
}
+ if (is_wet_towel(obj))
+ dry_a_towel(obj, -1, drying_feedback);
return 1;
}
-/* NetHack 3.6 objnam.c $NHDT-Date: 1444617222 2015/10/12 02:33:42 $ $NHDT-Branch: master $:$NHDT-Revision: 1.143 $ */
+/* NetHack 3.6 objnam.c $NHDT-Date: 1445126428 2015/10/18 00:00:28 $ $NHDT-Branch: master $:$NHDT-Revision: 1.148 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
case TOOL_CLASS:
if (typ == LENSES)
Strcpy(buf, "pair of ");
- else if (typ == TOWEL && obj->spe > 0)
+ else if (is_wet_towel(obj))
Strcpy(buf, (obj->spe < 3) ? "moist " : "wet ");
if (!dknown)
Strcat(buf, dn ? dn : actualn);
/* If we use an() here we'd have to remember never to use */
/* it whenever calling doname() or xname(). */
- if (typ == FIGURINE && omndx != NON_PM)
+ if (typ == FIGURINE && omndx != NON_PM) {
Sprintf(eos(buf), " of a%s %s",
index(vowels, *mons[omndx].mname) ? "n" : "",
mons[omndx].mname);
+ } else if (is_wet_towel(obj)) {
+ if (wizard)
+ Sprintf(eos(buf), " (%d)", obj->spe);
+ }
break;
case ARMOR_CLASS:
/* depends on order of the dragon scales objects */
}
break;
case TOWEL:
- if (wetness) otmp->spe = wetness;
+ if (wetness)
+ otmp->spe = wetness;
break;
case SLIME_MOLD:
otmp->spe = ftype;
-/* NetHack 3.6 trap.c $NHDT-Date: 1436753526 2015/07/13 02:12:06 $ $NHDT-Branch: master $:$NHDT-Revision: 1.237 $ */
+/* NetHack 3.6 trap.c $NHDT-Date: 1445126429 2015/10/18 00:00:29 $ $NHDT-Branch: master $:$NHDT-Revision: 1.241 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
"pungent", "chilling",
"acrid", "biting" };
-/* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode) */
-boolean /* returns TRUE if hit on torso */
- burnarmor(victim)
+/* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode);
+ returns TRUE if hit on torso */
+boolean
+burnarmor(victim)
struct monst *victim;
{
struct obj *item;
char buf[BUFSZ];
- int mat_idx;
+ int mat_idx, oldspe;
+ boolean hitting_u;
if (!victim)
return 0;
+ hitting_u = (victim == &youmonst);
+
+ /* burning damage may dry wet towel */
+ item = hitting_u ? carrying(TOWEL) : m_carrying(victim, TOWEL);
+ while (item) {
+ if (is_wet_towel(item)) {
+ oldspe = item->spe;
+ dry_a_towel(item, rn2(oldspe + 1), TRUE);
+ if (item->spe != oldspe)
+ break; /* stop once one towel has been affected */
+ }
+ item = item->nobj;
+ }
+
#define burn_dmg(obj, descr) erode_obj(obj, descr, ERODE_BURN, EF_GREASE)
while (1) {
switch (rn2(5)) {
case 0:
- item =
- (victim == &youmonst) ? uarmh : which_armor(victim, W_ARMH);
+ item = hitting_u ? uarmh : which_armor(victim, W_ARMH);
if (item) {
mat_idx = objects[item->otyp].oc_material;
Sprintf(buf, "%s %s", materialnm[mat_idx],
continue;
break;
case 1:
- item =
- (victim == &youmonst) ? uarmc : which_armor(victim, W_ARMC);
+ item = hitting_u ? uarmc : which_armor(victim, W_ARMC);
if (item) {
(void) burn_dmg(item, cloak_simple_name(item));
return TRUE;
}
- item = (victim == &youmonst) ? uarm : which_armor(victim, W_ARM);
+ item = hitting_u ? uarm : which_armor(victim, W_ARM);
if (item) {
(void) burn_dmg(item, xname(item));
return TRUE;
}
- item =
- (victim == &youmonst) ? uarmu : which_armor(victim, W_ARMU);
+ item = hitting_u ? uarmu : which_armor(victim, W_ARMU);
if (item)
(void) burn_dmg(item, "shirt");
return TRUE;
case 2:
- item =
- (victim == &youmonst) ? uarms : which_armor(victim, W_ARMS);
+ item = hitting_u ? uarms : which_armor(victim, W_ARMS);
if (!burn_dmg(item, "wooden shield"))
continue;
break;
case 3:
- item =
- (victim == &youmonst) ? uarmg : which_armor(victim, W_ARMG);
+ item = hitting_u ? uarmg : which_armor(victim, W_ARMG);
if (!burn_dmg(item, "gloves"))
continue;
break;
case 4:
- item =
- (victim == &youmonst) ? uarmf : which_armor(victim, W_ARMF);
+ item = hitting_u ? uarmf : which_armor(victim, W_ARMF);
if (!burn_dmg(item, "boots"))
continue;
break;
}
break; /* Out of while loop */
}
- return FALSE;
#undef burn_dmg
+
+ return FALSE;
}
/* Generic erode-item function.
if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
return ER_NOTHING;
} else if (obj->otyp == TOWEL && obj->spe < 7) {
- obj->spe = max(obj->spe, rn2(8));
+ wet_a_towel(obj, rnd(7), TRUE);
return ER_NOTHING;
} else if (obj->greased) {
if (!rn2(2))
-/* NetHack 3.6 uhitm.c $NHDT-Date: 1432512769 2015/05/25 00:12:49 $ $NHDT-Branch: master $:$NHDT-Revision: 1.144 $ */
+/* NetHack 3.6 uhitm.c $NHDT-Date: 1445126430 2015/10/18 00:00:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.148 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
tmp = (obj->corpsenm >= LOW_PM ? mons[obj->corpsenm].msize
: 0) + 1;
break;
- case EGG: {
+
#define useup_eggs(o) \
{ \
if (thrown) \
useupall(o); \
o = (struct obj *) 0; \
} /* now gone */
+ case EGG: {
long cnt = obj->quan;
tmp = 1; /* nominal physical damage */
/* non-weapons can damage because of their weight */
/* (but not too much) */
tmp = obj->owt / 100;
- if (obj->otyp == TOWEL && obj->spe > 0) { /* wet towel */
+ if (is_wet_towel(obj)) {
+ /* wielded wet towel should probably use whip skill
+ (but not by setting objects[TOWEL].oc_skill==P_WHIP
+ because that would turn towel into a weptool) */
tmp += obj->spe;
- obj->spe--;
+ if (rn2(obj->spe + 1)) /* usually lose some wetness */
+ dry_a_towel(obj, -1, TRUE);
}
if (tmp < 1)
tmp = 1;
monflee(mon, 10 * rnd(tmp), FALSE, FALSE);
}
if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
- &&
/* pudding is alive and healthy enough to split */
- mon->mhp > 1 && !mon->mcan &&
+ && mon->mhp > 1 && !mon->mcan
/* iron weapon using melee or polearm hit */
- obj && obj == uwep && objects[obj->otyp].oc_material == IRON
+ && obj && obj == uwep && objects[obj->otyp].oc_material == IRON
&& hand_to_hand) {
if (clone_mon(mon, 0, 0)) {
pline("%s divides as you hit it!", Monnam(mon));
-/* NetHack 3.6 weapon.c $NHDT-Date: 1436753527 2015/07/13 02:12:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.51 $ */
+/* NetHack 3.6 weapon.c $NHDT-Date: 1445126431 2015/10/18 00:00:31 $ $NHDT-Branch: master $:$NHDT-Revision: 1.54 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
static NEARDATA const char kebabable[] = { S_XORN, S_DRAGON, S_JABBERWOCK,
S_NAGA, S_GIANT, '\0' };
-/* weapon's skill category name for use as generalized description of weapon
- */
+/* weapon's skill category name for use as generalized description of weapon;
+ mostly used to shorten "you drop your <weapon>" messages when slippery
+ fingers or polymorph causes hero to involuntarily drop wielded weapon(s) */
const char *
weapon_descr(obj)
struct obj *obj;
/* assorted special cases */
switch (skill) {
case P_NONE:
- /* not a weapon: use item class name; override "food" for corpses,
- tins, and eggs and "large rock" for statues and boulders */
+ /* not a weapon or weptool: use item class name;
+ override class name "food" for corpses, tins, and eggs,
+ "large rock" for statues and boulders, and "tool" for towels */
descr = (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG
- || obj->otyp == STATUE || obj->otyp == BOULDER)
+ || obj->otyp == STATUE || obj->otyp == BOULDER
+ || obj->otyp == TOWEL)
? OBJ_NAME(objects[obj->otyp])
: def_oc_syms[(int) obj->oclass].name;
break;
if (is_ammo(obj))
descr = (obj->otyp == ROCK || is_graystone(obj))
? "stone"
- :
/* avoid "rock"; what about known glass? */
- (obj->oclass == GEM_CLASS)
+ : (obj->oclass == GEM_CLASS)
? "gem"
- :
/* in case somebody adds odd sling ammo */
- def_oc_syms[(int) obj->oclass].name;
+ : def_oc_syms[(int) obj->oclass].name;
break;
case P_BOW:
if (is_ammo(obj))
}
}
-int abon() /* attack bonus for strength & dexterity */
+/* attack bonus for strength & dexterity */
+int
+abon()
{
int sbon;
int str = ACURR(A_STR), dex = ACURR(A_DEX);
return (sbon + dex - 14);
}
-int dbon() /* damage bonus for strength */
+/* damage bonus for strength */
+int
+dbon()
{
int str = ACURR(A_STR);
return (6);
}
+/* increase a towel's wetness */
+void
+wet_a_towel(obj, amt, verbose)
+struct obj *obj;
+int amt; /* positive: new value; negative: increment by -amt; zero: no-op */
+boolean verbose;
+{
+ int newspe = (amt <= 0) ? obj->spe - amt : amt;
+
+ /* new state is only reported if it's an increase */
+ if (newspe > obj->spe) {
+ if (verbose) {
+ const char *wetness = (newspe < 3)
+ ? (!obj->spe ? "damp" : "damper")
+ : (!obj->spe ? "wet" : "wetter");
+
+ if (carried(obj))
+ pline("%s gets %s.", Yobjnam2(obj, (const char *) 0),
+ wetness);
+ else if (mcarried(obj) && canseemon(obj->ocarry))
+ pline("%s %s gets %s.", s_suffix(Monnam(obj->ocarry)),
+ xname(obj), wetness);
+ }
+ }
+ obj->spe = min(newspe, 7);
+
+ /* if hero is wielding this towel, don't give "you begin bashing
+ with your wet towel" message on next attack with it */
+ if (obj == uwep)
+ unweapon = !is_wet_towel(obj);
+}
+
+/* decrease a towel's wetness */
+void
+dry_a_towel(obj, amt, verbose)
+struct obj *obj;
+int amt; /* positive: new value; negative: decrement by -amt; zero: no-op */
+boolean verbose;
+{
+ int newspe = (amt <= 0) ? obj->spe + amt : amt;
+
+ /* new state is only reported if it's a decrease */
+ if (newspe < obj->spe) {
+ if (verbose) {
+ if (carried(obj))
+ pline("%s dries%s.", Yobjnam2(obj, (const char *) 0),
+ !newspe ? " out" : "");
+ else if (mcarried(obj) && canseemon(obj->ocarry))
+ pline("%s %s drie%s.", s_suffix(Monnam(obj->ocarry)),
+ xname(obj), !newspe ? " out" : "");
+ }
+ }
+ newspe = min(newspe, 7);
+ obj->spe = max(newspe, 0);
+
+ /* if hero is wielding this towel and it is now dry, give "you begin
+ bashing with your towel" message on next attack with it */
+ if (obj == uwep)
+ unweapon = !is_wet_towel(obj);
+}
+
/* copy the skill level name into the given buffer */
STATIC_OVL char *
skill_level_name(skill, buf)
-/* NetHack 3.6 wield.c $NHDT-Date: 1437877186 2015/07/26 02:19:46 $ $NHDT-Branch: master $:$NHDT-Revision: 1.44 $ */
+/* NetHack 3.6 wield.c $NHDT-Date: 1445126432 2015/10/18 00:00:32 $ $NHDT-Branch: master $:$NHDT-Revision: 1.45 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
* with the main weapon. If the "pushweapon" option is set,
* the (w)ield command will also store the old weapon in the
* secondary slot.
- * 2. Can be field with anything that will fit in the main weapon
+ * 2. Can be filled with anything that will fit in the main weapon
* slot; that is, any type of item.
* 3. Is usually NOT considered to be carried in the hands.
* That would force too many checks among the main weapon,
* 5. Never conveys intrinsics.
* 6. Cursed items never weld; their effect is handled by the normal
* throwing code.
+ * 7. The autoquiver option will fill it with something deemed
+ * suitable if (f)ire is used when it's empty.
*
* No item may be in more than one of these slots.
*/
unweapon = (obj->oclass == WEAPON_CLASS)
? is_launcher(obj) || is_ammo(obj) || is_missile(obj)
|| (is_pole(obj) && !u.usteed)
- : !is_weptool(obj);
+ : !is_weptool(obj) && !is_wet_towel(obj);
} else
unweapon = TRUE; /* for "bare hands" message */
update_inventory();
res++;
if (will_weld(wep)) {
const char *tmp = xname(wep), *thestr = "The ";
+
if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp), thestr, 4))
tmp = thestr;
else
* say "weapon in hand", thus this kludge.
*/
long dummy = wep->owornmask;
+
wep->owornmask |= W_WEP;
prinv((char *) 0, wep, 0L);
wep->owornmask = dummy;
pline("%s to shine %s!", Tobjnam(wep, "begin"),
arti_light_description(wep));
}
-
#if 0
- /* we'll get back to this someday, but it's not balanced yet */
- if (Race_if(PM_ELF) && !wep->oartifact &&
- objects[wep->otyp].oc_material == IRON) {
- /* Elves are averse to wielding cold iron */
- You("have an uneasy feeling about wielding cold iron.");
- change_luck(-1);
- }
+ /* we'll get back to this someday, but it's not balanced yet */
+ if (Race_if(PM_ELF) && !wep->oartifact
+ && objects[wep->otyp].oc_material == IRON) {
+ /* Elves are averse to wielding cold iron */
+ You("have an uneasy feeling about wielding cold iron.");
+ change_luck(-1);
+ }
#endif
-
if (wep->unpaid) {
struct monst *this_shkp;
return (0);
else if (wep == uwep) {
You("are already wielding that!");
- if (is_weptool(wep))
+ if (is_weptool(wep) || is_wet_towel(wep))
unweapon = FALSE; /* [see setuwep()] */
return (0);
} else if (welded(uwep)) {
return (0);
}
-/* used for #rub and for applying pick-axe, whip, grappling hook, or polearm
- */
-/* (moved from apply.c) */
+/* used for #rub and for applying pick-axe, whip, grappling hook or polearm */
boolean
wield_tool(obj, verb)
struct obj *obj;