github issue #1060 - crystal helmet

Issue reported by vultur-cadens:  changing helm of brilliance to
crystal made it stop being classified as "hard helmet" so it gave
less protection against things falling onto the hero's head.

Change the is_metallic() tests used on helmets to new hard_helmet().
Unlike when thrown, crystal helmets don't break when objects fall
on them.

Fixes #1060
This commit is contained in:
PatR
2023-06-14 06:13:11 -07:00
parent 0440eb5091
commit 450f060132
14 changed files with 44 additions and 14 deletions

View File

@@ -55,7 +55,7 @@ ballfall(void)
pline_The("iron ball falls on your %s.", body_part(HEAD));
if (uarmh) {
if (is_metallic(uarmh)) {
if (hard_helmet(uarmh)) {
pline("Fortunately, you are wearing a hard helmet.");
dmg = 3;
} else if (Verbose(0, ballfall))

View File

@@ -1459,7 +1459,7 @@ zap_dig(void)
}
You("loosen a rock from the %s.", ceiling(u.ux, u.uy));
pline("It falls on your %s!", body_part(HEAD));
dmg = rnd((uarmh && is_metallic(uarmh)) ? 2 : 6);
dmg = rnd(hard_helmet(uarmh) ? 2 : 6);
losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
otmp = mksobj_at(ROCK, u.ux, u.uy, FALSE, FALSE);
if (otmp) {

View File

@@ -512,6 +512,30 @@ Helmet_off(void)
return 0;
}
/* hard helms provide better protection against against falling rocks */
boolean
hard_helmet(struct obj *obj)
{
static const char crystal_[] = "crystal ";
const char *ostr;
int otyp;
if (!obj || !is_helmet(obj))
return FALSE;
if (is_metallic(obj))
return TRUE;
/* make helm of brilliance (crystal helmet) be classified 'hard'; this
test would work for crystal plate mail too if suits reached here */
otyp = obj->otyp;
if (objects[otyp].oc_material == GLASS
&& (((ostr = OBJ_NAME(objects[otyp])) != 0
&& !strncmp(ostr, crystal_, 8))
|| ((ostr = OBJ_DESCR(objects[otyp])) != 0
&& !strncmp(ostr, crystal_, 8))))
return TRUE;
return FALSE;
}
static int
Gloves_on(void)
{

View File

@@ -1334,7 +1334,7 @@ toss_up(struct obj *obj, boolean hitsroof)
} else { /* neither potion nor other breaking object */
int material = objects[otyp].oc_material;
boolean is_silver = (material == SILVER),
less_damage = (uarmh && is_metallic(uarmh)
less_damage = (hard_helmet(uarmh)
&& (!is_silver || !Hate_silver)),
harmless = (stone_missile(obj)
&& passes_rocks(gy.youmonst.data)),

View File

@@ -2945,7 +2945,7 @@ spoteffects(boolean pick)
ceiling(u.ux, u.uy));
if (mtmp->mtame) { /* jumps to greet you, not attack */
;
} else if (uarmh && is_metallic(uarmh)) {
} else if (hard_helmet(uarmh)) {
pline("Its blow glances off your %s.",
helm_simple_name(uarmh));
} else if (u.uac + 3 <= rnd(20)) {

View File

@@ -526,7 +526,7 @@ mattacku(register struct monst *mtmp)
return 0; /* lurkers don't attack */
obj = which_armor(mtmp, WORN_HELMET);
if (obj && is_metallic(obj)) {
if (hard_helmet(obj)) {
Your("blow glances off %s %s.", s_suffix(mon_nam(mtmp)),
helm_simple_name(obj));
} else {

View File

@@ -1430,7 +1430,7 @@ find_offensive(struct monst *mtmp)
*/
nomore(MUSE_SCR_EARTH);
if (obj->otyp == SCR_EARTH
&& ((helmet && is_metallic(helmet)) || mtmp->mconf
&& (hard_helmet(helmet) || mtmp->mconf
|| amorphous(mtmp->data) || passes_walls(mtmp->data)
|| noncorporeal(mtmp->data) || unsolid(mtmp->data)
|| !rn2(10))
@@ -1875,7 +1875,7 @@ rnd_offensive_item(struct monst *mtmp)
case 0: {
struct obj *helmet = which_armor(mtmp, W_ARMH);
if ((helmet && is_metallic(helmet)) || amorphous(pm)
if (hard_helmet(helmet) || amorphous(pm)
|| passes_walls(pm) || noncorporeal(pm) || unsolid(pm))
return SCR_EARTH;
} /* fall through */

View File

@@ -5095,7 +5095,7 @@ helm_simple_name(struct obj *helmet)
* fedora, cornuthaum, dunce cap -> hat
* all other types of helmets -> helm
*/
return (helmet && !is_metallic(helmet)) ? "hat" : "helm";
return !hard_helmet(helmet) ? "hat" : "helm";
}
/* gloves vs gauntlets; depends upon discovery state */

View File

@@ -1173,7 +1173,7 @@ peffect_levitation(struct obj *otmp)
resulted in incrementing 'nothing' */
gp.potion_nothing = 0; /* not nothing after all */
} else if (has_ceiling(&u.uz)) {
int dmg = rnd(!uarmh ? 10 : !is_metallic(uarmh) ? 6 : 3);
int dmg = rnd(!uarmh ? 10 : !hard_helmet(uarmh) ? 6 : 3);
You("hit your %s on the %s.", body_part(HEAD),
ceiling(u.ux, u.uy));

View File

@@ -2164,7 +2164,11 @@ seffects(struct obj *sobj) /* sobj - scroll or fake spellbook for spell */
}
void
drop_boulder_on_player(boolean confused, boolean helmet_protects, boolean byu, boolean skip_uswallow)
drop_boulder_on_player(
boolean confused,
boolean helmet_protects,
boolean byu,
boolean skip_uswallow)
{
int dmg;
struct obj *otmp2;
@@ -2185,7 +2189,7 @@ drop_boulder_on_player(boolean confused, boolean helmet_protects, boolean byu, b
You("are hit by %s!", doname(otmp2));
dmg = (int) (dmgval(otmp2, &gy.youmonst) * otmp2->quan);
if (uarmh && helmet_protects) {
if (is_metallic(uarmh)) {
if (hard_helmet(uarmh)) {
pline("Fortunately, you are wearing a hard helmet.");
if (dmg > 2)
dmg = 2;
@@ -2237,7 +2241,7 @@ drop_boulder_on_monster(coordxy x, coordxy y, boolean confused, boolean byu)
mdmg = dmgval(otmp2, mtmp) * otmp2->quan;
if (helmet) {
if (is_metallic(helmet)) {
if (hard_helmet(helmet)) {
if (canspotmon(mtmp))
pline("Fortunately, %s is wearing a hard helmet.",
mon_nam(mtmp));

View File

@@ -1197,7 +1197,7 @@ trapeffect_rocktrap(
pline("Unfortunately, you are wearing %s.",
an(helm_simple_name(uarmh))); /* helm or hat */
dmg = 2;
} else if (is_metallic(uarmh)) {
} else if (hard_helmet(uarmh)) {
pline("Fortunately, you are wearing a hard helmet.");
dmg = 2;
} else if (Verbose(3, trapeffect_rocktrap)) {

View File

@@ -3148,7 +3148,7 @@ zap_updown(struct obj *obj) /* wand or spell */
/* similar to zap_dig() */
pline("A rock is dislodged from the %s and falls on your %s.",
ceiling(x, y), body_part(HEAD));
dmg = rnd((uarmh && is_metallic(uarmh)) ? 2 : 6);
dmg = rnd(hard_helmet(uarmh) ? 2 : 6);
losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
if ((otmp = mksobj_at(ROCK, x, y, FALSE, FALSE)) != 0) {
(void) xname(otmp); /* set dknown, maybe bknown */