Fix: sitting on bidirectional teleportation traps

It is possible to create a bidirectional teleportation trap by making a
pair of teleportation traps with a fixed destination of each other's
coordinate. Moving or hurtling onto such a trap correctly materializes
the hero on top of the other trap without triggering it, but for some
reason I didn't dig into, sitting down to trigger the first trap does
also trigger the second one at the destination end, causing you to
counterintuitively teleport twice and end up back where you started.

Fix this by stopping tele_trap() from doing anything if it's called
recursively, using a static variable like spoteffects() does for the same
purpose. I had to adjust a bit of other tele_trap code to remove its
sole early return.
This commit is contained in:
copperwater
2025-02-19 16:54:19 -05:00
committed by Pasi Kallinen
parent 71e562def8
commit 55c3a7c6c5

View File

@@ -1458,6 +1458,14 @@ domagicportal(struct trap *ttmp)
void
tele_trap(struct trap *trap)
{
/* a fixed-destination teleport trap could theoretically place hero onto a
* second teleport trap; prevent the recursive call from spoteffects() from
* triggering the trap at the destination */
static boolean in_tele_trap = FALSE;
if (in_tele_trap)
return;
in_tele_trap = TRUE;
if (In_endgame(&u.uz) || Antimagic) {
if (Antimagic)
shieldeff(u.ux, u.uy);
@@ -1478,13 +1486,19 @@ tele_trap(struct trap *trap)
/* could not find some other place to put mtmp; the level must
* be nearly or completely full */
You1(shudder_for_moment);
return;
}
rloc_to(mtmp, cc.x, cc.y);
else {
rloc_to(mtmp, cc.x, cc.y);
mtmp = (struct monst *) 0; /* no longer a monster at dest */
}
}
if (!mtmp) {
teleds(trap->teledest.x, trap->teledest.y, TELEDS_TELEPORT);
}
teleds(trap->teledest.x, trap->teledest.y, TELEDS_TELEPORT);
} else
tele();
in_tele_trap = FALSE;
}
void