Handle buried zombifying corpses
When a zombifying corpse is buried, allow it to zombify and dig itself out of the ground. Also allow wishing for zombifying corpses.
This commit is contained in:
22
src/do.c
22
src/do.c
@@ -1848,6 +1848,7 @@ revive_corpse(struct obj *corpse)
|
||||
char cname[BUFSZ];
|
||||
struct obj *container = (struct obj *) 0;
|
||||
int container_where = 0;
|
||||
boolean is_zomb = (mons[corpse->corpsenm].mlet == S_ZOMBIE);
|
||||
|
||||
where = corpse->where;
|
||||
is_uwep = (corpse == uwep);
|
||||
@@ -1915,6 +1916,21 @@ revive_corpse(struct obj *corpse)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OBJ_BURIED:
|
||||
if (is_zomb) {
|
||||
maketrap(mtmp->mx, mtmp->my, PIT);
|
||||
if (cansee(mtmp->mx, mtmp->my)) {
|
||||
struct trap *ttmp;
|
||||
|
||||
ttmp = t_at(mtmp->mx, mtmp->my);
|
||||
ttmp->tseen = TRUE;
|
||||
pline("%s claws itself out of the ground!", Amonnam(mtmp));
|
||||
newsym(mtmp->mx, mtmp->my);
|
||||
} else if (distu(mtmp->mx, mtmp->my) < 5*5)
|
||||
You_hear("scratching noises.");
|
||||
break;
|
||||
}
|
||||
/*FALLTHRU*/
|
||||
default:
|
||||
/* we should be able to handle the other cases... */
|
||||
impossible("revive_corpse: lost corpse @ %d", where);
|
||||
@@ -1961,13 +1977,15 @@ revive_mon(anything *arg, long timeout UNUSED)
|
||||
action = REVIVE_MON;
|
||||
when = rider_revival_time(body, TRUE);
|
||||
} else { /* rot this corpse away */
|
||||
You_feel("%sless hassled.", is_rider(mptr) ? "much " : "");
|
||||
if (!obj_has_timer(body, ROT_CORPSE))
|
||||
You_feel("%sless hassled.", is_rider(mptr) ? "much " : "");
|
||||
action = ROT_CORPSE;
|
||||
when = (long) d(5, 50) - (g.moves - body->age);
|
||||
if (when < 1L)
|
||||
when = 1L;
|
||||
}
|
||||
(void) start_timer(when, TIMER_OBJECT, action, arg);
|
||||
if (!obj_has_timer(body, action))
|
||||
(void) start_timer(when, TIMER_OBJECT, action, arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ struct _readobjnam_data {
|
||||
int tmp, tinv, tvariety, mgend;
|
||||
int wetness, gsize;
|
||||
int ftype;
|
||||
boolean zombify;
|
||||
char globbuf[BUFSZ];
|
||||
char fruitbuf[BUFSZ];
|
||||
};
|
||||
@@ -3317,6 +3318,7 @@ readobjnam_init(char *bp, struct _readobjnam_data *d)
|
||||
d->actualn = d->dn = d->un = 0;
|
||||
d->wetness = 0;
|
||||
d->gsize = 0;
|
||||
d->zombify = FALSE;
|
||||
d->bp = d->origbp = bp;
|
||||
d->p = (char *) 0;
|
||||
d->name = (const char *) 0;
|
||||
@@ -3432,6 +3434,8 @@ readobjnam_preparse(struct _readobjnam_data *d)
|
||||
d->looted = 1;
|
||||
} else if (!strncmpi(d->bp, "greased ", l = 8)) {
|
||||
d->isgreased = 1;
|
||||
} else if (!strncmpi(d->bp, "zombifying ", l = 11)) {
|
||||
d->zombify = TRUE;
|
||||
} else if (!strncmpi(d->bp, "very ", l = 5)) {
|
||||
/* very rusted very heavy iron ball */
|
||||
d->very = 1;
|
||||
@@ -4499,6 +4503,10 @@ readobjnam(char *bp, struct obj *no_wish)
|
||||
d.mntmp = genus(d.mntmp, 1);
|
||||
set_corpsenm(d.otmp, d.mntmp);
|
||||
}
|
||||
if (d.zombify && zombie_form(&mons[d.mntmp])) {
|
||||
(void) start_timer(rn1(5, 10), TIMER_OBJECT,
|
||||
ZOMBIFY_MON, obj_to_any(d.otmp));
|
||||
}
|
||||
break;
|
||||
case EGG:
|
||||
d.mntmp = can_be_hatched(d.mntmp);
|
||||
|
||||
35
src/zap.c
35
src/zap.c
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
#define MAGIC_COOKIE 1000
|
||||
|
||||
static boolean zombie_can_dig(xchar x, xchar y);
|
||||
static void polyuse(struct obj *, int, int);
|
||||
static void create_polymon(struct obj *, int);
|
||||
static int stone_to_flesh_obj(struct obj *);
|
||||
@@ -742,6 +743,22 @@ get_container_location(struct obj *obj, int *loc, int *container_nesting)
|
||||
return (struct monst *) 0;
|
||||
}
|
||||
|
||||
/* can zombie dig the location at x,y */
|
||||
static boolean
|
||||
zombie_can_dig(xchar x, xchar y)
|
||||
{
|
||||
if (isok(x,y)) {
|
||||
schar typ = levl[x][y].typ;
|
||||
struct trap *ttmp;
|
||||
|
||||
if ((ttmp = t_at(x, y)) != 0)
|
||||
return FALSE;
|
||||
if (typ == ROOM || typ == CORR || typ == GRAVE)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to revive the given corpse, return the revived monster if
|
||||
* successful. Note: this does NOT use up the corpse if it fails.
|
||||
@@ -759,6 +776,7 @@ revive(struct obj *corpse, boolean by_hero)
|
||||
boolean one_of;
|
||||
long mmflags = NO_MINVENT | MM_NOWAIT;
|
||||
int montype, cgend, container_nesting = 0;
|
||||
boolean is_zomb = (mons[corpse->corpsenm].mlet == S_ZOMBIE);
|
||||
|
||||
if (corpse->otyp != CORPSE) {
|
||||
impossible("Attempting to revive %s?", xname(corpse));
|
||||
@@ -767,9 +785,11 @@ revive(struct obj *corpse, boolean by_hero)
|
||||
|
||||
x = y = 0;
|
||||
if (corpse->where != OBJ_CONTAINED) {
|
||||
/* only for invent, minvent, or floor */
|
||||
int locflags = is_zomb ? BURIED_TOO : 0;
|
||||
|
||||
/* only for invent, minvent, or floor, or if zombie, buried */
|
||||
container = 0;
|
||||
(void) get_obj_location(corpse, &x, &y, 0);
|
||||
(void) get_obj_location(corpse, &x, &y, locflags);
|
||||
} else {
|
||||
/* deal with corpses in [possibly nested] containers */
|
||||
struct monst *carrier;
|
||||
@@ -804,6 +824,10 @@ revive(struct obj *corpse, boolean by_hero)
|
||||
|| (container->otyp == BAG_OF_HOLDING && rn2(40)))))
|
||||
return (struct monst *) 0;
|
||||
|
||||
/* buried zombie cannot dig itself out, do not revive */
|
||||
if (is_zomb && corpse->where == OBJ_BURIED && !zombie_can_dig(x, y))
|
||||
return (struct monst *) 0;
|
||||
|
||||
/* record the object's location now that we're sure where it is */
|
||||
corpse->ox = x, corpse->oy = y;
|
||||
|
||||
@@ -977,6 +1001,13 @@ revive(struct obj *corpse, boolean by_hero)
|
||||
obj_extract_self(corpse);
|
||||
obfree(corpse, (struct obj *) 0);
|
||||
break;
|
||||
case OBJ_BURIED:
|
||||
if (is_zomb) {
|
||||
obj_extract_self(corpse);
|
||||
obfree(corpse, (struct obj *) 0);
|
||||
break;
|
||||
}
|
||||
/*FALLTHRU*/
|
||||
default:
|
||||
panic("revive");
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ local wishtest_objects = {
|
||||
["spinach"] = { otyp_name = "tin", oclass = "%", corpsenm = -1, spe = 1 },
|
||||
["trapped tin of floating eye meat"] = { otyp_name = "tin", oclass = "%", otrapped = 1, corpsenm_name = "floating eye" },
|
||||
["hill orc corpse"] = { otyp_name = "corpse", oclass = "%", corpsenm_name = "hill orc" },
|
||||
-- TODO: zombifying and other timers cannot be seen via lua
|
||||
["zombifying elf corpse"] = { otyp_name = "corpse", oclass = "%", corpsenm_name = "elf" },
|
||||
["destroy armor"] = { otyp_name = "destroy armor", oclass = "?" },
|
||||
["enchant weapon"] = { otyp_name = "enchant weapon", oclass = "?" },
|
||||
["scroll of food detection"] = { otyp_name = "food detection", oclass = "?" },
|
||||
|
||||
Reference in New Issue
Block a user