From e2eba2ae9a050d03ecb4b8d0bdf3f415072d06f2 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Sun, 25 Nov 2007 23:03:47 +0000 Subject: [PATCH] endgame portal detection (trunk only) In the newsgroup about three weeks ago someone described trying to use the Bell of Opening to find the magic portal on the Plane of Water and not succeeding. It's supposed to work like a wand of secret door detection to mark nearby traps as known. And does, but it turns out that the wand wasn't working as expected there either. They both require line of sight, and since the water outside of the bubbles blocks that they only found the portal if it was within the same bubble as the hero. (Clouds on the Plane of Air posed a similar problem, although monster activity usually reveals the portal on that level so this wasn't much of an issue there.) Since the detection magic doesn't require the hero to see the traps--wand and Bell both work while blind--this patch overrides the line of sight requirement on the Planes of Water and Air. As long as hero is within the detection magic's range, the portals on those levels will get marked as having been seen and when the hero gets into the right bubble or out of the clouds the portal traps will be shown on the map. The line-of-sight override code is simple-minded and lets players find traps through boulders when/if those are present (but the found traps won't be seen yet since vision still controls the map display). Also, it assumes that only water/air/cloud terrain is present so could potentially yield strange results if any other terrain gets introduced on either of those two levels. --- doc/fixes35.0 | 2 ++ include/extern.h | 1 + src/detect.c | 10 +++++++++- src/vision.c | 10 ++++++++-- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index d093c5a9e..a57ec2a47 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -271,6 +271,8 @@ it was possible to generate an object of 0 gold pieces by dropping 2**32 gold wizard mode's sanity_check option missed nested containers and migrating mons always update map display and use up turn if open or close command attempted while blind reveals change in door state or discloses non-door spot +secret door detection's trap finding is no longer blocked by water or clouds + on the Planes of Water and Air Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 8fc407724..2ab35d42b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -252,6 +252,7 @@ E void FDECL(openone, (int,int,genericptr_t)); #endif E int NDECL(findit); E int NDECL(openit); +E boolean FDECL(detecting, (void (*)(int,int,genericptr))); E void FDECL(find_trap, (struct trap *)); E int FDECL(dosearch0, (int)); E int NDECL(dosearch); diff --git a/src/detect.c b/src/detect.c index d24344f95..13285ac52 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)detect.c 3.5 2006/05/13 */ +/* SCCS Id: @(#)detect.c 3.5 2007/11/05 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1194,6 +1194,14 @@ openit() /* returns number of things found and opened */ return(num); } +/* callback hack for overriding vision in do_clear_area() */ +boolean +detecting(func) + void FDECL((*func), (int,int,genericptr_t)); +{ + return (func == findone || func == openone); +} + void find_trap(trap) struct trap *trap; diff --git a/src/vision.c b/src/vision.c index fb2b8bc48..3f4b9939f 100644 --- a/src/vision.c +++ b/src/vision.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)vision.c 3.5 2007/05/11 */ +/* SCCS Id: @(#)vision.c 3.5 2007/11/05 */ /* Copyright (c) Dean Luick, with acknowledgements to Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2606,6 +2606,12 @@ do_clear_area(scol,srow,range,func,arg) register int x; int y, min_x, max_x, max_y, offset; char *limits; + boolean override_vision; + + /* vision doesn't pass through water or clouds, detection should + [this probably ought to be an arg supplied by our caller...] */ + override_vision = (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) && + detecting(func); if (range > MAX_RADIUS || range < 1) panic("do_clear_area: illegal range %d", range); @@ -2619,7 +2625,7 @@ do_clear_area(scol,srow,range,func,arg) if((min_x = (scol - offset)) < 0) min_x = 0; if((max_x = (scol + offset)) >= COLNO) max_x = COLNO-1; for (x = min_x; x <= max_x; x++) - if (couldsee(x, y)) + if (couldsee(x, y) || override_vision) (*func)(x, y, arg); } }