Mentioned by <Someone>, who suspected that the fix for C343-114 dealt with
this. When a giant picks up a boulder from a location where more than one
is present, line-of-sight would be inappropriately cleared, as if the
remaining boulders were transparent. (He said that he got no pickup
message when the giant picked up the boulder. I do, and have not tried to
figure out whether this is a post-3.4.3 difference.) Pushing a boulder
onto a landmine had the same bug, although you wouldn't notice unless there
were at least three boulders to be pushed (mysterious ability to push more
than one boulder in a turn strikes again: first one triggers the trap and
is destroyed, allowing hero to see through any others; second fills in the
resulting pit; third gets moved to the former trap spot and [probably--I
haven't checked] re-blocks vision; fourth, if any, stays put; if only one
or two are present, the change in vision is expected and the fact that it
happens too soon in the two boulder case would probably go unnoticed.
Polymorph of a boulder also opened up vision without checking whether any
others are present.
An existing, evidently overly optimistic, fixes34.4 entry covers this.
if (rn2(10)) {
obj_extract_self(otmp);
place_object(otmp, rx, ry);
- unblock_point(sx, sy);
newsym(sx, sy);
pline("KAABLAMM!!! %s %s land mine.",
Tobjnam(otmp, "trigger"),
pline("%s picks up %s.", Monnam(mtmp),
(distu(mtmp->mx, mtmp->my) <= 5) ?
doname(otmp) : distant_name(otmp, doname));
- obj_extract_self(otmp);
- /* unblock point after extract, before pickup */
- if (otmp->otyp == BOULDER)
- unblock_point(otmp->ox,otmp->oy); /* vision */
+ obj_extract_self(otmp); /* remove from floor */
(void) mpickobj(mtmp, otmp); /* may merge and free otmp */
m_dowear(mtmp, FALSE);
newsym(mtmp->mx, mtmp->my);
otmp->owornmask = obj->owornmask;
no_unwear:
- if (obj_location == OBJ_FLOOR && obj->otyp == BOULDER &&
- otmp->otyp != BOULDER)
- unblock_point(obj->ox, obj->oy);
- else if (obj_location == OBJ_FLOOR && obj->otyp != BOULDER &&
- otmp->otyp == BOULDER)
- block_point(obj->ox, obj->oy);
-
/* ** we are now done adjusting the object ** */
freeinv_core(obj);
addinv_core1(otmp);
addinv_core2(otmp);
+ } else if (obj_location == OBJ_FLOOR) {
+ ox = otmp->ox, oy = otmp->oy; /* set by replace_object() */
+ if (obj->otyp == BOULDER && otmp->otyp != BOULDER &&
+ !does_block(ox, oy, &levl[ox][oy]))
+ unblock_point(ox, oy);
+ else if (obj->otyp != BOULDER && otmp->otyp == BOULDER)
+ /* (checking does_block() here would be redundant) */
+ block_point(ox, oy);
}
if ((!carried(otmp) || obj->unpaid) &&