fix #H4475 - shop message about disenchanted item

drain_item() always assumed player was responsible, so called
costly_alteration() to adjust shop price of disenchanted item.
If it was unpaid and the effect was caused by a disenchanter
attack rather than by the hero, the feedback was nonsensical.

This also lets a disenchanter hit worn rings, amulet, or blindfold
if no armor gets targetted.  Amulets, blindfolds, and most rings
have no charge to be drained, but several types of rings do.
This commit is contained in:
PatR
2016-08-10 02:04:09 -07:00
parent 62fd796271
commit a72d19b905
6 changed files with 50 additions and 19 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitm.c $NHDT-Date: 1456992461 2016/03/03 08:07:41 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.86 $ */
/* NetHack 3.6 mhitm.c $NHDT-Date: 1470819842 2016/08/10 09:04:02 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.92 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1524,7 +1524,7 @@ int mdead;
goto assess_dmg;
case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
if (mhit && !mdef->mcan && otmp) {
(void) drain_item(otmp);
(void) drain_item(otmp, FALSE);
/* No message */
}
break;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitu.c $NHDT-Date: 1456992469 2016/03/03 08:07:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.136 $ */
/* NetHack 3.6 mhitu.c $NHDT-Date: 1470819843 2016/08/10 09:04:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.144 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1597,7 +1597,27 @@ register struct attack *mattk;
if (uncancelled) {
struct obj *obj = some_armor(&youmonst);
if (drain_item(obj)) {
if (!obj) {
/* some rings are susceptible;
amulets and blindfolds aren't (at present) */
switch (rn2(5)) {
case 0:
break;
case 1:
obj = uright;
break;
case 2:
obj = uleft;
break;
case 3:
obj = uamul;
break;
case 4:
obj = ublindf;
break;
}
}
if (drain_item(obj, FALSE)) {
pline("%s less effective.", Yobjnam2(obj, "seem"));
}
}
@@ -2691,7 +2711,9 @@ register struct attack *mattk;
}
case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
if (otmp) {
(void) drain_item(otmp);
/* by_you==True: passive counterattack to hero's action
is hero's fault */
(void) drain_item(otmp, TRUE);
/* No message */
}
return 1;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1460103141 2016/04/08 08:12:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.156 $ */
/* NetHack 3.6 uhitm.c $NHDT-Date: 1470819843 2016/08/10 09:04:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.164 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2537,12 +2537,12 @@ boolean wep_was_destroyed;
*/
void
passive_obj(mon, obj, mattk)
register struct monst *mon;
register struct obj *obj; /* null means pick uwep, uswapwep or uarmg */
struct monst *mon;
struct obj *obj; /* null means pick uwep, uswapwep or uarmg */
struct attack *mattk; /* null means we find one internally */
{
struct permonst *ptr = mon->data;
register int i;
int i;
/* if caller hasn't specified an object, use uwep, uswapwep or uarmg */
if (!obj) {
@@ -2589,7 +2589,7 @@ struct attack *mattk; /* null means we find one internally */
break;
case AD_ENCH:
if (!mon->mcan) {
if (drain_item(obj) && carried(obj)
if (drain_item(obj, TRUE) && carried(obj)
&& (obj->known || obj->oclass == ARMOR_CLASS)) {
pline("%s less effective.", Yobjnam2(obj, "seem"));
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 zap.c $NHDT-Date: 1464163779 2016/05/25 08:09:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.258 $ */
/* NetHack 3.6 zap.c $NHDT-Date: 1470819844 2016/08/10 09:04:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.263 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1062,8 +1062,9 @@ register struct obj *obj;
* possibly carried by you or a monster
*/
boolean
drain_item(obj)
register struct obj *obj;
drain_item(obj, by_you)
struct obj *obj;
boolean by_you;
{
boolean u_ring;
@@ -1078,7 +1079,8 @@ register struct obj *obj;
return FALSE;
/* Charge for the cost of the object */
costly_alteration(obj, COST_DRAIN);
if (by_you)
costly_alteration(obj, COST_DRAIN);
/* Drain the object and any implied effects */
obj->spe--;
@@ -1110,6 +1112,10 @@ register struct obj *obj;
if ((obj->owornmask & W_RING) && u_ring)
u.udaminc--;
break;
case RIN_PROTECTION:
if (u_ring)
context.botl = 1; /* bot() will recalc u.uac */
break;
case HELM_OF_BRILLIANCE:
if ((obj->owornmask & W_ARMH) && (obj == uarmh)) {
ABON(A_INT)--;
@@ -1123,10 +1129,11 @@ register struct obj *obj;
context.botl = 1;
}
break;
case RIN_PROTECTION:
context.botl = 1;
default:
break;
}
if (context.botl)
bot();
if (carried(obj))
update_inventory();
return TRUE;
@@ -1935,7 +1942,7 @@ struct obj *obj, *otmp;
#endif
break;
case SPE_DRAIN_LIFE:
(void) drain_item(obj);
(void) drain_item(obj, TRUE);
break;
case WAN_TELEPORTATION:
case SPE_TELEPORT_AWAY: