worn or wielded become unworn/unwielded
hero with lycanthropy is vulnerable to silver in human form as well as beast
changing alignment or shape triggers a check for equipment evading hero's grasp
+passive fire effects can damage attackers weapons
Platform- and/or Interface-Specific Fixes
E void NDECL(uswapwepgone);
E void NDECL(uqwepgone);
E void NDECL(untwoweapon);
-E boolean FDECL(erode_obj, (struct obj *,BOOLEAN_P,BOOLEAN_P,BOOLEAN_P));
+E boolean FDECL(erode_obj, (struct obj *,int,BOOLEAN_P,BOOLEAN_P));
E int FDECL(chwepon, (struct obj *,int));
E int FDECL(welded, (struct obj *));
E void FDECL(weldmsg, (struct obj *));
struct obj *otmph = some_armor(victim);
if (otmph && (otmph != uarmf)) {
- (void) erode_obj(otmph, acid_dmg, FALSE, FALSE);
+ (void) erode_obj(otmph, acid_dmg ? 3 : 1, FALSE, FALSE);
if (carried(otmph)) update_inventory();
}
}
pline("It burns %s!", mon_nam(mdef));
}
if (!rn2(30)) erode_armor(mdef, TRUE);
- if (!rn2(6)) (void) erode_obj(MON_WEP(mdef), TRUE, TRUE, FALSE);
+ if (!rn2(6)) (void) erode_obj(MON_WEP(mdef), 3, TRUE, FALSE);
break;
case AD_RUST:
if (magr->mcan) break;
register struct monst *magr, *mdef;
register struct obj *obj;
{
- boolean is_acid;
+ int dmgtyp;
if (!magr || !mdef || !obj) return; /* just in case */
+ /* AD_ACID is handled in passivemm */
if (dmgtype(mdef->data, AD_CORR))
- is_acid = TRUE;
+ dmgtyp = 3;
else if (dmgtype(mdef->data, AD_RUST))
- is_acid = FALSE;
+ dmgtyp = 1;
+ else if (dmgtype(mdef->data, AD_FIRE))
+ dmgtyp = 0;
else
return;
- (void) erode_obj(obj, is_acid, FALSE, FALSE);
+ (void) erode_obj(obj, dmgtyp, FALSE, FALSE);
}
STATIC_OVL void
tmp = 0;
}
} else tmp = 0;
+ if (!rn2(30)) erode_armor(magr, TRUE);
+ if (!rn2(6)) (void)erode_obj(MON_WEP(magr), 3, TRUE, FALSE);
goto assess_dmg;
case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
if (mhit && !mdef->mcan && otmp) {
register struct monst *mon;
register struct obj *obj;
{
- boolean is_acid;
+ int dmgtyp;
if (!mon || !obj) return; /* just in case */
+ /* AD_ACID is handled in passiveum */
if (dmgtype(youmonst.data, AD_CORR))
- is_acid = TRUE;
+ dmgtyp = 3;
else if (dmgtype(youmonst.data, AD_RUST))
- is_acid = FALSE;
+ dmgtyp = 1;
+ else if (dmgtype(youmonst.data, AD_FIRE))
+ dmgtyp = 0;
else
return;
- (void) erode_obj(obj, is_acid, FALSE, FALSE);
+ (void) erode_obj(obj, dmgtyp, FALSE, FALSE);
}
int
}
} else tmp = 0;
if (!rn2(30)) erode_armor(mtmp, TRUE);
- if (!rn2(6)) (void)erode_obj(MON_WEP(mtmp), TRUE, TRUE, FALSE);
+ if (!rn2(6)) (void)erode_obj(MON_WEP(mtmp), 3, TRUE, FALSE);
goto assess_dmg;
case AD_STON: /* cockatrice */
{
}
if (potion->otyp == POT_ACID) {
- if (erode_obj(obj, TRUE, FALSE, TRUE))
+ if (erode_obj(obj, 3, FALSE, TRUE))
goto poof;
}
break;
if (u.twoweap || (uwep && bimanual(uwep)))
(void) erode_obj(u.twoweap ? uswapwep : uwep,
- FALSE, TRUE, FALSE);
+ 1, TRUE, FALSE);
glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE, &youmonst);
/* Not "metal gauntlets" since it gets called
* even if it's leather for the message
case 2:
pline("%s your right %s!", A_gush_of_water_hits,
body_part(ARM));
- (void) erode_obj(uwep, FALSE, TRUE, FALSE);
+ (void) erode_obj(uwep, 1, TRUE, FALSE);
goto glovecheck;
default:
pline("%s you!", A_gush_of_water_hits);
break;
target = MON_WEP(mtmp);
if (target && bimanual(target))
- (void) erode_obj(target, FALSE, TRUE, FALSE);
+ (void) erode_obj(target, 1, TRUE, FALSE);
glovecheck: target = which_armor(mtmp, W_ARMG);
(void) rust_dmg(target, "gauntlets", 1, TRUE, mtmp);
break;
if (in_sight)
pline("%s %s's right %s!", A_gush_of_water_hits,
mon_nam(mtmp), mbodypart(mtmp, ARM));
- (void) erode_obj(MON_WEP(mtmp), FALSE, TRUE, FALSE);
+ (void) erode_obj(MON_WEP(mtmp), 1, TRUE, FALSE);
goto glovecheck;
default:
if (in_sight)
switch(ptr->mattk[i].adtyp) {
+ case AD_FIRE:
+ if(mhit && !mon->mcan) {
+ if (aatyp == AT_KICK) {
+ if (uarmf && !rn2(6))
+ (void)rust_dmg(uarmf, xname(uarmf), 0, TRUE, &youmonst);
+ } else if (aatyp == AT_WEAP || aatyp == AT_CLAW ||
+ aatyp == AT_MAGC || aatyp == AT_TUCH)
+ passive_obj(mon, (struct obj*)0, &(ptr->mattk[i]));
+ }
+ break;
+
case AD_ACID:
if(mhit && rn2(2)) {
if (Blind || !flags.verbose) You("are splashed!");
switch(mattk->adtyp) {
+ case AD_FIRE:
+ if(!rn2(6) && !mon->mcan) {
+ (void) erode_obj(obj, 0, FALSE, FALSE);
+ }
+ break;
case AD_ACID:
if(!rn2(6)) {
- (void) erode_obj(obj, TRUE, FALSE, FALSE);
+ (void) erode_obj(obj, 3, FALSE, FALSE);
}
break;
case AD_RUST:
if(!mon->mcan) {
- (void) erode_obj(obj, FALSE, FALSE, FALSE);
+ (void) erode_obj(obj, 1, FALSE, FALSE);
}
break;
case AD_CORR:
if(!mon->mcan) {
- (void) erode_obj(obj, TRUE, FALSE, FALSE);
+ (void) erode_obj(obj, 3, FALSE, FALSE);
}
break;
case AD_ENCH:
return;
}
-/* Maybe rust object, or corrode it if acid damage is called for.
+/* Maybe rust (or corrode, burn, rot) object.
* Returns TRUE if something happened. */
boolean
-erode_obj(target, acid_dmg, fade_scrolls, for_dip)
+erode_obj(target, type, fade_scrolls, for_dip)
struct obj *target; /* object (e.g. weapon or armor) to erode */
-boolean acid_dmg;
+int type;
boolean fade_scrolls;
boolean for_dip;
{
+ static NEARDATA const char * const action[] = { "smoulder", "rust", "rot", "corrode" };
+ static NEARDATA const char * const msg[] = { "burnt", "rusty", "rotten", "corroded" };
+ boolean vulnerable = FALSE;
+ boolean grprot = FALSE;
+ boolean is_primary = TRUE;
int erosion;
+ int dmgtyp = AD_ACID;
struct monst *victim;
- boolean vismon, visobj, chill, erodible;
+ boolean vismon, visobj, chill;
boolean ret = FALSE;
boolean already_affected = FALSE;
vismon = victim && (victim != &youmonst) && canseemon(victim);
visobj = !victim && cansee(bhitpos.x, bhitpos.y); /* assume thrown */
- if (!acid_dmg && target->lamplit) {
- already_affected = snuff_lit(target);
- if (already_affected) ret = TRUE;
+ switch(type) {
+ case 0: vulnerable = is_flammable(target);
+ dmgtyp = AD_FIRE;
+ break;
+ case 1: vulnerable = is_rustprone(target);
+ dmgtyp = AD_RUST;
+ grprot = TRUE;
+ if (target->lamplit) {
+ already_affected = snuff_lit(target);
+ if (already_affected) ret = TRUE;
+ }
+ break;
+ case 2: vulnerable = is_rottable(target);
+ dmgtyp = AD_DCAY;
+ is_primary = FALSE;
+ break;
+ case 3: vulnerable = is_corrodeable(target);
+ dmgtyp = AD_ACID;
+ grprot = TRUE;
+ is_primary = FALSE;
+ break;
}
- erosion = acid_dmg ? target->oeroded2 : target->oeroded;
- erodible = acid_dmg ? is_corrodeable(target) : is_rustprone(target);
+ erosion = is_primary ? target->oeroded : target->oeroded2;
- if (target->greased) {
+ if (target->greased && grprot) {
grease_protect(target,(char *)0,victim);
ret = TRUE;
- } else if (target->oclass == SCROLL_CLASS) {
+ } else if (target->oclass == SCROLL_CLASS && (type == 1 || type == 3)) {
if(fade_scrolls && target->otyp != SCR_BLANK_PAPER
#ifdef MAIL
&& target->otyp != SCR_MAIL
target->spe = 0;
ret = TRUE;
}
- } else if (target->oartifact &&
- /* (no artifacts currently meet either of these criteria) */
- arti_immune(target, acid_dmg ? AD_ACID : AD_RUST)) {
- if (flags.verbose) {
+ } else if (target->oartifact && arti_immune(target, dmgtyp)) {
+ if (flags.verbose && (dmgtyp != AD_FIRE)) {
if (victim == &youmonst)
pline("%s.", Yobjnam2(target, "sizzle"));
}
/* no damage to object */
- } else if (target->oartifact && !acid_dmg &&
+ } else if (target->oartifact && (type == 1) &&
/* cold and fire provide partial protection against rust */
((chill = arti_immune(target, AD_COLD)) != 0 ||
arti_immune(target, AD_FIRE)) &&
Yobjnam2(target, chill ? "freeze" : "boil"));
}
/* no damage to object */
- } else if (target->oerodeproof || !erodible) {
+ } else if (target->oerodeproof || !vulnerable) {
/* no message if dipping or not carried */
if (for_dip) {
/* assumes that for_dip implies player action */
if (!Blind) target->rknown = 0;
} else if (victim == &youmonst || vismon) {
- if (flags.verbose || (erodible && !target->rknown))
+ if (flags.verbose || (vulnerable && !target->rknown))
pline("%s not %s.", Yobjnam2(target, "are"),
already_affected ? "harmed" : "affected");
- if (erodible) target->rknown = 1;
+ if (vulnerable) target->rknown = 1;
}
} else if (erosion < MAX_ERODE) {
if (victim == &youmonst || vismon || visobj) {
- pline("%s%s!", Yobjnam2(target, acid_dmg ? "corrode" : "rust"),
+ pline("%s%s!", Yobjnam2(target, action[type]),
erosion+1 == MAX_ERODE ? " completely" :
erosion ? " further" : "");
target->rknown = 1; /* it's obviously not erode-proof */
}
- if (acid_dmg)
- target->oeroded2++;
- else
+ if (is_primary)
target->oeroded++;
+ else
+ target->oeroded2++;
ret = TRUE;
} else {
if (flags.verbose && !for_dip) {
if (victim == &youmonst)
pline("%s completely %s.",
- Yobjnam2(target, Blind ? "feel" : "look"),
- acid_dmg ? "corroded" : "rusty");
+ Yobjnam2(target, Blind ? "feel" : "look"), msg[type]);
else if (vismon || visobj)
pline("%s completely %s.",
- Yobjnam2(target, "look"),
- acid_dmg ? "corroded" : "rusty");
+ Yobjnam2(target, "look"), msg[type]);
}
}
break;
}
tmp = d(nd,6);
- if (!rn2(6)) (void) erode_obj(MON_WEP(mon), TRUE, TRUE, FALSE);
+ if (!rn2(6)) (void) erode_obj(MON_WEP(mon), 3, TRUE, FALSE);
if (!rn2(6)) erode_armor(mon, TRUE);
break;
}
}
/* using two weapons at once makes both of them more vulnerable */
if (!rn2(u.twoweap ? 3 : 6))
- (void) erode_obj(uwep, TRUE, TRUE, FALSE);
+ (void) erode_obj(uwep, 3, TRUE, FALSE);
if (u.twoweap && !rn2(3))
- (void) erode_obj(uswapwep, TRUE, TRUE, FALSE);
+ (void) erode_obj(uswapwep, 3, TRUE, FALSE);
if (!rn2(6)) erode_armor(&youmonst, TRUE);
break;
}