Cover a couple of corner cases with rust_dmg().

This commit is contained in:
Sean Hunt
2015-03-02 12:49:57 -05:00
parent 9c4b0113aa
commit d588210a77
4 changed files with 96 additions and 54 deletions
+3
View File
@@ -858,6 +858,9 @@ fix "object_is_local" panic when saving bones after hero is killed by explosion
if lava burns up the player's water walking boots, the player falls in if lava burns up the player's water walking boots, the player falls in
the messages for lava burning items up are always printed the messages for lava burning items up are always printed
fix used-up magic trap trying to hit steed. 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
grease protects from all types of erosion
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
+1 -1
View File
@@ -2204,7 +2204,7 @@ E coord *FDECL(gettrack, (int,int));
E boolean FDECL(burnarmor,(struct monst *)); E boolean FDECL(burnarmor,(struct monst *));
E boolean FDECL(rust_dmg, (struct obj *,const char *,int,BOOLEAN_P)); E boolean FDECL(rust_dmg, (struct obj *,const char *,int,BOOLEAN_P));
E void FDECL(grease_protect, (struct obj *,const char *,struct monst *)); E boolean FDECL(grease_protect, (struct obj *,const char *,struct monst *));
E struct trap *FDECL(maketrap, (int,int,int)); E struct trap *FDECL(maketrap, (int,int,int));
E void FDECL(fall_through, (BOOLEAN_P)); E void FDECL(fall_through, (BOOLEAN_P));
E struct monst *FDECL(animate_statue, (struct obj *,XCHAR_P,XCHAR_P,int,int *)); E struct monst *FDECL(animate_statue, (struct obj *,XCHAR_P,XCHAR_P,int,int *));
+6
View File
@@ -319,6 +319,12 @@ struct obj {
#define CONTAINED_TOO 0x1 #define CONTAINED_TOO 0x1
#define BURIED_TOO 0x2 #define BURIED_TOO 0x2
/* object erosion types */
#define ERODE_BURN 0
#define ERODE_RUST 1
#define ERODE_ROT 2
#define ERODE_CORRODE 3
/* /*
* Notes for adding new oextra structures: * Notes for adding new oextra structures:
* *
+86 -53
View File
@@ -101,10 +101,9 @@ struct monst *victim;
#undef burn_dmg #undef burn_dmg
} }
/* Generic rust-armor function. Returns TRUE if a message was printed; /* Generic erode-item function. Returns TRUE if any change in state
* "print", if set, means to print a message (and thus to return TRUE) even * occurred. "print", if set, means to print a message even if no change
* if the item could not be rusted; otherwise a message is printed and TRUE is * occurs.
* returned only for rustable items.
*/ */
boolean boolean
rust_dmg(otmp, ostr, type, print) rust_dmg(otmp, ostr, type, print)
@@ -119,69 +118,95 @@ boolean print;
boolean grprot = FALSE; boolean grprot = FALSE;
boolean is_primary = TRUE; boolean is_primary = TRUE;
int erosion; int erosion;
struct monst *victim = struct monst *victim;
carried(otmp) ? &youmonst : mcarried(otmp) ? otmp->ocarry : NULL; boolean vismon;
boolean vismon = (victim != &youmonst) && canseemon(victim); boolean visobj;
if (!otmp) return(FALSE); if (!otmp) return(FALSE);
victim = carried(otmp) ? &youmonst : mcarried(otmp) ?
otmp->ocarry : NULL;
vismon = victim && (victim != &youmonst) && canseemon(victim);
/* Is bhitpos correct here? Ugh. */
visobj = !victim && cansee(bhitpos.x, bhitpos.y);
switch(type) { switch(type) {
case 0: vulnerable = is_flammable(otmp); case ERODE_BURN:
break; vulnerable = is_flammable(otmp);
case 1: vulnerable = is_rustprone(otmp); break;
grprot = TRUE; case ERODE_RUST:
break; vulnerable = is_rustprone(otmp);
case 2: vulnerable = is_rottable(otmp); grprot = TRUE;
is_primary = FALSE; break;
break; case ERODE_ROT:
case 3: vulnerable = is_corrodeable(otmp); vulnerable = is_rottable(otmp);
grprot = TRUE; is_primary = FALSE;
is_primary = FALSE; break;
break; case ERODE_CORRODE:
vulnerable = is_corrodeable(otmp);
grprot = TRUE;
is_primary = FALSE;
break;
default:
impossible("Invalid erosion type in rust_dmg");
return FALSE;
} }
erosion = is_primary ? otmp->oeroded : otmp->oeroded2; erosion = is_primary ? otmp->oeroded : otmp->oeroded2;
if (!print && (!vulnerable || otmp->oerodeproof || erosion == MAX_ERODE)) if (!ostr)
return FALSE; ostr = cxname(otmp);
if (!vulnerable) { if (grprot && otmp->greased) {
if (flags.verbose) { return grease_protect(otmp, ostr, victim);
} else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) {
if (print && flags.verbose) {
if (victim == &youmonst) if (victim == &youmonst)
Your("%s %s not affected.", ostr, vtense(ostr, "are")); Your("%s %s not affected.", ostr, vtense(ostr, "are"));
else if (vismon) else if (vismon)
pline("%s's %s %s not affected.", Monnam(victim), ostr, pline("%s's %s %s not affected.", Monnam(victim), ostr,
vtense(ostr, "are")); vtense(ostr, "are"));
} }
} else if (erosion < MAX_ERODE) { return FALSE;
if (grprot && otmp->greased) { } else if (otmp->oerodeproof || otmp->blessed && !rnl(4)) {
grease_protect(otmp,ostr,victim); if (flags.verbose && (print || otmp->oerodeproof)) {
} else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
if (flags.verbose) {
if (victim == &youmonst)
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"));
}
} else {
if (victim == &youmonst) if (victim == &youmonst)
Your("%s %s%s!", ostr, pline("Somehow, your %s %s not affected.",
vtense(ostr, action[type]), ostr, vtense(ostr, "are"));
erosion+1 == MAX_ERODE ? " completely" :
erosion ? " further" : "");
else if (vismon) else if (vismon)
pline("%s's %s %s%s!", Monnam(victim), ostr, pline("Somehow, %s's %s %s not affected.",
vtense(ostr, action[type]), mon_nam(victim), ostr, vtense(ostr, "are"));
erosion+1 == MAX_ERODE ? " completely" : else if (visobj)
erosion ? " further" : ""); pline("Somehow, the %s %s not affected." ostr,
if (is_primary) vtense(ostr, "are"));
otmp->oeroded++; }
else /* We assume here that if the object is protected because it
otmp->oeroded2++; * is blessed, it still shows some minor signs of wear, and
update_inventory(); * the hero can distinguish this from an object that is
} * actually proof against damage. */
if (otmp->oerodeproof)
otmp->rknown = TRUE;
return FALSE;
} else if (erosion < MAX_ERODE) {
const char *adverb = (erosion + 1 == MAX_ERODE) ?
" complete" : erosion ? " further" : "";
if (victim == &youmonst)
Your("%s %s%s!", ostr, vtense(ostr, action[type]), adverb);
else if (vismon)
pline("%s's %s %s%s!", Monnam(victim), ostr,
vtense(ostr, action[type]), adverb);
else if (visobj)
pline("The %s %s%s!", ostr, vtense(ostr, action[type]), adverb);
if (is_primary)
otmp->oeroded++;
else
otmp->oeroded2++;
update_inventory();
return TRUE;
} else { } else {
if (flags.verbose) { if (flags.verbose && print) {
if (victim == &youmonst) if (victim == &youmonst)
Your("%s %s completely %s.", ostr, Your("%s %s completely %s.", ostr,
vtense(ostr, Blind ? "feel" : "look"), vtense(ostr, Blind ? "feel" : "look"),
@@ -190,12 +215,18 @@ boolean print;
pline("%s's %s %s completely %s.", pline("%s's %s %s completely %s.",
Monnam(victim), ostr, Monnam(victim), ostr,
vtense(ostr, "look"), msg[type]); vtense(ostr, "look"), msg[type]);
else if (visobj)
pline("The %s %s completely %s.", ostr,
vtense(ostr, "look"), msg[type]);
} }
return FALSE;
} }
return(TRUE);
} }
void /* Protect an item from erosion with grease. Returns TRUE if the grease
* wears off.
*/
boolean
grease_protect(otmp,ostr,victim) grease_protect(otmp,ostr,victim)
register struct obj *otmp; register struct obj *otmp;
register const char *ostr; register const char *ostr;
@@ -219,7 +250,9 @@ struct monst *victim;
pline_The("grease dissolves."); pline_The("grease dissolves.");
update_inventory(); update_inventory();
} }
return TRUE;
} }
return FALSE;
} }
struct trap * struct trap *