"sound" option renamed to "acoustics"
deafness now a full-fledged attribute
water should flow into pits from broken wand of digging
+objects that fall thru trapdoors, et al, can break on impact
Platform- and/or Interface-Specific Fixes
#define MIGR_SSTAIRS 7 /* dungeon branch */
#define MIGR_PORTAL 8 /* magic portal */
#define MIGR_NEAR_PLAYER 9 /* mon: followers; obj: trap door */
+#define MIGR_NOBREAK 1024 /* bitmask: don't break on delivery */
/* level information (saved via ledger number) */
E void FDECL(container_impact_dmg, (struct obj *));
E int NDECL(dokick);
E boolean FDECL(ship_object, (struct obj *,XCHAR_P,XCHAR_P,BOOLEAN_P));
-E void NDECL(obj_delivery);
+E void FDECL(obj_delivery, (BOOLEAN_P));
E schar FDECL(down_gate, (XCHAR_P,XCHAR_P));
E void FDECL(impact_drop, (struct obj *,XCHAR_P,XCHAR_P,XCHAR_P));
E boolean FDECL(tele_restrict, (struct monst *));
E void FDECL(mtele_trap, (struct monst *, struct trap *,int));
E int FDECL(mlevel_tele_trap, (struct monst *, struct trap *,BOOLEAN_P,int));
-E void FDECL(rloco, (struct obj *));
+E boolean FDECL(rloco, (struct obj *));
E int NDECL(random_teleport_level);
E boolean FDECL(u_teleport_mon, (struct monst *,BOOLEAN_P));
}
if (Punished) placebc();
- obj_delivery(); /* before killing geno'd monsters' eggs */
+ obj_delivery(FALSE);
losedogs();
kill_genocided_monsters(); /* for those wiped out while in limbo */
/*
/* give room entrance message, if any */
check_special_room(FALSE);
+ /* deliver objects traveling with player */
+ obj_delivery(TRUE);
+
/* Check whether we just entered Gehennom. */
if (!In_hell(&u.uz0) && Inhell) {
if (Is_valley(&u.uz)) {
obj->owornmask = 0L;
if (xlocale && ylocale)
place_object(obj, xlocale, ylocale);
- else {
- rloco(obj);
+ else if (rloco(obj)) {
get_obj_location(obj, &xlocale, &ylocale, 0);
}
}
}
}
+/* player or missile impacts location, causing objects to fall down */
void
impact_drop(missile, x, y, dlev)
-struct obj *missile;
-xchar x, y, dlev;
+struct obj *missile; /* caused impact, won't drop itself */
+xchar x, y; /* location affected */
+xchar dlev; /* if !0 send to dlev near player */
{
schar toloc;
register struct obj *obj, *obj2;
}
void
-obj_delivery()
+obj_delivery(near_hero)
+boolean near_hero;
{
register struct obj *otmp, *otmp2;
register int nx, ny;
long where;
+ boolean nobreak;
for (otmp = migrating_objs; otmp; otmp = otmp2) {
otmp2 = otmp->nobj;
if (otmp->ox != u.uz.dnum || otmp->oy != u.uz.dlevel) continue;
- obj_extract_self(otmp);
where = otmp->owornmask; /* destination code */
+ nobreak = (where & MIGR_NOBREAK) != 0;
+ where &= ~MIGR_NOBREAK;
+
+ if ((!near_hero && where == MIGR_NEAR_PLAYER) ||
+ (near_hero && where != MIGR_NEAR_PLAYER)) continue;
+
+ obj_extract_self(otmp);
otmp->owornmask = 0L;
switch ((int)where) {
}
if (nx > 0) {
place_object(otmp, nx, ny);
+ if (!nobreak && !IS_SOFT(levl[nx][ny].typ)) {
+ if (where == MIGR_NEAR_PLAYER) {
+ if (breaks(otmp, nx, ny)) continue;
+ } else if (breaktest(otmp)) {
+ /* assume it broke before player arrived, no messages */
+ delobj(otmp);
+ continue;
+ }
+ }
stackobj(otmp);
(void)scatter(nx, ny, rnd(2), 0, otmp);
} else { /* random location */
/* set dummy coordinates because there's no
current position for rloco() to update */
otmp->ox = otmp->oy = 0;
- rloco(otmp);
+ if (rloco(otmp) && !nobreak && breaktest(otmp)) {
+ /* assume it broke before player arrived, no messages */
+ delobj(otmp);
+ }
}
}
}
You("push %s and suddenly it disappears!",
the(xname(otmp)));
if (ttmp->ttyp == TELEP_TRAP)
- rloco(otmp);
+ (void)rloco(otmp);
else {
int newlev = random_teleport_level();
d_level dest;
impossible("making corpstat type %d", objtype);
if (x == 0 && y == 0) { /* special case - random placement */
otmp = mksobj(objtype, init, FALSE);
- if (otmp) rloco(otmp);
+ if (otmp) (void)rloco(otmp);
} else
otmp = mksobj_at(objtype, x, y, init, FALSE);
if (otmp) {
kill_eggs(invent);
kill_eggs(fobj);
+ kill_eggs(migrating_objs);
kill_eggs(level.buriedobjlist);
}
}
-void
+/* place object randomly, returns FALSE if it's gone (eg broken) as a result */
+boolean
rloco(obj)
register struct obj *obj;
{
int try_limit = 4000;
if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
- if (revive_corpse(obj)) return;
+ if (revive_corpse(obj)) return FALSE;
}
obj_extract_self(obj);
dndest.nhx, dndest.nhy)))));
if (flooreffects(obj, tx, ty, "fall")) {
- return;
+ return FALSE;
} else if (otx == 0 && oty == 0) {
; /* fell through a trap door; no update of old loc needed */
} else {
}
place_object(obj, tx, ty);
newsym(tx, ty);
+ return TRUE;
}
/* Returns an absolute depth */
You_hear("a rumbling stop abruptly.");
singleobj->otrapped = 0;
if (t->ttyp == TELEP_TRAP)
- rloco(singleobj);
+ (void)rloco(singleobj);
else {
int newlev = random_teleport_level();
d_level dest;
break;
case WAN_TELEPORTATION:
case SPE_TELEPORT_AWAY:
- rloco(obj);
+ (void) rloco(obj);
break;
case WAN_MAKE_INVISIBLE:
#ifdef INVISIBLE_OBJECTS