From: PatR Date: Fri, 9 Oct 2020 19:02:26 +0000 (-0700) Subject: fix #K2393 - brass lantern hit by water X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c154dd2609f0012726b1be77cd51104ae1c67e47;p=nethack fix #K2393 - brass lantern hit by water Don't extinguish a brass lantern when hit by water unless it is being submerged. --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 6b92c5b02..56101a98d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.323 $ $NHDT-Date: 1602022805 2020/10/06 22:20:05 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.325 $ $NHDT-Date: 1602270140 2020/10/09 19:02:20 $ General Fixes and Modified Features ----------------------------------- @@ -271,6 +271,7 @@ fire sources can ignite candles, lamps, and potions of oil for multiple drop ('D') with menustyle traditional or combination, if the only object class player picked was '$' then it operated on all classes small monsters could seep through their shirt +don't snuff brass lantern when it's hit by water unless it is submerged Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 52b28f616..83a1cd30f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1600933440 2020/09/24 07:44:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.859 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1602270114 2020/10/09 19:01:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.867 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -47,6 +47,7 @@ E void FDECL(check_leash, (XCHAR_P, XCHAR_P)); E boolean FDECL(um_dist, (XCHAR_P, XCHAR_P, XCHAR_P)); E boolean FDECL(snuff_candle, (struct obj *)); E boolean FDECL(snuff_lit, (struct obj *)); +E boolean FDECL(splash_lit, (struct obj *)); E boolean FDECL(catch_lit, (struct obj *)); E void FDECL(use_unicorn_horn, (struct obj **)); E boolean FDECL(tinnable, (struct obj *)); diff --git a/src/apply.c b/src/apply.c index faef080bf..32e33f97f 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 apply.c $NHDT-Date: 1597090815 2020/08/10 20:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.327 $ */ +/* NetHack 3.7 apply.c $NHDT-Date: 1602270122 2020/10/09 19:02:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.328 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1346,6 +1346,63 @@ struct obj *obj; return FALSE; } +/* called when lit object is hit by water */ +boolean +splash_lit(obj) +struct obj *obj; +{ + boolean result, dunk = FALSE; + + /* lantern won't be extinguished by a rust trap or rust monster attack + but will be if submerged or placed into a container or swallowed by + a monster (for mobile light source handling, not because it ought + to stop being lit in all those situations...) */ + if (obj->lamplit && obj->otyp == BRASS_LANTERN) { + struct monst *mtmp; + boolean useeit = FALSE, uhearit = FALSE, snuff = TRUE; + + if (obj->where == OBJ_INVENT) { + useeit = !Blind; + uhearit = !Deaf; + /* underwater light sources aren't allowed but if hero + is just entering water, Underwater won't be set yet */ + dunk = (is_pool(u.ux, u.uy) + && ((!Levitation && !Flying && !Wwalking) + || Is_waterlevel(&u.uz))); + snuff = FALSE; + } else if (obj->where == OBJ_MINVENT + /* don't assume that lit lantern has been swallowed; + a nymph might have stolen it or picked it up */ + && ((mtmp = obj->ocarry), humanoid(mtmp->data))) { + xchar x, y; + + useeit = get_obj_location(obj, &x, &y, 0) && cansee(x, y); + uhearit = couldsee(x, y) && distu(x, y) < 5 * 5; + dunk = (is_pool(mtmp->mx, mtmp->my) + && ((!is_flyer(mtmp->data) && !is_floater(mtmp->data)) + || Is_waterlevel(&u.uz))); + snuff = FALSE; + } + + if (useeit || uhearit) + pline("%s %s%s%s.", Yname2(obj), + uhearit ? "crackles" : "", + (uhearit && useeit) ? " and " : "", + useeit ? "flickers" : ""); + if (!dunk && !snuff) + return FALSE; + } + + result = snuff_lit(obj); + + /* this is simpler when we wait until after lantern has been snuffed */ + if (dunk) { + /* drain some of the battery but don't short it out entirely */ + obj->age -= (obj->age > 200L) ? 100L : (obj->age / 2L); + } + return result; +} + /* Called when potentially lightable object is affected by fire_damage(). Return TRUE if object was lit and FALSE otherwise --ALI */ boolean diff --git a/src/trap.c b/src/trap.c index 7aa3f3e71..5ba5bdc74 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 trap.c $NHDT-Date: 1596498220 2020/08/03 23:43:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.362 $ */ +/* NetHack 3.7 trap.c $NHDT-Date: 1602270123 2020/10/09 19:02:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.364 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1149,10 +1149,7 @@ unsigned trflags; if (u.twoweap || (uwep && bimanual(uwep))) (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE); glovecheck: - (void) water_damage(uarmg, "gauntlets", TRUE); - /* Not "metal gauntlets" since it gets called - * even if it's leather for the message - */ + (void) water_damage(uarmg, gloves_simple_name(uarmg), TRUE); break; case 2: pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM)); @@ -1160,10 +1157,12 @@ unsigned trflags; goto glovecheck; default: pline("%s you!", A_gush_of_water_hits); + /* note: exclude primary and seconary weapons from splashing + because cases 1 and 2 target them [via water_damage()] */ for (otmp = g.invent; otmp; otmp = otmp->nobj) if (otmp->lamplit && otmp != uwep && (otmp != uswapwep || !u.twoweap)) - (void) snuff_lit(otmp); + (void) splash_lit(otmp); if (uarmc) (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE); else if (uarm) @@ -2344,7 +2343,7 @@ register struct monst *mtmp; (void) water_damage(target, 0, TRUE); glovecheck: target = which_armor(mtmp, W_ARMG); - (void) water_damage(target, "gauntlets", TRUE); + (void) water_damage(target, gloves_simple_name(target), TRUE); break; case 2: if (in_sight) @@ -2357,8 +2356,9 @@ register struct monst *mtmp; pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp)); for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) if (otmp->lamplit + /* exclude weapon(s) because cases 1 and 2 do them */ && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0) - (void) snuff_lit(otmp); + (void) splash_lit(otmp); if ((target = which_armor(mtmp, W_ARMC)) != 0) (void) water_damage(target, cloak_simple_name(target), TRUE); @@ -3538,7 +3538,7 @@ boolean force; if (!obj) return ER_NOTHING; - if (snuff_lit(obj)) + if (splash_lit(obj)) return ER_DAMAGED; if (!ostr)