diff -Nwaur nethack-3.4.1/include/mkroom.h nethack-lenses/include/mkroom.h --- nethack-3.4.1/include/mkroom.h 2003-02-24 01:43:21.000000000 +1100 +++ nethack-lenses/include/mkroom.h 2003-08-11 18:09:44.000000000 +1000 @@ -30,7 +30,7 @@ struct itp { int iprob; /* probability of an item type */ int itype; /* item type: if >=0 a class, if < 0 a specific item */ - } iprobs[5]; + } iprobs[11]; const char * const *shknms; /* list of shopkeeper names for this type */ }; diff -Nwaur nethack-3.4.1/include/obj.h nethack-lenses/include/obj.h --- nethack-3.4.1/include/obj.h 2003-02-24 01:43:21.000000000 +1100 +++ nethack-lenses/include/obj.h 2003-08-11 17:44:51.000000000 +1000 @@ -274,6 +274,14 @@ #define is_flimsy(otmp) (objects[(otmp)->otyp].oc_material <= LEATHER) #endif +#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) + /* helpers, simple enough to be macros */ #define is_plural(o) ((o)->quan > 1 || \ (o)->oartifact == ART_EYES_OF_THE_OVERWORLD) diff -Nwaur nethack-3.4.1/include/youprop.h nethack-lenses/include/youprop.h --- nethack-3.4.1/include/youprop.h 2003-02-24 01:43:24.000000000 +1100 +++ nethack-lenses/include/youprop.h 2003-08-11 17:44:51.000000000 +1000 @@ -94,7 +94,7 @@ #define Confusion HConfusion #define Blinded u.uprops[BLINDED].intrinsic -#define Blindfolded (ublindf && ublindf->otyp != LENSES) +#define Blindfolded (ublindf && !is_lenses(ublindf)) /* ...means blind because of a cover */ #define Blind ((Blinded || Blindfolded || !haseyes(youmonst.data)) && \ !(ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD)) diff -Nwaur nethack-3.4.1/src/CHANGES nethack-lenses/src/CHANGES --- nethack-3.4.1/src/CHANGES 1970-01-01 10:00:00.000000000 +1000 +++ nethack-lenses/src/CHANGES 2003-08-11 17:44:51.000000000 +1000 @@ -0,0 +1,90 @@ + +* objects.c + + Added six new lens types: searching, warning, see invisible, + increase_accuracy, infravision, darkness + Probability deducted from blindfolds, towels and leashes. + Ordinary lenses are retained, but prob = 0. This is so that the + Eyes of the Overworld can be based on them. + + Removed rings of searching, warning, see invis, inc accuracy + Probability redistributed evenly. + +* obj.h + + Addeed is_lenses() macro. + +* apply.c detect.c do_wear.c dothrow.c invent.c objnam.c pray.c spell.c + + replaces LENSES with new names/macro + +* do.c eat.c zap.c do_wear.c + + removed old rings + +* o_init.c + + Rings do not have assigned probabilities. Instead they are + set in o_init.c. I changed this so that nameless rings were + assigned zero probability. + +* do_wear.c + + Changed so that vision is recalculated whenever lenses are + put on or taken off. Taking off lenses of infravision also + requires calling see_monsters() again. + + Ideally this should be generalised so that whenever a vision- + related extrinsic is activated/deactivated, the appropriate + calls are made. + +* vision.c + + Lenses of darkness limit your vision to night-vision only. + There is still a bug - light pools remain around doors. (Fixed) + +* eat.c + + Magic lenses cause hunger at the same rate as rings. + +* display.c + + Fixed light pool problem. + +* mkobj.c + + Lenses of darkness are created cursed. + Lenses of accuracy are created with a charge. + +* o_init.c + + Shuffle lens descriptions. + +* detect.c + + Lenses are no longer helpful for searching + (except lenses of searching, of course). + +* spell.c + + Different lens types have different effects on your + ability to read spellbooks. + +* mondata.c + + Lenses of darkness protect against blindness attacks. + +* u_init.c + + Wizards sometimes get a pair of lenses instead of a + ring in their starting kit. + +* shknam.c mkroom.h + + Jewelers now stock lenses. + +* objnam.c + + You can't tell what tint your lenses are if you're blind. + (Except by dropping them and looking at the glyph + - what a dead give-away.) \ No newline at end of file diff -Nwaur nethack-3.4.1/src/apply.c nethack-lenses/src/apply.c --- nethack-3.4.1/src/apply.c 2003-02-24 01:43:24.000000000 +1100 +++ nethack-lenses/src/apply.c 2003-08-11 17:44:51.000000000 +1000 @@ -115,7 +115,7 @@ (old ? "has more" : "now has")); make_blinded(Blinded + (long)u.ucreamed - old, TRUE); } else { - const char *what = (ublindf->otyp == LENSES) ? + const char *what = is_lenses(ublindf) ? "lenses" : "blindfold"; if (ublindf->cursed) { You("push your %s %s.", what, @@ -2738,6 +2738,12 @@ switch(obj->otyp){ case BLINDFOLD: case 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: if (obj == ublindf) { if (!cursed(obj)) Blindf_off(obj); } else if (!ublindf) diff -Nwaur nethack-3.4.1/src/detect.c nethack-lenses/src/detect.c --- nethack-3.4.1/src/detect.c 2003-02-24 01:43:25.000000000 +1100 +++ nethack-lenses/src/detect.c 2003-08-11 17:44:51.000000000 +1000 @@ -1151,8 +1151,11 @@ int fund = (uwep && uwep->oartifact && spec_ability(uwep, SPFX_SEARCH)) ? uwep->spe : 0; - if (ublindf && ublindf->otyp == LENSES && !Blind) +#if 0 + /* MRKR: Lenses now have other uses */ + if (ublindf && is_lenses(ublindf) && !Blind) fund += 2; /* JDS: lenses help searching */ +#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 -Nwaur nethack-3.4.1/src/display.c nethack-lenses/src/display.c --- nethack-3.4.1/src/display.c 2003-02-24 01:43:25.000000000 +1100 +++ nethack-lenses/src/display.c 2003-08-11 17:44:51.000000000 +1000 @@ -663,7 +663,12 @@ * Perhaps ALL areas should revert to their "unlit" look when * out of sight. */ - lev->waslit = (lev->lit!=0); /* remember lit condition */ + + /* remember lit condition */ + /* MRKR: Lenses of darkess make all areas appear dark */ + + lev->waslit = (lev->lit != 0) && + (!ublindf || ublindf->otyp != LENSES_OF_DARKNESS); if (reg != NULL && ACCESSIBLE(lev->typ)) { show_region(reg,x,y); diff -Nwaur nethack-3.4.1/src/do.c nethack-lenses/src/do.c --- nethack-3.4.1/src/do.c 2003-02-24 01:43:25.000000000 +1100 +++ nethack-lenses/src/do.c 2003-08-11 17:45:38.000000000 +1000 @@ -257,10 +257,6 @@ 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 */ - case RIN_SEARCHING: - You("thought your %s got lost in the sink, but there it is!", - xname(obj)); - goto giveback; case RIN_SLOW_DIGESTION: pline_The("ring is regurgitated!"); giveback: @@ -294,10 +290,6 @@ pline_The("water flow seems %ser now.", (obj->spe<0) ? "less" : "great"); break; - case RIN_INCREASE_ACCURACY: /* KMH */ - pline_The("water flow %s the drain.", - (obj->spe<0) ? "misses" : "hits"); - break; case RIN_INCREASE_DAMAGE: pline_The("water's force seems %ser now.", (obj->spe<0) ? "small" : "great"); @@ -340,9 +332,6 @@ case RIN_FREE_ACTION: You("see the ring slide right down the drain!"); break; - case RIN_SEE_INVISIBLE: - You("see some air in the sink."); - break; case RIN_STEALTH: pline_The("sink seems to blend into the floor for a moment."); break; @@ -359,9 +348,6 @@ pline_The("sink glows %s for a moment.", hcolor((obj->spe<0) ? NH_BLACK : NH_SILVER)); break; - case RIN_WARNING: - pline_The("sink glows %s for a moment.", hcolor(NH_WHITE)); - break; case RIN_TELEPORTATION: pline_The("sink momentarily vanishes."); break; diff -Nwaur nethack-3.4.1/src/do_wear.c nethack-lenses/src/do_wear.c --- nethack-3.4.1/src/do_wear.c 2003-02-24 01:43:26.000000000 +1100 +++ nethack-lenses/src/do_wear.c 2003-08-11 17:51:23.000000000 +1000 @@ -648,7 +648,6 @@ switch(obj->otyp){ case RIN_TELEPORTATION: case RIN_REGENERATION: - case RIN_SEARCHING: case RIN_STEALTH: case RIN_HUNGER: case RIN_AGGRAVATE_MONSTER: @@ -665,24 +664,6 @@ case RIN_SUSTAIN_ABILITY: case MEAT_RING: break; - case RIN_WARNING: - see_monsters(); - break; - case RIN_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(RIN_SEE_INVISIBLE); - } - break; case RIN_INVISIBILITY: if (!oldprop && !HInvis && !BInvis && !Blind) { makeknown(RIN_INVISIBILITY); @@ -717,9 +698,6 @@ update_inventory(); } break; - case RIN_INCREASE_ACCURACY: /* KMH */ - u.uhitinc += obj->spe; - break; case RIN_INCREASE_DAMAGE: u.udaminc += obj->spe; break; @@ -753,7 +731,6 @@ switch(obj->otyp) { case RIN_TELEPORTATION: case RIN_REGENERATION: - case RIN_SEARCHING: case RIN_STEALTH: case RIN_HUNGER: case RIN_AGGRAVATE_MONSTER: @@ -770,25 +747,6 @@ case RIN_SUSTAIN_ABILITY: case MEAT_RING: break; - case RIN_WARNING: - see_monsters(); - break; - case RIN_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(RIN_SEE_INVISIBLE); - } - break; case RIN_INVISIBILITY: if (!Invis && !BInvis && !Blind) { newsym(u.ux,u.uy); @@ -819,9 +777,6 @@ update_inventory(); } break; - case RIN_INCREASE_ACCURACY: /* KMH */ - u.uhitinc -= obj->spe; - break; case RIN_INCREASE_DAMAGE: u.udaminc -= obj->spe; break; @@ -839,6 +794,7 @@ */ restartcham(); break; + } } @@ -861,6 +817,7 @@ register struct obj *otmp; { boolean already_blind = Blind, changed = FALSE; + long oldprop = u.uprops[objects[otmp->otyp].oc_oprop].extrinsic; if (otmp == uwep) setuwep((struct obj *) 0); @@ -881,6 +838,47 @@ /* "You are now wearing the Eyes of the Overworld." */ You("can see!"); } + + 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; + } + if (changed) { /* blindness has just been toggled */ if (Blind_telepat || Infravision) see_monsters(); @@ -894,6 +892,7 @@ register struct obj *otmp; { boolean was_blind = Blind, changed = FALSE; + long oldprop = u.uprops[objects[otmp->otyp].oc_oprop].extrinsic; setworn((struct obj *)0, otmp->owornmask); off_msg(otmp); @@ -902,7 +901,7 @@ if (was_blind) { /* "still cannot see" makes no sense when removing lenses since they can't have been the cause of your blindness */ - if (otmp->otyp != LENSES) + if (is_lenses(otmp)) You("still cannot see."); } else { changed = TRUE; /* !was_blind */ @@ -915,9 +914,43 @@ changed = TRUE; /* !Blind */ You("can see again."); } + 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; + } + if (changed) { /* blindness has just been toggled */ - if (Blind_telepat || Infravision) see_monsters(); + if (Blind_telepat || Infravision + || otmp->otyp == LENSES_OF_INFRAVISION) see_monsters(); vision_full_recalc = 1; /* recalc vision limits */ flags.botl = 1; } @@ -1082,7 +1115,8 @@ /* Curses, like chickens, come home to roost. */ if((otmp == uwep) ? welded(otmp) : (int)otmp->cursed) { You("can't. %s cursed.", - (is_boots(otmp) || is_gloves(otmp) || otmp->quan > 1L) + (is_boots(otmp) || is_gloves(otmp) || + is_lenses(otmp) ||otmp->quan > 1L) ? "They are" : "It is"); otmp->bknown = TRUE; return(1); @@ -1380,7 +1414,7 @@ Your("%s%s are full, and you're already wearing an amulet and %s.", humanoid(youmonst.data) ? "ring-" : "", makeplural(body_part(FINGER)), - ublindf->otyp==LENSES ? "some lenses" : "a blindfold"); + is_lenses(ublindf) ? "some lenses" : "a blindfold"); return(0); } otmp = getobj(accessories, "put on"); @@ -1467,11 +1501,11 @@ Your("%s is already covered by a towel.", body_part(FACE)); else if (ublindf->otyp == BLINDFOLD) { - if (otmp->otyp == LENSES) + if (is_lenses(otmp)) already_wearing2("lenses", "a blindfold"); else already_wearing("a blindfold"); - } else if (ublindf->otyp == LENSES) { + } else if (is_lenses(ublindf)) { if (otmp->otyp == BLINDFOLD) already_wearing2("a blindfold", "some lenses"); else @@ -1480,7 +1514,8 @@ already_wearing(something); /* ??? */ return(0); } - if (otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL && otmp->otyp != LENSES) { + if (otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL + && !is_lenses(otmp)) { You_cant("wear that!"); return(0); } diff -Nwaur nethack-3.4.1/src/dothrow.c nethack-lenses/src/dothrow.c --- nethack-3.4.1/src/dothrow.c 2003-02-24 01:43:26.000000000 +1100 +++ nethack-lenses/src/dothrow.c 2003-08-11 17:44:51.000000000 +1000 @@ -1626,6 +1626,12 @@ impossible("breaking odd object?"); case CRYSTAL_PLATE_MAIL: case 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: case MIRROR: case CRYSTAL_BALL: #ifdef TOURIST diff -Nwaur nethack-3.4.1/src/eat.c nethack-lenses/src/eat.c --- nethack-3.4.1/src/eat.c 2003-02-24 01:43:26.000000000 +1100 +++ nethack-lenses/src/eat.c 2003-08-11 17:52:41.000000000 +1000 @@ -1459,16 +1459,6 @@ u.uprops[objects[typ].oc_oprop].intrinsic |= FROMOUTSIDE; switch (typ) { - case RIN_SEE_INVISIBLE: - set_mimic_blocking(); - see_monsters(); - if (Invis && !oldprop && !ESee_invisible && - !perceives(youmonst.data) && !Blind) { - newsym(u.ux,u.uy); - pline("Suddenly you can see yourself."); - makeknown(typ); - } - break; case RIN_INVISIBILITY: if (!oldprop && !EInvis && !BInvis && !See_invisible && !Blind) { @@ -1507,10 +1497,6 @@ if (adjattrib(A_CON, otmp->spe, -1)) makeknown(typ); break; - case RIN_INCREASE_ACCURACY: - accessory_has_effect(otmp); - u.uhitinc += otmp->spe; - break; case RIN_INCREASE_DAMAGE: accessory_has_effect(otmp); u.udaminc += otmp->spe; @@ -2105,6 +2091,13 @@ /* +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 */ + case 0: + if (ublindf && is_lenses(ublindf) + && objects[ublindf->otyp].oc_magic) { + /* MRKR: magic lenses cause hunger */ + u.uhunger--; + } + break; case 4: if (uleft && (uleft->spe || !objects[uleft->otyp].oc_charged)) u.uhunger--; diff -Nwaur nethack-3.4.1/src/invent.c nethack-lenses/src/invent.c --- nethack-3.4.1/src/invent.c 2003-02-24 01:43:27.000000000 +1100 +++ nethack-lenses/src/invent.c 2003-08-11 17:44:51.000000000 +1000 @@ -846,7 +846,7 @@ else if ((putting_on(word) && ((otmp->oclass == FOOD_CLASS && otmp->otyp != MEAT_RING) || (otmp->oclass == TOOL_CLASS && - otyp != BLINDFOLD && otyp != TOWEL && otyp != LENSES))) + otyp != BLINDFOLD && otyp != TOWEL && !is_lenses(otmp)))) || (!strcmp(word, "wield") && (otmp->oclass == TOOL_CLASS && !is_weptool(otmp))) || (!strcmp(word, "eat") && !is_edible(otmp)) diff -Nwaur nethack-3.4.1/src/mkobj.c nethack-lenses/src/mkobj.c --- nethack-3.4.1/src/mkobj.c 2003-02-24 01:43:28.000000000 +1100 +++ nethack-lenses/src/mkobj.c 2003-08-11 17:44:51.000000000 +1000 @@ -498,6 +498,25 @@ case CAN_OF_GREASE: otmp->spe = rnd(25); blessorcurse(otmp, 10); break; + 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; case CRYSTAL_BALL: otmp->spe = rnd(5); blessorcurse(otmp, 2); break; diff -Nwaur nethack-3.4.1/src/mondata.c nethack-lenses/src/mondata.c --- nethack-3.4.1/src/mondata.c 2003-02-24 01:43:28.000000000 +1100 +++ nethack-lenses/src/mondata.c 2003-08-11 17:44:51.000000000 +1000 @@ -108,7 +108,8 @@ boolean is_you = (mon == &youmonst); struct obj *o; - if (is_you ? (Blind || u.usleep) : + if (is_you ? (Blind || u.usleep || + (ublindf && ublindf->otyp == LENSES_OF_DARKNESS)) : (mon->mblinded || !mon->mcansee || !haseyes(ptr) || /* BUG: temporary sleep sets mfrozen, but since paralysis does too, we can't check it */ @@ -161,7 +162,7 @@ if (is_you && Blindfolded) return FALSE; } else if (obj && (obj->otyp == BLINDING_VENOM)) { - /* all ublindf, including LENSES, protect, cream-pies too */ + /* all ublindf, including lenses, protect, cream-pies too */ if (is_you && (ublindf || u.ucreamed)) return FALSE; check_visor = TRUE; @@ -181,7 +182,7 @@ break; case AT_CLAW: - /* e.g. raven: all ublindf, including LENSES, protect */ + /* e.g. raven: all ublindf, including lenses, protect */ if (is_you && ublindf) return FALSE; if ((magr == &youmonst) && u.uswallow) diff -Nwaur nethack-3.4.1/src/o_init.c nethack-lenses/src/o_init.c --- nethack-3.4.1/src/o_init.c 2003-02-24 01:43:28.000000000 +1100 +++ nethack-lenses/src/o_init.c 2003-08-11 17:44:51.000000000 +1000 @@ -161,8 +161,16 @@ sum = 0; for(i = first; i < last; i++) sum += objects[i].oc_prob; if(sum == 0) { + int named_cnt = 0; + /* MRKR: unnamed things get probability zero */ for(i = first; i < last; i++) - objects[i].oc_prob = (1000+i-first)/(last-first); + 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; + goto check; } if(sum != 1000) @@ -223,6 +231,9 @@ /* shuffle the boots [if they change, update find_skates() below] */ shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE); + + /* shuffle the lenses */ + shuffle(LENSES_OF_SEARCHING, LENSES_OF_DARKNESS, FALSE); } /* find the object index for snow boots; used [once] by slippery ice code */ diff -Nwaur nethack-3.4.1/src/objects.c nethack-lenses/src/objects.c --- nethack-3.4.1/src/objects.c 2003-02-24 01:43:28.000000000 +1100 +++ nethack-lenses/src/objects.c 2003-08-11 17:44:51.000000000 +1000 @@ -499,12 +499,10 @@ 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), -RING("increase accuracy", 0, "clay", 150, 1, 1, 4, MINERAL, CLR_RED), 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), -RING("searching", SEARCHING, "tiger eye", 200, 1, 0, 6, GEMSTONE, CLR_BROWN), 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 +511,6 @@ RING("aggravate monster", AGGRAVATE_MONSTER, "sapphire", 150, 1, 0, 9, GEMSTONE, CLR_BLUE), RING("conflict", CONFLICT, "ruby", 300, 1, 0, 9, GEMSTONE, CLR_RED), -RING("warning", WARNING, "diamond", 100, 1, 0,10, GEMSTONE, CLR_WHITE), 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 +528,26 @@ 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), -RING("see invisible", SEE_INVIS, "engagement", - 150, 1, 0, 5, IRON, HI_METAL), RING("protection from shape changers", PROT_FROM_SHAPE_CHANGERS, "shiny", 100, 1, 0, 5, IRON, CLR_BRIGHT_CYAN), +/* + * MRKR: Rings turned into lenses: + * increase accuracy, searching, warning, see invisible + */ + +#if 0 +RING("increase accuracy", 0, "clay", 150, 1, 1, 4, MINERAL, CLR_RED), +RING("searching", SEARCHING, "tiger eye", 200, 1, 0, 6, GEMSTONE, CLR_BROWN), +RING("warning", WARNING, "diamond", 100, 1, 0,10, GEMSTONE, CLR_WHITE), +RING("see invisible", SEE_INVIS, "engagement", + 150, 1, 0, 5, IRON, HI_METAL), +#endif + +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), + #undef RING /* amulets ... - THE Amulet comes last because it is special */ @@ -567,6 +580,11 @@ 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 ) +#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 ) #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 +629,27 @@ #endif TOOL("crystal ball", "glass orb", 0, 0, 1, 1, 15,150, 60, GLASS, HI_GLASS), -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), +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), #ifdef STEED TOOL("saddle", (char *)0, 1, 0, 0, 0, 5,200, 150, LEATHER, HI_LEATHER), -TOOL("leash", (char *)0, 1, 0, 0, 0, 65, 12, 20, LEATHER, HI_LEATHER), +TOOL("leash", (char *)0, 1, 0, 0, 0, 60, 12, 20, LEATHER, HI_LEATHER), #else -TOOL("leash", (char *)0, 1, 0, 0, 0, 70, 12, 20, LEATHER, HI_LEATHER), +TOOL("leash", (char *)0, 1, 0, 0, 0, 65, 12, 20, LEATHER, HI_LEATHER), #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), diff -Nwaur nethack-3.4.1/src/objnam.c nethack-lenses/src/objnam.c --- nethack-3.4.1/src/objnam.c 2003-02-24 01:43:28.000000000 +1100 +++ nethack-lenses/src/objnam.c 2003-08-11 17:44:51.000000000 +1000 @@ -3,9 +3,8 @@ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" - -/* "an uncursed greased partly eaten guardian naga hatchling [corpse]" */ -#define PREFIX 80 /* (56) */ +/* "an uncursed greased pair of lenses of see invisible (being worn)" */ +#define PREFIX 80 /* (64) */ #define SCHAR_LIM 127 #define NUMOBUF 12 @@ -278,10 +277,13 @@ Strcpy(buf, "poisoned "); case VENOM_CLASS: case TOOL_CLASS: - if (typ == LENSES) + if (is_lenses(obj)) Strcpy(buf, "pair of "); if (!obj->dknown) + if (is_lenses(obj)) + Strcat(buf, "lenses"); + else Strcat(buf, dn ? dn : actualn); else if (nn) Strcat(buf, actualn); @@ -602,7 +604,8 @@ Strcat(prefix, "blessed "); else if ((!obj->known || !objects[obj->otyp].oc_charged || (obj->oclass == ARMOR_CLASS || - obj->oclass == RING_CLASS)) + obj->oclass == RING_CLASS || + is_lenses(obj))) /* 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, @@ -654,13 +657,12 @@ #endif )) { Strcat(bp, " (being worn)"); - break; } if (obj->otyp == LEASH && obj->leashmon != 0) { Strcat(bp, " (in use)"); break; } - if (is_weptool(obj)) + if (is_weptool(obj) || obj->otyp == LENSES_OF_ACCURACY) goto plus; if (obj->otyp == CANDELABRUM_OF_INVOCATION) { if (!obj->spe) @@ -1476,7 +1478,8 @@ /* but don't singularize "gauntlets", "boots", "Eyes of the.." */ if (BSTRNCMPI(bp, p-3, "Eye", 3) && BSTRNCMP(bp, p-4, "boot", 4) && - BSTRNCMP(bp, p-8, "gauntlet", 8)) + BSTRNCMP(bp, p-8, "gauntlet", 8) && + BSTRNCMP(bp, p-5, "lense", 5)) while ((*p = *(p+1)) != 0) p++; return bp; } @@ -2058,6 +2061,7 @@ register int j = strlen(wrp[i]); if(!strncmpi(bp, wrp[i], j)){ oclass = wrpsym[i]; + if(oclass != AMULET_CLASS) { bp += j; if(!strncmpi(bp, " of ", 4)) actualn = bp+4; @@ -2124,6 +2128,7 @@ } } } + i = oclass ? bases[(int)oclass] : 1; while(i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)){ register const char *zn; diff -Nwaur nethack-3.4.1/src/shknam.c nethack-lenses/src/shknam.c --- nethack-3.4.1/src/shknam.c 2003-02-24 01:43:30.000000000 +1100 +++ nethack-lenses/src/shknam.c 2003-08-11 17:44:51.000000000 +1000 @@ -110,7 +110,7 @@ "Htargcm", "Enrobwem", "Kachzi Rellim", "Regien", "Donmyar", "Yelpur", "Nosnehpets", "Stewe", "Renrut", "_Zlaw", "Nosalnef", "Rewuorb", "Rellenk", "Yad", "Cire Htims", "Y-crad", "Nenilukah", - "Corsh", "Aned", + "Corsh", "Aned", "Nayr", #ifdef OVERLAY "Erreip", "Nehpets", "Mron", "Snivek", "Lapu", "Kahztiy", #endif @@ -196,7 +196,11 @@ {{83, FOOD_CLASS}, {5, -POT_FRUIT_JUICE}, {4, -POT_BOOZE}, {5, -POT_WATER}, {3, -ICE_BOX}}, shkfoods}, {"jewelers", RING_CLASS, 3, D_SHOP, - {{85, RING_CLASS}, {10, GEM_CLASS}, {5, AMULET_CLASS}, {0, 0}}, + {{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}}, shkrings}, {"quality apparel and accessories", WAND_CLASS, 3, D_SHOP, {{90, WAND_CLASS}, {5, -LEATHER_GLOVES}, {5, -ELVEN_CLOAK}, {0, 0}}, diff -Nwaur nethack-3.4.1/src/spell.c nethack-lenses/src/spell.c --- nethack-3.4.1/src/spell.c 2003-02-24 01:43:30.000000000 +1100 +++ nethack-lenses/src/spell.c 2003-08-11 17:54:40.000000000 +1000 @@ -321,7 +321,34 @@ boolean costly = TRUE; /* JDS: lenses give 50% faster reading; 33% smaller read time */ - if (delay && ublindf && ublindf->otyp == LENSES && rn2(2)) delay++; + /* 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; + } + } if (Confusion) { /* became confused while learning */ (void) confused_book(book); book = 0; /* no longer studying */ @@ -439,8 +466,23 @@ } else { /* uncursed - chance to fail */ int read_ability = ACURR(A_INT) + 4 + u.ulevel/2 - - 2*objects[booktype].oc_level - + ((ublindf && ublindf->otyp == LENSES) ? 2 : 0); + - 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); /* only wizards know if a spell is too difficult */ if (Role_if(PM_WIZARD) && read_ability < 20 && !confused) { diff -Nwaur nethack-3.4.1/src/u_init.c nethack-lenses/src/u_init.c --- nethack-3.4.1/src/u_init.c 2003-02-24 01:43:31.000000000 +1100 +++ nethack-lenses/src/u_init.c 2003-08-11 17:44:51.000000000 +1000 @@ -163,7 +163,7 @@ { 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 }, - { UNDEF_TYP, UNDEF_SPE, RING_CLASS, 2, UNDEF_BLESS }, +/* { UNDEF_TYP, UNDEF_SPE, RING_CLASS, 2, UNDEF_BLESS }, */ { 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 +175,20 @@ * Optional extra inventory items. */ +/* 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 } +}; + static struct trobj Tinopener[] = { { TIN_OPENER, 0, TOOL_CLASS, 1, 0 }, { 0, 0, 0, 0, 0 } @@ -725,6 +739,29 @@ break; case PM_WIZARD: ini_inv(Wizard); + /* 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); + } if(!rn2(5)) ini_inv(Magicmarker); if(!rn2(5)) ini_inv(Blindfold); skill_init(Skill_W); diff -Nwaur nethack-3.4.1/src/vision.c nethack-lenses/src/vision.c --- nethack-3.4.1/src/vision.c 2003-02-24 01:43:31.000000000 +1100 +++ nethack-lenses/src/vision.c 2003-08-11 17:44:51.000000000 +1000 @@ -722,7 +722,10 @@ } else if ((next_row[col] & COULD_SEE) - && (lev->lit || (next_row[col] & TEMP_LIT))) { + && (lev->lit || (next_row[col] & TEMP_LIT)) + /* MRKR: lenses of darkness leave you with only */ + /* night vision. */ + && (!ublindf || ublindf->otyp != LENSES_OF_DARKNESS)) { /* * We see this position because it is lit. */ diff -Nwaur nethack-3.4.1/src/zap.c nethack-lenses/src/zap.c --- nethack-3.4.1/src/zap.c 2003-02-24 01:43:32.000000000 +1100 +++ nethack-lenses/src/zap.c 2003-08-11 17:44:51.000000000 +1000 @@ -807,6 +807,10 @@ register boolean holy = (obj->otyp == POT_WATER && obj->blessed); switch(obj->otyp) { + case LENSES_OF_ACCURACY: + if ((obj->owornmask & W_TOOL) && (obj == ublindf)) + u.uhitinc--; + break; case RIN_GAIN_STRENGTH: if ((obj->owornmask & W_RING) && u_ring) { ABON(A_STR) -= obj->spe; @@ -825,10 +829,6 @@ flags.botl = 1; } break; - case RIN_INCREASE_ACCURACY: - if ((obj->owornmask & W_RING) && u_ring) - u.uhitinc -= obj->spe; - break; case RIN_INCREASE_DAMAGE: if ((obj->owornmask & W_RING) && u_ring) u.udaminc -= obj->spe; @@ -941,10 +941,6 @@ flags.botl = 1; } break; - case RIN_INCREASE_ACCURACY: - if ((obj->owornmask & W_RING) && u_ring) - u.uhitinc--; - break; case RIN_INCREASE_DAMAGE: if ((obj->owornmask & W_RING) && u_ring) u.udaminc--;