From: Sean Hunt Date: Mon, 2 Mar 2015 17:36:33 +0000 (-0500) Subject: Cover a couple of corner cases with `rust_dmg()`. X-Git-Tag: NetHack-3.6.0_RC01~641 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d588210a776c6bd7d28cfe6ce8ffb0cf87aeb7fb;p=nethack Cover a couple of corner cases with `rust_dmg()`. --- diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 3cc0e61dd..4fd81cff5 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -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 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 +grease protects from all types of erosion Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 120f7d506..87427dd3a 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2204,7 +2204,7 @@ E coord *FDECL(gettrack, (int,int)); E boolean FDECL(burnarmor,(struct monst *)); 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 void FDECL(fall_through, (BOOLEAN_P)); E struct monst *FDECL(animate_statue, (struct obj *,XCHAR_P,XCHAR_P,int,int *)); diff --git a/include/obj.h b/include/obj.h index dc522b338..12b1fce35 100644 --- a/include/obj.h +++ b/include/obj.h @@ -319,6 +319,12 @@ struct obj { #define CONTAINED_TOO 0x1 #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: * diff --git a/src/trap.c b/src/trap.c index d819724a5..1220105f5 100644 --- a/src/trap.c +++ b/src/trap.c @@ -101,10 +101,9 @@ struct monst *victim; #undef burn_dmg } -/* Generic rust-armor function. Returns TRUE if a message was printed; - * "print", if set, means to print a message (and thus to return TRUE) even - * if the item could not be rusted; otherwise a message is printed and TRUE is - * returned only for rustable items. +/* Generic erode-item function. Returns TRUE if any change in state + * occurred. "print", if set, means to print a message even if no change + * occurs. */ boolean rust_dmg(otmp, ostr, type, print) @@ -119,69 +118,95 @@ boolean print; boolean grprot = FALSE; boolean is_primary = TRUE; int erosion; - struct monst *victim = - carried(otmp) ? &youmonst : mcarried(otmp) ? otmp->ocarry : NULL; - boolean vismon = (victim != &youmonst) && canseemon(victim); + struct monst *victim; + boolean vismon; + boolean visobj; 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) { - case 0: vulnerable = is_flammable(otmp); - break; - case 1: vulnerable = is_rustprone(otmp); - grprot = TRUE; - break; - case 2: vulnerable = is_rottable(otmp); - is_primary = FALSE; - break; - case 3: vulnerable = is_corrodeable(otmp); - grprot = TRUE; - is_primary = FALSE; - break; + case ERODE_BURN: + vulnerable = is_flammable(otmp); + break; + case ERODE_RUST: + vulnerable = is_rustprone(otmp); + grprot = TRUE; + break; + case ERODE_ROT: + vulnerable = is_rottable(otmp); + is_primary = FALSE; + 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; - if (!print && (!vulnerable || otmp->oerodeproof || erosion == MAX_ERODE)) - return FALSE; + if (!ostr) + ostr = cxname(otmp); - if (!vulnerable) { - if (flags.verbose) { + if (grprot && otmp->greased) { + return grease_protect(otmp, ostr, victim); + } else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) { + if (print && flags.verbose) { 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")); } - } else if (erosion < MAX_ERODE) { - if (grprot && otmp->greased) { - grease_protect(otmp,ostr,victim); - } 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 { + return FALSE; + } else if (otmp->oerodeproof || otmp->blessed && !rnl(4)) { + if (flags.verbose && (print || otmp->oerodeproof)) { if (victim == &youmonst) - Your("%s %s%s!", ostr, - vtense(ostr, action[type]), - erosion+1 == MAX_ERODE ? " completely" : - erosion ? " further" : ""); + pline("Somehow, your %s %s not affected.", + ostr, vtense(ostr, "are")); else if (vismon) - pline("%s's %s %s%s!", Monnam(victim), ostr, - vtense(ostr, action[type]), - erosion+1 == MAX_ERODE ? " completely" : - erosion ? " further" : ""); - if (is_primary) - otmp->oeroded++; - else - otmp->oeroded2++; - update_inventory(); - } + pline("Somehow, %s's %s %s not affected.", + mon_nam(victim), ostr, vtense(ostr, "are")); + else if (visobj) + pline("Somehow, the %s %s not affected." ostr, + vtense(ostr, "are")); + } + /* We assume here that if the object is protected because it + * is blessed, it still shows some minor signs of wear, and + * 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 { - if (flags.verbose) { + if (flags.verbose && print) { if (victim == &youmonst) Your("%s %s completely %s.", ostr, vtense(ostr, Blind ? "feel" : "look"), @@ -190,12 +215,18 @@ boolean print; pline("%s's %s %s completely %s.", Monnam(victim), ostr, 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) register struct obj *otmp; register const char *ostr; @@ -219,7 +250,9 @@ struct monst *victim; pline_The("grease dissolves."); update_inventory(); } + return TRUE; } + return FALSE; } struct trap *