From: PatR Date: Thu, 10 Mar 2016 00:37:43 +0000 (-0800) Subject: fix #H4057 - rusting amulets X-Git-Tag: NetHack-3.6.1_RC01~876 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ef863f3c9f6988d9efbda755dad26bf8b3f24f29;p=nethack fix #H4057 - rusting amulets There have been two or three reports on getting feedback about amulets rusting. Object formatting doesn't display erosion for them, so being told about damage then not seeing that damage feels like a bug. Even if damage was displayed, it has no effect on them so would still feel somewhat strange. It does display erosion for wands and rings, which is strange too. This limits erosion damage--and its feedback--to items which are actually impacted by erosion: armor, weapons and weapon-tools; also heavy iron balls and iron chains since they've traditionally shown rust even though it has little effect. A side-effect of this change is that flammable items (other than armor and weapons) which don't burn up immediately will no longer become burnt, then very burnt, thorougly burnt, and finally be destroyed. Since the player couldn't see or possibly repair the erosion state, it seemed incomplete. It could be reinstated by making other flammable items be subject to erosion and displayed as such by xname() & co. Wishing now avoids applying erosion and erosion-proofing to items that aren't affected by it, regardless of material. It also now allows wishing for "rusty rustproof " which used to suppress "rusty" in that combination and triggered a couple of old bug reports. Heavy iron balls and iron chains can have rust repaired and can be made rustproof by wielding, then reading enchant weapon while confused, as if they were weapons. --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 54445094a..8dd08e546 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -182,6 +182,8 @@ when looting multiple containers, add 'n' for "loot next container", change change looting to choose ":iobrs nq" action from a menu for menustyle:Partial wand/spell/breath zaps that reached the edge of the level on the Plane of Air and "vanished into the aether" left temporary display effects on screen +stop amulets and other items which aren't affected by erosion damage from + being subjected to erosion damage Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index a0b47449a..a85f5ce4e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1457397476 2016/03/08 00:37:56 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.551 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1457570257 2016/03/10 00:37:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.552 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1591,6 +1591,7 @@ E char *FDECL(xname, (struct obj *)); E char *FDECL(mshot_xname, (struct obj *)); E boolean FDECL(the_unique_obj, (struct obj *)); E boolean FDECL(the_unique_pm, (struct permonst *)); +E boolean FDECL(erosion_matters, (struct obj *)); E char *FDECL(doname, (struct obj *)); E char *FDECL(doname_with_price, (struct obj *)); E boolean FDECL(not_fully_identified, (struct obj *)); diff --git a/src/objnam.c b/src/objnam.c index e90a2d53f..33c781744 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1455672990 2016/02/17 01:36:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.165 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1457570258 2016/03/10 00:37:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.166 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -730,6 +730,31 @@ char *prefix; : ""); } +/* used to prevent rust on items where rust makes no difference */ +boolean +erosion_matters(obj) +struct obj *obj; +{ + switch (obj->oclass) { + case TOOL_CLASS: + /* it's possible for a rusty weptool to be polymorphed into some + non-weptool iron tool, in which case the rust implicitly goes + away, but it's also possible for it to be polymorphed into a + non-iron tool, in which case rust also implicitly goes away, + so there's no particular reason to try to handle the first + instance differently [this comment belongs in poly_obj()...] */ + return is_weptool(obj) ? TRUE : FALSE; + case WEAPON_CLASS: + case ARMOR_CLASS: + case BALL_CLASS: + case CHAIN_CLASS: + return TRUE; + default: + break; + } + return FALSE; +} + static char * doname_base(obj, with_price) register struct obj *obj; @@ -853,31 +878,27 @@ boolean with_price; plur(itemcount)); } - switch (obj->oclass) { + switch (is_weptool(obj) ? WEAPON_CLASS : obj->oclass) { case AMULET_CLASS: if (obj->owornmask & W_AMUL) Strcat(bp, " (being worn)"); break; + case ARMOR_CLASS: + if (obj->owornmask & W_ARMOR) + Strcat(bp, (obj == uskin) ? " (embedded in your skin)" + : " (being worn)"); + /*FALLTHRU*/ case WEAPON_CLASS: if (ispoisoned) Strcat(prefix, "poisoned "); - plus: add_erosion_words(obj, prefix); if (known) { Strcat(prefix, sitoa(obj->spe)); Strcat(prefix, " "); } break; - case ARMOR_CLASS: - if (obj->owornmask & W_ARMOR) - Strcat(bp, (obj == uskin) ? " (embedded in your skin)" - : " (being worn)"); - goto plus; case TOOL_CLASS: - /* weptools already get this done when we go to the +n code */ - if (!is_weptool(obj)) - add_erosion_words(obj, prefix); - if (obj->owornmask & (W_TOOL /* blindfold */ | W_SADDLE)) { + if (obj->owornmask & (W_TOOL | W_SADDLE)) { /* blindfold */ Strcat(bp, " (being worn)"); break; } @@ -885,8 +906,6 @@ boolean with_price; Strcat(bp, " (in use)"); break; } - if (is_weptool(obj)) - goto plus; if (obj->otyp == CANDELABRUM_OF_INVOCATION) { if (!obj->spe) Strcpy(tmpbuf, "no"); @@ -908,7 +927,6 @@ boolean with_price; goto charges; break; case WAND_CLASS: - add_erosion_words(obj, prefix); charges: if (known) Sprintf(eos(bp), " (%d:%d)", (int) obj->recharged, obj->spe); @@ -918,7 +936,6 @@ boolean with_price; Strcat(bp, " (lit)"); break; case RING_CLASS: - add_erosion_words(obj, prefix); ring: if (obj->owornmask & W_RINGR) Strcat(bp, " (on right "); @@ -3443,15 +3460,19 @@ typfnd: curse(otmp); } - /* set eroded */ - if (is_damageable(otmp) || otmp->otyp == CRYSKNIFE) { + /* set eroded and erodeproof */ + if (erosion_matters(otmp)) { if (eroded && (is_flammable(otmp) || is_rustprone(otmp))) otmp->oeroded = eroded; if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp))) otmp->oeroded2 = eroded2; - - /* set erodeproof */ - if (erodeproof && !eroded && !eroded2) + /* + * 3.6.1: earlier versions included `&& !eroded && !eroded2' here, + * but damageproof combined with damaged is feasible (eroded + * armor modified by confused reading of cursed destroy armor) + * so don't prevent player from wishing for such a combination. + */ + if (erodeproof && (is_damageable(otmp) || otmp->otyp == CRYSKNIFE)) otmp->oerodeproof = (Luck >= 0 || wizard); } diff --git a/src/read.c b/src/read.c index 815dfe731..2d5b4f2a7 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 read.c $NHDT-Date: 1450577673 2015/12/20 02:14:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.131 $ */ +/* NetHack 3.6 read.c $NHDT-Date: 1457570260 2016/03/10 00:37:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.135 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -60,6 +60,7 @@ struct obj *otmp; char *buf; { int erosion = greatest_erosion(otmp); + if (erosion) wipeout_text(buf, (int) (strlen(buf) * erosion / (2 * MAX_ERODE)), otmp->o_id ^ (unsigned) ubirthday); @@ -1312,8 +1313,11 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ */ break; case SCR_ENCHANT_WEAPON: + /* [What about twoweapon mode? Proofing/repairing/enchanting both + would be too powerful, but shouldn't we choose randomly between + primary and secondary instead of always acting on primary?] */ if (confused && uwep - && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) { + && erosion_matters(uwep) && uwep->oclass != ARMOR_CLASS) { old_erodeproof = (uwep->oerodeproof != 0); new_erodeproof = !scursed; uwep->oerodeproof = 0; /* for messages */ diff --git a/src/trap.c b/src/trap.c index 716962de1..aa8a1724b 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 trap.c $NHDT-Date: 1454528963 2016/02/03 19:49:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.261 $ */ +/* NetHack 3.6 trap.c $NHDT-Date: 1457570259 2016/03/10 00:37:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.262 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -197,6 +197,8 @@ int ef_flags; if (check_grease && otmp->greased) { grease_protect(otmp, ostr, victim); return ER_GREASED; + } else if (!erosion_matters(otmp)) { + return ER_NOTHING; } else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) { if (flags.verbose && print && (uvictim || vismon)) pline("%s %s %s not affected by %s.", diff --git a/src/zap.c b/src/zap.c index dd20de275..854c62fad 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 zap.c $NHDT-Date: 1457482920 2016/03/09 00:22:00 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.248 $ */ +/* NetHack 3.6 zap.c $NHDT-Date: 1457570259 2016/03/10 00:37:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.249 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1423,14 +1423,15 @@ int id; otmp->cursed = obj->cursed; otmp->blessed = obj->blessed; - otmp->oeroded = obj->oeroded; - otmp->oeroded2 = obj->oeroded2; - if (!is_flammable(otmp) && !is_rustprone(otmp)) - otmp->oeroded = 0; - if (!is_corrodeable(otmp) && !is_rottable(otmp)) - otmp->oeroded2 = 0; - if (is_damageable(otmp)) - otmp->oerodeproof = obj->oerodeproof; + + if (erosion_matters(otmp)) { + if (is_flammable(otmp) || is_rustprone(otmp)) + otmp->oeroded = obj->oeroded; + if (is_corrodeable(otmp) || is_rottable(otmp)) + otmp->oeroded2 = obj->oeroded2; + if (is_damageable(otmp)) + otmp->oerodeproof = obj->oerodeproof; + } /* Keep chest/box traps and poisoned ammo if we may */ if (obj->otrapped && Is_box(otmp))