still more silver - untouchable objects (trunk only)
When retouch_object() prevents hero to wielding or wearing a silver object, dish out some damage. Do the same for <foo>bane if hero is a <foo>.
This commit is contained in:
+50
-12
@@ -18,6 +18,7 @@ extern boolean notonhead; /* for long worms */
|
|||||||
#define get_artifact(o) \
|
#define get_artifact(o) \
|
||||||
(((o)&&(o)->oartifact) ? &artilist[(int) (o)->oartifact] : 0)
|
(((o)&&(o)->oartifact) ? &artilist[(int) (o)->oartifact] : 0)
|
||||||
|
|
||||||
|
STATIC_DCL boolean FDECL(bane_applies, (const struct artifact *,struct monst *));
|
||||||
STATIC_DCL int FDECL(spec_applies, (const struct artifact *,struct monst *));
|
STATIC_DCL int FDECL(spec_applies, (const struct artifact *,struct monst *));
|
||||||
STATIC_DCL int FDECL(arti_invoke, (struct obj*));
|
STATIC_DCL int FDECL(arti_invoke, (struct obj*));
|
||||||
STATIC_DCL boolean FDECL(Mb_hit, (struct monst *magr,struct monst *mdef,
|
STATIC_DCL boolean FDECL(Mb_hit, (struct monst *magr,struct monst *mdef,
|
||||||
@@ -497,6 +498,11 @@ long wp_mask;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* touch_artifact()'s return value isn't sufficient to tell whether it
|
||||||
|
dished out damage, and tracking changes to u.uhp, u.mh, Lifesaved
|
||||||
|
when trying to avoid second wounding is too cumbersome */
|
||||||
|
STATIC_VAR touch_blasted; /* for retouch_object() */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* creature (usually player) tries to touch (pick up or wield) an artifact obj.
|
* creature (usually player) tries to touch (pick up or wield) an artifact obj.
|
||||||
* Returns 0 if the object refuses to be touched.
|
* Returns 0 if the object refuses to be touched.
|
||||||
@@ -512,6 +518,7 @@ touch_artifact(obj,mon)
|
|||||||
register const struct artifact *oart = get_artifact(obj);
|
register const struct artifact *oart = get_artifact(obj);
|
||||||
boolean badclass, badalign, self_willed, yours;
|
boolean badclass, badalign, self_willed, yours;
|
||||||
|
|
||||||
|
touch_blasted = FALSE;
|
||||||
if(!oart) return 1;
|
if(!oart) return 1;
|
||||||
|
|
||||||
yours = (mon == &youmonst);
|
yours = (mon == &youmonst);
|
||||||
@@ -536,22 +543,20 @@ touch_artifact(obj,mon)
|
|||||||
}
|
}
|
||||||
/* weapons which attack specific categories of monsters are
|
/* weapons which attack specific categories of monsters are
|
||||||
bad for them even if their alignments happen to match */
|
bad for them even if their alignments happen to match */
|
||||||
if (!badalign && (oart->spfx & SPFX_DBONUS) != 0) {
|
if (!badalign) badalign = bane_applies(oart, mon);
|
||||||
struct artifact tmp;
|
|
||||||
|
|
||||||
tmp = *oart;
|
|
||||||
tmp.spfx &= SPFX_DBONUS;
|
|
||||||
badalign = !!spec_applies(&tmp, mon);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((badclass || badalign) && self_willed) ||
|
if (((badclass || badalign) && self_willed) ||
|
||||||
(badalign && (!yours || !rn2(4)))) {
|
(badalign && (!yours || !rn2(4)))) {
|
||||||
int dmg;
|
int dmg, tmp;
|
||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
|
|
||||||
if (!yours) return 0;
|
if (!yours) return 0;
|
||||||
You("are blasted by %s power!", s_suffix(the(xname(obj))));
|
You("are blasted by %s power!", s_suffix(the(xname(obj))));
|
||||||
|
touch_blasted = TRUE;
|
||||||
dmg = d((Antimagic ? 2 : 4), (self_willed ? 10 : 4));
|
dmg = d((Antimagic ? 2 : 4), (self_willed ? 10 : 4));
|
||||||
|
/* add half (maybe quarter) of the usual silver damage bonus */
|
||||||
|
if (objects[obj->otyp].oc_material == SILVER && Hate_silver)
|
||||||
|
tmp = rnd(10), dmg += Maybe_Half_Phys(tmp);
|
||||||
Sprintf(buf, "touching %s", oart->name);
|
Sprintf(buf, "touching %s", oart->name);
|
||||||
losehp(dmg, buf, KILLED_BY); /* magic damage, not physical */
|
losehp(dmg, buf, KILLED_BY); /* magic damage, not physical */
|
||||||
exercise(A_WIS, FALSE);
|
exercise(A_WIS, FALSE);
|
||||||
@@ -587,6 +592,21 @@ int dtyp;
|
|||||||
weap->cary.adtyp == dtyp);
|
weap->cary.adtyp == dtyp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC_OVL boolean
|
||||||
|
bane_applies(oart, mon)
|
||||||
|
const struct artifact *oart;
|
||||||
|
struct monst *mon;
|
||||||
|
{
|
||||||
|
struct artifact atmp;
|
||||||
|
|
||||||
|
if (oart && (oart->spfx & SPFX_DBONUS) != 0) {
|
||||||
|
atmp = *oart;
|
||||||
|
atmp.spfx &= SPFX_DBONUS; /* clear other spfx fields */
|
||||||
|
if (spec_applies(&atmp, mon)) return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* decide whether an artifact's special attacks apply against mtmp */
|
/* decide whether an artifact's special attacks apply against mtmp */
|
||||||
STATIC_OVL int
|
STATIC_OVL int
|
||||||
spec_applies(weap, mtmp)
|
spec_applies(weap, mtmp)
|
||||||
@@ -1612,11 +1632,29 @@ boolean loseit; /* whether to drop it if hero can longer touch it */
|
|||||||
struct obj *obj = *objp;
|
struct obj *obj = *objp;
|
||||||
|
|
||||||
if (touch_artifact(obj, &youmonst)) {
|
if (touch_artifact(obj, &youmonst)) {
|
||||||
/* nothing to do if hero can successfully handle this object */
|
char buf[BUFSZ];
|
||||||
if (!(objects[obj->otyp].oc_material == SILVER && Hate_silver))
|
int dmg = 0, tmp;
|
||||||
|
boolean ag = (objects[obj->otyp].oc_material == SILVER && Hate_silver),
|
||||||
|
bane = bane_applies(get_artifact(obj), &youmonst);
|
||||||
|
|
||||||
|
/* nothing else to do if hero can successfully handle this object */
|
||||||
|
if (!ag && !bane)
|
||||||
return 1;
|
return 1;
|
||||||
/* we didn't get "<obj> evades your grasp" message; give alt message */
|
|
||||||
You_cant("handle %s anymore!", thesimpleoname(obj));
|
/* hero can't handle this object, but didn't get touch_artifact()'s
|
||||||
|
"<obj> evades your grasp|control" message; give an alternate one */
|
||||||
|
You_cant("handle %s%s!",
|
||||||
|
yname(obj), obj->owornmask ? " anymore" : "");
|
||||||
|
/* also inflict damage unless touch_artifact() already did so */
|
||||||
|
if (!touch_blasted) {
|
||||||
|
/* damage is somewhat arbitrary; half the usual 1d20 physical
|
||||||
|
for silver, 1d10 magical for <foo>bane, potentially both */
|
||||||
|
if (ag) tmp = rnd(10), dmg += Maybe_Half_Phys(tmp);
|
||||||
|
if (bane) dmg += rnd(10);
|
||||||
|
Sprintf(buf, "handling %s", killer_xname(obj));
|
||||||
|
losehp(dmg, buf, KILLED_BY);
|
||||||
|
exercise(A_CON, FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* removing a worn item might result in loss of levitation,
|
/* removing a worn item might result in loss of levitation,
|
||||||
|
|||||||
Reference in New Issue
Block a user