]> granicus.if.org Git - nethack/commitdiff
fire traps on ice
authornethack.allison <nethack.allison>
Sat, 5 Jun 2004 15:50:48 +0000 (15:50 +0000)
committernethack.allison <nethack.allison>
Sat, 5 Jun 2004 15:50:48 +0000 (15:50 +0000)
"<Someone>" on January 8, 2004, wrote:
> A Valkyrie on the Quest home level, wearing an
> amulet of magical breathing, enters a fire trap
> out on the ice:
>
>> A tower of flame erupts from the ice!
>> The ice crackles and melts.
>> You fall into the water.  You sink like a rock.
>> But you aren't drowning.  You touch bottom.
>> A cascade of steamy bubbles erupts from the bottom!
>
>Should the trap really be being triggered twice, once on ice and
>once underwater, when I've only moved onto the location once?

doc/fixes34.4
src/hack.c

index aeefbc06b727f5fc067f56cdfd00ec5830b87384..6849c495354e5f42065a58ee642aa97732491117 100644 (file)
@@ -34,6 +34,7 @@ change the wording slightly to use "one of " when a monster wielding
        multiple daggers thrusts them
 if you didn't see a rolling boulder fall into a pit, you only heard the sound
        of it doing so if you were blind
+fire trap was triggered twice in the same turn when melting ice was involved
 
 
 Platform- and/or Interface-Specific Fixes
index 95ece8025bc5103c625e95f9e3576016a1db58b4..bc504494a14839e8da33c7e80c23b07857b28275 100644 (file)
@@ -1500,8 +1500,10 @@ void
 spoteffects(pick)
 boolean pick;
 {
+       static struct trap *spottrap = (struct trap *)0;
+       static unsigned spottraptyp = NO_TRAP;
        register struct monst *mtmp;
-
+       
        if(u.uinwater) {
                int was_underwater;
 
@@ -1560,12 +1562,33 @@ stillinwater:;
        if (!in_steed_dismounting) { /* if dismounting, we'll check again later */
                struct trap *trap = t_at(u.ux, u.uy);
                boolean pit;
+
+              /*
+               * If not a pit, pickup before triggering trap.
+               * If pit, trigger trap before pickup.
+               */
                pit = (trap && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT));
-               if (trap && pit)
-                       dotrap(trap, 0);        /* fall into pit */
-               if (pick) (void) pickup(1);
-               if (trap && !pit)
-                       dotrap(trap, 0);        /* fall into arrow trap, etc. */
+               if (pick && !pit) (void) pickup(1);
+
+               if (trap) {
+
+                      /*
+                       * dotrap on a fire trap calls melt_ice() which triggers
+                       * spoteffects() (again) which can trigger the same fire
+                       * trap (again). Use static spottrap to prevent that.
+                       * We track spottraptyp because some traps morph
+                       * (landmine to pit) and any new trap type
+                       * should get triggered.
+                       */
+                       if (!spottrap || spottraptyp != trap->ttyp) {
+                               spottrap = trap;
+                               spottraptyp = trap->ttyp;
+                               dotrap(trap, 0);    /* fall into arrow trap, etc. */
+                               spottrap = (struct trap *)0;
+                               spottraptyp = NO_TRAP;
+                       }
+               }
+               if (pick && pit) (void) pickup(1);
        }
        /* Warning alerts you to ice danger */
        if (Warning && is_ice(u.ux,u.uy)) {