From 8f3c74d8045733b6d6839098a5c164476d47cd84 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Thu, 28 May 2009 14:09:30 +0000 Subject: [PATCH] wand/spell/breath zaps hitting secret doors (trunk only) From a bug report, black dragon breath destroys closed doors didn't acknowledge hitting secret doors. bhit() reveals secret doors, but zap_over_floor() (called by buzz() for ray-type wands and spells, and for breath attacks) didn't check for hitting those. When testing the fix, I noticed that feedback for an explosion caused by breaking a wand was worded oddly for zaps like magic missile which don't damage doors. "The door absorbs your bolt" didn't make much sense; what bolt? That was first changed to "absords your blast", which still sounded weird, then to "absorbs the blast", which seemed better but was inaccurate. Next was "absorbs some of the blast" since the explosion continues to hit adjacent spots, but since it still has full strength that wasn't accurate either. It's finally become "The door remains intact." Unlike with zaps, there is no additional range being lost, so no reference to absorption. --- doc/fixes35.0 | 2 ++ src/apply.c | 6 ++---- src/explode.c | 17 ++++++++++++++--- src/zap.c | 44 +++++++++++++++++++++++++++++++++++++------- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 0d827f205..e62c33552 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -321,6 +321,8 @@ pearl rings shouldn't rust shouldn't be able to read a worn T-shirt when it's covered by a worn suit simplify hero placement on Castle level when climbing up stairs from Valley spell attack by low-Int hero could inflict negative damage +some wand/spell/breath zaps that hit a secret door failed to reveal it +wand explosion feedback about adjacent door was phrased as if for a wand zap Platform- and/or Interface-Specific Fixes diff --git a/src/apply.c b/src/apply.c index 8d30db21d..5592943f4 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,5 +1,4 @@ /* NetHack 3.5 apply.c $Date$ $Revision$ */ -/* SCCS Id: @(#)apply.c 3.5 2009/02/21 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2939,9 +2938,8 @@ do_break_wand(obj) dmg *= 2; case WAN_MAGIC_MISSILE: wanexpl: - explode(u.ux, u.uy, - (obj->otyp - WAN_MAGIC_MISSILE), dmg, WAND_CLASS, expltype); - makeknown(obj->otyp); /* explode described the effect */ + explode(u.ux, u.uy, -(obj->otyp), dmg, WAND_CLASS, expltype); + makeknown(obj->otyp); /* explode describes the effect */ goto discard_broken_wand; case WAN_STRIKING: /* we want this before the explosion instead of at the very end */ diff --git a/src/explode.c b/src/explode.c index 4b460a92a..c17748420 100644 --- a/src/explode.c +++ b/src/explode.c @@ -1,5 +1,4 @@ /* NetHack 3.5 explode.c $Date$ $Revision$ */ -/* SCCS Id: @(#)explode.c 3.5 2009/01/04 */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -51,9 +50,21 @@ int expltype; short exploding_wand_typ = 0; if (olet == WAND_CLASS) { /* retributive strike */ - /* If 'type' < 0 it indicates (wand type * -1) */ + /* 'type' is passed as (wand's object type * -1); save + object type and convert 'type' itself to zap-type */ if (type < 0) { - exploding_wand_typ = (short)(type * -1); + type = -type; + exploding_wand_typ = (short)type; + /* most attack wands produce specific explosions; + other types produce a generic magical explosion */ + if (objects[type].oc_dir == RAY && type != WAN_DIGGING) { + type -= WAN_MAGIC_MISSILE; + if (type < 0 || type > 9) { + impossible("explode: wand has bad zap type (%d).", + type); + type = 0; + } + } else type = 0; } switch (Role_switch) { diff --git a/src/zap.c b/src/zap.c index 68b293357..684d5f1d8 100644 --- a/src/zap.c +++ b/src/zap.c @@ -3975,10 +3975,11 @@ int type; boolean *shopdamage; short exploding_wand_typ; { + const char *zapverb; struct monst *mon; struct trap *t; struct rm *lev = &levl[x][y]; - boolean see_it = cansee(x, y); + boolean see_it = cansee(x, y), yourzap; int rangemod = 0, abstype = abs(type) % 10; switch (abstype) { @@ -4122,6 +4123,31 @@ short exploding_wand_typ; break; } + /* set up zap text for possible door feedback; for exploding wand, we + want "the blast" rather than "your blast" even if hero caused it */ + yourzap = (type >= 0 && !exploding_wand_typ); + zapverb = "blast"; /* breath attack or wand explosion */ + if (!exploding_wand_typ) { + if (abs(type) < ZT_SPELL(0)) zapverb = "bolt"; /* wand zap */ + else if (abs(type) < ZT_BREATH(0)) zapverb = "spell"; + } + + /* secret door gets revealed, converted into regular door */ + if (levl[x][y].typ == SDOOR) { + cvt_sdoor_to_door(&levl[x][y]); /* .typ = DOOR */ + /* target spot will now pass closed_door() test below + (except on rogue level) */ + newsym(x, y); + if (see_it) + pline("%s %s reveals a secret door.", + yourzap ? "Your" : "The", zapverb); +#ifdef REINCARNATION + else if (Is_rogue_level(&u.uz)) + You_feel("a draft."); /* new open doorway */ +#endif + } + + /* regular door absorbs remaining zap range, possibly gets destroyed */ if(closed_door(x, y)) { int new_doormask = -1; const char *see_txt = 0, *sense_txt = 0, *hear_txt = 0; @@ -4162,12 +4188,16 @@ short exploding_wand_typ; } } if (see_it) { - pline_The("door absorbs %s %s!", - (type < 0) ? "the" : "your", - abs(type) < ZT_SPELL(0) ? "bolt" : - abs(type) < ZT_BREATH(0) ? "spell" : - "blast"); - } else You_feel("vibrations."); + /* "the door absorbs the blast" would be + inaccurate for an exploding wand since + other adjacent locations still get hit */ + if (exploding_wand_typ) + pline_The("door remains intact."); + else + pline_The("door absorbs %s %s!", + yourzap ? "your" : "the", zapverb); + } else + You_feel("vibrations."); break; } if (new_doormask >= 0) { /* door gets broken */