breaking migrated objects
Allow migrated objects to break on arrival. Added code to obj_delivery to cause this, along with a flag to keep breakage from occurring. The new flag isn't used yet, because all the current object migration involve objects that were moving/dropping. To help make this change, rloco now returns whether the object was placed or not, so caller can know if an obj pointer is still valid or not. Making the breakage messages for MIGR_NEAR_PLAYER objects show up after the new level is displayed required some effort (rather than while the old level was still displayed, which was confusing), due to the needs of goto_level. - obj_delivery now has 2 passes, one for before player arrives, another after, allowing the two cases to be treated differently - goto_level calls obj_delivery twice (run_timers is not called twice, since the run required before the level is displayed will have already run any timers on migrating object) - kill_genocided_monsters now kills eggs on the migrating_objs list too
This commit is contained in:
32
src/dokick.c
32
src/dokick.c
@@ -1137,10 +1137,12 @@ schar loc;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@@ -1379,18 +1381,26 @@ boolean shop_floor_obj;
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -1408,13 +1418,25 @@ obj_delivery()
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user