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

@@ -1618,6 +1618,7 @@ entering the tutorial stashed hero's equipment for eventual return to normal
too soon and allowed any items gathered on the first level to be kept
entering the tutorial and then returning to play made the tutorial branch be
eligible for a portal destination via wizard's Eye of the Aethiopica
'hard helmet' was based on being metallic so overlooked crystal helmet
Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository

View File

@@ -564,6 +564,7 @@ extern int stop_donning(struct obj *);
extern int Armor_off(void);
extern int Armor_gone(void);
extern int Helmet_off(void);
extern boolean hard_helmet(struct obj *);
extern void wielding_corpse(struct obj *, struct obj *, boolean);
extern int Gloves_off(void);
extern int Boots_on(void);

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 */