fix #K3802 - sanity_check: boulder not on top

This should fix the problem of polymorphing or stone-to-fleshing a
pile of multiple boulders and having some underneath ones which get
changed resist and not get changed, producing a pile with one or more
non-boulders above one or more boulders.  If that situation arises,
re-stack the pile so that boulders are moved to the top.

This also revises zapping up or down while hiding under something
(if that is even possible; the types of creatures which can hide
under things can't zap wands or cast spells; maybe there are some
exceptions?).  Zapping up used to hit only the top item, but zapping
down hit the whole stack.  Now up still hits only the top, but down
skips the top and hits the rest.

Caveat: not adquately tested.
This commit is contained in:
PatR
2022-12-10 17:48:55 -08:00
parent 9e2effe710
commit 0e1f1c653b
3 changed files with 72 additions and 10 deletions

View File

@@ -2159,6 +2159,29 @@ place_object(struct obj *otmp, coordxy x, coordxy y)
obj_timer_checks(otmp, x, y, 0);
}
/* tear down the object pile at <x,y> and create it again, so that any
boulders which are present get forced to the top */
void
recreate_pile_at(coordxy x, coordxy y)
{
struct obj *otmp, *next_obj, *reversed = 0;
/* remove all objects at <x,y>, saving a reversed temporary list */
for (otmp = gl.level.objects[x][y]; otmp; otmp = next_obj) {
next_obj = otmp->nexthere;
remove_object(otmp); /* obj_extract_self() for floor */
otmp->nobj = reversed;
reversed = otmp;
}
/* pile at <tx,ty> is now empty; create new one, re-reversing to restore
original order; place_object() handles making boulders be on top */
for (otmp = reversed; otmp; otmp = next_obj) {
next_obj = otmp->nobj;
otmp->nobj = 0; /* obj->where is OBJ_FREE */
place_object(otmp, x, y);
}
}
#define ROT_ICE_ADJUSTMENT 2 /* rotting on ice takes 2 times as long */
/* If ice was affecting any objects correct that now