]> granicus.if.org Git - nethack/commitdiff
Resistances gained from worn or wielded items also protect inventory
authorPasi Kallinen <paxed@alt.org>
Mon, 6 Sep 2021 17:06:19 +0000 (20:06 +0300)
committerPasi Kallinen <paxed@alt.org>
Mon, 6 Sep 2021 17:24:44 +0000 (20:24 +0300)
doc/fixes37.0
include/extern.h
src/insight.c
src/trap.c
src/zap.c

index efda5f29d13560f1e6a909e20006afc5d65744fc..e5f97aae49b9fde351b3dd1977f3dcdf0a2bceaf 100644 (file)
@@ -605,6 +605,7 @@ yet another fix for display problems during restore:  if game is saved while
        restore will try to update hero's spot when making sure objects aren't
        being obfuscated by hallucination, but when displaying the hero there
        instead it would access steed pointer before that has been set up
+resistances gained from worn or wielded items also protect hero's inventory
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index 59164576395fd4316990e02ace296c4c26214f00..27ce86eafcd3ce955860a5aab9d08e886a452d2f 100644 (file)
@@ -3222,6 +3222,7 @@ extern void melt_ice_away(union any *, long);
 extern int zap_over_floor(xchar, xchar, int, boolean *, short);
 extern void fracture_rock(struct obj *);
 extern boolean break_statue(struct obj *);
+extern boolean u_adtyp_resistance_obj(int);
 extern void destroy_item(int, int);
 extern int destroy_mitem(struct monst *, int, int);
 extern int resist(struct monst *, char, int, int);
index 908001c9123e30ba5e66de30962ef13629a5af89..2bfd58e053424ea8c6f3a5d8124a3dc1c0ddeb0b 100644 (file)
@@ -1373,18 +1373,28 @@ attributes_enlightenment(int unused_mode UNUSED, int final)
         you_are("magic-protected", from_what(ANTIMAGIC));
     if (Fire_resistance)
         you_are("fire resistant", from_what(FIRE_RES));
+    if (u_adtyp_resistance_obj(AD_FIRE))
+        enl_msg("Your items ", "are", "were", " protected from fire", "");
     if (Cold_resistance)
         you_are("cold resistant", from_what(COLD_RES));
+    if (u_adtyp_resistance_obj(AD_COLD))
+        enl_msg("Your items ", "are", "were", " protected from cold", "");
     if (Sleep_resistance)
         you_are("sleep resistant", from_what(SLEEP_RES));
     if (Disint_resistance)
         you_are("disintegration-resistant", from_what(DISINT_RES));
+    if (u_adtyp_resistance_obj(AD_DISN))
+        enl_msg("Your items ", "are", "were", " protected from disintegration", "");
     if (Shock_resistance)
         you_are("shock resistant", from_what(SHOCK_RES));
+    if (u_adtyp_resistance_obj(AD_ELEC))
+        enl_msg("Your items ", "are", "were", " protected from electric shocks", "");
     if (Poison_resistance)
         you_are("poison resistant", from_what(POISON_RES));
     if (Acid_resistance)
         you_are("acid resistant", from_what(ACID_RES));
+    if (u_adtyp_resistance_obj(AD_ACID))
+        enl_msg("Your items ", "are", "were", " protected from acid", "");
     if (Drain_resistance)
         you_are("level-drain resistant", from_what(DRAIN_RES));
     if (Sick_resistance)
index 6fd29ecf55d216a644a2dd37c8b5b7a8fa2271bd..c55e02d23b9344720e9d9ed56200455472188495 100644 (file)
@@ -187,6 +187,8 @@ erode_obj(
 
     switch (type) {
     case ERODE_BURN:
+        if (uvictim && u_adtyp_resistance_obj(AD_FIRE) && rn2(100))
+            return ER_NOTHING;
         vulnerable = is_flammable(otmp);
         check_grease = FALSE;
         cost_type = COST_BURN;
@@ -202,6 +204,8 @@ erode_obj(
         cost_type = COST_ROT;
         break;
     case ERODE_CORRODE:
+        if (uvictim && u_adtyp_resistance_obj(AD_ACID) && rn2(100))
+            return ER_NOTHING;
         vulnerable = is_corrodeable(otmp);
         is_primary = FALSE;
         cost_type = COST_CORRODE;
@@ -3871,6 +3875,9 @@ acid_damage(struct obj* obj)
     victim = carried(obj) ? &g.youmonst : mcarried(obj) ? obj->ocarry : NULL;
     vismon = victim && (victim != &g.youmonst) && canseemon(victim);
 
+    if (victim == &g.youmonst && u_adtyp_resistance_obj(AD_ACID) && rn2(100))
+        return;
+
     if (obj->greased) {
         grease_protect(obj, (char *) 0, victim);
     } else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
index 245968e64c46c6f09b5fa8e97866beefac939bfe..f27f82d2384cfb990912ce4e4d095f3246945f45 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -23,6 +23,7 @@ static boolean zap_steed(struct obj *);
 static void skiprange(int, int *, int *);
 static int zap_hit(int, int);
 static void disintegrate_mon(struct monst *, int, const char *);
+static int adtyp_to_prop(int);
 static void backfire(struct obj *);
 static int zap_ok(struct obj *);
 static void boxlock_invent(struct obj *);
@@ -3965,10 +3966,14 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy)
         break;
     case ZT_DEATH:
         if (abstyp == ZT_BREATH(ZT_DEATH)) {
+            boolean disn_prot = u_adtyp_resistance_obj(AD_DISN) && rn2(100);
+
             if (Disint_resistance) {
                 You("are not disintegrated.");
                 monstseesu(M_SEEN_DISINT);
                 break;
+            } else if (disn_prot) {
+                break;
             } else if (uarms) {
                 /* destroy shield; other possessions are safe */
                 (void) destroy_arm(uarms);
@@ -4940,6 +4945,36 @@ break_statue(struct obj *obj)
     return TRUE;
 }
 
+/* convert attack damage AD_foo to property resistance */
+static int
+adtyp_to_prop(int dmgtyp)
+{
+    switch (dmgtyp) {
+    case AD_COLD: return COLD_RES;
+    case AD_FIRE: return FIRE_RES;
+    case AD_ELEC: return SHOCK_RES;
+    case AD_ACID: return ACID_RES;
+    case AD_DISN: return DISINT_RES;
+    default: return 0; /* prop_types start at 1 */
+    }
+}
+
+/* is hero wearing or wielding an object with resistance
+   to attack damage type */
+boolean
+u_adtyp_resistance_obj(int dmgtyp)
+{
+    int prop = adtyp_to_prop(dmgtyp);
+
+    if (!prop)
+        return FALSE;
+
+    if ((u.uprops[prop].extrinsic & (W_ARMOR | W_ACCESSORY | W_WEP)) != 0)
+        return TRUE;
+
+    return FALSE;
+}
+
 /*
  * destroy_strings[dindx][0:singular,1:plural,2:killer_reason]
  *      [0] freezing potion
@@ -4979,6 +5014,10 @@ destroy_one_item(struct obj *obj, int osym, int dmgtyp)
     dmg = dindx = 0;
     quan = 0L;
 
+    /* external worn item protects inventory? */
+    if (u_adtyp_resistance_obj(dmgtyp) && rn2(100))
+        return;
+
     switch (dmgtyp) {
     case AD_COLD:
         if (osym == POTION_CLASS && obj->otyp != POT_OIL) {