Make monster destroy armor -spell erode armor first
Instead of outright destroying the armor, the spell will instead first erode the armor. The spell hits 2-4 times, so if it hits the same armor 4 times, it will get destroyed. This does not hit erodeproof armor. Also change the scroll of destroy armor, so that blessed one will destroy a cursed armor, if hero is only wearing that.
This commit is contained in:
@@ -2890,12 +2890,15 @@ enlightenment/attribute disclosure for saving-grace: include a line for have
|
||||
tourists gain experience by "taking photos" of new creatures, and
|
||||
going to new dungeon levels
|
||||
healers gain experience by healing pets
|
||||
blessed scroll of destroy armor asks which armor to destroy
|
||||
blessed scroll of destroy armor asks which armor to destroy if wearing more
|
||||
than one armor; otherwise it'll destroy a cursed armor, or erodes
|
||||
random armor
|
||||
archeologists' fedora is lucky
|
||||
telepathic hero can discern which particular monster just read a scroll
|
||||
add "make fetch-docs" to download pre-formatted documentation
|
||||
monsters will use throw-and-return weapons such as an aklys
|
||||
archeologists can identify scrolls by deciphering their labels
|
||||
monster destroy armor -spell first erodes armor
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
@@ -766,7 +766,8 @@ extern struct obj *unchanger(void);
|
||||
extern void reset_remarm(void);
|
||||
extern int doddoremarm(void);
|
||||
extern int remarm_swapwep(void);
|
||||
extern int destroy_arm(struct obj *);
|
||||
extern int disintegrate_arm(struct obj *);
|
||||
extern int destroy_arm(void);
|
||||
extern void adj_abon(struct obj *, schar) NONNULLARG1;
|
||||
extern boolean inaccessible_equipment(struct obj *, const char *, boolean);
|
||||
extern int any_worn_armor_ok(struct obj *);
|
||||
|
||||
@@ -451,6 +451,7 @@ struct obj {
|
||||
#define BURIED_TOO 0x2
|
||||
|
||||
/* object erosion types */
|
||||
#define ERODE_NONE -1
|
||||
#define ERODE_BURN 0
|
||||
#define ERODE_RUST 1
|
||||
#define ERODE_ROT 2
|
||||
|
||||
@@ -52,6 +52,7 @@ staticfn int takeoff_ok(struct obj *);
|
||||
/* maybe_destroy_armor() may return NULL */
|
||||
staticfn struct obj *maybe_destroy_armor(struct obj *, struct obj *,
|
||||
boolean *) NONNULLARG3;
|
||||
staticfn int obj_erode_type(struct obj *) NONNULLARG1;
|
||||
staticfn boolean better_not_take_that_off(struct obj *) NONNULLARG1;
|
||||
|
||||
/* plural "fingers" or optionally "gloves" */
|
||||
@@ -3191,9 +3192,9 @@ maybe_destroy_armor(struct obj *armor, struct obj *atmp, boolean *resisted)
|
||||
return (struct obj *) 0;
|
||||
}
|
||||
|
||||
/* hit by destroy armor scroll/black dragon breath/monster spell */
|
||||
/* hit by destroy armor scroll/black dragon breath */
|
||||
int
|
||||
destroy_arm(struct obj *atmp)
|
||||
disintegrate_arm(struct obj *atmp)
|
||||
{
|
||||
struct obj *otmp = (struct obj *) 0;
|
||||
boolean losing_gloves = FALSE, resisted = FALSE,
|
||||
@@ -3250,6 +3251,66 @@ destroy_arm(struct obj *atmp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* return ERODE_foo erosion type which can apply to object */
|
||||
staticfn int
|
||||
obj_erode_type(struct obj *otmp)
|
||||
{
|
||||
if (is_flammable(otmp))
|
||||
return ERODE_BURN;
|
||||
else if (is_rustprone(otmp))
|
||||
return ERODE_RUST;
|
||||
else if (is_crackable(otmp))
|
||||
return ERODE_CRACK;
|
||||
else if (is_rottable(otmp))
|
||||
return ERODE_ROT;
|
||||
else if (is_corrodeable(otmp))
|
||||
return ERODE_CORRODE;
|
||||
return ERODE_NONE;
|
||||
}
|
||||
|
||||
/* erode a number of worn armor(s).
|
||||
if the armor is hit when max eroded, destroys it. */
|
||||
int
|
||||
destroy_arm(void)
|
||||
{
|
||||
struct obj *armors[7] = { NULL };
|
||||
struct obj *otmp;
|
||||
int i, idx = 0, hits = rn2(4) + 1;
|
||||
int ret = 0;
|
||||
|
||||
/* gather worn armor; include non-erodeable ones */
|
||||
if (uarm) armors[idx++] = uarm;
|
||||
if (uarmc) armors[idx++] = uarmc;
|
||||
if (uarmh) armors[idx++] = uarmh;
|
||||
if (uarms) armors[idx++] = uarms;
|
||||
if (uarmg) armors[idx++] = uarmg;
|
||||
if (uarmf) armors[idx++] = uarmf;
|
||||
if (uarmu) armors[idx++] = uarmu;
|
||||
if (!idx)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < hits; i++) {
|
||||
otmp = armors[rn2(idx)];
|
||||
|
||||
if (erosion_matters(otmp) && is_damageable(otmp) && !otmp->oerodeproof) {
|
||||
int erosion = obj_erode_type(otmp);
|
||||
|
||||
if (erosion != ERODE_NONE) {
|
||||
int r = erode_obj(otmp, xname(otmp), erosion, EF_PAY|EF_DESTROY);
|
||||
|
||||
if (r != ER_NOTHING)
|
||||
ret = 1;
|
||||
if (r == ER_DESTROYED)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
stop_occupation();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
adj_abon(struct obj *otmp, schar delta)
|
||||
{
|
||||
|
||||
@@ -530,7 +530,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
|
||||
shieldeff(u.ux, u.uy);
|
||||
monstseesu(M_SEEN_MAGR);
|
||||
pline("A field of force surrounds you!");
|
||||
} else if (!destroy_arm(some_armor(&gy.youmonst))) {
|
||||
} else if (!destroy_arm()) {
|
||||
Your("skin itches.");
|
||||
} else {
|
||||
/* monsters only realize you aren't magic-protected if armor is
|
||||
|
||||
@@ -660,15 +660,15 @@ god_zaps_you(aligntyp resp_god)
|
||||
*/
|
||||
if (uarms && !(EReflecting & W_ARMS)
|
||||
&& !(EDisint_resistance & W_ARMS))
|
||||
(void) destroy_arm(uarms);
|
||||
(void) disintegrate_arm(uarms);
|
||||
if (uarmc && !(EReflecting & W_ARMC)
|
||||
&& !(EDisint_resistance & W_ARMC))
|
||||
(void) destroy_arm(uarmc);
|
||||
(void) disintegrate_arm(uarmc);
|
||||
if (uarm && !(EReflecting & W_ARM) && !(EDisint_resistance & W_ARM)
|
||||
&& !uarmc)
|
||||
(void) destroy_arm(uarm);
|
||||
(void) disintegrate_arm(uarm);
|
||||
if (uarmu && !uarm && !uarmc)
|
||||
(void) destroy_arm(uarmu);
|
||||
(void) disintegrate_arm(uarmu);
|
||||
if (!Disint_resistance) {
|
||||
fry_by_god(resp_god, TRUE);
|
||||
monstunseesu(M_SEEN_DISINT);
|
||||
|
||||
58
src/read.c
58
src/read.c
@@ -22,6 +22,7 @@ staticfn int maybe_tame(struct monst *, struct obj *);
|
||||
staticfn boolean can_center_cloud(coordxy, coordxy);
|
||||
staticfn void display_stinking_cloud_positions(boolean);
|
||||
staticfn void seffect_enchant_armor(struct obj **);
|
||||
staticfn boolean disintegrate_cursed_armor(void);
|
||||
staticfn void seffect_destroy_armor(struct obj **);
|
||||
staticfn void seffect_confuse_monster(struct obj **);
|
||||
staticfn void seffect_scare_monster(struct obj **);
|
||||
@@ -1281,6 +1282,29 @@ seffect_enchant_armor(struct obj **sobjp)
|
||||
Blind ? "again" : "unexpectedly");
|
||||
}
|
||||
|
||||
/* destroy a random cursed armor worn by hero */
|
||||
staticfn boolean
|
||||
disintegrate_cursed_armor(void)
|
||||
{
|
||||
struct obj *armors[7] = { NULL };
|
||||
int idx = 0;
|
||||
|
||||
if (uarm && uarm->cursed) armors[idx++] = uarm;
|
||||
if (uarmc && uarmc->cursed) armors[idx++] = uarmc;
|
||||
if (uarmh && uarmh->cursed) armors[idx++] = uarmh;
|
||||
if (uarms && uarms->cursed) armors[idx++] = uarms;
|
||||
if (uarmg && uarmg->cursed) armors[idx++] = uarmg;
|
||||
if (uarmf && uarmf->cursed) armors[idx++] = uarmf;
|
||||
if (uarmu && uarmu->cursed) armors[idx++] = uarmu;
|
||||
if (!idx)
|
||||
return FALSE;
|
||||
|
||||
if (disintegrate_arm(armors[rn2(idx)]))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
staticfn void
|
||||
seffect_destroy_armor(struct obj **sobjp)
|
||||
{
|
||||
@@ -1310,7 +1334,21 @@ seffect_destroy_armor(struct obj **sobjp)
|
||||
otmp->oerodeproof = new_erodeproof ? 1 : 0;
|
||||
return;
|
||||
}
|
||||
if (!scursed || !otmp || !otmp->cursed) {
|
||||
|
||||
if (scursed) {
|
||||
if (otmp && otmp->cursed) {
|
||||
/* armor and scroll both cursed */
|
||||
pline("%s.", Yobjnam2(otmp, "vibrate"));
|
||||
if (otmp->spe >= -6) {
|
||||
otmp->spe += -1;
|
||||
adj_abon(otmp, -1);
|
||||
}
|
||||
make_stunned((HStun & TIMEOUT) + (long) rn1(10, 10), TRUE);
|
||||
} else if (disintegrate_arm(otmp)) {
|
||||
gk.known = TRUE;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
boolean gets_choice = (otmp && sobj && sobj->blessed
|
||||
&& count_worn_armor() > 1);
|
||||
|
||||
@@ -1324,9 +1362,14 @@ seffect_destroy_armor(struct obj **sobjp)
|
||||
/* check the return value, if user picked non-valid obj */
|
||||
if (any_worn_armor_ok(atmp) == GETOBJ_SUGGEST)
|
||||
otmp = atmp;
|
||||
}
|
||||
|
||||
if (!destroy_arm(otmp)) {
|
||||
if (disintegrate_arm(otmp)) {
|
||||
gk.known = TRUE;
|
||||
return;
|
||||
}
|
||||
} else if (sobj->blessed && disintegrate_cursed_armor()) {
|
||||
gk.known = TRUE;
|
||||
return;
|
||||
} else if (!destroy_arm()) {
|
||||
strange_feeling(sobj, "Your skin itches.");
|
||||
*sobjp = 0; /* useup() in strange_feeling() */
|
||||
exercise(A_STR, FALSE);
|
||||
@@ -1334,13 +1377,6 @@ seffect_destroy_armor(struct obj **sobjp)
|
||||
return;
|
||||
} else
|
||||
gk.known = TRUE;
|
||||
} else { /* armor and scroll both cursed */
|
||||
pline("%s.", Yobjnam2(otmp, "vibrate"));
|
||||
if (otmp->spe >= -6) {
|
||||
otmp->spe += -1;
|
||||
adj_abon(otmp, -1);
|
||||
}
|
||||
make_stunned((HStun & TIMEOUT) + (long) rn1(10, 10), TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
src/zap.c
10
src/zap.c
@@ -4462,21 +4462,21 @@ zhitu(
|
||||
monstunseesu(M_SEEN_DISINT);
|
||||
if (uarms) {
|
||||
/* destroy shield; other possessions are safe */
|
||||
(void) destroy_arm(uarms);
|
||||
(void) disintegrate_arm(uarms);
|
||||
break;
|
||||
} else if (uarm) {
|
||||
/* destroy suit; if present, cloak goes too */
|
||||
if (uarmc)
|
||||
(void) destroy_arm(uarmc);
|
||||
(void) destroy_arm(uarm);
|
||||
(void) disintegrate_arm(uarmc);
|
||||
(void) disintegrate_arm(uarm);
|
||||
break;
|
||||
}
|
||||
/* no shield or suit, you're dead; wipe out cloak
|
||||
and/or shirt in case of life-saving or bones */
|
||||
if (uarmc)
|
||||
(void) destroy_arm(uarmc);
|
||||
(void) disintegrate_arm(uarmc);
|
||||
if (uarmu)
|
||||
(void) destroy_arm(uarmu);
|
||||
(void) disintegrate_arm(uarmu);
|
||||
} else if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) {
|
||||
shieldeff(sx, sy);
|
||||
You("seem unaffected.");
|
||||
|
||||
Reference in New Issue
Block a user