From 6a081301c62e01fe5402a4f207d87afbb635c064 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Thu, 23 Nov 2006 03:06:19 +0000 Subject: [PATCH] levitation timeout vs traps (trunk only) : > If you enter a magic trap on the same turn that you lose your levitation > and "float gently to the floor", you are hit by the trap twice. I don't think this is actually a bug, but it does look fairly strange if there aren't any monsters attacking (after you move on to the trap, monsters get a chance to move too before timeouts are run, but if there aren't any messages triggered by monster activity then it feels like the timeout and second activation happens immediately). To prevent this, if levitation is due to time out on the same turn that a trap is being entered, either extend the duration by an extra move or make it end immediately instead of waiting until end of current turn. Deferring timeout is a lot easier but doing that unconditionally would allow player to move back and forth between adjacent traps without ever descending. The early timeout might lead to anomalous behavior in obscure cases; it seems to be working ok so far though. --- doc/fixes35.0 | 1 + src/hack.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index a90bfd2b7..1648c5f2a 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -170,6 +170,7 @@ for inventory display, include cost info on hero-owned containers holding shop goods shops now claim ownership of items created by using an unpaid horn of plenty shopkeepers shouldn't refer to non-male character as "cad" +tweak levitation timeout if trap is being triggered on same turn it is to end Platform- and/or Interface-Specific Fixes diff --git a/src/hack.c b/src/hack.c index 826be5e06..010abee8c 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1638,6 +1638,22 @@ stillinwater:; if (!in_steed_dismounting) { /* if dismounting, we'll check again later */ boolean pit; + /* if levitation is due to time out at the end of this + turn, allowing it to do so could give the perception + that a trap here is being triggered twice, so adjust + the timeout to prevent that */ + if (trap && (HLevitation & TIMEOUT) == 1L) { + if (rn2(2)) { /* defer timeout */ + HLevitation += 1L; + } else { /* timeout early */ + if (float_down(I_SPECIAL|TIMEOUT, 0L)) { + /* levitation has ended; we've already triggered + any trap and [usually] performed autopickup */ + trap = 0; + pick = FALSE; + } + } + } /* * If not a pit, pickup before triggering trap. * If pit, trigger trap before pickup. -- 2.40.0