Skip to content

Commit 657b64c

Browse files
committed
Fix: lit magic lamps were extinguished by water on dry land.
A magic lamp's flame is meant to be impervious to water and engulfing, but snuff_lit() granted the exemption by location - is_damp_terrain() at the lamp's spot, or the hero being swallowed - rather than by cause. Any water event on dry land therefore snuffed the lamp: the water-bucket door trap (player-reported, hero and monster carriers), a rust trap's gush hitting a wielded lamp, water blasts wetting weapons, and a lamp dropped or thrown into water (in transit the object is OBJ_FREE, so get_obj_location() reports (0,0), which reads as dry land). The heuristic also leaked the other way: stowing a lit magic lamp into a container while swallowed left it burning inside the container, and magical darkness could not douse a magic lamp while the hero stood on damp terrain. Replace the heuristic with a caller-supplied cause flag: snuff_lit() gains a forced parameter, and a lit magic lamp only goes out when it is TRUE. Water and engulf callers pass FALSE, so an engulfed monster's magic lamp now also stays lit, matching the hero's. * include/extern.h: add the boolean parameter to the prototype. * src/apply.c: snuff_lit() checks forced instead of terrain/uswallow. * src/trap.c: water_damage() and both rust-trap gush loops pass FALSE; drop the loops' magic-lamp exclusions, now redundant since the call is a silent no-op for magic lamps. * src/pickup.c: container insertion passes TRUE (put-in must always snuff). * src/read.c: darkness passes TRUE (magic douses regardless of terrain). * src/mhitu.c, src/mhitm.c, src/uhitm.c: engulf sites pass FALSE.
1 parent 7a6acfc commit 657b64c

9 files changed

Lines changed: 27 additions & 28 deletions

File tree

‎doc/evilhack-changelog.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5558,4 +5558,5 @@ The following changes to date are:
55585558
- Monster lookup now reports many more species attributes
55595559
- Object lookup now reports rarity, materials, and more
55605560
- Artifact lookup: fix missing aasimar, add prices and special details
5561+
- Fix: lit magic lamps were extinguished by water on dry land
55615562

‎include/extern.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ E void FDECL(check_leash, (XCHAR_P, XCHAR_P));
4848
E boolean FDECL(um_dist, (XCHAR_P, XCHAR_P, XCHAR_P));
4949
E boolean FDECL(snuff_candle, (struct obj *));
5050
E boolean FDECL(check_mon_jump, (struct monst *, int, int));
51-
E boolean FDECL(snuff_lit, (struct obj *));
51+
E boolean FDECL(snuff_lit, (struct obj *, BOOLEAN_P));
5252
E boolean FDECL(catch_lit, (struct obj *));
5353
E void FDECL(use_unicorn_horn, (struct obj *));
5454
E void FDECL(use_figurine, (struct obj **));

‎src/apply.c‎

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,30 +1477,29 @@ struct obj *otmp;
14771477

14781478
/* called when lit lamp is hit by water or put into a container or
14791479
you've been swallowed by a monster; obj might be in transit while
1480-
being thrown or dropped so don't assume that its location is valid */
1480+
being thrown or dropped so don't assume that its location is valid.
1481+
A magic lamp's flame is impervious to water and engulfing; callers
1482+
that must snuff one anyway (stowing it in a container, dousing it
1483+
via magic) pass forced as TRUE */
14811484
boolean
1482-
snuff_lit(obj)
1485+
snuff_lit(obj, forced)
14831486
struct obj *obj;
1487+
boolean forced; /* TRUE: snuff even a magic lamp */
14841488
{
14851489
xchar x, y;
14861490

14871491
if (obj->lamplit) {
14881492
if (obj->otyp == OIL_LAMP || obj->otyp == LANTERN
14891493
|| obj->otyp == POT_OIL || obj->otyp == MAGIC_LAMP) {
1490-
(void) get_obj_location(obj, &x, &y, 0);
1491-
1492-
if (obj->otyp == MAGIC_LAMP
1493-
&& (is_damp_terrain(x, y) || u.uswallow)) {
1494+
if (obj->otyp == MAGIC_LAMP && !forced)
14941495
return FALSE;
1495-
} else {
1496-
/* Print message only if player can perceive it */
1497-
if (obj->where == OBJ_MINVENT ? cansee(x, y) : !Blind) {
1498-
pline("%s %s out!", Yname2(obj), otense(obj, "go"));
1499-
}
1500-
/* Always extinguish, regardless of visibility */
1501-
end_burn(obj, TRUE);
1502-
return TRUE;
1503-
}
1496+
(void) get_obj_location(obj, &x, &y, 0);
1497+
/* Print message only if player can perceive it */
1498+
if (obj->where == OBJ_MINVENT ? cansee(x, y) : !Blind)
1499+
pline("%s %s out!", Yname2(obj), otense(obj, "go"));
1500+
/* Always extinguish, regardless of visibility */
1501+
end_burn(obj, TRUE);
1502+
return TRUE;
15041503
}
15051504
if (snuff_candle(obj))
15061505
return TRUE;

‎src/mhitm.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1180,7 +1180,7 @@ struct attack *mattk;
11801180
pline("%s %s.", buf, mon_nam(mdef));
11811181
}
11821182
for (obj = mdef->minvent; obj; obj = obj->nobj)
1183-
(void) snuff_lit(obj);
1183+
(void) snuff_lit(obj, FALSE);
11841184

11851185
if (is_vampshifter(mdef)
11861186
&& newcham(mdef, &mons[mdef->cham], FALSE, FALSE)) {

‎src/mhitu.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3207,7 +3207,7 @@ struct attack *mattk;
32073207
swallowed(1);
32083208
for (otmp2 = invent; otmp2; otmp2 = nextobj) {
32093209
nextobj = otmp2->nobj;
3210-
(void) snuff_lit(otmp2);
3210+
(void) snuff_lit(otmp2, FALSE);
32113211
}
32123212
}
32133213

‎src/pickup.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2664,7 +2664,7 @@ struct obj *obj;
26642664
freeinv(obj);
26652665

26662666
if (obj_is_burning(obj)) /* this used to be part of freeinv() */
2667-
(void) snuff_lit(obj);
2667+
(void) snuff_lit(obj, TRUE);
26682668

26692669
if (floor_container && costly_spot(u.ux, u.uy)) {
26702670
/* defer gold until after put-in message */
@@ -3785,7 +3785,7 @@ boolean creation;
37853785
(void) stop_timer(FIG_TRANSFORM, (genericptr_t) obj);
37863786

37873787
if (obj_is_burning(obj))
3788-
(void) snuff_lit(obj);
3788+
(void) snuff_lit(obj, TRUE);
37893789

37903790
if (bag->otyp == ICE_BOX && !age_is_relative(obj)) {
37913791
obj->age = monstermoves - obj->age;

‎src/read.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,7 +2654,7 @@ xchar x, y; /* coordinates for centering do_clear_area() */
26542654
continue;
26552655
} else {
26562656
if (!artifact_light(otmp))
2657-
(void) snuff_lit(otmp);
2657+
(void) snuff_lit(otmp, TRUE);
26582658
else if (!mon)
26592659
/* wielded Sunsword or worn shield of light/gold dragon
26602660
scales; maybe lower its BUC state if not already
@@ -2708,7 +2708,7 @@ xchar x, y; /* coordinates for centering do_clear_area() */
27082708

27092709
if (otmp->lamplit && !mon) {
27102710
if (!artifact_light(otmp) && lamp) {
2711-
(void) snuff_lit(otmp);
2711+
(void) snuff_lit(otmp, TRUE);
27122712
} else {
27132713
/* wielded Sunsword or worn shield of light/gold dragon
27142714
scales; maybe raise its BUC state if not already

‎src/trap.c‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,9 +1451,8 @@ unsigned trflags;
14511451
for (otmp = invent; otmp; otmp = nextobj) {
14521452
nextobj = otmp->nobj;
14531453
if (otmp->lamplit && otmp != uwep
1454-
&& otmp->otyp != MAGIC_LAMP
14551454
&& (otmp != uswapwep || !u.twoweap))
1456-
(void) snuff_lit(otmp);
1455+
(void) snuff_lit(otmp, FALSE);
14571456
}
14581457
if (uarmc)
14591458
(void) water_damage(uarmc, cloak_simple_name(uarmc),
@@ -2883,9 +2882,9 @@ struct monst *mtmp;
28832882
pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp));
28842883
for (otmp = mtmp->minvent; otmp; otmp = nextobj) {
28852884
nextobj = otmp->nobj;
2886-
if (otmp->lamplit && otmp->otyp != MAGIC_LAMP
2885+
if (otmp->lamplit
28872886
&& (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0)
2888-
(void) snuff_lit(otmp);
2887+
(void) snuff_lit(otmp, FALSE);
28892888
}
28902889
if ((target = which_armor(mtmp, W_ARMC)) != 0)
28912890
(void) water_damage(target, cloak_simple_name(target),
@@ -4473,7 +4472,7 @@ xchar x, y;
44734472
if (!obj)
44744473
return ER_NOTHING;
44754474

4476-
if (snuff_lit(obj))
4475+
if (snuff_lit(obj, FALSE))
44774476
return ER_DAMAGED;
44784477

44794478
if (!ostr)

‎src/uhitm.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4064,7 +4064,7 @@ struct attack *mattk;
40644064

40654065
if (u.uhunger < 1500 && !u.uswallow) {
40664066
for (otmp = mdef->minvent; otmp; otmp = otmp->nobj)
4067-
(void) snuff_lit(otmp);
4067+
(void) snuff_lit(otmp, FALSE);
40684068

40694069
/* force vampire in bat, cloud, or wolf form to revert back to
40704070
vampire form now instead of dealing with that when it dies */

0 commit comments

Comments
 (0)