Eliminate erode_obj() and other erosion.

Now all erosion that isn't fire-based goes through `rust_dmg()`
This commit is contained in:
Sean Hunt
2015-02-24 15:20:01 -05:00
parent 7e0d552b06
commit 3a049cf66e
10 changed files with 73 additions and 196 deletions

View File

@@ -859,9 +859,11 @@ if lava burns up the player's water walking boots, the player falls in
the messages for lava burning items up are always printed
fix used-up magic trap trying to hit steed.
messages are now printed when objects on the ground are eroded
object erosion now always identifies rust/rot/fire/corrodeproof objects
object erosion now always identifies fooproof objects
grease protects from all types of erosion
all sources of erosion now affect objects the same way
passive attacks no longer erode armor covered by other armor
dipping a fooproof item into acid no longer forgets that it's fooproof
Platform- and/or Interface-Specific Fixes

View File

@@ -1070,6 +1070,7 @@ E int FDECL(sleep_monst, (struct monst *,int,int));
E void FDECL(slept_monst, (struct monst *));
E void FDECL(xdrainenergym, (struct monst *,BOOLEAN_P));
E long FDECL(attk_protection, (int));
E void FDECL(rustm, (struct monst *,struct obj *));
/* ### mhitu.c ### */
@@ -2222,6 +2223,7 @@ E void FDECL(fill_pit, (int,int));
E int FDECL(float_down, (long, long));
E void NDECL(climb_pit);
E int FDECL(fire_damage, (struct obj *,BOOLEAN_P,BOOLEAN_P,XCHAR_P,XCHAR_P));
E void acid_damage(struct obj *);
E int FDECL(water_damage, (struct obj *,const char*,BOOLEAN_P));
E void FDECL(water_damage_chain, (struct obj *,BOOLEAN_P));
E boolean NDECL(drown);
@@ -2516,7 +2518,6 @@ E void NDECL(uwepgone);
E void NDECL(uswapwepgone);
E void NDECL(uqwepgone);
E void NDECL(untwoweapon);
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 *));

View File

@@ -16,7 +16,6 @@ static const char brief_feeling[] =
"have a %s feeling for a moment, then it passes.";
STATIC_DCL char *FDECL(mon_nam_too, (char *,struct monst *,struct monst *));
STATIC_DCL void FDECL(mrustm, (struct monst *, struct monst *, struct obj *));
STATIC_DCL int FDECL(hitmm, (struct monst *,struct monst *,struct attack *));
STATIC_DCL int FDECL(gazemm, (struct monst *,struct monst *,struct attack *));
STATIC_DCL int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *));
@@ -796,7 +795,7 @@ mdamagem(magr, mdef, mattk)
(grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
}
if (tmp)
mrustm(magr, mdef, otmp);
rustm(mdef, otmp);
}
} else if (pa == &mons[PM_PURPLE_WORM] &&
pd == &mons[PM_SHRIEKER]) {
@@ -884,7 +883,7 @@ mdamagem(magr, mdef, mattk)
pline("It burns %s!", mon_nam(mdef));
}
if (!rn2(30)) erode_armor(mdef, ERODE_CORRODE);
if (!rn2(6)) (void) erode_obj(MON_WEP(mdef), 3, TRUE, FALSE);
if (!rn2(6)) acid_damage(MON_WEP(mdef));
break;
case AD_RUST:
if (magr->mcan) break;
@@ -1287,24 +1286,24 @@ struct monst *mon;
}
}
STATIC_OVL void
mrustm(magr, mdef, obj)
register struct monst *magr, *mdef;
void
rustm(mdef, obj)
register struct monst *mdef;
register struct obj *obj;
{
int dmgtyp;
if (!magr || !mdef || !obj) return; /* just in case */
if (!mdef || !obj) return; /* just in case */
/* AD_ACID is handled in passivemm */
if (dmgtype(mdef->data, AD_CORR))
dmgtyp = 3;
dmgtyp = ERODE_CORRODE;
else if (dmgtype(mdef->data, AD_RUST))
dmgtyp = 1;
dmgtyp = ERODE_RUST;
else if (dmgtype(mdef->data, AD_FIRE))
dmgtyp = 0;
dmgtyp = ERODE_BURN;
else
return;
(void) erode_obj(obj, dmgtyp, FALSE, FALSE);
(void) rust_dmg(obj, 0, dmgtyp, TRUE, TRUE);
}
STATIC_OVL void
@@ -1362,7 +1361,7 @@ int mdead;
}
} else tmp = 0;
if (!rn2(30)) erode_armor(magr, ERODE_CORRODE);
if (!rn2(6)) (void)erode_obj(MON_WEP(magr), 3, TRUE, FALSE);
if (!rn2(6)) acid_damage(MON_WEP(magr));
goto assess_dmg;
case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
if (mhit && !mdef->mcan && otmp) {

View File

@@ -8,7 +8,6 @@
STATIC_VAR NEARDATA struct obj *otmp;
STATIC_DCL void FDECL(urustm, (struct monst *, struct obj *));
STATIC_DCL boolean FDECL(u_slip_free, (struct monst *,struct attack *));
STATIC_DCL int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *));
@@ -920,7 +919,7 @@ hitmu(mtmp, mattk)
if (cloneu())
You("divide as %s hits you!", mon_nam(mtmp));
}
urustm(mtmp, otmp);
rustm(&youmonst, otmp);
} else if (mattk->aatyp != AT_TUCH || dmg != 0 ||
mtmp != u.ustuck)
hitmsg(mtmp, mattk);
@@ -2079,26 +2078,6 @@ register int n;
}
}
STATIC_OVL void
urustm(mon, obj)
register struct monst *mon;
register struct obj *obj;
{
int dmgtyp;
if (!mon || !obj) return; /* just in case */
/* AD_ACID is handled in passiveum */
if (dmgtype(youmonst.data, AD_CORR))
dmgtyp = 3;
else if (dmgtype(youmonst.data, AD_RUST))
dmgtyp = 1;
else if (dmgtype(youmonst.data, AD_FIRE))
dmgtyp = 0;
else
return;
(void) erode_obj(obj, dmgtyp, FALSE, FALSE);
}
int
could_seduce(magr,mdef,mattk)
struct monst *magr, *mdef;
@@ -2442,7 +2421,7 @@ register struct attack *mattk;
}
} else tmp = 0;
if (!rn2(30)) erode_armor(mtmp, ERODE_CORRODE);
if (!rn2(6)) (void)erode_obj(MON_WEP(mtmp), 3, TRUE, FALSE);
if (!rn2(6)) acid_damage(MON_WEP(mtmp));
goto assess_dmg;
case AD_STON: /* cockatrice */
{

View File

@@ -1931,7 +1931,7 @@ dodip()
}
if (potion->otyp == POT_ACID) {
if (erode_obj(obj, 3, FALSE, TRUE))
if (rust_dmg(obj, 0, ERODE_CORRODE, TRUE, FALSE))
goto poof;
}

View File

@@ -144,21 +144,7 @@ cursed_book(bp)
case 5:
pline_The("book was coated with contact poison!");
if (uarmg) {
if (uarmg->oerodeproof || !is_corrodeable(uarmg)) {
Your("gloves seem unaffected.");
} else if (uarmg->oeroded2 < MAX_ERODE) {
if (uarmg->greased) {
grease_protect(uarmg, "gloves", &youmonst);
} else {
Your("gloves corrode%s!",
uarmg->oeroded2+1 == MAX_ERODE ?
" completely" : uarmg->oeroded2 ?
" further" : "");
uarmg->oeroded2++;
}
} else
Your("gloves %s completely corroded.",
Blind ? "feel" : "look");
rust_dmg(uarmg, "gloves", ERODE_CORRODE, TRUE, TRUE);
break;
}
/* temp disable in_use; death should not destroy the book */

View File

@@ -103,6 +103,8 @@ struct monst *victim;
/* Generic erode-item function. Returns TRUE if any change in state
* occurred, or if grease protected the item.
* "ostr", if non-null, is an alternate string to print instead of the
* object's name.
* "check_grease", if FALSE, means that grease is not checked for
* "print", if set, means to print a message even if no change occurs.
*/
@@ -165,8 +167,8 @@ boolean print;
if (victim == &youmonst)
Your("%s %s not affected.", ostr, vtense(ostr, "are"));
else if (vismon)
pline("%s's %s %s not affected.", Monnam(victim), ostr,
vtense(ostr, "are"));
pline("%s %s %s not affected.", s_suffix(Monnam(victim)),
ostr, vtense(ostr, "are"));
}
return FALSE;
} else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
@@ -175,8 +177,9 @@ boolean print;
pline("Somehow, your %s %s not affected.",
ostr, vtense(ostr, "are"));
else if (vismon)
pline("Somehow, %s's %s %s not affected.",
mon_nam(victim), ostr, vtense(ostr, "are"));
pline("Somehow, %s %s %s not affected.",
s_suffix(mon_nam(victim)), ostr,
vtense(ostr, "are"));
else if (visobj)
pline("Somehow, the %s %s not affected.", ostr,
vtense(ostr, "are"));
@@ -214,8 +217,8 @@ boolean print;
vtense(ostr, Blind ? "feel" : "look"),
msg[type]);
else if (vismon)
pline("%s's %s %s completely %s.",
Monnam(victim), ostr,
pline("%s %s %s completely %s.",
s_suffix(Monnam(victim)), ostr,
vtense(ostr, "look"), msg[type]);
else if (visobj)
pline("The %s %s completely %s.", ostr,
@@ -952,8 +955,8 @@ unsigned trflags;
if (water_damage(uarms, "shield", TRUE))
break;
if (u.twoweap || (uwep && bimanual(uwep)))
(void) erode_obj(u.twoweap ? uswapwep : uwep,
1, TRUE, FALSE);
(void) water_damage(u.twoweap ? uswapwep : uwep, 0,
TRUE);
glovecheck: (void) water_damage(uarmg, "gauntlets", TRUE);
/* Not "metal gauntlets" since it gets called
* even if it's leather for the message
@@ -962,7 +965,7 @@ glovecheck: (void) water_damage(uarmg, "gauntlets", TRUE);
case 2:
pline("%s your right %s!", A_gush_of_water_hits,
body_part(ARM));
(void) erode_obj(uwep, 1, TRUE, FALSE);
(void) water_damage(uwep, 0, TRUE);
goto glovecheck;
default:
pline("%s you!", A_gush_of_water_hits);
@@ -2098,7 +2101,7 @@ register struct monst *mtmp;
break;
target = MON_WEP(mtmp);
if (target && bimanual(target))
(void) erode_obj(target, 1, TRUE, FALSE);
(void) water_damage(target, 0, TRUE);
glovecheck: target = which_armor(mtmp, W_ARMG);
(void) water_damage(target, "gauntlets", TRUE);
break;
@@ -2106,7 +2109,7 @@ glovecheck: target = which_armor(mtmp, W_ARMG);
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), 1, TRUE, FALSE);
(void) water_damage(MON_WEP(mtmp), 0, TRUE);
goto glovecheck;
default:
if (in_sight)
@@ -3069,6 +3072,38 @@ xchar x, y;
return retval;
}
void
acid_damage(obj)
struct obj *obj;
{
/* Scrolls but not spellbooks can be erased by acid. */
struct monst *victim =
carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
boolean vismon = victim && (victim != &youmonst) && canseemon(victim);
if (obj->greased)
grease_protect(obj, NULL, victim);
else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
if (obj->otyp != SCR_BLANK_PAPER
#ifdef MAIL
&& obj->otyp != SCR_MAIL
#endif
) {
if (!Blind) {
if (victim == &youmonst)
pline("Your %s.", aobjnam(obj, "fade"));
else if (vismon)
pline("%s %s.", s_suffix(Monnam(victim)),
aobjnam(obj, "fade"));
}
}
obj->otyp = SCR_BLANK_PAPER;
obj->spe = 0;
obj->dknown = 0;
} else
rust_dmg(obj, NULL, ERODE_CORRODE, TRUE, TRUE);
}
/* returns:
* 0 if obj is unaffected
* 1 if obj is protected by grease

View File

@@ -2446,22 +2446,22 @@ struct attack *mattk; /* null means we find one internally */
case AD_FIRE:
if(!rn2(6) && !mon->mcan) {
(void) erode_obj(obj, 0, FALSE, FALSE);
(void) rust_dmg(obj, 0, ERODE_BURN, FALSE, FALSE);
}
break;
case AD_ACID:
if(!rn2(6)) {
(void) erode_obj(obj, 3, FALSE, FALSE);
(void) rust_dmg(obj, 0, ERODE_CORRODE, FALSE, FALSE);
}
break;
case AD_RUST:
if(!mon->mcan) {
(void) erode_obj(obj, 1, FALSE, FALSE);
(void) rust_dmg(obj, 0, ERODE_RUST, FALSE, FALSE);
}
break;
case AD_CORR:
if(!mon->mcan) {
(void) erode_obj(obj, 3, FALSE, FALSE);
(void) rust_dmg(obj, 0, ERODE_CORRODE, FALSE, FALSE);
}
break;
case AD_ENCH:

View File

@@ -597,131 +597,6 @@ untwoweapon()
return;
}
/* Maybe rust (or corrode, burn, rot) object.
* Returns TRUE if something happened. */
boolean
erode_obj(target, type, fade_scrolls, for_dip)
struct obj *target; /* object (e.g. weapon or armor) to erode */
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;
boolean ret = FALSE;
boolean already_affected = FALSE;
if (!target)
return FALSE;
victim = carried(target) ? &youmonst :
mcarried(target) ? target->ocarry : (struct monst *)0;
vismon = victim && (victim != &youmonst) && canseemon(victim);
visobj = !victim && cansee(bhitpos.x, bhitpos.y); /* assume thrown */
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 = is_primary ? target->oeroded : target->oeroded2;
if (target->greased && grprot) {
grease_protect(target,(char *)0,victim);
ret = TRUE;
} else if (target->oclass == SCROLL_CLASS && (type == 1 || type == 3)) {
if(fade_scrolls && target->otyp != SCR_BLANK_PAPER
#ifdef MAIL
&& target->otyp != SCR_MAIL
#endif
)
{
if (!Blind) {
if ((victim == &youmonst) || vismon || visobj)
pline("%s.", Yobjnam2(target, "fade"));
}
target->otyp = SCR_BLANK_PAPER;
target->spe = 0;
ret = TRUE;
}
} 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 && (type == 1) &&
/* cold and fire provide partial protection against rust */
((chill = arti_immune(target, AD_COLD)) != 0 ||
arti_immune(target, AD_FIRE)) &&
/* once rusted, the chance for further rusting goes up */
rn2(2 * (MAX_ERODE + 1 - erosion))) {
if (flags.verbose && target->oclass == WEAPON_CLASS) {
if (victim == &youmonst || vismon || visobj)
pline("%s some water.",
Yobjnam2(target, chill ? "freeze" : "boil"));
}
/* no damage to object */
} 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 || (vulnerable && !target->rknown))
pline("%s not %s.", Yobjnam2(target, "are"),
already_affected ? "harmed" : "affected");
if (vulnerable) target->rknown = 1;
}
} else if (erosion < MAX_ERODE) {
if (victim == &youmonst || vismon || visobj) {
pline("%s%s!", Yobjnam2(target, action[type]),
erosion+1 == MAX_ERODE ? " completely" :
erosion ? " further" : "");
target->rknown = 1; /* it's obviously not erode-proof */
}
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"), msg[type]);
else if (vismon || visobj)
pline("%s completely %s.",
Yobjnam2(target, "look"), msg[type]);
}
}
return ret;
}
int
chwepon(otmp, amount)
register struct obj *otmp;

View File

@@ -3395,7 +3395,7 @@ struct obj **ootmp; /* to return worn armor for caller to disintegrate */
break;
}
tmp = d(nd,6);
if (!rn2(6)) (void) erode_obj(MON_WEP(mon), 3, TRUE, FALSE);
if (!rn2(6)) acid_damage(MON_WEP(mon));
if (!rn2(6)) erode_armor(mon, ERODE_CORRODE);
break;
}
@@ -3522,9 +3522,9 @@ xchar sx, sy;
}
/* using two weapons at once makes both of them more vulnerable */
if (!rn2(u.twoweap ? 3 : 6))
(void) erode_obj(uwep, 3, TRUE, FALSE);
acid_damage(uwep);
if (u.twoweap && !rn2(3))
(void) erode_obj(uswapwep, 3, TRUE, FALSE);
acid_damage(uswapwep);
if (!rn2(6)) erode_armor(&youmonst, ERODE_CORRODE);
break;
}