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);
}
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);
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);
}
}
int tmp, tinv, tvariety, mgend;
int wetness, gsize;
int ftype;
+ boolean zombify;
char globbuf[BUFSZ];
char fruitbuf[BUFSZ];
};
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;
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;
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);
*/
#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 *);
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.
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));
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;
|| (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;
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");
}
["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 = "?" },