From f90bb4fb6b4be1911d7989db875efc6ce10af6a6 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 17 Apr 2021 12:41:30 -0700 Subject: [PATCH] container vulnerability to water damage We used to have the contents of chests and large boxes be immune to water damage, oilskin sacks immune unless the sack was cursed, other containers be vulnerable. Some reddit discussion about ice boxes in unnethack indicates that they are treated like oilskin sacks, which makes sense. This adds that to nethack and also makes chests and large boxes behave similarly. So it's now: nothing is immune even when cursed (except statues); oilskin sacks, ice boxes, and other boxes are immune to water damage unless cursed; all other containers vulnerable even when not cursed. | | Old New |immune all statues, statues | the time chests, large boxes | |immune when BU, oilskin sacks oilskin sacks, | vulnerable if C ice boxes, | chests, large boxes | |vulnerable ordinary sacks, ordinary sacks, | all the time bags of holding, bags of holding | ice boxes | I suspect that the old ice box classification might have been an accident caused by the Is_box() predicate yielding False for it. The changes won't make much difference to actual play. Chests and large boxes are rarely carried and never start out cursed, ice boxes even more so, and sacks/bags haven't been changed. However, players might intentionally curse a container to keep strong pets from picking it up, or be carrying a box because they haven't found a bag yet and then muck about with fountains or thrones and get it cursed. --- doc/fixes37.0 | 9 ++++++--- include/obj.h | 9 ++++++--- src/trap.c | 16 ++++++++-------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c98096082..a6ec8281d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -457,9 +457,12 @@ opening/unlocking magic zapped at monster holding the hero will release hold when riding, allow scroll of remove curse to affect to affect steed's saddle the 'scores' option for final top ten display left default values in place if only some of the three settings were set; 'scores:own' should have - produced '0 top/0 around/own' but ended up as '3 top/2 around/own'; - also, allow 'scores:none' as shorthand for 'scores:0 t/0 a/!o' (player - will to told whether new score made the list but no scores get shown) + produced '0 top/0 around/own' but ended up as '3 top/2 around/own' +allow 'scores:none' as shorthand for 'scores:0 t/0 a/!o' (player will be told + whether new score made the list but no scores will be shown) +contents of chests, large boxes, and ice boxes are now immune to water damage + unless the container is cursed, same as for oilskin sacks (previously, + chests+large boxes were always immune and ice boxes always vulnerable) Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/obj.h b/include/obj.h index 0a434a66c..bc00a7388 100644 --- a/include/obj.h +++ b/include/obj.h @@ -274,10 +274,13 @@ struct obj { (/* (Is_container(o) || (o)->otyp == STATUE) && */ \ (o)->cobj != (struct obj *) 0) #define Is_container(o) ((o)->otyp >= LARGE_BOX && (o)->otyp <= BAG_OF_TRICKS) -#define Is_box(otmp) (otmp->otyp == LARGE_BOX || otmp->otyp == CHEST) -#define Is_mbag(otmp) \ - (otmp->otyp == BAG_OF_HOLDING || otmp->otyp == BAG_OF_TRICKS) +#define Is_box(o) ((o)->otyp == LARGE_BOX || (o)->otyp == CHEST) +#define Is_mbag(o) ((o)->otyp == BAG_OF_HOLDING || (o)->otyp == BAG_OF_TRICKS) #define SchroedingersBox(o) ((o)->otyp == LARGE_BOX && (o)->spe == 1) +/* usually waterproof; random chance to be subjected to leakage if cursed; + excludes statues, which aren't vulernable to water even when cursed */ +#define Waterproof_container(o) \ + ((o)->otyp == OILSKIN_SACK || (o)->otyp == ICE_BOX || Is_box(o)) /* dragon gear */ #define Is_dragon_scales(obj) \ diff --git a/src/trap.c b/src/trap.c index 2b6f060e0..2894c298b 100644 --- a/src/trap.c +++ b/src/trap.c @@ -3914,17 +3914,17 @@ water_damage( if (carried(obj)) update_inventory(); return ER_GREASED; - } else if (Is_container(obj) && !Is_box(obj) - && (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) { + } else if (Is_container(obj) + && (!Waterproof_container(obj) || (obj->cursed && !rn2(3)))) { if (carried(obj)) - pline("Water gets into your %s!", ostr); - + pline("Some water gets into your %s!", ostr); water_damage_chain(obj->cobj, FALSE); return ER_DAMAGED; /* contents were damaged */ - } else if (obj->otyp == OILSKIN_SACK) { - if (carried(obj)) - pline("Some water slides right off your %s.", ostr); - makeknown(OILSKIN_SACK); + } else if (Waterproof_container(obj)) { + if (carried(obj)) { + pline_The("water slides right off your %s.", ostr); + makeknown(obj->otyp); + } /* not actually damaged, but because we /didn't/ get the "water gets into!" message, the player now has more information and thus we need to waste any potion they may have used (also, -- 2.50.0