diff --git a/include/extern.h b/include/extern.h index a8f57c305..7f0e72aaa 100644 --- a/include/extern.h +++ b/include/extern.h @@ -3582,7 +3582,8 @@ extern void melt_ice_away(union any *, long); extern int zap_over_floor(coordxy, coordxy, int, boolean *, boolean, short); extern void fracture_rock(struct obj *); extern boolean break_statue(struct obj *); -extern boolean u_adtyp_resistance_obj(int); +extern int u_adtyp_resistance_obj(int); +extern boolean inventory_resistance_check(int); extern char *item_what(int); extern void destroy_item(int, int); extern int destroy_mitem(struct monst *, int, int); diff --git a/src/dothrow.c b/src/dothrow.c index 1ca322c2e..8ecab42e9 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -2524,8 +2524,9 @@ breakobj( } /* - * Check to see if obj is going to break, but don't actually break it. - * Return 0 if the object isn't going to break, 1 if it is. + * Check to see if obj (which has just hit hard something at speed, e.g. + * thrown or dropped from height) is going to break, but don't actually + * break it. Return 0 if the object isn't going to break, 1 if it is. */ boolean breaktest(struct obj *obj) diff --git a/src/insight.c b/src/insight.c index ddeb56c67..e5b4964a4 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1429,6 +1429,19 @@ weapon_insight(int final) } /* skill applies */ } +static void +item_resistance_message(int adtyp, const char *prot_message, int final) +{ + int protection = u_adtyp_resistance_obj(adtyp); + if (protection) { + boolean somewhat = protection < 99; + enl_msg("Your items ", + somewhat ? "are somewhat" : "are", + somewhat ? "were somewhat" : "were", + prot_message, item_what(adtyp)); + } +} + /* attributes: intrinsics and the like, other non-obvious capabilities */ static void attributes_enlightenment(int unused_mode UNUSED, int final) @@ -1469,26 +1482,18 @@ 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", - item_what(AD_FIRE)); + item_resistance_message(AD_FIRE, " protected from fire", final); 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", - item_what(AD_COLD)); + item_resistance_message(AD_COLD, " protected from cold", final); 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", item_what(AD_DISN)); + item_resistance_message(AD_DISN, " protected from disintegration", final); 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", item_what(AD_ELEC)); + item_resistance_message(AD_ELEC, " protected from electric shocks", final); if (Poison_resistance) you_are("poison resistant", from_what(POISON_RES)); if (Acid_resistance) { @@ -1497,9 +1502,7 @@ attributes_enlightenment(int unused_mode UNUSED, int final) "acid resistant"); you_are(buf, from_what(ACID_RES)); } - if (u_adtyp_resistance_obj(AD_ACID)) - enl_msg("Your items ", "are", "were", " protected from acid", - item_what(AD_ACID)); + item_resistance_message(AD_ACID, " protected from acid", final); if (Drain_resistance) you_are("level-drain resistant", from_what(DRAIN_RES)); if (Sick_resistance) diff --git a/src/trap.c b/src/trap.c index 8dee860a3..4f41c2d0e 100644 --- a/src/trap.c +++ b/src/trap.c @@ -198,7 +198,7 @@ erode_obj( switch (type) { case ERODE_BURN: - if (uvictim && u_adtyp_resistance_obj(AD_FIRE) && rn2(100)) + if (uvictim && inventory_resistance_check(AD_FIRE)) return ER_NOTHING; vulnerable = is_flammable(otmp); check_grease = FALSE; @@ -215,7 +215,7 @@ erode_obj( cost_type = COST_ROT; break; case ERODE_CORRODE: - if (uvictim && u_adtyp_resistance_obj(AD_ACID) && rn2(100)) + if (uvictim && inventory_resistance_check(AD_ACID)) return ER_NOTHING; vulnerable = is_corrodeable(otmp); is_primary = FALSE; @@ -4362,7 +4362,7 @@ acid_damage(struct obj* obj) victim = carried(obj) ? &gy.youmonst : mcarried(obj) ? obj->ocarry : NULL; vismon = victim && (victim != &gy.youmonst) && canseemon(victim); - if (victim == &gy.youmonst && u_adtyp_resistance_obj(AD_ACID) && rn2(100)) + if (victim == &gy.youmonst && inventory_resistance_check(AD_ACID)) return; if (obj->greased) { diff --git a/src/zap.c b/src/zap.c index e10c43e5a..dd3f6d259 100644 --- a/src/zap.c +++ b/src/zap.c @@ -4317,7 +4317,7 @@ zhitu( break; case ZT_DEATH: if (abstyp == ZT_BREATH(ZT_DEATH)) { - boolean disn_prot = u_adtyp_resistance_obj(AD_DISN) && rn2(100); + boolean disn_prot = inventory_resistance_check(AD_DISN); if (Disint_resistance) { You("are not disintegrated."); @@ -5391,20 +5391,41 @@ adtyp_to_prop(int dmgtyp) return 0; /* prop_types start at 1 */ } -/* is hero wearing or wielding an object with resistance - to attack damage type */ -boolean +/* Is hero wearing or wielding an object with resistance to attack + damage type? Returns the percentage protectoin that the object + gives. */ +int u_adtyp_resistance_obj(int dmgtyp) { int prop = adtyp_to_prop(dmgtyp); if (!prop) - return FALSE; + return 0; if ((u.uprops[prop].extrinsic & (W_ARMOR | W_ACCESSORY | W_WEP)) != 0) - return TRUE; + return 99; /* 99% protected */ - return FALSE; + return 0; +} + +/* Rolls to see whether an object in inventory resists damage from the + given damage type, due to an equipped item protecting it. Use + u_adtyp_resistance_obj to discover whether objects are protected in + general (e.g. for enlightenment) and this function to actually do + the roll to see whether a specific object is protected. + + This function doesn't check for other reasons why an object might + be protected; you will usually need to do an obj_resists() call + too. */ +boolean +inventory_resistance_check(int dmgtyp) +{ + int prob = u_adtyp_resistance_obj(dmgtyp); + + if (!prob) + return FALSE; + + return rn2(100) < prob; } /* for enlightenment; currently only useful in wizard mode; cf from_what() */ @@ -5491,7 +5512,7 @@ destroy_one_item(struct obj *obj, int osym, int dmgtyp) quan = 0L; /* external worn item protects inventory? */ - if (u_adtyp_resistance_obj(dmgtyp) && rn2(100)) + if (inventory_resistance_check(dmgtyp)) return; switch (dmgtyp) {