Reduce code duplication in extrinsics-protect-items code
The same checks were being repeated for every damage type; this sends them through two centralised functions (one for checking whether an extrinsic blocks a specific instance of item destruction and one for the enlightenment message), so that new mechanisms of item destruction prevention will need to change only one point in the code.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
37
src/zap.c
37
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) {
|
||||
|
||||
Reference in New Issue
Block a user