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];
|
char cname[BUFSZ];
|
||||||
struct obj *container = (struct obj *) 0;
|
struct obj *container = (struct obj *) 0;
|
||||||
int container_where = 0;
|
int container_where = 0;
|
||||||
|
boolean is_zomb = (mons[corpse->corpsenm].mlet == S_ZOMBIE);
|
||||||
|
|
||||||
where = corpse->where;
|
where = corpse->where;
|
||||||
is_uwep = (corpse == uwep);
|
is_uwep = (corpse == uwep);
|
||||||
@@ -1915,6 +1916,21 @@ revive_corpse(struct obj *corpse)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
/* we should be able to handle the other cases... */
|
/* we should be able to handle the other cases... */
|
||||||
impossible("revive_corpse: lost corpse @ %d", where);
|
impossible("revive_corpse: lost corpse @ %d", where);
|
||||||
@@ -1961,13 +1977,15 @@ revive_mon(anything *arg, long timeout UNUSED)
|
|||||||
action = REVIVE_MON;
|
action = REVIVE_MON;
|
||||||
when = rider_revival_time(body, TRUE);
|
when = rider_revival_time(body, TRUE);
|
||||||
} else { /* rot this corpse away */
|
} 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;
|
action = ROT_CORPSE;
|
||||||
when = (long) d(5, 50) - (g.moves - body->age);
|
when = (long) d(5, 50) - (g.moves - body->age);
|
||||||
if (when < 1L)
|
if (when < 1L)
|
||||||
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 tmp, tinv, tvariety, mgend;
|
||||||
int wetness, gsize;
|
int wetness, gsize;
|
||||||
int ftype;
|
int ftype;
|
||||||
|
boolean zombify;
|
||||||
char globbuf[BUFSZ];
|
char globbuf[BUFSZ];
|
||||||
char fruitbuf[BUFSZ];
|
char fruitbuf[BUFSZ];
|
||||||
};
|
};
|
||||||
@@ -3317,6 +3318,7 @@ readobjnam_init(char *bp, struct _readobjnam_data *d)
|
|||||||
d->actualn = d->dn = d->un = 0;
|
d->actualn = d->dn = d->un = 0;
|
||||||
d->wetness = 0;
|
d->wetness = 0;
|
||||||
d->gsize = 0;
|
d->gsize = 0;
|
||||||
|
d->zombify = FALSE;
|
||||||
d->bp = d->origbp = bp;
|
d->bp = d->origbp = bp;
|
||||||
d->p = (char *) 0;
|
d->p = (char *) 0;
|
||||||
d->name = (const char *) 0;
|
d->name = (const char *) 0;
|
||||||
@@ -3432,6 +3434,8 @@ readobjnam_preparse(struct _readobjnam_data *d)
|
|||||||
d->looted = 1;
|
d->looted = 1;
|
||||||
} else if (!strncmpi(d->bp, "greased ", l = 8)) {
|
} else if (!strncmpi(d->bp, "greased ", l = 8)) {
|
||||||
d->isgreased = 1;
|
d->isgreased = 1;
|
||||||
|
} else if (!strncmpi(d->bp, "zombifying ", l = 11)) {
|
||||||
|
d->zombify = TRUE;
|
||||||
} else if (!strncmpi(d->bp, "very ", l = 5)) {
|
} else if (!strncmpi(d->bp, "very ", l = 5)) {
|
||||||
/* very rusted very heavy iron ball */
|
/* very rusted very heavy iron ball */
|
||||||
d->very = 1;
|
d->very = 1;
|
||||||
@@ -4499,6 +4503,10 @@ readobjnam(char *bp, struct obj *no_wish)
|
|||||||
d.mntmp = genus(d.mntmp, 1);
|
d.mntmp = genus(d.mntmp, 1);
|
||||||
set_corpsenm(d.otmp, d.mntmp);
|
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;
|
break;
|
||||||
case EGG:
|
case EGG:
|
||||||
d.mntmp = can_be_hatched(d.mntmp);
|
d.mntmp = can_be_hatched(d.mntmp);
|
||||||
|
|||||||
35
src/zap.c
35
src/zap.c
@@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
#define MAGIC_COOKIE 1000
|
#define MAGIC_COOKIE 1000
|
||||||
|
|
||||||
|
static boolean zombie_can_dig(xchar x, xchar y);
|
||||||
static void polyuse(struct obj *, int, int);
|
static void polyuse(struct obj *, int, int);
|
||||||
static void create_polymon(struct obj *, int);
|
static void create_polymon(struct obj *, int);
|
||||||
static int stone_to_flesh_obj(struct obj *);
|
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;
|
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
|
* Attempt to revive the given corpse, return the revived monster if
|
||||||
* successful. Note: this does NOT use up the corpse if it fails.
|
* 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;
|
boolean one_of;
|
||||||
long mmflags = NO_MINVENT | MM_NOWAIT;
|
long mmflags = NO_MINVENT | MM_NOWAIT;
|
||||||
int montype, cgend, container_nesting = 0;
|
int montype, cgend, container_nesting = 0;
|
||||||
|
boolean is_zomb = (mons[corpse->corpsenm].mlet == S_ZOMBIE);
|
||||||
|
|
||||||
if (corpse->otyp != CORPSE) {
|
if (corpse->otyp != CORPSE) {
|
||||||
impossible("Attempting to revive %s?", xname(corpse));
|
impossible("Attempting to revive %s?", xname(corpse));
|
||||||
@@ -767,9 +785,11 @@ revive(struct obj *corpse, boolean by_hero)
|
|||||||
|
|
||||||
x = y = 0;
|
x = y = 0;
|
||||||
if (corpse->where != OBJ_CONTAINED) {
|
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;
|
container = 0;
|
||||||
(void) get_obj_location(corpse, &x, &y, 0);
|
(void) get_obj_location(corpse, &x, &y, locflags);
|
||||||
} else {
|
} else {
|
||||||
/* deal with corpses in [possibly nested] containers */
|
/* deal with corpses in [possibly nested] containers */
|
||||||
struct monst *carrier;
|
struct monst *carrier;
|
||||||
@@ -804,6 +824,10 @@ revive(struct obj *corpse, boolean by_hero)
|
|||||||
|| (container->otyp == BAG_OF_HOLDING && rn2(40)))))
|
|| (container->otyp == BAG_OF_HOLDING && rn2(40)))))
|
||||||
return (struct monst *) 0;
|
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 */
|
/* record the object's location now that we're sure where it is */
|
||||||
corpse->ox = x, corpse->oy = y;
|
corpse->ox = x, corpse->oy = y;
|
||||||
|
|
||||||
@@ -977,6 +1001,13 @@ revive(struct obj *corpse, boolean by_hero)
|
|||||||
obj_extract_self(corpse);
|
obj_extract_self(corpse);
|
||||||
obfree(corpse, (struct obj *) 0);
|
obfree(corpse, (struct obj *) 0);
|
||||||
break;
|
break;
|
||||||
|
case OBJ_BURIED:
|
||||||
|
if (is_zomb) {
|
||||||
|
obj_extract_self(corpse);
|
||||||
|
obfree(corpse, (struct obj *) 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*FALLTHRU*/
|
||||||
default:
|
default:
|
||||||
panic("revive");
|
panic("revive");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ local wishtest_objects = {
|
|||||||
["spinach"] = { otyp_name = "tin", oclass = "%", corpsenm = -1, spe = 1 },
|
["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" },
|
["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" },
|
["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 = "?" },
|
["destroy armor"] = { otyp_name = "destroy armor", oclass = "?" },
|
||||||
["enchant weapon"] = { otyp_name = "enchant weapon", oclass = "?" },
|
["enchant weapon"] = { otyp_name = "enchant weapon", oclass = "?" },
|
||||||
["scroll of food detection"] = { otyp_name = "food detection", oclass = "?" },
|
["scroll of food detection"] = { otyp_name = "food detection", oclass = "?" },
|
||||||
|
|||||||
Reference in New Issue
Block a user