mimic-as-door stealing key (trunk only)
Suggested by <email deleted> a month ago when he
reported that attempting to unlock a door which was actually a mimic
simply told the player that the door was not locked or that there was
no door. He thought that mimic should take the key/pick/card away from
the hero. This gives a 50% chance for the unlocking tool to be stolen
and become part of the mimic's inventory; it will be dropped when mimic
is killed.
The theft routine has groundwork to be able to be used to take the
hero's wielded or thrown weapon when hitting, but the attack code doesn't
call it so that won't happen (and the theft code hasn't been tested under
that circumstance). I'm not sure whether mimics should be able to grab
weapons, but g.cubes perhaps should, and if puddings could then "pudding
farming" [using a low damage iron weapon to split puddings, yielding tons
of experience, death drops, and #offer fodder when they're killed and
repeatable for as long as at least one pudding is kept healthy enough to
be split again] would become tougher to accomplish. [The item drop and
corpse aspects have been toned down quite a bit since 3.4.3, but with
sufficient patience it is still possible to abuse.]
This commit is contained in:
@@ -467,6 +467,7 @@ Add M-C and M-R meta-key shortcuts for #conduct and #ride, respectively
|
||||
can now use ESC to cancel out of prompts for playing musical instruments
|
||||
being crowned gives an additional benefit: one extra skill slot/credit
|
||||
chatting to a gecko or shopkeeper while hallucinating gives alternate message
|
||||
mimic posing as door might steal hero's key when [un]locking is attempted
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
@@ -2171,6 +2171,7 @@ E void FDECL(remove_worn_item, (struct obj *,BOOLEAN_P));
|
||||
E int FDECL(steal, (struct monst *, char *));
|
||||
E int FDECL(mpickobj, (struct monst *,struct obj *));
|
||||
E void FDECL(stealamulet, (struct monst *));
|
||||
E void FDECL(maybe_absorb_item, (struct monst *,struct obj *,int,int));
|
||||
E void FDECL(mdrop_obj, (struct monst *,struct obj *,BOOLEAN_P));
|
||||
E void FDECL(mdrop_special_objs, (struct monst *));
|
||||
E void FDECL(relobj, (struct monst *,int,BOOLEAN_P));
|
||||
|
||||
@@ -406,6 +406,8 @@ pick_lock(pick)
|
||||
mtmp->mappearance == S_hcdoor)) {
|
||||
/* "The door actually was a <mimic>!" */
|
||||
stumble_onto_mimic(mtmp);
|
||||
/* mimic might keep the key (50% chance, 10% for PYEC) */
|
||||
maybe_absorb_item(mtmp, pick, 50, 10);
|
||||
return PICKLOCK_LEARNED_SOMETHING;
|
||||
}
|
||||
if(!IS_DOOR(door->typ)) {
|
||||
|
||||
44
src/steal.c
44
src/steal.c
@@ -509,6 +509,10 @@ register struct obj *otmp;
|
||||
pline("%s out.", Tobjnam(otmp, "go"));
|
||||
snuff_otmp = TRUE;
|
||||
}
|
||||
/* if monster is acquiring a thrown or kicked object, the throwing
|
||||
or kicking code shouldn't continue to track and place it */
|
||||
if (otmp == thrownobj) thrownobj = 0;
|
||||
else if (otmp == kickedobj) kickedobj = 0;
|
||||
/* for hero owned object on shop floor, mtmp is taking possession
|
||||
and if it's eventually dropped in a shop, shk will claim it */
|
||||
if (!mtmp->mtame) otmp->no_charge = 0;
|
||||
@@ -571,6 +575,46 @@ struct monst *mtmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* when a mimic gets poked with something, it might take that thing
|
||||
(at present, only implemented for when the hero does the poking) */
|
||||
void
|
||||
maybe_absorb_item(mon, obj, ochance, achance)
|
||||
struct monst *mon;
|
||||
struct obj *obj;
|
||||
int ochance, achance; /* percent chance for ordinary item, artifact */
|
||||
{
|
||||
if (obj == uball || obj == uchain || obj->oclass == ROCK_CLASS ||
|
||||
obj_resists(obj, 100 - ochance, 100 - achance) ||
|
||||
!touch_artifact(obj, mon))
|
||||
return;
|
||||
|
||||
if (carried(obj)) {
|
||||
if (obj->owornmask) remove_worn_item(obj, TRUE);
|
||||
if (obj->unpaid) subfrombill(obj, shop_keeper(*u.ushops));
|
||||
if (cansee(mon->mx, mon->my)) {
|
||||
const char *MonName = Monnam(mon);
|
||||
|
||||
/* mon might be invisible; avoid "It pulls ... and absorbs it!" */
|
||||
if (!strcmp(MonName, "It")) MonName = "Something";
|
||||
pline("%s pulls %s away from you and absorbs %s!",
|
||||
MonName, yname(obj), (obj->quan > 1L) ? "them" : "it");
|
||||
} else {
|
||||
const char *hand_s = body_part(HAND);
|
||||
|
||||
if (bimanual(obj)) hand_s = makeplural(hand_s);
|
||||
pline("%s %s pulled from your %s!",
|
||||
upstart(yname(obj)), otense(obj, "are"), hand_s);
|
||||
}
|
||||
freeinv(obj);
|
||||
} else {
|
||||
/* not carried; presumeably thrown or kicked */
|
||||
if (canspotmon(mon))
|
||||
pline("%s absorbs %s!", Monnam(mon), yname(obj));
|
||||
}
|
||||
/* add to mon's inventory */
|
||||
(void) mpickobj(mon, obj);
|
||||
}
|
||||
|
||||
/* drop one object taken from a (possibly dead) monster's inventory */
|
||||
void
|
||||
mdrop_obj(mon, obj, verbosely)
|
||||
|
||||
Reference in New Issue
Block a user