diff -Naur nethack-3.4.3/README.patches nethack-all/README.patches --- nethack-3.4.3/README.patches 1970-01-01 10:00:00.000000000 +1000 +++ nethack-all/README.patches 2004-12-14 15:56:21.000000000 +1100 @@ -0,0 +1,7 @@ +The following patches have been applied: + +* Combined alchemy patch (colour-based and gem-based) +* Cancellation patch +* Mining lamps patch +* Magic lenses patch +* Poison patch diff -Naur nethack-3.4.3/include/config.h nethack-all/include/config.h --- nethack-3.4.3/include/config.h 2004-03-16 17:31:08.000000000 +1100 +++ nethack-all/include/config.h 2004-11-13 13:51:17.000000000 +1100 @@ -340,6 +340,15 @@ #define EXP_ON_BOTL /* Show experience on bottom line */ /* #define SCORE_ON_BOTL */ /* added by Gary Erickson (erickson@ucivax) */ +/* MRKR: All my patches */ + +#define MAGIC_LENSES /* MRKR: A variety of magical lenses */ +#define MINING_LAMPS /* MRKR: Mining helmets have lamps */ +#define POISION_VARIETY /* MRKR: Can coat arrows in various potions */ +#define ALCHEMY /* MRKR: Extended alchemy (includes Nephi's patch) */ +#define CANCEL_DSM /* MRKR: DSM reverts when cancelled. Monsters use */ + /* wands of cancellation. */ + /* * Section 5: EXPERIMENTAL STUFF * diff -Naur nethack-3.4.3/include/mkroom.h nethack-all/include/mkroom.h --- nethack-3.4.3/include/mkroom.h 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/include/mkroom.h 2004-11-13 13:45:54.000000000 +1100 @@ -30,7 +30,11 @@ struct itp { int iprob; /* probability of an item type */ int itype; /* item type: if >=0 a class, if < 0 a specific item */ +#ifndef MAGIC_LENSES } iprobs[5]; +#else + } iprobs[11]; +#endif const char * const *shknms; /* list of shopkeeper names for this type */ }; diff -Naur nethack-3.4.3/include/obj.h nethack-all/include/obj.h --- nethack-3.4.3/include/obj.h 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/include/obj.h 2004-11-13 13:57:22.000000000 +1100 @@ -76,7 +76,18 @@ Bitfield(otrapped,1); /* container is trapped */ /* or accidental tripped rolling boulder trap */ #define opoisoned otrapped /* object (weapon) is coated with poison */ +#ifndef POISION_VARIETY +#else +#define opoistype recharged +#define OPOISON_SICKNESS 0 +#define OPOISON_SLEEPING 1 +#define OPOISON_CONFUSION 2 +#define OPOISON_PARALYSIS 3 +#define OPOISON_KNOWN 4 +#define poison_type(otmp) ((otmp)->opoistype & 3) +#define poison_known(otmp) ((otmp)->opoistype & OPOISON_KNOWN) +#endif Bitfield(recharged,3); /* number of times it's been recharged */ Bitfield(lamplit,1); /* a light-source -- can be lit */ #ifdef INVISIBLE_OBJECTS @@ -267,19 +278,39 @@ /* MAGIC_LAMP intentionally excluded below */ /* age field of this is relative age rather than absolute */ +#ifdef MINING_LAMPS +#define age_is_relative(otmp) ((otmp)->otyp == BRASS_LANTERN\ + || (otmp)->otyp == DWARVISH_IRON_HELM\ + || (otmp)->otyp == OIL_LAMP\ + || (otmp)->otyp == CANDELABRUM_OF_INVOCATION\ + || (otmp)->otyp == TALLOW_CANDLE\ + || (otmp)->otyp == WAX_CANDLE\ + || (otmp)->otyp == POT_OIL) +#else #define age_is_relative(otmp) ((otmp)->otyp == BRASS_LANTERN\ || (otmp)->otyp == OIL_LAMP\ || (otmp)->otyp == CANDELABRUM_OF_INVOCATION\ || (otmp)->otyp == TALLOW_CANDLE\ || (otmp)->otyp == WAX_CANDLE\ || (otmp)->otyp == POT_OIL) +#endif /* object can be ignited */ +#ifdef MINING_LAMPS #define ignitable(otmp) ((otmp)->otyp == BRASS_LANTERN\ + || (otmp)->otyp == DWARVISH_IRON_HELM\ || (otmp)->otyp == OIL_LAMP\ || (otmp)->otyp == CANDELABRUM_OF_INVOCATION\ || (otmp)->otyp == TALLOW_CANDLE\ || (otmp)->otyp == WAX_CANDLE\ || (otmp)->otyp == POT_OIL) +#else +#define ignitable(otmp) ((otmp)->otyp == BRASS_LANTERN\ + || (otmp)->otyp == OIL_LAMP\ + || (otmp)->otyp == CANDELABRUM_OF_INVOCATION\ + || (otmp)->otyp == TALLOW_CANDLE\ + || (otmp)->otyp == WAX_CANDLE\ + || (otmp)->otyp == POT_OIL) +#endif /* special stones */ #define is_graystone(obj) ((obj)->otyp == LUCKSTONE || \ @@ -295,6 +326,16 @@ #define is_flimsy(otmp) (objects[(otmp)->otyp].oc_material <= LEATHER) #endif +#ifdef MAGIC_LENSES +#define is_lenses(otmp) ((otmp)->otyp == LENSES || \ + (otmp)->otyp == LENSES_OF_SEARCHING || \ + (otmp)->otyp == LENSES_OF_SEE_INVISIBLE || \ + (otmp)->otyp == LENSES_OF_ACCURACY || \ + (otmp)->otyp == LENSES_OF_WARNING || \ + (otmp)->otyp == LENSES_OF_INFRAVISION || \ + (otmp)->otyp == LENSES_OF_DARKNESS) + +#endif /* helpers, simple enough to be macros */ #define is_plural(o) ((o)->quan > 1 || \ (o)->oartifact == ART_EYES_OF_THE_OVERWORLD) diff -Naur nethack-3.4.3/include/youprop.h nethack-all/include/youprop.h --- nethack-3.4.3/include/youprop.h 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/include/youprop.h 2004-11-13 13:45:54.000000000 +1100 @@ -94,7 +94,11 @@ #define Confusion HConfusion #define Blinded u.uprops[BLINDED].intrinsic +#ifndef MAGIC_LENSES #define Blindfolded (ublindf && ublindf->otyp != LENSES) +#else +#define Blindfolded (ublindf && !is_lenses(ublindf)) +#endif /* ...means blind because of a cover */ #define Blind ((Blinded || Blindfolded || !haseyes(youmonst.data)) && \ !(ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD)) diff -Naur nethack-3.4.3/src/apply.c nethack-all/src/apply.c --- nethack-3.4.3/src/apply.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/apply.c 2004-11-13 13:46:47.000000000 +1100 @@ -115,7 +115,11 @@ (old ? "has more" : "now has")); make_blinded(Blinded + (long)u.ucreamed - old, TRUE); } else { +#ifndef MAGIC_LENSES const char *what = (ublindf->otyp == LENSES) ? +#else + const char *what = is_lenses(ublindf) ? +#endif "lenses" : "blindfold"; if (ublindf->cursed) { You("push your %s %s.", what, @@ -1070,7 +1074,12 @@ } if(obj->lamplit) { if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP || +#ifndef MINING_LAMPS obj->otyp == BRASS_LANTERN) +#else + obj->otyp == BRASS_LANTERN || + obj->otyp == DWARVISH_IRON_HELM) +#endif pline("%s lamp is now off.", Shk_Your(buf, obj)); else You("snuff out %s.", yname(obj)); @@ -1080,7 +1089,12 @@ /* magic lamps with an spe == 0 (wished for) cannot be lit */ if ((!Is_candle(obj) && obj->age == 0) || (obj->otyp == MAGIC_LAMP && obj->spe == 0)) { +#ifndef MINING_LAMPS if (obj->otyp == BRASS_LANTERN) +#else + if (obj->otyp == BRASS_LANTERN + || obj->otyp == DWARVISH_IRON_HELM) +#endif Your("lamp has run out of power."); else pline("This %s has no oil.", xname(obj)); return; @@ -1090,7 +1104,12 @@ Tobjnam(obj, "flicker"), otense(obj, "die")); } else { if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP || +#ifndef MINING_LAMPS obj->otyp == BRASS_LANTERN) { +#else + obj->otyp == BRASS_LANTERN + || obj->otyp == DWARVISH_IRON_HELM) { +#endif check_unpaid(obj); pline("%s lamp is now on.", Shk_Your(buf, obj)); } else { /* candle(s) */ @@ -2785,13 +2804,22 @@ if(check_capacity((char *)0)) return (0); +#ifndef MINING_LAMPS if (carrying(POT_OIL) || uhave_graystone()) +#else + if (carrying(POT_OIL) || uhave_graystone()) +#endif Strcpy(class_list, tools_too); else Strcpy(class_list, tools); if (carrying(CREAM_PIE) || carrying(EUCALYPTUS_LEAF)) add_class(class_list, FOOD_CLASS); +#ifdef MINING_LAMPS + if (carrying(DWARVISH_IRON_HELM)) + add_class(class_list, ARMOR_CLASS); + +#endif obj = getobj(class_list, "use or apply"); if(!obj) return 0; @@ -2805,6 +2833,14 @@ switch(obj->otyp){ case BLINDFOLD: case LENSES: +#ifdef MAGIC_LENSES + case LENSES_OF_SEARCHING: + case LENSES_OF_SEE_INVISIBLE: + case LENSES_OF_WARNING: + case LENSES_OF_ACCURACY: + case LENSES_OF_INFRAVISION: + case LENSES_OF_DARKNESS: +#endif if (obj == ublindf) { if (!cursed(obj)) Blindf_off(obj); } else if (!ublindf) @@ -2903,6 +2939,14 @@ case TALLOW_CANDLE: use_candle(&obj); break; +#ifdef MINING_LAMPS + +/* MRKR: dwarvish helms are mining helmets. + * They can be used as brass lanterns. + * From an idea posted to RGRN by "Dr Darth" + */ + case DWARVISH_IRON_HELM: +#endif case OIL_LAMP: case MAGIC_LAMP: case BRASS_LANTERN: diff -Naur nethack-3.4.3/src/detect.c nethack-all/src/detect.c --- nethack-3.4.3/src/detect.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/detect.c 2004-11-13 13:45:54.000000000 +1100 @@ -1179,8 +1179,17 @@ int fund = (uwep && uwep->oartifact && spec_ability(uwep, SPFX_SEARCH)) ? uwep->spe : 0; +#ifndef MAGIC_LENSES if (ublindf && ublindf->otyp == LENSES && !Blind) +#else +#if 0 + /* MRKR: Lenses now have other uses */ + if (ublindf && is_lenses(ublindf) && !Blind) +#endif fund += 2; /* JDS: lenses help searching */ +#ifdef MAGIC_LENSES +#endif +#endif if (fund > 5) fund = 5; for(x = u.ux-1; x < u.ux+2; x++) for(y = u.uy-1; y < u.uy+2; y++) { diff -Naur nethack-3.4.3/src/display.c nethack-all/src/display.c --- nethack-3.4.3/src/display.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/display.c 2004-11-13 13:45:54.000000000 +1100 @@ -665,7 +665,16 @@ * Perhaps ALL areas should revert to their "unlit" look when * out of sight. */ +#ifndef MAGIC_LENSES lev->waslit = (lev->lit!=0); /* remember lit condition */ +#else + + /* remember lit condition */ + /* MRKR: Lenses of darkess make all areas appear dark */ + + lev->waslit = (lev->lit != 0) && + (!ublindf || ublindf->otyp != LENSES_OF_DARKNESS); +#endif if (reg != NULL && ACCESSIBLE(lev->typ)) { show_region(reg,x,y); diff -Naur nethack-3.4.3/src/do.c nethack-all/src/do.c --- nethack-3.4.3/src/do.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/do.c 2004-11-13 13:45:54.000000000 +1100 @@ -272,10 +272,12 @@ You("drop %s down the drain.", doname(obj)); obj->in_use = TRUE; /* block free identification via interrupt */ switch(obj->otyp) { /* effects that can be noticed without eyes */ +#ifndef MAGIC_LENSES case RIN_SEARCHING: You("thought your %s got lost in the sink, but there it is!", xname(obj)); goto giveback; +#endif case RIN_SLOW_DIGESTION: pline_The("ring is regurgitated!"); giveback: @@ -309,10 +311,12 @@ pline_The("water flow seems %ser now.", (obj->spe<0) ? "less" : "great"); break; +#ifndef MAGIC_LENSES case RIN_INCREASE_ACCURACY: /* KMH */ pline_The("water flow %s the drain.", (obj->spe<0) ? "misses" : "hits"); break; +#endif case RIN_INCREASE_DAMAGE: pline_The("water's force seems %ser now.", (obj->spe<0) ? "small" : "great"); @@ -355,9 +359,11 @@ case RIN_FREE_ACTION: You("see the ring slide right down the drain!"); break; +#ifndef MAGIC_LENSES case RIN_SEE_INVISIBLE: You("see some air in the sink."); break; +#endif case RIN_STEALTH: pline_The("sink seems to blend into the floor for a moment."); break; @@ -374,9 +380,11 @@ pline_The("sink glows %s for a moment.", hcolor((obj->spe<0) ? NH_BLACK : NH_SILVER)); break; +#ifndef MAGIC_LENSES case RIN_WARNING: pline_The("sink glows %s for a moment.", hcolor(NH_WHITE)); break; +#endif case RIN_TELEPORTATION: pline_The("sink momentarily vanishes."); break; diff -Naur nethack-3.4.3/src/do_wear.c nethack-all/src/do_wear.c --- nethack-3.4.3/src/do_wear.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/do_wear.c 2004-11-13 13:45:54.000000000 +1100 @@ -695,7 +695,9 @@ switch(obj->otyp){ case RIN_TELEPORTATION: case RIN_REGENERATION: +#ifndef MAGIC_LENSES case RIN_SEARCHING: +#endif case RIN_STEALTH: case RIN_HUNGER: case RIN_AGGRAVATE_MONSTER: @@ -712,6 +714,7 @@ case RIN_SUSTAIN_ABILITY: case MEAT_RING: break; +#ifndef MAGIC_LENSES case RIN_WARNING: see_monsters(); break; @@ -730,6 +733,7 @@ makeknown(RIN_SEE_INVISIBLE); } break; +#endif case RIN_INVISIBILITY: if (!oldprop && !HInvis && !BInvis && !Blind) { makeknown(RIN_INVISIBILITY); @@ -764,9 +768,11 @@ update_inventory(); } break; +#ifndef MAGIC_LENSES case RIN_INCREASE_ACCURACY: /* KMH */ u.uhitinc += obj->spe; break; +#endif case RIN_INCREASE_DAMAGE: u.udaminc += obj->spe; break; @@ -801,7 +807,9 @@ switch(obj->otyp) { case RIN_TELEPORTATION: case RIN_REGENERATION: +#ifndef MAGIC_LENSES case RIN_SEARCHING: +#endif case RIN_STEALTH: case RIN_HUNGER: case RIN_AGGRAVATE_MONSTER: @@ -818,6 +826,7 @@ case RIN_SUSTAIN_ABILITY: case MEAT_RING: break; +#ifndef MAGIC_LENSES case RIN_WARNING: see_monsters(); break; @@ -837,6 +846,7 @@ makeknown(RIN_SEE_INVISIBLE); } break; +#endif case RIN_INVISIBILITY: if (!Invis && !BInvis && !Blind) { newsym(u.ux,u.uy); @@ -867,9 +877,11 @@ update_inventory(); } break; +#ifndef MAGIC_LENSES case RIN_INCREASE_ACCURACY: /* KMH */ u.uhitinc -= obj->spe; break; +#endif case RIN_INCREASE_DAMAGE: u.udaminc -= obj->spe; break; @@ -887,6 +899,9 @@ */ restartcham(); break; +#ifdef MAGIC_LENSES + +#endif } } @@ -909,6 +924,9 @@ register struct obj *otmp; { boolean already_blind = Blind, changed = FALSE; +#ifdef MAGIC_LENSES + long oldprop = u.uprops[objects[otmp->otyp].oc_oprop].extrinsic; +#endif if (otmp == uwep) setuwep((struct obj *) 0); @@ -929,6 +947,49 @@ /* "You are now wearing the Eyes of the Overworld." */ You("can see!"); } +#ifdef MAGIC_LENSES + + switch (otmp->otyp) { + case LENSES_OF_WARNING: + see_monsters(); + break; + case LENSES_OF_SEE_INVISIBLE: + /* can now see invisible monsters */ + set_mimic_blocking(); /* do special mimic handling */ + see_monsters(); +#ifdef INVISIBLE_OBJECTS + see_objects(); +#endif + if (Invis && !oldprop && !HSee_invisible && + !perceives(youmonst.data) && !Blind) { + newsym(u.ux,u.uy); + pline("Suddenly you are transparent, but there!"); + makeknown(LENSES_OF_SEE_INVISIBLE); + } + break; + case LENSES_OF_ACCURACY: /* KMH */ + u.uhitinc += otmp->spe; + break; + case LENSES_OF_INFRAVISION: + see_monsters(); + break; + case LENSES_OF_DARKNESS: + if (levl[u.ux][u.uy].lit) { + if (Hallucination) { + pline("Who turned out the lights?"); + } + else { + pline("Everything goes dark."); + } + makeknown(LENSES_OF_DARKNESS); + } + vision_full_recalc = 1; /* recalc vision limits */ + break; + default: + break; + } + +#endif if (changed) { /* blindness has just been toggled */ if (Blind_telepat || Infravision) see_monsters(); @@ -942,6 +1003,9 @@ register struct obj *otmp; { boolean was_blind = Blind, changed = FALSE; +#ifdef MAGIC_LENSES + long oldprop = u.uprops[objects[otmp->otyp].oc_oprop].extrinsic; +#endif takeoff_mask &= ~W_TOOL; setworn((struct obj *)0, otmp->owornmask); @@ -951,7 +1015,11 @@ if (was_blind) { /* "still cannot see" makes no sense when removing lenses since they can't have been the cause of your blindness */ +#ifndef MAGIC_LENSES if (otmp->otyp != LENSES) +#else + if (is_lenses(otmp)) +#endif You("still cannot see."); } else { changed = TRUE; /* !was_blind */ @@ -964,9 +1032,49 @@ changed = TRUE; /* !Blind */ You("can see again."); } +#ifdef MAGIC_LENSES + switch(otmp->otyp) { + case LENSES_OF_WARNING: + see_monsters(); + break; + case LENSES_OF_SEE_INVISIBLE: + /* Make invisible monsters go away */ + if (!See_invisible) { + set_mimic_blocking(); /* do special mimic handling */ + see_monsters(); +#ifdef INVISIBLE_OBJECTS + see_objects(); +#endif + } + + if (Invisible && !Blind) { + newsym(u.ux,u.uy); + pline("Suddenly you cannot see yourself."); + makeknown(LENSES_OF_SEE_INVISIBLE); + } + break; + case LENSES_OF_ACCURACY: /* KMH */ + u.uhitinc -= otmp->spe; + break; + case LENSES_OF_INFRAVISION: + see_monsters(); + break; + case LENSES_OF_DARKNESS: + vision_full_recalc = 1; /* recalc vision limits */ + break; + default: + break; + } + +#endif if (changed) { /* blindness has just been toggled */ +#ifndef MAGIC_LENSES if (Blind_telepat || Infravision) see_monsters(); +#else + if (Blind_telepat || Infravision + || otmp->otyp == LENSES_OF_INFRAVISION) see_monsters(); +#endif vision_full_recalc = 1; /* recalc vision limits */ flags.botl = 1; } @@ -1168,7 +1276,12 @@ /* Curses, like chickens, come home to roost. */ if((otmp == uwep) ? welded(otmp) : (int)otmp->cursed) { You("can't. %s cursed.", +#ifndef MAGIC_LENSES (is_boots(otmp) || is_gloves(otmp) || otmp->quan > 1L) +#else + (is_boots(otmp) || is_gloves(otmp) || + is_lenses(otmp) ||otmp->quan > 1L) +#endif ? "They are" : "It is"); otmp->bknown = TRUE; return(1); @@ -1469,7 +1582,11 @@ Your("%s%s are full, and you're already wearing an amulet and %s.", humanoid(youmonst.data) ? "ring-" : "", makeplural(body_part(FINGER)), +#ifndef MAGIC_LENSES ublindf->otyp==LENSES ? "some lenses" : "a blindfold"); +#else + is_lenses(ublindf) ? "some lenses" : "a blindfold"); +#endif return(0); } otmp = getobj(accessories, "put on"); @@ -1560,11 +1677,19 @@ Your("%s is already covered by a towel.", body_part(FACE)); else if (ublindf->otyp == BLINDFOLD) { +#ifndef MAGIC_LENSES if (otmp->otyp == LENSES) +#else + if (is_lenses(otmp)) +#endif already_wearing2("lenses", "a blindfold"); else already_wearing("a blindfold"); +#ifndef MAGIC_LENSES } else if (ublindf->otyp == LENSES) { +#else + } else if (is_lenses(ublindf)) { +#endif if (otmp->otyp == BLINDFOLD) already_wearing2("a blindfold", "some lenses"); else @@ -1573,7 +1698,12 @@ already_wearing(something); /* ??? */ return(0); } +#ifndef MAGIC_LENSES if (otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL && otmp->otyp != LENSES) { +#else + if (otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL + && !is_lenses(otmp)) { +#endif You_cant("wear that!"); return(0); } diff -Naur nethack-3.4.3/src/dothrow.c nethack-all/src/dothrow.c --- nethack-3.4.3/src/dothrow.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/dothrow.c 2004-11-13 13:45:54.000000000 +1100 @@ -1660,6 +1660,14 @@ impossible("breaking odd object?"); case CRYSTAL_PLATE_MAIL: case LENSES: +#ifdef MAGIC_LENSES + case LENSES_OF_SEARCHING: + case LENSES_OF_SEE_INVISIBLE: + case LENSES_OF_WARNING: + case LENSES_OF_ACCURACY: + case LENSES_OF_INFRAVISION: + case LENSES_OF_DARKNESS: +#endif case MIRROR: case CRYSTAL_BALL: #ifdef TOURIST diff -Naur nethack-3.4.3/src/eat.c nethack-all/src/eat.c --- nethack-3.4.3/src/eat.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/eat.c 2004-11-13 13:47:28.000000000 +1100 @@ -1489,6 +1489,7 @@ u.uprops[objects[typ].oc_oprop].intrinsic |= FROMOUTSIDE; switch (typ) { +#ifndef MAGIC_LENSES case RIN_SEE_INVISIBLE: set_mimic_blocking(); see_monsters(); @@ -1499,6 +1500,7 @@ makeknown(typ); } break; +#endif case RIN_INVISIBILITY: if (!oldprop && !EInvis && !BInvis && !See_invisible && !Blind) { @@ -1537,10 +1539,12 @@ if (adjattrib(A_CON, otmp->spe, -1)) makeknown(typ); break; +#ifndef MAGIC_LENSES case RIN_INCREASE_ACCURACY: accessory_has_effect(otmp); u.uhitinc += otmp->spe; break; +#endif case RIN_INCREASE_DAMAGE: accessory_has_effect(otmp); u.udaminc += otmp->spe; @@ -1968,12 +1972,70 @@ (void) rottenfood(otmp); if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) { +#ifndef POISION_VARIETY pline("Ecch - that must have been poisonous!"); if(!Poison_resistance) { losestr(rnd(4)); losehp(rnd(15), xname(otmp), KILLED_BY_AN); } else You("seem unaffected by the poison."); +#else + switch (poison_type(otmp)) { + case OPOISON_SICKNESS: + pline("Ecch - that must have been poisonous!"); + if(!Poison_resistance) { + losestr(rnd(4)); + losehp(rnd(15), xname(otmp), KILLED_BY_AN); + } else + You("seem unaffected by the poison."); + break; + + case OPOISON_SLEEPING: + if(Sleep_resistance || Free_action) + You("yawn."); + else { + You("suddenly fall asleep!"); + fall_asleep(-rn1(10, 25 - 12*bcsign(otmp)), TRUE); + } + break; + + case OPOISON_CONFUSION: + if(!Confusion) { + if (Hallucination) { + pline("What a trippy feeling!"); + } else { + pline("Huh, What? Where am I?"); + } + } + make_confused(HConfusion + rn1(7, 16), FALSE); + break; + + case OPOISON_PARALYSIS: + if (Free_action) { + You("stiffen momentarily."); + } + else { + if (Levitation || + Is_airlevel(&u.uz)||Is_waterlevel(&u.uz)) { + You("are motionlessly suspended."); + } +#ifdef STEED + else if (u.usteed) { + You("are frozen in place!"); + } +#endif + else { + Your("%s are frozen to the %s!", + makeplural(body_part(FOOT)), surface(u.ux, u.uy)); + } + nomul(-(rn1(10, 25 - 12*bcsign(otmp)))); + nomovemsg = You_can_move_again; + exercise(A_DEX, FALSE); + } + + break; + } +#endif } else if (!otmp->cursed) pline("This %s is delicious!", otmp->oclass == COIN_CLASS ? foodword(otmp) : @@ -2145,6 +2207,15 @@ /* +0 charged rings don't do anything, so don't affect hunger */ /* Slow digestion still uses ring hunger */ switch ((int)(moves % 20)) { /* note: use even cases only */ +#ifdef MAGIC_LENSES + case 0: + if (ublindf && is_lenses(ublindf) + && objects[ublindf->otyp].oc_magic) { + /* MRKR: magic lenses cause hunger */ + u.uhunger--; + } + break; +#endif case 4: if (uleft && (uleft->spe || !objects[uleft->otyp].oc_charged)) u.uhunger--; diff -Naur nethack-3.4.3/src/invent.c nethack-all/src/invent.c --- nethack-3.4.3/src/invent.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/invent.c 2004-11-13 13:47:28.000000000 +1100 @@ -857,7 +857,11 @@ else if ((putting_on(word) && ((otmp->oclass == FOOD_CLASS && otmp->otyp != MEAT_RING) || (otmp->oclass == TOOL_CLASS && +#ifndef MAGIC_LENSES otyp != BLINDFOLD && otyp != TOWEL && otyp != LENSES))) +#else + otyp != BLINDFOLD && otyp != TOWEL && !is_lenses(otmp)))) +#endif || (!strcmp(word, "wield") && (otmp->oclass == TOOL_CLASS && !is_weptool(otmp))) || (!strcmp(word, "eat") && !is_edible(otmp)) @@ -889,6 +893,11 @@ !objects[POT_OIL].oc_name_known)) || (otmp->oclass == FOOD_CLASS && otyp != CREAM_PIE && otyp != EUCALYPTUS_LEAF) || +#ifdef MINING_LAMPS + /* MRKR: mining helmets */ + (otmp->oclass == ARMOR_CLASS && + otyp != DWARVISH_IRON_HELM) || +#endif (otmp->oclass == GEM_CLASS && !is_graystone(otmp)))) || (!strcmp(word, "invoke") && (!otmp->oartifact && !objects[otyp].oc_unique && @@ -1473,6 +1482,11 @@ otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1; if (otmp->otyp == EGG && otmp->corpsenm != NON_PM) learn_egg_type(otmp->corpsenm); +#ifdef POISION_VARIETY + if (otmp->opoisoned) { + otmp->opoistype |= OPOISON_KNOWN; + } +#endif } /* ggetobj callback routine; identify an object and give immediate feedback */ @@ -2343,6 +2357,14 @@ obj->bypass != otmp->bypass) return(FALSE); +#ifdef POISION_VARIETY + /* MRKR: Don't merge different poisoned weapon types */ + /* or unknown coating with known. */ + if (is_poisonable(obj) && obj->opoistype != otmp->opoistype) { + return FALSE; + } + +#endif if ((obj->oclass==WEAPON_CLASS || obj->oclass==ARMOR_CLASS) && (obj->oerodeproof!=otmp->oerodeproof || obj->rknown!=otmp->rknown)) return FALSE; diff -Naur nethack-3.4.3/src/makemon.c nethack-all/src/makemon.c --- nethack-3.4.3/src/makemon.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/makemon.c 2004-11-13 13:47:28.000000000 +1100 @@ -153,7 +153,14 @@ otmp = mksobj(otyp, TRUE, FALSE); otmp->quan = (long) rn1(oquan, 3); otmp->owt = weight(otmp); +#ifndef POISION_VARIETY if (otyp == ORCISH_ARROW) otmp->opoisoned = TRUE; +#else + if (otyp == ORCISH_ARROW) { + otmp->opoisoned = TRUE; + otmp->opoistype = OPOISON_SICKNESS; + } +#endif (void) mpickobj(mtmp, otmp); } @@ -310,7 +317,21 @@ (void)mongets(mtmp, AXE); (void)mongets(mtmp, DWARVISH_ROUNDSHIELD); } +#ifndef MINING_LAMPS (void)mongets(mtmp, DWARVISH_IRON_HELM); +#else + if (In_mines(&u.uz)) { + /* MRKR: Dwarves in dark mines have their lamps on. */ + otmp = mksobj(DWARVISH_IRON_HELM, TRUE, FALSE); + (void) mpickobj(mtmp, otmp); + + if (!levl[mtmp->mx][mtmp->my].lit) { + begin_burn(otmp, FALSE); + } + } + else + (void)mongets(mtmp, DWARVISH_IRON_HELM); +#endif if (!rn2(3)) (void)mongets(mtmp, DWARVISH_MITHRIL_COAT); } else { diff -Naur nethack-3.4.3/src/mkobj.c nethack-all/src/mkobj.c --- nethack-3.4.3/src/mkobj.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/mkobj.c 2004-11-13 13:47:28.000000000 +1100 @@ -397,9 +397,18 @@ curse(otmp); otmp->spe = -rne(3); } else blessorcurse(otmp, 10); +#ifndef POISION_VARIETY if (is_poisonable(otmp) && !rn2(100)) +#else + if (is_poisonable(otmp) && !rn2(100)) { +#endif otmp->opoisoned = 1; +#ifndef POISION_VARIETY +#else + otmp->opoistype = rn2(4); + } +#endif if (artif && !rn2(20)) otmp = mk_artifact(otmp, (aligntyp)A_NONE); break; @@ -498,6 +507,27 @@ case CAN_OF_GREASE: otmp->spe = rnd(25); blessorcurse(otmp, 10); break; +#ifdef MAGIC_LENSES + case LENSES_OF_DARKNESS: + curse(otmp); + break; + case LENSES_OF_ACCURACY: + blessorcurse(otmp, 3); + if(rn2(10)) { + if(rn2(10) && bcsign(otmp)) + otmp->spe = bcsign(otmp) * rne(3); + else + otmp->spe = rn2(2) ? rne(3) + : -rne(3); + } + + if (otmp->spe == 0) + otmp->spe = rn2(4) - rn2(3); + + if (otmp->spe < 0 && rn2(5)) + curse(otmp); + break; +#endif case CRYSTAL_BALL: otmp->spe = rnd(5); blessorcurse(otmp, 2); break; @@ -572,6 +602,14 @@ otmp->oerodeproof = otmp->rknown = 1; #endif } +#ifdef MINING_LAMPS + + /* MRKR: Mining helmets have lamps */ + if (otmp->otyp == DWARVISH_IRON_HELM) { + otmp->age = (long) rn1(500,1000); + otmp->lamplit = 0; + } +#endif break; case WAND_CLASS: if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else diff -Naur nethack-3.4.3/src/mondata.c nethack-all/src/mondata.c --- nethack-3.4.3/src/mondata.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/mondata.c 2004-11-13 13:45:54.000000000 +1100 @@ -108,7 +108,12 @@ boolean is_you = (mon == &youmonst); struct obj *o; +#ifndef MAGIC_LENSES if (is_you ? (Blind || u.usleep) : +#else + if (is_you ? (Blind || u.usleep || + (ublindf && ublindf->otyp == LENSES_OF_DARKNESS)) : +#endif (mon->mblinded || !mon->mcansee || !haseyes(ptr) || /* BUG: temporary sleep sets mfrozen, but since paralysis does too, we can't check it */ @@ -161,7 +166,11 @@ if (is_you && Blindfolded) return FALSE; } else if (obj && (obj->otyp == BLINDING_VENOM)) { +#ifndef MAGIC_LENSES /* all ublindf, including LENSES, protect, cream-pies too */ +#else + /* all ublindf, including lenses, protect, cream-pies too */ +#endif if (is_you && (ublindf || u.ucreamed)) return FALSE; check_visor = TRUE; @@ -181,7 +190,11 @@ break; case AT_CLAW: +#ifndef MAGIC_LENSES /* e.g. raven: all ublindf, including LENSES, protect */ +#else + /* e.g. raven: all ublindf, including lenses, protect */ +#endif if (is_you && ublindf) return FALSE; if ((magr == &youmonst) && u.uswallow) diff -Naur nethack-3.4.3/src/mthrowu.c nethack-all/src/mthrowu.c --- nethack-3.4.3/src/mthrowu.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/mthrowu.c 2004-11-13 13:47:28.000000000 +1100 @@ -179,6 +179,7 @@ else if (verbose) pline("%s is hit%s", Monnam(mtmp), exclam(damage)); if (otmp->opoisoned && is_poisonable(otmp)) { +#ifndef POISION_VARIETY if (resists_poison(mtmp)) { if (vis) pline_The("poison doesn't seem to affect %s.", mon_nam(mtmp)); @@ -188,8 +189,56 @@ } else { if (vis) pline_The("poison was deadly..."); damage = mtmp->mhp; +#else + /* MRKR: Different types of poison */ + /* Stole code from potionhit() in potion.c */ + switch (poison_type(otmp)) { + case OPOISON_SICKNESS: + if (!resists_poison(mtmp)) { + if (rn2(30)) { + damage += rnd(6); + } else { + if (vis) { + pline_The("poison was deadly..."); + otmp->opoistype |= OPOISON_KNOWN; + } + damage = mtmp->mhp; + } +#endif } +#ifndef POISION_VARIETY } +#else + break; + + case OPOISON_SLEEPING: + if (rn2(4) && sleep_monst(mtmp, rnd(12), POTION_CLASS)) { + if (vis) { + pline("%s falls asleep.", Monnam(mtmp)); + otmp->opoistype |= OPOISON_KNOWN; + } + slept_monst(mtmp); + otmp->opoistype |= OPOISON_KNOWN; + } + + break; + + case OPOISON_CONFUSION: + if(rn2(4) && !resist(mtmp, POTION_CLASS, 0, NOTELL)) { + mtmp->mconf = TRUE; + otmp->opoistype |= OPOISON_KNOWN; + } + break; + + case OPOISON_PARALYSIS: + if (rn2(4) && mtmp->mcanmove) { + mtmp->mcanmove = 0; + mtmp->mfrozen = rnd(25); + otmp->opoistype |= OPOISON_KNOWN; + } + break; + } +#endif } if (objects[otmp->otyp].oc_material == SILVER && hates_silver(mtmp->data)) { @@ -384,9 +433,61 @@ is_poisonable(singleobj)) { char onmbuf[BUFSZ], knmbuf[BUFSZ]; +#ifndef POISION_VARIETY Strcpy(onmbuf, xname(singleobj)); Strcpy(knmbuf, killer_xname(singleobj)); poisoned(onmbuf, A_STR, knmbuf, -10); +#else + /* MRKR: Different kinds of poison */ + /* Stole effects from potionbreathe() */ + + switch (poison_type(singleobj)) { + case OPOISON_SICKNESS: + Strcpy(onmbuf, xname(singleobj)); + Strcpy(knmbuf, killer_xname(singleobj)); + + poisoned(onmbuf, A_STR, knmbuf, -10); + singleobj->opoistype |= OPOISON_KNOWN; + obj->opoistype |= OPOISON_KNOWN; + break; + + case OPOISON_SLEEPING: + if (!Free_action && !Sleep_resistance) { + You_feel("rather tired."); + nomul(-rnd(5)); + nomovemsg = You_can_move_again; + exercise(A_DEX, FALSE); + } else { + You("yawn."); + } + singleobj->opoistype |= OPOISON_KNOWN; + obj->opoistype |= OPOISON_KNOWN; + + break; + + case OPOISON_CONFUSION: + if(!Confusion) { + You_feel("somewhat dizzy."); + } + make_confused(HConfusion + rnd(5), FALSE); + singleobj->opoistype |= OPOISON_KNOWN; + obj->opoistype |= OPOISON_KNOWN; + break; + + case OPOISON_PARALYSIS: + if (!Free_action) { + pline("%s seems to be holding you.", Something); + nomul(-rnd(5)); + nomovemsg = You_can_move_again; + exercise(A_DEX, FALSE); + } else { + You("stiffen momentarily."); + } + singleobj->opoistype |= OPOISON_KNOWN; + obj->opoistype |= OPOISON_KNOWN; + break; + } +#endif } if(hitu && can_blnd((struct monst*)0, &youmonst, diff -Naur nethack-3.4.3/src/muse.c nethack-all/src/muse.c --- nethack-3.4.3/src/muse.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/muse.c 2004-11-13 13:45:35.000000000 +1100 @@ -957,6 +957,9 @@ /*#define MUSE_WAN_TELEPORTATION 15*/ #define MUSE_POT_SLEEPING 16 #define MUSE_SCR_EARTH 17 +#ifdef CANCEL_DSM +#define MUSE_WAN_CANCELLATION 18 +#endif /* Select an offensive item/action for a monster. Returns TRUE iff one is * found. @@ -1034,6 +1037,13 @@ m.offensive = obj; m.has_offense = MUSE_WAN_STRIKING; } +#ifdef CANCEL_DSM + nomore(MUSE_WAN_CANCELLATION); + if(obj->otyp == WAN_CANCELLATION && obj->spe > 0) { + m.offensive = obj; + m.has_offense = MUSE_WAN_CANCELLATION; + } +#endif nomore(MUSE_POT_PARALYSIS); if(obj->otyp == POT_PARALYSIS && multi >= 0) { m.offensive = obj; @@ -1308,6 +1318,9 @@ return (mtmp->mhp <= 0) ? 1 : 2; case MUSE_WAN_TELEPORTATION: case MUSE_WAN_STRIKING: +#ifdef CANCEL_DSM + case MUSE_WAN_CANCELLATION: +#endif zap_oseen = oseen; mzapmsg(mtmp, otmp, FALSE); otmp->spe--; diff -Naur nethack-3.4.3/src/o_init.c nethack-all/src/o_init.c --- nethack-3.4.3/src/o_init.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/o_init.c 2004-11-13 13:45:54.000000000 +1100 @@ -161,8 +161,22 @@ sum = 0; for(i = first; i < last; i++) sum += objects[i].oc_prob; if(sum == 0) { +#ifdef MAGIC_LENSES + int named_cnt = 0; + /* MRKR: unnamed things get probability zero */ +#endif for(i = first; i < last; i++) +#ifndef MAGIC_LENSES objects[i].oc_prob = (1000+i-first)/(last-first); +#else + if (OBJ_NAME(objects[i])) { + objects[i].oc_prob = (1000+named_cnt); + named_cnt++; + } + for(i = first; i < last; i++) + objects[i].oc_prob /= named_cnt; + +#endif goto check; } if(sum != 1000) @@ -223,6 +237,11 @@ /* shuffle the boots [if they change, update find_skates() below] */ shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE); +#ifdef MAGIC_LENSES + + /* shuffle the lenses */ + shuffle(LENSES_OF_SEARCHING, LENSES_OF_DARKNESS, FALSE); +#endif } /* find the object index for snow boots; used [once] by slippery ice code */ diff -Naur nethack-3.4.3/src/objects.c nethack-all/src/objects.c --- nethack-3.4.3/src/objects.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/objects.c 2004-11-13 13:53:17.000000000 +1100 @@ -499,12 +499,16 @@ RING("adornment", ADORNED, "wooden", 100, 1, 1, 2, WOOD, HI_WOOD), RING("gain strength", 0, "granite", 150, 1, 1, 7, MINERAL, HI_MINERAL), RING("gain constitution", 0, "opal", 150, 1, 1, 7, MINERAL, HI_MINERAL), +#ifndef MAGIC_LENSES RING("increase accuracy", 0, "clay", 150, 1, 1, 4, MINERAL, CLR_RED), +#endif RING("increase damage", 0, "coral", 150, 1, 1, 4, MINERAL, CLR_ORANGE), RING("protection", PROTECTION, "black onyx",100, 1, 1, 7, MINERAL, CLR_BLACK), RING("regeneration", REGENERATION, "moonstone", 200, 1, 0, 6, MINERAL, HI_MINERAL), +#ifndef MAGIC_LENSES RING("searching", SEARCHING, "tiger eye", 200, 1, 0, 6, GEMSTONE, CLR_BROWN), +#endif RING("stealth", STEALTH, "jade", 100, 1, 0, 6, GEMSTONE, CLR_GREEN), RING("sustain ability", FIXED_ABIL, "bronze", 100, 1, 0, 4, COPPER, HI_COPPER), @@ -513,7 +517,9 @@ RING("aggravate monster", AGGRAVATE_MONSTER, "sapphire", 150, 1, 0, 9, GEMSTONE, CLR_BLUE), RING("conflict", CONFLICT, "ruby", 300, 1, 0, 9, GEMSTONE, CLR_RED), +#ifndef MAGIC_LENSES RING("warning", WARNING, "diamond", 100, 1, 0,10, GEMSTONE, CLR_WHITE), +#endif RING("poison resistance", POISON_RES, "pearl", 150, 1, 0, 4, IRON, CLR_WHITE), RING("fire resistance", FIRE_RES, "iron", 200, 1, 0, 5, IRON, HI_METAL), @@ -531,10 +537,24 @@ RING("polymorph control", POLYMORPH_CONTROL, "emerald", 300, 1, 0, 8, GEMSTONE, CLR_BRIGHT_GREEN), RING("invisibility", INVIS, "wire", 150, 1, 0, 5, IRON, HI_METAL), +#ifndef MAGIC_LENSES RING("see invisible", SEE_INVIS, "engagement", 150, 1, 0, 5, IRON, HI_METAL), +#endif RING("protection from shape changers", PROT_FROM_SHAPE_CHANGERS, "shiny", 100, 1, 0, 5, IRON, CLR_BRIGHT_CYAN), +#ifdef MAGIC_LENSES +/* + * MRKR: Rings turned into lenses: + * increase accuracy, searching, warning, see invisible + */ + +RING((char *)0, 0, "clay", 150, 1, 0, 4, MINERAL, CLR_RED), +RING((char *)0, 0, "tiger eye", 200, 1, 0, 6, GEMSTONE, CLR_BROWN), +RING((char *)0, 0, "diamond", 100, 1, 0,10, GEMSTONE, CLR_WHITE), +RING((char *)0, 0, "engagement", 150, 1, 0, 5, IRON, HI_METAL), + +#endif #undef RING /* amulets ... - THE Amulet comes last because it is special */ @@ -567,6 +587,13 @@ BITS(kn,mrg,chg,0,mgc,chg,0,0,0,0,0,P_NONE,mat), \ 0, TOOL_CLASS, prob, 0, \ wt, cost, 0, 0, 0, 0, wt, color ) +#ifdef MAGIC_LENSES +#define LENSES(name,power,desc,mgc,chg,prob,wt,cost,mat,color) \ + OBJECT( OBJ(name,desc), \ + BITS(0,0,chg,0,mgc,chg,0,0,0,0,0,P_NONE,mat), \ + power, TOOL_CLASS, prob, 0, \ + wt, cost, 0, 0, 0, 0, wt, color ) +#endif #define CONTAINER(name,desc,kn,mgc,chg,prob,wt,cost,mat,color) \ OBJECT( OBJ(name,desc), \ BITS(kn,0,chg,1,mgc,chg,0,0,0,0,0,P_NONE,mat), \ @@ -611,14 +638,41 @@ #endif TOOL("crystal ball", "glass orb", 0, 0, 1, 1, 15,150, 60, GLASS, HI_GLASS), +#ifndef MAGIC_LENSES TOOL("lenses", (char *)0, 1, 0, 0, 0, 5, 3, 80, GLASS, HI_GLASS), TOOL("blindfold", (char *)0, 1, 0, 0, 0, 50, 2, 20, CLOTH, CLR_BLACK), TOOL("towel", (char *)0, 1, 0, 0, 0, 50, 2, 50, CLOTH, CLR_MAGENTA), +#else +LENSES("lenses", 0, (char *)0, + 0, 0, 0, 3, 20, GLASS, HI_GLASS), +LENSES("lenses of searching", SEARCHING, "rose-tinted lenses", + 1, 0, 5, 3, 200, GLASS, CLR_BRIGHT_MAGENTA), +LENSES("lenses of see invisible", SEE_INVIS, "blue-tinted lenses", + 1, 0, 5, 3, 150, GLASS, CLR_BRIGHT_CYAN), +LENSES("lenses of warning", WARNING, "green-tinted lenses", + 1, 0, 5, 3, 100, GLASS, CLR_BRIGHT_GREEN), +LENSES("lenses of accuracy", 0, "gold-tinted lenses", + 1, 1, 5, 3, 150, GLASS, HI_GOLD), +LENSES("lenses of infravision", INFRAVISION, "violet-tinted lenses", + 1, 0, 5, 3, 100, GLASS, CLR_MAGENTA), +LENSES("lenses of darkness", 0, "mirrored lenses", + 1, 0, 5, 3, 150, GLASS, CLR_GRAY), +TOOL("blindfold", (char *)0, 1, 0, 0, 0, 40, 2, 20, CLOTH, CLR_BLACK), +TOOL("towel", (char *)0, 1, 0, 0, 0, 40, 2, 50, CLOTH, CLR_MAGENTA), +#endif #ifdef STEED TOOL("saddle", (char *)0, 1, 0, 0, 0, 5,200, 150, LEATHER, HI_LEATHER), +#ifndef MAGIC_LENSES TOOL("leash", (char *)0, 1, 0, 0, 0, 65, 12, 20, LEATHER, HI_LEATHER), #else +TOOL("leash", (char *)0, 1, 0, 0, 0, 60, 12, 20, LEATHER, HI_LEATHER), +#endif +#else +#ifndef MAGIC_LENSES TOOL("leash", (char *)0, 1, 0, 0, 0, 70, 12, 20, LEATHER, HI_LEATHER), +#else +TOOL("leash", (char *)0, 1, 0, 0, 0, 65, 12, 20, LEATHER, HI_LEATHER), +#endif #endif TOOL("stethoscope", (char *)0, 1, 0, 0, 0, 25, 4, 75, IRON, HI_METAL), TOOL("tinning kit", (char *)0, 1, 0, 0, 1, 15,100, 30, IRON, HI_METAL), @@ -729,11 +783,19 @@ POTION("blindness", "yellow", 1, BLINDED, 40, 150, CLR_YELLOW), POTION("paralysis", "emerald", 1, 0, 42, 300, CLR_BRIGHT_GREEN), POTION("speed", "dark green", 1, FAST, 42, 200, CLR_GREEN), +#ifndef ALCHEMY POTION("levitation", "cyan", 1, LEVITATION, 42, 200, CLR_CYAN), +#else +POTION("levitation", "viscous", 1, LEVITATION, 42, 200, CLR_GRAY), +#endif POTION("hallucination", "sky blue", 1, HALLUC, 40, 100, CLR_CYAN), POTION("invisibility", "brilliant blue",1, INVIS, 40, 150, CLR_BRIGHT_BLUE), POTION("see invisible", "magenta", 1, SEE_INVIS, 42, 50, CLR_MAGENTA), +#ifndef ALCHEMY POTION("healing", "purple-red", 1, 0, 57, 100, CLR_MAGENTA), +#else +POTION("healing", "amber", 1, 0, 57, 100, CLR_ORANGE), +#endif POTION("extra healing", "puce", 1, 0, 47, 100, CLR_RED), POTION("gain level", "milky", 1, 0, 20, 300, CLR_WHITE), POTION("enlightenment", "swirly", 1, 0, 20, 200, CLR_BROWN), diff -Naur nethack-3.4.3/src/objnam.c nethack-all/src/objnam.c --- nethack-3.4.3/src/objnam.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/objnam.c 2004-11-13 13:47:28.000000000 +1100 @@ -3,9 +3,14 @@ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" +#ifndef MAGIC_LENSES /* "an uncursed greased partly eaten guardian naga hatchling [corpse]" */ #define PREFIX 80 /* (56) */ +#else +/* "an uncursed greased pair of lenses of see invisible (being worn)" */ +#define PREFIX 80 /* (64) */ +#endif #define SCHAR_LIM 127 #define NUMOBUF 12 @@ -54,6 +59,9 @@ #endif /* OVLB */ STATIC_DCL const char *FDECL(Japanese_item_name,(int i)); +#ifdef POISION_VARIETY +STATIC_DCL const char *FDECL(poison_name, (struct obj* otmp)); +#endif #ifdef OVL1 @@ -274,14 +282,29 @@ Sprintf(buf,"%s amulet", dn); break; case WEAPON_CLASS: +#ifndef POISION_VARIETY if (is_poisonable(obj) && obj->opoisoned) Strcpy(buf, "poisoned "); +#else + if (is_poisonable(obj) && obj->opoisoned) { + Strcpy(buf, poison_name(obj)); + } +#endif case VENOM_CLASS: case TOOL_CLASS: +#ifndef MAGIC_LENSES if (typ == LENSES) +#else + if (is_lenses(obj)) +#endif Strcpy(buf, "pair of "); if (!obj->dknown) +#ifdef MAGIC_LENSES + if (is_lenses(obj)) + Strcat(buf, "lenses"); + else +#endif Strcat(buf, dn ? dn : actualn); else if (nn) Strcat(buf, actualn); @@ -571,9 +594,21 @@ * combining both into one function taking a parameter. */ /* must check opoisoned--someone can have a weirdly-named fruit */ +#ifndef POISION_VARIETY if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) { bp += 9; +#else + if (obj->opoisoned) { + const char* pname = poison_name(obj); + int len = strlen(pname); + + if (!strncmp(bp, pname, len)) { + bp += len; +#endif ispoisoned = TRUE; +#ifdef POISION_VARIETY + } +#endif } if(obj->quan != 1L) @@ -602,7 +637,12 @@ Strcat(prefix, "blessed "); else if ((!obj->known || !objects[obj->otyp].oc_charged || (obj->oclass == ARMOR_CLASS || +#ifndef MAGIC_LENSES obj->oclass == RING_CLASS)) +#else + obj->oclass == RING_CLASS || + is_lenses(obj))) +#endif /* For most items with charges or +/-, if you know how many * charges are left or what the +/- is, then you must have * totally identified the item, so "uncursed" is unneccesary, @@ -631,7 +671,11 @@ break; case WEAPON_CLASS: if(ispoisoned) +#ifndef POISION_VARIETY Strcat(prefix, "poisoned "); +#else + Strcat(prefix, poison_name(obj)); +#endif plus: add_erosion_words(obj, prefix); if(obj->known) { @@ -654,13 +698,19 @@ #endif )) { Strcat(bp, " (being worn)"); +#ifndef MAGIC_LENSES break; +#endif } if (obj->otyp == LEASH && obj->leashmon != 0) { Strcat(bp, " (in use)"); break; } +#ifndef MAGIC_LENSES if (is_weptool(obj)) +#else + if (is_weptool(obj) || obj->otyp == LENSES_OF_ACCURACY) +#endif goto plus; if (obj->otyp == CANDELABRUM_OF_INVOCATION) { if (!obj->spe) @@ -812,6 +862,13 @@ return TRUE; if (otmp->oartifact && undiscovered_artifact(otmp->oartifact)) return TRUE; +#ifdef POISION_VARIETY + + /* MRKR: Unidentified poison coating */ + if (otmp->opoisoned && !poison_known(otmp)) { + return TRUE; + } +#endif /* otmp->rknown is the only item of interest if we reach here */ /* * Note: if a revision ever allows scrolls to become fireproof or @@ -1553,7 +1610,12 @@ /* but don't singularize "gauntlets", "boots", "Eyes of the.." */ if (BSTRNCMPI(bp, p-3, "Eye", 3) && BSTRNCMP(bp, p-4, "boot", 4) && +#ifndef MAGIC_LENSES BSTRNCMP(bp, p-8, "gauntlet", 8)) +#else + BSTRNCMP(bp, p-8, "gauntlet", 8) && + BSTRNCMP(bp, p-5, "lense", 5)) +#endif while ((*p = *(p+1)) != 0) p++; return bp; } @@ -1757,6 +1819,9 @@ register struct obj *otmp; int cnt, spe, spesgn, typ, very, rechrg; int blessed, uncursed, iscursed, ispoisoned, isgreased; +#ifdef POISION_VARIETY + int poison; +#endif int eroded, eroded2, erodeproof; #ifdef INVISIBLE_OBJECTS int isinvisible; @@ -1786,7 +1851,11 @@ const char *name=0; cnt = spe = spesgn = typ = very = rechrg = +#ifndef POISION_VARIETY blessed = uncursed = iscursed = +#else + blessed = uncursed = iscursed = poison = +#endif #ifdef INVISIBLE_OBJECTS isinvisible = #endif @@ -1860,12 +1929,40 @@ !strncmpi(bp,"unlabelled ", l=11) || !strncmpi(bp,"blank ", l=6)) { unlabeled = 1; +#ifndef POISION_VARIETY } else if(!strncmpi(bp, "poisoned ",l=9) +#else + } else if(!strncmpi(bp, "coated ",l=7)) { + ispoisoned=1; + poison = rn2(4); + } else if(!strncmpi(bp, "poisoned ",l=9)) { + ispoisoned=1; + poison = OPOISON_SICKNESS; + } else if(!strncmpi(bp, "poison coated ",l=14)) { + ispoisoned=1; + poison = OPOISON_SICKNESS; + } else if(!strncmpi(bp, "sleep coated ",l=13)) { + ispoisoned=1; + poison = OPOISON_SLEEPING; + } else if(!strncmpi(bp, "paralysis coated ",l=17)) { + ispoisoned=1; + poison = OPOISON_SICKNESS; + } else if(!strncmpi(bp, "confusion coated ",l=17)) { + ispoisoned=1; + poison = OPOISON_SICKNESS; +#endif #ifdef WIZARD +#ifndef POISION_VARIETY || (wizard && !strncmpi(bp, "trapped ",l=8)) +#else + } else if(wizard && !strncmpi(bp, "trapped ",l=8)) { + ispoisoned=1; #endif +#endif +#ifndef POISION_VARIETY ) { ispoisoned=1; +#endif } else if(!strncmpi(bp, "greased ",l=8)) { isgreased=1; } else if (!strncmpi(bp, "very ", l=5)) { @@ -2136,6 +2233,9 @@ register int j = strlen(wrp[i]); if(!strncmpi(bp, wrp[i], j)){ oclass = wrpsym[i]; +#ifdef MAGIC_LENSES + +#endif if(oclass != AMULET_CLASS) { bp += j; if(!strncmpi(bp, " of ", 4)) actualn = bp+4; @@ -2202,6 +2302,9 @@ } } } +#ifdef MAGIC_LENSES + +#endif i = oclass ? bases[(int)oclass] : 1; while(i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)){ register const char *zn; @@ -2659,8 +2762,15 @@ /* set poisoned */ if (ispoisoned) { +#ifndef POISION_VARIETY if (is_poisonable(otmp)) otmp->opoisoned = (Luck >= 0); +#else + if (is_poisonable(otmp) && Luck >= 0) { + otmp->opoisoned = 1; + otmp->opoistype = poison; + } +#endif else if (Is_box(otmp) || typ == TIN) otmp->otrapped = 1; else if (oclass == FOOD_CLASS) @@ -2675,7 +2785,11 @@ otmp->odiluted = 1; if (name) { +#ifndef POISION_VARIETY const char *aname; +#else + const char *aname; +#endif short objtyp; /* an artifact name might need capitalization fixing */ @@ -2782,6 +2896,29 @@ } return "whatcha-may-callit"; } +#ifdef POISION_VARIETY + +STATIC_OVL const char * +poison_name(otmp) +struct obj *otmp; +{ + if (poison_known(otmp)) { + switch (poison_type(otmp)) { + case OPOISON_SICKNESS: + return "poisoned "; + case OPOISON_SLEEPING: + return "sleep coated "; + case OPOISON_CONFUSION: + return "confusion coated "; + case OPOISON_PARALYSIS: + return "paralysis coated "; + } + } + else { + return "coated "; + } +} +#endif #endif /* OVLB */ /*objnam.c*/ diff -Naur nethack-3.4.3/src/potion.c nethack-all/src/potion.c --- nethack-3.4.3/src/potion.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/potion.c 2004-11-13 13:47:28.000000000 +1100 @@ -13,6 +13,9 @@ STATIC_DCL long FDECL(itimeout, (long)); STATIC_DCL long FDECL(itimeout_incr, (long,int)); STATIC_DCL void NDECL(ghost_from_bottle); +#ifdef ALCHEMY +STATIC_OVL void NDECL(alchemy_init); +#endif STATIC_DCL short FDECL(mixtype, (struct obj *,struct obj *)); /* force `val' to be within valid range for intrinsic timeout value */ @@ -1318,11 +1321,120 @@ } } +#ifdef ALCHEMY +/* new alchemy scheme based on color mixing + * YANI by Graham Cox + * Implemented by Nephi Allred on 15 Apr 2003 + * + * Alchemical tables are based on 4 bits describing dark/light level, yellow, blue and red + * + * DYBR + * 0000 white + * 0001 pink + * 0010 sky-blue + * 0011 puce + * 0100 yellow + * 0101 orange + * 0110 emerald + * 0111 brown + * 1000 black + * 1001 ruby + * 1010 brilliant blue + * 1011 magenta + * 1100 golden + * 1101 amber + * 1110 dark green + * 1111 brown + */ + +/* Assumes gain ability is first potion and water is last */ +char alchemy_table1[POT_WATER - POT_GAIN_ABILITY]; +short alchemy_table2[17]; + +#define ALCHEMY_WHITE 0 +#define ALCHEMY_BLACK 8 +#define ALCHEMY_GRAY (alchemy_table2[16]) +#define IS_PRIMARY_COLOR(x) (((x)&7)==1 || ((x)&7)==2 || ((x)&7)==4) +#define IS_SECONDARY_COLOR(x) (((x)&7)==3 || ((x)&7)==5 || ((x)&7)==6) +#define IS_LIGHT_COLOR(x) (((x)&8)==0) +#define IS_DARK_COLOR(x) ((x)&8) + +/* do a one-time set up of alchemical tables */ +STATIC_OVL void +alchemy_init() +{ + static boolean init = FALSE; + + if(init==FALSE) { + short i; + const char* potion_desc; + + for(i=POT_GAIN_ABILITY;i<=POT_WATER;i++) { + potion_desc = OBJ_DESCR(objects[i]); + if(0==strcmp(potion_desc,"white")) { + alchemy_table1[i-POT_GAIN_ABILITY]=0; + alchemy_table2[0]=i; + } else if (0==strcmp(potion_desc,"pink")) { + alchemy_table1[i-POT_GAIN_ABILITY]=1; + alchemy_table2[1]=i; + } else if (0==strcmp(potion_desc,"sky blue")) { + alchemy_table1[i-POT_GAIN_ABILITY]=2; + alchemy_table2[2]=i; + } else if (0==strcmp(potion_desc,"puce")) { + alchemy_table1[i-POT_GAIN_ABILITY]=3; + alchemy_table2[3]=i; + } else if (0==strcmp(potion_desc,"yellow")) { + alchemy_table1[i-POT_GAIN_ABILITY]=4; + alchemy_table2[4]=i; + } else if (0==strcmp(potion_desc,"orange")) { + alchemy_table1[i-POT_GAIN_ABILITY]=5; + alchemy_table2[5]=i; + } else if (0==strcmp(potion_desc,"emerald")) { + alchemy_table1[i-POT_GAIN_ABILITY]=6; + alchemy_table2[6]=i; + } else if (0==strcmp(potion_desc,"brown")) { + alchemy_table1[i-POT_GAIN_ABILITY]=7; + alchemy_table2[7]=i; + alchemy_table2[15]=i; + } else if (0==strcmp(potion_desc,"black")) { + alchemy_table1[i-POT_GAIN_ABILITY]=8; + alchemy_table2[8]=i; + } else if (0==strcmp(potion_desc,"ruby")) { + alchemy_table1[i-POT_GAIN_ABILITY]=9; + alchemy_table2[9]=i; + } else if (0==strcmp(potion_desc,"brilliant blue")) { + alchemy_table1[i-POT_GAIN_ABILITY]=10; + alchemy_table2[10]=i; + } else if (0==strcmp(potion_desc,"magenta")) { + alchemy_table1[i-POT_GAIN_ABILITY]=11; + alchemy_table2[11]=i; + } else if (0==strcmp(potion_desc,"golden")) { + alchemy_table1[i-POT_GAIN_ABILITY]=12; + alchemy_table2[12]=i; + } else if (0==strcmp(potion_desc,"amber")) { + alchemy_table1[i-POT_GAIN_ABILITY]=13; + alchemy_table2[13]=i; + } else if (0==strcmp(potion_desc,"dark green")) { + alchemy_table1[i-POT_GAIN_ABILITY]=14; + alchemy_table2[14]=i; + } else if (0==strcmp(potion_desc,"cloudy")) { + alchemy_table1[i-POT_GAIN_ABILITY]=-1; + alchemy_table2[16]=i; + } else { + alchemy_table1[i-POT_GAIN_ABILITY]=-1; + } + } + init = TRUE; + } +} + +#endif STATIC_OVL short mixtype(o1, o2) register struct obj *o1, *o2; /* returns the potion type when o1 is dipped in o2 */ { +#ifndef ALCHEMY /* cut down on the number of cases below */ if (o1->oclass == POTION_CLASS && (o2->otyp == POT_GAIN_LEVEL || @@ -1403,7 +1515,67 @@ switch (o2->otyp) { case POT_LEVITATION: if (rn2(3)) return POT_GAIN_LEVEL; +#else + if(o1->oclass == POTION_CLASS) { + char i1,i2,result; + + alchemy_init(); + i1 = alchemy_table1[o1->otyp-POT_GAIN_ABILITY]; + i2 = alchemy_table1[o2->otyp-POT_GAIN_ABILITY]; + + /* check that both potions are of mixable types */ + if(i1<0 || i2<0) + return 0; + + /* swap for simplified checks */ + if(i2==ALCHEMY_WHITE || (i2==ALCHEMY_BLACK && i1!=ALCHEMY_WHITE)) { + result = i1; + i1 = i2; + i2 = result; + } + + if(i1==ALCHEMY_WHITE && i2==ALCHEMY_BLACK) { + return ALCHEMY_GRAY; + } else if( (IS_PRIMARY_COLOR(i1) && IS_PRIMARY_COLOR(i2)) + || (IS_SECONDARY_COLOR(i1) && IS_SECONDARY_COLOR(i2)) ) { + /* bitwise OR simulates pigment addition */ + result = i1 | i2; + /* adjust light/dark level if necessary */ + if((i1^i2)&8) { + if(o1->odiluted==o2->odiluted) { + /* same dilution level, randomly toggle */ + result ^= (rn2(2)<<3); + } else { + /* use dark/light level of undiluted potion */ + result ^= (o1->odiluted ? i1:i2)&8; + } + } + } else if ( (i1==ALCHEMY_WHITE && IS_DARK_COLOR(i2)) + || (i1==ALCHEMY_BLACK && IS_LIGHT_COLOR(i2))) { + /* toggle light/dark bit */ + result = i2 ^ 8; + } else { + return 0; + } + return alchemy_table2[result]; + } else { + switch (o1->otyp) { + case UNICORN_HORN: + switch (o2->otyp) { + case POT_SICKNESS: + return POT_FRUIT_JUICE; + case POT_HALLUCINATION: + case POT_BLINDNESS: + case POT_CONFUSION: + return POT_WATER; + } + break; + case AMETHYST: /* "a-methyst" == "not intoxicated" */ + if (o2->otyp == POT_BOOZE) + return POT_FRUIT_JUICE; +#endif break; +#ifndef ALCHEMY case POT_FRUIT_JUICE: return POT_BOOZE; case POT_BOOZE: @@ -1411,7 +1583,134 @@ } break; } +#else + } + } +#endif + +#ifdef ALCHEMY + /* MRKR: Extra alchemical effects. */ + if (o2->otyp == POT_ACID && o1->oclass == GEM_CLASS) { + char *potion_descr = NULL; + + /* Note: you can't create smoky, milky or clear potions */ + + switch (o1->otyp) { + + /* white */ + + case DILITHIUM_CRYSTAL: + /* explodes - special treatment in dodip */ + /* here we just want to return something non-zero */ + return POT_WATER; + break; + case DIAMOND: + /* won't dissolve */ + break; + case OPAL: + potion_descr = "cloudy"; + break; + + /* red */ + + case RUBY: + potion_descr = "ruby"; + break; + case GARNET: + potion_descr = "pink"; + break; + case JASPER: + potion_descr = "murky"; + break; + + /* orange */ + + case JACINTH: + potion_descr = "orange"; + break; + case AGATE: + potion_descr = "swirly"; + break; + + /* yellow */ + + case CITRINE: + potion_descr = "yellow"; + break; + case CHRYSOBERYL: + potion_descr = "golden"; + break; + + /* yellowish brown */ + + case AMBER: + potion_descr = "amber"; + break; + case TOPAZ: + potion_descr = "brown"; + break; + + /* green */ + + case EMERALD: + potion_descr = "emerald"; + break; + case TURQUOISE: + potion_descr = "sky blue"; + break; + case AQUAMARINE: + potion_descr = "viscous"; + break; + case JADE: + potion_descr = "dark green"; + break; + + /* blue */ + + case SAPPHIRE: + potion_descr = "brilliant blue"; + break; + + /* violet */ + + case AMETHYST: + potion_descr = "magenta"; + break; + case FLUORITE: + potion_descr = "white"; + break; + + /* black */ + + case BLACK_OPAL: + potion_descr = "black"; + break; + case JET: + potion_descr = "dark"; + break; + case OBSIDIAN: + potion_descr = "effervescent"; + break; + } + + if (potion_descr) { + int typ; + + /* find a potion that matches the description */ + + for (typ = bases[POTION_CLASS]; + objects[typ].oc_class == POTION_CLASS; + typ++) { + + if (strcmp(potion_descr, OBJ_DESCR(objects[typ])) == 0) { + return typ; + } + } + } + } + +#endif return 0; } @@ -1438,8 +1737,16 @@ if (obj->otyp == POT_ACID) { pline("It boils vigorously!"); You("are caught in the explosion!"); +#ifndef ALCHEMY losehp(rnd(10), "elementary chemistry", KILLED_BY); +#else + losehp(Acid_resistance ? rnd(5) : rnd(10), + "elementary chemistry", KILLED_BY); +#endif makeknown(obj->otyp); +#ifdef ALCHEMY + useup(obj); +#endif update_inventory(); return (TRUE); } @@ -1524,7 +1831,11 @@ int dodip() { +#ifndef ALCHEMY register struct obj *potion, *obj; +#else + struct obj *potion, *obj; +#endif struct obj *singlepotion; const char *tmp; uchar here; @@ -1556,7 +1867,9 @@ #endif } else { (void) get_wet(obj); +#ifndef ALCHEMY if (obj->otyp == POT_ACID) useup(obj); +#endif } return 1; } @@ -1568,6 +1881,15 @@ pline("That is a potion bottle, not a Klein bottle!"); return 0; } +#ifdef ALCHEMY + + if(potion->otyp != POT_WATER && obj->otyp == POT_WATER) { + /* swap roles, to ensure symmetry */ + struct obj *otmp = potion; + potion = obj; + obj = otmp; + } +#endif potion->in_use = TRUE; /* assume it will be used up */ if(potion->otyp == POT_WATER) { boolean useeit = !Blind; @@ -1664,16 +1986,38 @@ return(1); } else if(obj->oclass == POTION_CLASS && obj->otyp != potion->otyp) { /* Mixing potions is dangerous... */ +#ifndef ALCHEMY pline_The("potions mix..."); +#else + /* Give a clue to what's going on ... */ + if(potion->dknown && obj->dknown) { + You("mix the %s potion with the %s one ...", + OBJ_DESCR(objects[potion->otyp]), + OBJ_DESCR(objects[obj->otyp])); + } else + pline_The("potions mix..."); +#endif /* KMH, balance patch -- acid is particularly unstable */ +#ifndef ALCHEMY if (obj->cursed || obj->otyp == POT_ACID || !rn2(10)) { +#else + if (obj->cursed || obj->otyp == POT_ACID || + potion->cursed || potion->otyp == POT_ACID || !rn2(10)) { +#endif pline("BOOM! They explode!"); exercise(A_STR, FALSE); if (!breathless(youmonst.data) || haseyes(youmonst.data)) potionbreathe(obj); useup(obj); useup(potion); +#ifndef ALCHEMY losehp(rnd(10), "alchemic blast", KILLED_BY_AN); +#else + /* MRKR: an alchemy smock ought to be */ + /* some protection against this: */ + losehp(Acid_resistance ? rnd(5) : rnd(10), + "alchemic blast", KILLED_BY_AN); +#endif return(1); } @@ -1745,7 +2089,18 @@ #endif if(is_poisonable(obj)) { +#ifndef POISION_VARIETY if(potion->otyp == POT_SICKNESS && !obj->opoisoned) { +#else + + /* MRKR: More kinds of coated weapons */ + + if(!obj->opoisoned && + (potion->otyp == POT_SICKNESS || + potion->otyp == POT_SLEEPING || + potion->otyp == POT_CONFUSION || + potion->otyp == POT_PARALYSIS)) { +#endif char buf[BUFSZ]; if (potion->quan > 1L) Sprintf(buf, "One of %s", the(xname(potion))); @@ -1754,6 +2109,25 @@ pline("%s forms a coating on %s.", buf, the(xname(obj))); obj->opoisoned = TRUE; +#ifdef POISION_VARIETY + switch (potion->otyp) { + case POT_SICKNESS: + obj->opoistype = OPOISON_SICKNESS; + break; + case POT_SLEEPING: + obj->opoistype = OPOISON_SLEEPING; + break; + case POT_CONFUSION: + obj->opoistype = OPOISON_CONFUSION; + break; + case POT_PARALYSIS: + obj->opoistype = OPOISON_PARALYSIS; + break; + } + if (objects[potion->otyp].oc_name_known) { + obj->opoistype |= OPOISON_KNOWN; + } +#endif goto poof; } else if(obj->opoisoned && (potion->otyp == POT_HEALING || @@ -1861,7 +2235,11 @@ } potion->in_use = FALSE; /* didn't go poof */ +#ifndef ALCHEMY if ((obj->otyp == UNICORN_HORN || obj->otyp == AMETHYST) && +#else + if ((obj->otyp == UNICORN_HORN || obj->oclass == GEM_CLASS) && +#endif (mixture = mixtype(obj, potion)) != 0) { char oldbuf[BUFSZ], newbuf[BUFSZ]; short old_otyp = potion->otyp; @@ -1880,10 +2258,59 @@ singlepotion = splitobj(potion, 1L); } else singlepotion = potion; +#ifdef ALCHEMY + /* MRKR: Gems dissolve in acid to produce new potions */ + + if (obj->oclass == GEM_CLASS && potion->otyp == POT_ACID) { + + struct obj *singlegem = (obj->quan > 1L ? + splitobj(obj, 1L) : obj); + + if (potion->otyp == POT_ACID && + (obj->otyp == DILITHIUM_CRYSTAL || + potion->cursed || !rn2(10))) { + + /* Just to keep them on their toes */ + + if (Hallucination && obj->otyp == DILITHIUM_CRYSTAL) { + /* Thanks to Robin Johnson */ + pline("Warning, Captain! The warp core has been breached!"); + } + pline("BOOM! %s explodes!", The(xname(singlegem))); + exercise(A_STR, FALSE); + if (!breathless(youmonst.data) || haseyes(youmonst.data)) + potionbreathe(singlepotion); + useup(singlegem); + useup(singlepotion); + /* MRKR: an alchemy smock ought to be */ + /* some protection against this: */ + losehp(Acid_resistance ? rnd(5) : rnd(10), + "alchemic blast", KILLED_BY_AN); + return(1); + } + + pline("%s dissolves in %s.", The(xname(singlegem)), + the(xname(singlepotion))); + makeknown(POT_ACID); + useup(singlegem); + } + +#endif if(singlepotion->unpaid && costly_spot(u.ux, u.uy)) { You("use it, you pay for it."); bill_dummy_object(singlepotion); } +#ifdef ALCHEMY + + if (singlepotion->otyp == mixture) { + /* no change - merge it back in */ + if (more_than_one && !merged(&potion, &singlepotion)) { + /* should never happen */ + impossible("singlepotion won't merge with parent potion."); + } + } + else { +#endif singlepotion->otyp = mixture; singlepotion->blessed = 0; if (mixture == POT_WATER) @@ -1918,6 +2345,10 @@ "You juggle and drop %s!", doname(singlepotion), (const char *)0); update_inventory(); +#ifdef ALCHEMY + } + +#endif return(1); } diff -Naur nethack-3.4.3/src/read.c nethack-all/src/read.c --- nethack-3.4.3/src/read.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/read.c 2004-11-13 13:46:47.000000000 +1100 @@ -294,7 +294,12 @@ ever created the above will need to be revised */ } +#ifndef MINING_LAMPS } else if (obj->oclass == TOOL_CLASS) { +#else + } else if (obj->oclass == TOOL_CLASS + || obj->otyp == DWARVISH_IRON_HELM) { +#endif int rechrg = (int)obj->recharged; if (objects[obj->otyp].oc_charged) { @@ -349,21 +354,45 @@ p_glow2(obj, NH_WHITE); } break; +#ifdef MINING_LAMPS + case DWARVISH_IRON_HELM: +#endif case OIL_LAMP: case BRASS_LANTERN: if (is_cursed) { +#ifndef MINING_LAMPS stripspe(obj); +#else + if (obj->otyp == DWARVISH_IRON_HELM) { + /* Don't affect the +/- of the helm */ + obj->age = 0; + } + else + stripspe(obj); +#endif if (obj->lamplit) { if (!Blind) pline("%s out!", Tobjnam(obj, "go")); end_burn(obj, TRUE); } } else if (is_blessed) { +#ifndef MINING_LAMPS obj->spe = 1; +#else + if (obj->otyp != DWARVISH_IRON_HELM) { + obj->spe = 1; + } +#endif obj->age = 1500; p_glow2(obj, NH_BLUE); } else { +#ifndef MINING_LAMPS obj->spe = 1; +#else + if (obj->otyp != DWARVISH_IRON_HELM) { + obj->spe = 1; + } +#endif obj->age += 750; if (obj->age > 1500) obj->age = 1500; p_glow1(obj); diff -Naur nethack-3.4.3/src/shknam.c nethack-all/src/shknam.c --- nethack-3.4.3/src/shknam.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/shknam.c 2004-11-13 13:45:54.000000000 +1100 @@ -112,7 +112,11 @@ "Htargcm", "Enrobwem", "Kachzi Rellim", "Regien", "Donmyar", "Yelpur", "Nosnehpets", "Stewe", "Renrut", "_Zlaw", "Nosalnef", "Rewuorb", "Rellenk", "Yad", "Cire Htims", "Y-crad", "Nenilukah", +#ifndef MAGIC_LENSES "Corsh", "Aned", +#else + "Corsh", "Aned", "Nayr", +#endif #ifdef OVERLAY "Erreip", "Nehpets", "Mron", "Snivek", "Lapu", "Kahztiy", #endif @@ -198,7 +202,15 @@ {{83, FOOD_CLASS}, {5, -POT_FRUIT_JUICE}, {4, -POT_BOOZE}, {5, -POT_WATER}, {3, -ICE_BOX}}, shkfoods}, {"jewelers", RING_CLASS, 3, D_SHOP, +#ifndef MAGIC_LENSES {{85, RING_CLASS}, {10, GEM_CLASS}, {5, AMULET_CLASS}, {0, 0}}, +#else + {{65, RING_CLASS}, {10, GEM_CLASS}, {5, AMULET_CLASS}, + {2, -LENSES}, {3, -LENSES_OF_SEARCHING}, + {3, -LENSES_OF_SEE_INVISIBLE}, {3, -LENSES_OF_WARNING}, + {3, -LENSES_OF_ACCURACY}, {3, -LENSES_OF_INFRAVISION}, + {3, -LENSES_OF_DARKNESS}, {0, 0}}, +#endif shkrings}, {"quality apparel and accessories", WAND_CLASS, 3, D_SHOP, {{90, WAND_CLASS}, {5, -LEATHER_GLOVES}, {5, -ELVEN_CLOAK}, {0, 0}}, diff -Naur nethack-3.4.3/src/spell.c nethack-all/src/spell.c --- nethack-3.4.3/src/spell.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/spell.c 2004-11-13 13:45:54.000000000 +1100 @@ -321,7 +321,38 @@ boolean costly = TRUE; /* JDS: lenses give 50% faster reading; 33% smaller read time */ +#ifndef MAGIC_LENSES if (delay && ublindf && ublindf->otyp == LENSES && rn2(2)) delay++; +#else + /* MRKR: some lenses are better than others... */ + if (delay && ublindf && is_lenses(ublindf)) { + switch(ublindf->otyp) { + case LENSES_OF_ACCURACY: { + register schar spe = ublindf->spe; + + /* ublindf->spe: +0 +1 +2 +3 +4 +5 +6 +7 */ + /* reading time: 2/3 2/3 3/5 3/5 4/7 4/7 5/9 5/9 */ + /* ublindf->spe: -1 -2 -3 -4 -5 -6 -7 */ + /* reading time: 1 3/2 3/2 5/3 5/3 7/4 7/4 */ + + if (spe >= 0) { + if (!rn2(2 + spe / 2)) delay++; + } + else { + if (rn2(1 - 2*(spe / 2)) >= 1 - spe/2) + delay--; + } + } + break; + case LENSES_OF_DARKNESS: + if (rn2(3)) delay--; + break; + default: + if (rn2(2)) delay++; + break; + } + } +#endif if (Confusion) { /* became confused while learning */ (void) confused_book(book); book = 0; /* no longer studying */ @@ -439,8 +470,28 @@ } else { /* uncursed - chance to fail */ int read_ability = ACURR(A_INT) + 4 + u.ulevel/2 +#ifndef MAGIC_LENSES - 2*objects[booktype].oc_level + ((ublindf && ublindf->otyp == LENSES) ? 2 : 0); +#else + - 2*objects[booktype].oc_level; + + if (ublindf && is_lenses(ublindf)) { + switch(ublindf->otyp) { + case LENSES_OF_ACCURACY: + read_ability += ublindf->spe/2 + + (ublindf->spe >= 0 ? 2 : 0); + break; + case LENSES_OF_DARKNESS: + read_ability -= 2; + break; + default: + read_ability += 2; + break; + } + } + + ((ublindf && is_lenses(ublindf)) ? 2 : 0); +#endif /* only wizards know if a spell is too difficult */ if (Role_if(PM_WIZARD) && read_ability < 20 && !confused) { diff -Naur nethack-3.4.3/src/timeout.c nethack-all/src/timeout.c --- nethack-3.4.3/src/timeout.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/timeout.c 2004-11-13 13:46:47.000000000 +1100 @@ -810,6 +810,9 @@ obj = (struct obj *) 0; break; +#ifdef MINING_LAMPS + case DWARVISH_IRON_HELM: +#endif case BRASS_LANTERN: case OIL_LAMP: switch((int)obj->age) { @@ -817,7 +820,12 @@ case 100: case 50: if (canseeit) { +#ifndef MINING_LAMPS if (obj->otyp == BRASS_LANTERN) +#else + if (obj->otyp == BRASS_LANTERN + || obj->otyp == DWARVISH_IRON_HELM) +#endif lantern_message(obj); else see_lamp_flicker(obj, @@ -827,7 +835,12 @@ case 25: if (canseeit) { +#ifndef MINING_LAMPS if (obj->otyp == BRASS_LANTERN) +#else + if (obj->otyp == BRASS_LANTERN + || obj->otyp == DWARVISH_IRON_HELM) +#endif lantern_message(obj); else { switch (obj->where) { @@ -851,7 +864,12 @@ switch (obj->where) { case OBJ_INVENT: case OBJ_MINVENT: +#ifndef MINING_LAMPS if (obj->otyp == BRASS_LANTERN) +#else + if (obj->otyp == BRASS_LANTERN + || obj->otyp == DWARVISH_IRON_HELM) +#endif pline("%s lantern has run out of power.", whose); else @@ -859,7 +877,12 @@ whose, xname(obj)); break; case OBJ_FLOOR: +#ifndef MINING_LAMPS if (obj->otyp == BRASS_LANTERN) +#else + if (obj->otyp == BRASS_LANTERN + || obj->otyp == DWARVISH_IRON_HELM) +#endif You("see a lantern run out of power."); else You("see %s go out.", @@ -1062,6 +1085,9 @@ radius = 1; /* very dim light */ break; +#ifdef MINING_LAMPS + case DWARVISH_IRON_HELM: +#endif case BRASS_LANTERN: case OIL_LAMP: /* magic times are 150, 100, 50, 25, and 0 */ diff -Naur nethack-3.4.3/src/trap.c nethack-all/src/trap.c --- nethack-3.4.3/src/trap.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/trap.c 2004-11-13 13:47:28.000000000 +1100 @@ -673,14 +673,63 @@ otmp = mksobj(DART, TRUE, FALSE); otmp->quan = 1L; otmp->owt = weight(otmp); +#ifndef POISION_VARIETY if (!rn2(6)) otmp->opoisoned = 1; +#else + if (!rn2(4)) { + otmp->opoisoned = 1; + otmp->opoistype = rn2(4); + } +#endif #ifdef STEED if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) /* nothing */; else #endif if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) { +#ifndef POISION_VARIETY if (otmp->opoisoned) poisoned("dart", A_CON, "little dart", -10); +#else + if (otmp->opoisoned) { + /* MRKR: Different kinds of poison */ + /* Stole effects from potionbreathe() */ + + switch (poison_type(otmp)) { + case OPOISON_SICKNESS: + poisoned("dart", A_CON, "little dart", -10); + break; + + case OPOISON_SLEEPING: + if (!Free_action && !Sleep_resistance) { + You_feel("rather tired."); + nomul(-rnd(5)); + nomovemsg = You_can_move_again; + exercise(A_DEX, FALSE); + } else { + You("yawn."); + } + break; + + case OPOISON_CONFUSION: + if(!Confusion) { + You_feel("somewhat dizzy."); + } + make_confused(HConfusion + rnd(5), FALSE); + break; + + case OPOISON_PARALYSIS: + if (!Free_action) { + pline("%s seems to be holding you.", Something); + nomul(-rnd(5)); + nomovemsg = You_can_move_again; + exercise(A_DEX, FALSE); + } else { + You("stiffen momentarily."); + } + break; + } + } +#endif obfree(otmp, (struct obj *)0); } else { place_object(otmp, u.ux, u.uy); @@ -1752,7 +1801,14 @@ otmp = mksobj(DART, TRUE, FALSE); otmp->quan = 1L; otmp->owt = weight(otmp); +#ifndef POISION_VARIETY if (!rn2(6)) otmp->opoisoned = 1; +#else + if (!rn2(4)) { + otmp->opoisoned = 1; + otmp->opoistype = rn2(4); + } +#endif if (in_sight) seetrap(trap); if (thitm(7, mtmp, otmp, 0, FALSE)) trapkilled = TRUE; break; diff -Naur nethack-3.4.3/src/u_init.c nethack-all/src/u_init.c --- nethack-3.4.3/src/u_init.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/u_init.c 2004-11-13 13:45:54.000000000 +1100 @@ -163,7 +163,11 @@ { QUARTERSTAFF, 1, WEAPON_CLASS, 1, 1 }, { CLOAK_OF_MAGIC_RESISTANCE, 0, ARMOR_CLASS, 1, UNDEF_BLESS }, { UNDEF_TYP, UNDEF_SPE, WAND_CLASS, 1, UNDEF_BLESS }, +#ifndef MAGIC_LENSES { UNDEF_TYP, UNDEF_SPE, RING_CLASS, 2, UNDEF_BLESS }, +#else +/* { UNDEF_TYP, UNDEF_SPE, RING_CLASS, 2, UNDEF_BLESS }, */ +#endif { UNDEF_TYP, UNDEF_SPE, POTION_CLASS, 3, UNDEF_BLESS }, { UNDEF_TYP, UNDEF_SPE, SCROLL_CLASS, 3, UNDEF_BLESS }, { SPE_FORCE_BOLT, 0, SPBOOK_CLASS, 1, 1 }, @@ -175,6 +179,22 @@ * Optional extra inventory items. */ +#ifdef MAGIC_LENSES +/* MRKR: Sometimes wizards get a pair of lenses instead of a second ring. */ +/* The ordinary LENSES will be replaced by a magical pair. */ + +static struct trobj Wiz_Ring_and_Lenses[] = { + { UNDEF_TYP, UNDEF_SPE, RING_CLASS, 1, UNDEF_BLESS }, + { LENSES, UNDEF_SPE, TOOL_CLASS, 1, UNDEF_BLESS }, + { 0, 0, 0, 0, 0 } +}; + +static struct trobj Wiz_Two_Rings[] = { + { UNDEF_TYP, UNDEF_SPE, RING_CLASS, 2, UNDEF_BLESS }, + { 0, 0, 0, 0, 0 } +}; + +#endif static struct trobj Tinopener[] = { { TIN_OPENER, 0, TOOL_CLASS, 1, 0 }, { 0, 0, 0, 0, 0 } @@ -725,6 +745,31 @@ break; case PM_WIZARD: ini_inv(Wizard); +#ifdef MAGIC_LENSES + /* MRKR Sometimes replace one ring with lenses */ + if(rn2(AMULET_CLASS - RING_CLASS + 5) < 5) { + /* randomly assign a set of lenses */ + static int trotyp[] = { + LENSES_OF_SEARCHING, + LENSES_OF_SEE_INVISIBLE, + LENSES_OF_WARNING, + LENSES_OF_ACCURACY, + LENSES_OF_INFRAVISION + }; + if (Infravision) { + Wiz_Ring_and_Lenses[1].trotyp = + trotyp[rn2(SIZE(trotyp))-1]; + } + else { + Wiz_Ring_and_Lenses[1].trotyp = + trotyp[rn2(SIZE(trotyp))]; + } + ini_inv(Wiz_Ring_and_Lenses); + } + else { + ini_inv(Wiz_Two_Rings); + } +#endif if(!rn2(5)) ini_inv(Magicmarker); if(!rn2(5)) ini_inv(Blindfold); skill_init(Skill_W); diff -Naur nethack-3.4.3/src/uhitm.c nethack-all/src/uhitm.c --- nethack-3.4.3/src/uhitm.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/uhitm.c 2004-11-13 13:47:28.000000000 +1100 @@ -908,6 +908,9 @@ } if (ispoisoned) { +#ifdef POISION_VARIETY + int poison = poison_type(obj); +#endif int nopoison = (10 - (obj->owt/10)); if(nopoison < 2) nopoison = 2; if Role_if(PM_SAMURAI) { @@ -922,11 +925,54 @@ Your("%s %s no longer poisoned.", xname(obj), otense(obj, "are")); } +#ifndef POISION_VARIETY if (resists_poison(mon)) needpoismsg = TRUE; else if (rn2(10)) tmp += rnd(6); else poiskilled = TRUE; +#else + + switch (poison) { + case OPOISON_SICKNESS: + if (resists_poison(mon)) { + needpoismsg = TRUE; + obj->opoistype |= OPOISON_KNOWN; + } + else if (rn2(10)) + tmp += rnd(6); + else { + poiskilled = TRUE; + obj->opoistype |= OPOISON_KNOWN; + } + + break; + + case OPOISON_SLEEPING: + if (rn2(4) && sleep_monst(mon, rnd(12), POTION_CLASS)) { + pline("%s falls asleep.", Monnam(mon)); + obj->opoistype |= OPOISON_KNOWN; + slept_monst(mon); + } + + break; + + case OPOISON_CONFUSION: + if(rn2(4) && !resist(mon, POTION_CLASS, 0, NOTELL)) { + mon->mconf = TRUE; + obj->opoistype |= OPOISON_KNOWN; + } + break; + + case OPOISON_PARALYSIS: + if (rn2(4) && mon->mcanmove) { + mon->mcanmove = 0; + mon->mfrozen = rnd(25); + obj->opoistype |= OPOISON_KNOWN; + } + break; + } +#endif } if (tmp < 1) { /* make sure that negative damage adjustment can't result diff -Naur nethack-3.4.3/src/vision.c nethack-all/src/vision.c --- nethack-3.4.3/src/vision.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/vision.c 2004-11-13 13:45:54.000000000 +1100 @@ -722,7 +722,14 @@ } else if ((next_row[col] & COULD_SEE) +#ifndef MAGIC_LENSES && (lev->lit || (next_row[col] & TEMP_LIT))) { +#else + && (lev->lit || (next_row[col] & TEMP_LIT)) + /* MRKR: lenses of darkness leave you with only */ + /* night vision. */ + && (!ublindf || ublindf->otyp != LENSES_OF_DARKNESS)) { +#endif /* * We see this position because it is lit. */ diff -Naur nethack-3.4.3/src/zap.c nethack-all/src/zap.c --- nethack-3.4.3/src/zap.c 2003-12-08 10:39:13.000000000 +1100 +++ nethack-all/src/zap.c 2004-11-13 13:47:28.000000000 +1100 @@ -804,6 +804,19 @@ } } +#ifdef CANCEL_DSM +boolean cancellable(obj) +register struct obj *obj; +{ + return objects[obj->otyp].oc_magic + || (obj->spe && (obj->oclass == ARMOR_CLASS || + obj->oclass == WEAPON_CLASS || is_weptool(obj))) + || obj->otyp == POT_ACID + || obj->otyp == POT_SICKNESS; + +} + +#endif /* cancel obj, possibly carried by you or a monster */ void cancel_item(obj) @@ -813,6 +826,12 @@ register boolean holy = (obj->otyp == POT_WATER && obj->blessed); switch(obj->otyp) { +#ifdef MAGIC_LENSES + case LENSES_OF_ACCURACY: + if ((obj->owornmask & W_TOOL) && (obj == ublindf)) + u.uhitinc--; + break; +#endif case RIN_GAIN_STRENGTH: if ((obj->owornmask & W_RING) && u_ring) { ABON(A_STR) -= obj->spe; @@ -831,10 +850,12 @@ flags.botl = 1; } break; +#ifndef MAGIC_LENSES case RIN_INCREASE_ACCURACY: if ((obj->owornmask & W_RING) && u_ring) u.uhitinc -= obj->spe; break; +#endif case RIN_INCREASE_DAMAGE: if ((obj->owornmask & W_RING) && u_ring) u.udaminc -= obj->spe; @@ -854,6 +875,42 @@ break; /* case RIN_PROTECTION: not needed */ } +#ifdef CANCEL_DSM + + + /* MRKR: Cancelled *DSM reverts to scales. */ + /* Suggested by Daniel Morris in RGRN */ + + if (obj->otyp >= GRAY_DRAGON_SCALE_MAIL && + obj->otyp <= YELLOW_DRAGON_SCALE_MAIL) { + /* dragon scale mail reverts to dragon scales */ + + boolean worn = (obj == uarm); + + if (!Blind) { + char buf[BUFSZ]; + pline("%s %s reverts to natural form!", + Shk_Your(buf, obj), xname(obj)); + } + else if (worn) { + Your("armor feels looser."); + } + costly_cancel(obj); + + if (worn) { + setworn((struct obj *)0, W_ARM); + } + + /* assumes same order */ + obj->otyp = GRAY_DRAGON_SCALES + + obj->otyp - GRAY_DRAGON_SCALE_MAIL; + + if (worn) { + setworn(obj, W_ARM); + } + } + +#endif if (objects[obj->otyp].oc_magic || (obj->spe && (obj->oclass == ARMOR_CLASS || obj->oclass == WEAPON_CLASS || is_weptool(obj))) @@ -904,6 +961,9 @@ return; } +#ifdef CANCEL_DSM + +#endif /* Remove a positive enchantment or charge from obj, * possibly carried by you or a monster */ @@ -947,10 +1007,12 @@ flags.botl = 1; } break; +#ifndef MAGIC_LENSES case RIN_INCREASE_ACCURACY: if ((obj->owornmask & W_RING) && u_ring) u.uhitinc--; break; +#endif case RIN_INCREASE_DAMAGE: if ((obj->owornmask & W_RING) && u_ring) u.udaminc--; @@ -1289,8 +1351,16 @@ /* Keep chest/box traps and poisoned ammo if we may */ if (obj->otrapped && Is_box(otmp)) otmp->otrapped = TRUE; +#ifndef POISION_VARIETY if (obj->opoisoned && is_poisonable(otmp)) +#else + if (obj->opoisoned && is_poisonable(otmp)) { +#endif otmp->opoisoned = TRUE; +#ifdef POISION_VARIETY + otmp->opoistype = obj->opoistype; + } +#endif if (id == STRANGE_OBJECT && obj->otyp == CORPSE) { /* turn crocodile corpses into shoes */ @@ -2248,6 +2318,38 @@ find_ac(); } } +#ifdef CANCEL_DSM + else { /* select one random item to cancel */ + struct obj *otmp; + int count = 0; + + for (otmp = (youdefend ? invent : mdef->minvent); + otmp; otmp = otmp->nobj) { + if (cancellable(otmp)) { + count++; + } + } + + if (count > 0) { + int o = rnd(count); + + for (otmp = (youdefend ? invent : mdef->minvent); + otmp; otmp = otmp->nobj) { + if (cancellable(otmp)) { + o--; + if (o == 0) { + cancel_item(otmp); + break; + } + } + } + if (youdefend) { + flags.botl = 1; /* potential AC change */ + find_ac(); + } + } + } +#endif /* now handle special cases */ if (youdefend) {