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:
+4
-1
@@ -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
|
tourists gain experience by "taking photos" of new creatures, and
|
||||||
going to new dungeon levels
|
going to new dungeon levels
|
||||||
healers gain experience by healing pets
|
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
|
archeologists' fedora is lucky
|
||||||
telepathic hero can discern which particular monster just read a scroll
|
telepathic hero can discern which particular monster just read a scroll
|
||||||
add "make fetch-docs" to download pre-formatted documentation
|
add "make fetch-docs" to download pre-formatted documentation
|
||||||
monsters will use throw-and-return weapons such as an aklys
|
monsters will use throw-and-return weapons such as an aklys
|
||||||
archeologists can identify scrolls by deciphering their labels
|
archeologists can identify scrolls by deciphering their labels
|
||||||
|
monster destroy armor -spell first erodes armor
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific New Features
|
Platform- and/or Interface-Specific New Features
|
||||||
|
|||||||
+2
-1
@@ -766,7 +766,8 @@ extern struct obj *unchanger(void);
|
|||||||
extern void reset_remarm(void);
|
extern void reset_remarm(void);
|
||||||
extern int doddoremarm(void);
|
extern int doddoremarm(void);
|
||||||
extern int remarm_swapwep(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 void adj_abon(struct obj *, schar) NONNULLARG1;
|
||||||
extern boolean inaccessible_equipment(struct obj *, const char *, boolean);
|
extern boolean inaccessible_equipment(struct obj *, const char *, boolean);
|
||||||
extern int any_worn_armor_ok(struct obj *);
|
extern int any_worn_armor_ok(struct obj *);
|
||||||
|
|||||||
@@ -451,6 +451,7 @@ struct obj {
|
|||||||
#define BURIED_TOO 0x2
|
#define BURIED_TOO 0x2
|
||||||
|
|
||||||
/* object erosion types */
|
/* object erosion types */
|
||||||
|
#define ERODE_NONE -1
|
||||||
#define ERODE_BURN 0
|
#define ERODE_BURN 0
|
||||||
#define ERODE_RUST 1
|
#define ERODE_RUST 1
|
||||||
#define ERODE_ROT 2
|
#define ERODE_ROT 2
|
||||||
|
|||||||
+63
-2
@@ -52,6 +52,7 @@ staticfn int takeoff_ok(struct obj *);
|
|||||||
/* maybe_destroy_armor() may return NULL */
|
/* maybe_destroy_armor() may return NULL */
|
||||||
staticfn struct obj *maybe_destroy_armor(struct obj *, struct obj *,
|
staticfn struct obj *maybe_destroy_armor(struct obj *, struct obj *,
|
||||||
boolean *) NONNULLARG3;
|
boolean *) NONNULLARG3;
|
||||||
|
staticfn int obj_erode_type(struct obj *) NONNULLARG1;
|
||||||
staticfn boolean better_not_take_that_off(struct obj *) NONNULLARG1;
|
staticfn boolean better_not_take_that_off(struct obj *) NONNULLARG1;
|
||||||
|
|
||||||
/* plural "fingers" or optionally "gloves" */
|
/* plural "fingers" or optionally "gloves" */
|
||||||
@@ -3191,9 +3192,9 @@ maybe_destroy_armor(struct obj *armor, struct obj *atmp, boolean *resisted)
|
|||||||
return (struct obj *) 0;
|
return (struct obj *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hit by destroy armor scroll/black dragon breath/monster spell */
|
/* hit by destroy armor scroll/black dragon breath */
|
||||||
int
|
int
|
||||||
destroy_arm(struct obj *atmp)
|
disintegrate_arm(struct obj *atmp)
|
||||||
{
|
{
|
||||||
struct obj *otmp = (struct obj *) 0;
|
struct obj *otmp = (struct obj *) 0;
|
||||||
boolean losing_gloves = FALSE, resisted = FALSE,
|
boolean losing_gloves = FALSE, resisted = FALSE,
|
||||||
@@ -3250,6 +3251,66 @@ destroy_arm(struct obj *atmp)
|
|||||||
return 1;
|
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
|
void
|
||||||
adj_abon(struct obj *otmp, schar delta)
|
adj_abon(struct obj *otmp, schar delta)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -530,7 +530,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
|
|||||||
shieldeff(u.ux, u.uy);
|
shieldeff(u.ux, u.uy);
|
||||||
monstseesu(M_SEEN_MAGR);
|
monstseesu(M_SEEN_MAGR);
|
||||||
pline("A field of force surrounds you!");
|
pline("A field of force surrounds you!");
|
||||||
} else if (!destroy_arm(some_armor(&gy.youmonst))) {
|
} else if (!destroy_arm()) {
|
||||||
Your("skin itches.");
|
Your("skin itches.");
|
||||||
} else {
|
} else {
|
||||||
/* monsters only realize you aren't magic-protected if armor is
|
/* monsters only realize you aren't magic-protected if armor is
|
||||||
|
|||||||
+4
-4
@@ -660,15 +660,15 @@ god_zaps_you(aligntyp resp_god)
|
|||||||
*/
|
*/
|
||||||
if (uarms && !(EReflecting & W_ARMS)
|
if (uarms && !(EReflecting & W_ARMS)
|
||||||
&& !(EDisint_resistance & W_ARMS))
|
&& !(EDisint_resistance & W_ARMS))
|
||||||
(void) destroy_arm(uarms);
|
(void) disintegrate_arm(uarms);
|
||||||
if (uarmc && !(EReflecting & W_ARMC)
|
if (uarmc && !(EReflecting & W_ARMC)
|
||||||
&& !(EDisint_resistance & W_ARMC))
|
&& !(EDisint_resistance & W_ARMC))
|
||||||
(void) destroy_arm(uarmc);
|
(void) disintegrate_arm(uarmc);
|
||||||
if (uarm && !(EReflecting & W_ARM) && !(EDisint_resistance & W_ARM)
|
if (uarm && !(EReflecting & W_ARM) && !(EDisint_resistance & W_ARM)
|
||||||
&& !uarmc)
|
&& !uarmc)
|
||||||
(void) destroy_arm(uarm);
|
(void) disintegrate_arm(uarm);
|
||||||
if (uarmu && !uarm && !uarmc)
|
if (uarmu && !uarm && !uarmc)
|
||||||
(void) destroy_arm(uarmu);
|
(void) disintegrate_arm(uarmu);
|
||||||
if (!Disint_resistance) {
|
if (!Disint_resistance) {
|
||||||
fry_by_god(resp_god, TRUE);
|
fry_by_god(resp_god, TRUE);
|
||||||
monstunseesu(M_SEEN_DISINT);
|
monstunseesu(M_SEEN_DISINT);
|
||||||
|
|||||||
+47
-11
@@ -22,6 +22,7 @@ staticfn int maybe_tame(struct monst *, struct obj *);
|
|||||||
staticfn boolean can_center_cloud(coordxy, coordxy);
|
staticfn boolean can_center_cloud(coordxy, coordxy);
|
||||||
staticfn void display_stinking_cloud_positions(boolean);
|
staticfn void display_stinking_cloud_positions(boolean);
|
||||||
staticfn void seffect_enchant_armor(struct obj **);
|
staticfn void seffect_enchant_armor(struct obj **);
|
||||||
|
staticfn boolean disintegrate_cursed_armor(void);
|
||||||
staticfn void seffect_destroy_armor(struct obj **);
|
staticfn void seffect_destroy_armor(struct obj **);
|
||||||
staticfn void seffect_confuse_monster(struct obj **);
|
staticfn void seffect_confuse_monster(struct obj **);
|
||||||
staticfn void seffect_scare_monster(struct obj **);
|
staticfn void seffect_scare_monster(struct obj **);
|
||||||
@@ -1281,6 +1282,29 @@ seffect_enchant_armor(struct obj **sobjp)
|
|||||||
Blind ? "again" : "unexpectedly");
|
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
|
staticfn void
|
||||||
seffect_destroy_armor(struct obj **sobjp)
|
seffect_destroy_armor(struct obj **sobjp)
|
||||||
{
|
{
|
||||||
@@ -1310,7 +1334,21 @@ seffect_destroy_armor(struct obj **sobjp)
|
|||||||
otmp->oerodeproof = new_erodeproof ? 1 : 0;
|
otmp->oerodeproof = new_erodeproof ? 1 : 0;
|
||||||
return;
|
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
|
boolean gets_choice = (otmp && sobj && sobj->blessed
|
||||||
&& count_worn_armor() > 1);
|
&& count_worn_armor() > 1);
|
||||||
|
|
||||||
@@ -1324,9 +1362,14 @@ seffect_destroy_armor(struct obj **sobjp)
|
|||||||
/* check the return value, if user picked non-valid obj */
|
/* check the return value, if user picked non-valid obj */
|
||||||
if (any_worn_armor_ok(atmp) == GETOBJ_SUGGEST)
|
if (any_worn_armor_ok(atmp) == GETOBJ_SUGGEST)
|
||||||
otmp = atmp;
|
otmp = atmp;
|
||||||
}
|
if (disintegrate_arm(otmp)) {
|
||||||
|
gk.known = TRUE;
|
||||||
if (!destroy_arm(otmp)) {
|
return;
|
||||||
|
}
|
||||||
|
} else if (sobj->blessed && disintegrate_cursed_armor()) {
|
||||||
|
gk.known = TRUE;
|
||||||
|
return;
|
||||||
|
} else if (!destroy_arm()) {
|
||||||
strange_feeling(sobj, "Your skin itches.");
|
strange_feeling(sobj, "Your skin itches.");
|
||||||
*sobjp = 0; /* useup() in strange_feeling() */
|
*sobjp = 0; /* useup() in strange_feeling() */
|
||||||
exercise(A_STR, FALSE);
|
exercise(A_STR, FALSE);
|
||||||
@@ -1334,13 +1377,6 @@ seffect_destroy_armor(struct obj **sobjp)
|
|||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
gk.known = TRUE;
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4462,21 +4462,21 @@ zhitu(
|
|||||||
monstunseesu(M_SEEN_DISINT);
|
monstunseesu(M_SEEN_DISINT);
|
||||||
if (uarms) {
|
if (uarms) {
|
||||||
/* destroy shield; other possessions are safe */
|
/* destroy shield; other possessions are safe */
|
||||||
(void) destroy_arm(uarms);
|
(void) disintegrate_arm(uarms);
|
||||||
break;
|
break;
|
||||||
} else if (uarm) {
|
} else if (uarm) {
|
||||||
/* destroy suit; if present, cloak goes too */
|
/* destroy suit; if present, cloak goes too */
|
||||||
if (uarmc)
|
if (uarmc)
|
||||||
(void) destroy_arm(uarmc);
|
(void) disintegrate_arm(uarmc);
|
||||||
(void) destroy_arm(uarm);
|
(void) disintegrate_arm(uarm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* no shield or suit, you're dead; wipe out cloak
|
/* no shield or suit, you're dead; wipe out cloak
|
||||||
and/or shirt in case of life-saving or bones */
|
and/or shirt in case of life-saving or bones */
|
||||||
if (uarmc)
|
if (uarmc)
|
||||||
(void) destroy_arm(uarmc);
|
(void) disintegrate_arm(uarmc);
|
||||||
if (uarmu)
|
if (uarmu)
|
||||||
(void) destroy_arm(uarmu);
|
(void) disintegrate_arm(uarmu);
|
||||||
} else if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) {
|
} else if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) {
|
||||||
shieldeff(sx, sy);
|
shieldeff(sx, sy);
|
||||||
You("seem unaffected.");
|
You("seem unaffected.");
|
||||||
|
|||||||
Reference in New Issue
Block a user