diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 050615acd..96e9f8179 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1151,6 +1151,9 @@ some monsters (riders, shopkeepers, priests, quest leader) can break boulders corpse-eating monsters will go out of their way to eat corpses on the floor warnings via impossible() would be unseen if message suppression via ESC at --More-- prompt was in effect +wearing the Eyes of the Overworld overrides OPTIONS:blind; breaking the + always-blind conduct by doing that was intended but having permanent + blindness stay cured after removing them was not Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/include/objects.h b/include/objects.h index ddebbc9b2..bc017ba79 100644 --- a/include/objects.h +++ b/include/objects.h @@ -850,10 +850,16 @@ MARKER(LAST_AMULET, AMULET_OF_YENDOR) OBJECT(OBJ(name, desc), \ BITS(kn, 0, chg, 1, mgc, chg, 0, 0, 0, 0, 0, P_NONE, mat), \ 0, TOOL_CLASS, prob, 0, wt, cost, 0, 0, 0, 0, wt, color, sn) -#define WEPTOOL(name,desc,kn,mgc,bi,prob,wt,cost,sdam,ldam,hitbon,sub,mat,clr,sn)\ +#define EYEWEAR(name,desc,kn,prop,prob,wt,cost,mat,color,sn) \ + OBJECT(OBJ(name, desc), \ + BITS(kn, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, P_NONE, mat), \ + prop, TOOL_CLASS, prob, 0, wt, cost, 0, 0, 0, 0, wt, color, sn) +#define WEPTOOL(name,desc,kn,mgc,bi,prob,wt,cost,sdam,ldam,hitbon,sub, \ + mat,clr,sn) \ OBJECT(OBJ(name, desc), \ BITS(kn, 0, 1, 0, mgc, 1, 0, 0, bi, 0, hitbon, sub, mat), \ - 0, TOOL_CLASS, prob, 0, wt, cost, sdam, ldam, hitbon, 0, wt, clr, sn) + 0, TOOL_CLASS, prob, 0, wt, cost, sdam, ldam, hitbon, 0, wt, \ + clr, sn) /* containers */ CONTAINER("large box", NoDes, 1, 0, 0, 40, 350, 8, WOOD, HI_WOOD, LARGE_BOX), @@ -891,17 +897,24 @@ TOOL("magic lamp", "lamp", 0, 0, 1, 0, 15, 20, 50, COPPER, CLR_YELLOW, MAGIC_LAMP), /* other tools */ TOOL("expensive camera", NoDes, 1, 0, 0, 1, 15, 12,200, PLASTIC, CLR_BLACK, - EXPENSIVE_CAMERA), + EXPENSIVE_CAMERA), TOOL("mirror", "looking glass", 0, 0, 0, 0, 45, 13, 10, GLASS, HI_SILVER, MIRROR), TOOL("crystal ball", "glass orb", 0, 0, 1, 1, 15,150, 60, GLASS, HI_GLASS, CRYSTAL_BALL), -TOOL("lenses", NoDes, 1, 0, 0, 0, 5, 3, 80, GLASS, HI_GLASS, +/* eyewear - tools which can be worn on the face; (!mrg, !chg, !mgc) + worn lenses don't confer the Blinded property, blindfolds and towels do; + wet towel can be used as a weapon but is not a weptool and uses obj->spe + differently from weapons and weptools */ +EYEWEAR("lenses", NoDes, 1, 0, 5, 3, 80, GLASS, HI_GLASS, LENSES), -TOOL("blindfold", NoDes, 1, 0, 0, 0, 50, 2, 20, CLOTH, CLR_BLACK, +EYEWEAR("blindfold", NoDes, 1, BLINDED, 50, 2, 20, CLOTH, CLR_BLACK, BLINDFOLD), -TOOL("towel", NoDes, 1, 0, 0, 0, 50, 5, 50, CLOTH, CLR_MAGENTA, +EYEWEAR("towel", NoDes, 1, BLINDED, 50, 2, 50, CLOTH, CLR_MAGENTA, TOWEL), +#undef EYEWEAR + +/* still other tools */ TOOL("saddle", NoDes, 1, 0, 0, 0, 5,200,150, LEATHER, HI_LEATHER, SADDLE), TOOL("leash", NoDes, 1, 0, 0, 0, 65, 12, 20, LEATHER, HI_LEATHER, @@ -1540,7 +1553,7 @@ ROCK("luckstone", "gray", 0, 10, 10, 60, 3, 3, 1, 10, 7, MINERAL, CLR_GRAY, ROCK("loadstone", "gray", 0, 10, 500, 1, 3, 3, 1, 10, 6, MINERAL, CLR_GRAY, LOADSTONE), ROCK("touchstone", "gray", 0, 8, 10, 45, 3, 3, 1, 10, 6, MINERAL, CLR_GRAY, - TOUCHSTONE), + TOUCHSTONE), ROCK("flint", "gray", 0, 10, 10, 1, 6, 6, 0, 10, 7, MINERAL, CLR_GRAY, FLINT), ROCK("rock", NoDes, 1, 100, 10, 0, 3, 3, 0, 10, 7, MINERAL, CLR_GRAY, diff --git a/include/youprop.h b/include/youprop.h index 5301e800d..7ffe08d4a 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -83,20 +83,28 @@ #define HConfusion u.uprops[CONFUSION].intrinsic #define Confusion HConfusion -#define Blinded u.uprops[BLINDED].intrinsic -#define Blindfolded (ublindf && ublindf->otyp != LENSES) -/* ...means blind because of a cover */ -#define Blind \ - ((u.uroleplay.blind || Blinded || Blindfolded \ - || !haseyes(gy.youmonst.data)) \ - && !(ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD)) -/* ...the Eyes operate even when you really are blind - or don't have any eyes */ -#define Blindfolded_only \ - (Blindfolded && ublindf->oartifact != ART_EYES_OF_THE_OVERWORLD \ - && !u.uroleplay.blind && !Blinded && haseyes(gy.youmonst.data)) -/* ...blind because of a blindfold, and *only* that */ +/* Blindness is more complex than other properties */ +#define HBlinded u.uprops[BLINDED].intrinsic /* TIMEOUT|FROMOUTSIDE|FROMFORM */ +#define EBlinded u.uprops[BLINDED].extrinsic /* W_TOOL */ + /* wearing the Eyes of the Overworld overrides blindness */ +#define BBlinded u.uprops[BLINDED].blocked /* W_TOOL */ + /* non-blindfold: timed effect | u.uroleplay.blind | !haseyes() */ +#define Blinded (HBlinded && !BBlinded) +#define BlindedTimeout (HBlinded & TIMEOUT) +#define PermaBlind ((HBlinded & FROMOUTSIDE) != 0L) /* OPTIONS:blind */ + /* worn blindfold (or towel; lenses don't set [BLINDED].extrinsic) */ +#define Blindfolded EBlinded +#define Blindfolded_only (Blindfolded && !Blinded) + /* '#define Blind (Blinded || Blindfolded)' would work, but only + because BBlinded (conferred by artifact lenses) and Blindfolded + are mutually exclusive; explicitly applying !BBlinded to both + internal and external blindness should be more robust in case + of future changes */ +#define Blind ((HBlinded || EBlinded) && !BBlinded) +/* + * Maladies + */ #define Sick u.uprops[SICK].intrinsic #define Stoned u.uprops[STONED].intrinsic #define Strangled u.uprops[STRANGLED].intrinsic diff --git a/src/apply.c b/src/apply.c index 1501ebf0f..b58033728 100644 --- a/src/apply.c +++ b/src/apply.c @@ -122,7 +122,7 @@ use_towel(struct obj *obj) u.ucreamed += rn1(10, 3); pline("Yecch! Your %s %s gunk on it!", body_part(FACE), (old ? "has more" : "now has")); - make_blinded(Blinded + (long) u.ucreamed - old, TRUE); + make_blinded(BlindedTimeout + (long) u.ucreamed - old, TRUE); } else { const char *what; @@ -156,12 +156,12 @@ use_towel(struct obj *obj) dry_a_towel(obj, -1, drying_feedback); return ECMD_TIME; } else if (u.ucreamed) { - Blinded -= u.ucreamed; + incr_itimeout(&HBlinded, -u.ucreamed); u.ucreamed = 0; if (!Blinded) { pline("You've got the glop off."); if (!gulp_blnd_check()) { - Blinded = 1; + set_itimeout(&HBlinded, 1L); make_blinded(0L, TRUE); } } else { @@ -2194,7 +2194,7 @@ use_unicorn_horn(struct obj **optr) xname(obj), TRUE, SICK_NONVOMITABLE); break; case 1: - make_blinded((Blinded & TIMEOUT) + lcount, TRUE); + make_blinded(BlindedTimeout + lcount, TRUE); break; case 2: if (!Confusion) @@ -2235,7 +2235,7 @@ use_unicorn_horn(struct obj **optr) /* collect property troubles */ if (TimedTrouble(Sick)) prop_trouble(SICK); - if (TimedTrouble(Blinded) > (long) u.ucreamed + if (TimedTrouble(Blinded) > (long) u.ucreamed && !PermaBlind && !(u.uswallow && attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND))) prop_trouble(BLINDED); @@ -3435,8 +3435,9 @@ use_cream_pie(struct obj *obj) several ? makeplural(the(xname(obj))) : the(xname(obj))); if (can_blnd((struct monst *) 0, &gy.youmonst, AT_WEAP, obj)) { int blindinc = rnd(25); + u.ucreamed += blindinc; - make_blinded(Blinded + (long) blindinc, FALSE); + make_blinded(BlindedTimeout + (long) blindinc, FALSE); if (!Blind || (Blind && wasblind)) pline("There's %ssticky goop all over your %s.", wascreamed ? "more " : "", body_part(FACE)); diff --git a/src/artifact.c b/src/artifact.c index 7a90b4119..04e219bb2 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1692,6 +1692,14 @@ arti_invoke(struct obj *obj) healamt = (u.mhmax + 1 - u.mh) / 2; if (healamt || Sick || Slimed || Blinded > creamed) You_feel("better."); + if (healamt || Sick || Slimed || BlindedTimeout > creamed) + You_feel("%sbetter.", + (!healamt && !Sick && !Slimed + /* when healing temporary blindness (aside from + goop covering face), might still be blind + due to PermaBlind or eyeless polymorph; + vary the message in that situation */ + && (HBlinded & ~TIMEOUT) != 0L) ? "slightly " : ""); else goto nothing_special; if (healamt > 0) { @@ -1704,7 +1712,7 @@ arti_invoke(struct obj *obj) make_sick(0L, (char *) 0, FALSE, SICK_ALL); if (Slimed) make_slimed(0L, (char *) 0); - if (Blinded > creamed) + if (BlindedTimeout > creamed) make_blinded(creamed, FALSE); gc.context.botl = TRUE; break; diff --git a/src/attrib.c b/src/attrib.c index 5052641f0..b6080602e 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -914,6 +914,11 @@ from_what(int propidx) /* special cases can have negative values */ : ysimple_name(obj)); else if (propidx == BLINDED && Blindfolded_only) Sprintf(buf, because_of, ysimple_name(ublindf)); + else if (propidx == BLINDED && u.ucreamed + && BlindedTimeout == (long) u.ucreamed + && !EBlinded && !(HBlinded & ~TIMEOUT)) + Sprintf(buf, "due to goop coverting your %s", + body_part(FACE)); /* remove some verbosity and/or redundancy */ if ((p = strstri(buf, " pair of ")) != 0) @@ -927,7 +932,8 @@ from_what(int propidx) /* special cases can have negative values */ replace this with what_blocks() comparable to what_gives() */ switch (-propidx) { case BLINDED: - if (is_art(ublindf, ART_EYES_OF_THE_OVERWORLD)) + /* wearing the Eyes of the Overworld overrides blindness */ + if (BBlinded && is_art(ublindf, ART_EYES_OF_THE_OVERWORLD)) Sprintf(buf, because_of, bare_artifactname(ublindf)); break; case INVIS: diff --git a/src/cmd.c b/src/cmd.c index 4f7ce2b28..771ac9b7f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2126,7 +2126,7 @@ wiz_intrinsic(void) oldtimeout ? "increased by" : "set to", amt); break; } - /* this has to be after incr_timeout() */ + /* this has to be after incr_itimeout() */ if (p == LEVITATION || p == FLYING) float_vs_flight(); else if (p == PROT_FROM_SHAPE_CHANGERS) diff --git a/src/detect.c b/src/detect.c index e25a1ca2a..53ffca0dc 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1185,7 +1185,7 @@ use_crystal_ball(struct obj **optr) case 3: if (!resists_blnd(&gy.youmonst)) { pline("%s your vision!", Tobjnam(obj, "damage")); - make_blinded((Blinded & TIMEOUT) + impair, FALSE); + make_blinded(BlindedTimeout + impair, FALSE); if (!Blind) Your1(vision_clears); } else { diff --git a/src/do.c b/src/do.c index ca3c9819f..6de5df6e3 100644 --- a/src/do.c +++ b/src/do.c @@ -2234,19 +2234,21 @@ donull(void) static int wipeoff(void) { - if (u.ucreamed < 4) - u.ucreamed = 0; - else - u.ucreamed -= 4; - if (Blinded < 4) - Blinded = 0; - else - Blinded -= 4; - if (!Blinded) { + unsigned udelta = u.ucreamed; + long ldelta = BlindedTimeout; + + if (udelta > 4) + udelta = 4; + u.ucreamed -= udelta; /*u.ucreamed -= min(u.ucreamed,4);*/ + if (ldelta > 4L) + ldelta = 4L; + incr_itimeout(&HBlinded, -ldelta); /*HBlinded -= min(BlindedTimeout,4L);*/ + + if (!HBlinded) { pline("You've got the glop off."); u.ucreamed = 0; if (!gulp_blnd_check()) { - Blinded = 1; + set_itimeout(&HBlinded, 1L); make_blinded(0L, TRUE); } return 0; diff --git a/src/dothrow.c b/src/dothrow.c index 493f70aa0..be50ce4e8 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1289,7 +1289,7 @@ toss_up(struct obj *obj, boolean hitsroof) if (otyp == BLINDING_VENOM && !Blind) pline("It blinds you!"); u.ucreamed += blindinc; - make_blinded(Blinded + (long) blindinc, FALSE); + make_blinded(BlindedTimeout + (long) blindinc, FALSE); if (!Blind) Your1(vision_clears); } diff --git a/src/eat.c b/src/eat.c index 3224bd95c..854e3797b 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1723,7 +1723,7 @@ rottenfood(struct obj *obj) pline("Everything suddenly goes dark."); /* hero is not Blind, but Blinded timer might be nonzero if blindness is being overridden by the Eyes of the Overworld */ - make_blinded((Blinded & TIMEOUT) + (long) d(2, 10), FALSE); + make_blinded(BlindedTimeout + (long) d(2, 10), FALSE); if (!Blind) Your1(vision_clears); } else if (!rn2(3)) { diff --git a/src/insight.c b/src/insight.c index ef00fca02..456d5e095 100644 --- a/src/insight.c +++ b/src/insight.c @@ -998,17 +998,16 @@ status_enlightenment(int mode, int final) if (Hallucination) you_are("hallucinating", ""); if (Blind) { - /* from_what() (currently wizard-mode only) checks !haseyes() - before u.uroleplay.blind, so we should too */ + /* check the reasons in same order as from_what() */ Sprintf(buf, "%s blind", - !haseyes(gy.youmonst.data) ? "innately" - : u.uroleplay.blind ? "permanently" - /* better phrasing desperately wanted... */ + (HBlinded & FROMOUTSIDE) != 0L ? "permanently" + : (HBlinded & FROMFORM) ? "innately" + /* better phrasing desparately wanted... */ : Blindfolded_only ? "deliberately" + /* timed, possibly combined with blindfold */ : "temporarily"); - if (wizard && (Blinded & TIMEOUT) != 0L - && !u.uroleplay.blind && haseyes(gy.youmonst.data)) - Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT)); + if (wizard && (HBlinded == BlindedTimeout && !Blindfolded)) + Sprintf(eos(buf), " (%ld)", BlindedTimeout); /* !haseyes: avoid "you are innately blind innately" */ you_are(buf, !haseyes(gy.youmonst.data) ? "" : from_what(BLINDED)); } @@ -1493,14 +1492,17 @@ attributes_enlightenment(int unused_mode UNUSED, int final) you_can("recognize detrimental food", ""); /*** Vision and senses ***/ - if (!Blind && (Blinded || !haseyes(gy.youmonst.data))) + if ((HBlinded || EBlinded) && BBlinded) /* blind w/ blindness blocked */ you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */ if (See_invisible) { if (!Blind) enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS)); - else + else if (!PermaBlind) enl_msg(You_, "will see", "would have seen", - " invisible when not blind", from_what(SEE_INVIS)); + " invisible when not blind", ""); + else + enl_msg(You_, "would see", "would have seen", + " invisible if not blind", ""); } if (Blind_telepat) you_are("telepathic", from_what(TELEPAT)); @@ -3177,7 +3179,7 @@ ustatusline(void) if (Blind) { Strcat(info, ", blind"); if (u.ucreamed) { - if ((long) u.ucreamed < Blinded || Blindfolded + if ((long) u.ucreamed < BlindedTimeout || Blindfolded || !haseyes(gy.youmonst.data)) Strcat(info, ", cover"); Strcat(info, "ed by sticky goop"); diff --git a/src/lock.c b/src/lock.c index 45a195fc7..6dc2ac3ea 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1259,7 +1259,7 @@ chest_shatter_msg(struct obj *otmp) { const char *disposition; const char *thing; - long save_Blinded; + long save_HBlinded, save_BBlinded; if (otmp->oclass == POTION_CLASS) { You("%s %s shatter!", Blind ? "hear" : "see", an(bottlename())); @@ -1269,10 +1269,10 @@ chest_shatter_msg(struct obj *otmp) } /* We have functions for distant and singular names, but not one */ /* which does _both_... */ - save_Blinded = Blinded; - Blinded = 1; + save_HBlinded = HBlinded, save_BBlinded = BBlinded; + HBlinded = 1L, BBlinded = 0L; thing = singular(otmp, xname); - Blinded = save_Blinded; + HBlinded = save_HBlinded, BBlinded = save_BBlinded; switch (objects[otmp->otyp].oc_material) { case PAPER: disposition = "is torn to shreds"; diff --git a/src/mhitu.c b/src/mhitu.c index 94371dbfd..f17538a19 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1361,7 +1361,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) Your1(vision_clears); } else /* keep him blind until disgorged */ - make_blinded(Blinded + 1, FALSE); + incr_itimeout(&HBlinded, 1L); } tmp = 0; break; diff --git a/src/mthrowu.c b/src/mthrowu.c index 3dccb9256..8207a2ff8 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -766,7 +766,7 @@ m_throw( if (blindinc) { u.ucreamed += blindinc; - make_blinded(Blinded + (long) blindinc, FALSE); + make_blinded(BlindedTimeout + (long) blindinc, FALSE); if (!Blind) Your1(vision_clears); } diff --git a/src/muse.c b/src/muse.c index d92b1fa23..bf996ac5c 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1759,7 +1759,7 @@ use_offensive(struct monst *mtmp) gm.m_using = TRUE; if (!Blind) { You("are blinded by the flash of light!"); - make_blinded(Blinded + (long) rnd(1 + 50), FALSE); + make_blinded(BlindedTimeout + (long) rnd(1 + 50), FALSE); } lightdamage(otmp, TRUE, 5); gm.m_using = FALSE; diff --git a/src/polyself.c b/src/polyself.c index 583f18e68..34207e6e1 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -102,6 +102,7 @@ set_uasmon(void) PROPSET(PASSES_WALLS, passes_walls(mdat)); PROPSET(REGENERATION, regenerates(mdat)); PROPSET(REFLECTING, (mdat == &mons[PM_SILVER_DRAGON])); + PROPSET(BLINDED, !haseyes(mdat)); #undef PROPSET float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */ @@ -224,7 +225,7 @@ polyman(const char *fmt, const char *arg) set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */ } if (was_blind && !Blind) { /* reverting from eyeless */ - Blinded = 1L; + set_itimeout(&HBlinded, 1L); make_blinded(0L, TRUE); /* remove blindness */ } check_strangling(TRUE); @@ -675,8 +676,7 @@ polyself(int psflags) } } -/* (try to) make a mntmp monster out of the player; - returns 1 if polymorph successful */ +/* (try to) make a mntmp monster out of the player; return 1 if successful */ int polymon(int mntmp) { @@ -839,7 +839,7 @@ polymon(int mntmp) set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */ } if (was_blind && !Blind) { /* previous form was eyeless */ - Blinded = 1L; + set_itimeout(&HBlinded, 1L); make_blinded(0L, TRUE); /* remove blindness */ } newsym(u.ux, u.uy); /* Change symbol */ diff --git a/src/potion.c b/src/potion.c index 91aa6c825..0a0205af0 100644 --- a/src/potion.c +++ b/src/potion.c @@ -54,8 +54,8 @@ itimeout(long val) { if (val >= TIMEOUT) val = TIMEOUT; - else if (val < 1) - val = 0; + else if (val < 1L) + val = 0L; return val; } @@ -257,16 +257,16 @@ static const char eyemsg[] = "%s momentarily %s."; void make_blinded(long xtime, boolean talk) { - long old = Blinded; + long old = BlindedTimeout; boolean u_could_see, can_see_now; const char *eyes; - /* we need to probe ahead in case the Eyes of the Overworld + /* we probe ahead in case the Eyes of the Overworld are or will be overriding blindness */ u_could_see = !Blind; - Blinded = xtime ? 1L : 0L; + set_itimeout(&HBlinded, xtime ? 1L : 0L); can_see_now = !Blind; - Blinded = old; /* restore */ + set_itimeout(&HBlinded, old); if (Unaware) talk = FALSE; @@ -320,7 +320,7 @@ make_blinded(long xtime, boolean talk) } } - set_itimeout(&Blinded, xtime); + set_itimeout(&HBlinded, xtime); if (u_could_see ^ can_see_now) { /* one or the other but not both */ toggle_blindness(); @@ -1048,9 +1048,9 @@ peffect_speed(struct obj *otmp) static void peffect_blindness(struct obj *otmp) { - if (Blind) + if (Blind || ((HBlinded || EBlinded) && BBlinded)) gp.potion_nothing++; - make_blinded(itimeout_incr(Blinded, + make_blinded(itimeout_incr(BlindedTimeout, rn1(200, 250 - 125 * bcsign(otmp))), (boolean) !Blind); } @@ -2037,7 +2037,7 @@ potionbreathe(struct obj *obj) kn++; pline("It suddenly gets dark."); } - make_blinded(itimeout_incr(Blinded, rnd(5)), FALSE); + make_blinded(itimeout_incr(BlindedTimeout, rnd(5)), FALSE); if (!Blind && !Unaware) Your1(vision_clears); break; diff --git a/src/pray.c b/src/pray.c index 64940bf79..63e17d212 100644 --- a/src/pray.c +++ b/src/pray.c @@ -246,7 +246,7 @@ in_trouble(void) return TROUBLE_SADDLE; } - if (Blinded > 1 && haseyes(gy.youmonst.data) + if (BlindedTimeout > 1L && !(HBlinded & ~TIMEOUT) && (!u.uswallow || !attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND))) return TROUBLE_BLIND; diff --git a/src/region.c b/src/region.c index d3905a77c..46bcb27d7 100644 --- a/src/region.c +++ b/src/region.c @@ -1238,7 +1238,7 @@ region_safety(void) pline_The("gas cloud has dissipated."); } /* maybe cure blindness too */ - if ((Blinded & TIMEOUT) == 1L) + if (BlindedTimeout == 1L) make_blinded(0L, TRUE); } diff --git a/src/sit.c b/src/sit.c index cfc6afd70..2dec45bdc 100644 --- a/src/sit.c +++ b/src/sit.c @@ -107,9 +107,9 @@ throne_sit_effect(void) pline("A voice echoes:"); SetVoice((struct monst *) 0, 0, 80, voice_throne); verbalize( - "A curse upon thee for sitting upon this most holy throne!"); + "A curse upon thee for sitting upon this most holy throne!"); if (Luck > 0) { - make_blinded(Blinded + rn1(100, 250), TRUE); + make_blinded(BlindedTimeout + rn1(100, 250), TRUE); change_luck((Luck > 1) ? -rnd(2) : -1); } else rndcurse(); diff --git a/src/spell.c b/src/spell.c index da887aa53..abd8a1f81 100644 --- a/src/spell.c +++ b/src/spell.c @@ -134,7 +134,7 @@ cursed_book(struct obj* bp) aggravate(); break; case 2: - make_blinded(Blinded + rn1(100, 250), TRUE); + make_blinded(BlindedTimeout + rn1(100, 250), TRUE); break; case 3: take_gold(); diff --git a/src/timeout.c b/src/timeout.c index 65caadfea..516788501 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -687,12 +687,15 @@ nh_timeout(void) if (!Stunned) stop_occupation(); break; - case BLINDED: - set_itimeout(&Blinded, 1L); + case BLINDED: { + boolean was_blind = !!Blind; + + set_itimeout(&HBlinded, 1L); make_blinded(0L, TRUE); - if (!Blind) + if (was_blind && !Blind) stop_occupation(); break; + } case DEAF: set_itimeout(&HDeaf, 1L); make_deaf(0L, TRUE); diff --git a/src/u_init.c b/src/u_init.c index 59698c614..da653e3c1 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -676,6 +676,12 @@ u_init(void) */ u.nv_range = 1; u.xray_range = -1; + /* OPTIONS:blind results in permanent blindness (unless overridden + by the Eyes of the Overworld, which will clear 'u.uroleplay.blind' + to void the conduct, but will leave the PermaBlind bit set so that + blindness resumes when the Eyes are removed). */ + if (u.uroleplay.blind) + HBlinded |= FROMOUTSIDE; /* set PermaBlind */ /*** Role-specific initializations ***/ switch (Role_switch) { diff --git a/src/uhitm.c b/src/uhitm.c index 9cac3da4e..68b3b519d 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2773,7 +2773,7 @@ mhitm_ad_blnd( if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { if (!Blind) pline("%s blinds you!", Monnam(magr)); - make_blinded(Blinded + (long) mhm->damage, FALSE); + make_blinded(BlindedTimeout + (long) mhm->damage, FALSE); if (!Blind) /* => Eyes of the Overworld */ Your1(vision_clears); } diff --git a/src/worn.c b/src/worn.c index 4bb8b0bfc..f09ea5374 100644 --- a/src/worn.c +++ b/src/worn.c @@ -37,7 +37,9 @@ const struct worn { ((o->otyp == MUMMY_WRAPPING && ((m) & W_ARMC) != 0L) ? INVIS \ : (o->otyp == CORNUTHAUM && ((m) & W_ARMH) != 0L \ && !Role_if(PM_WIZARD)) ? CLAIRVOYANT \ - : 0) + : (is_art(o, ART_EYES_OF_THE_OVERWORLD) \ + && ((m) & W_TOOL) != 0L) ? BLINDED \ + : 0) /* note: monsters don't have clairvoyance, so dependency on hero's role here has no significant effect on their use of w_blocks() */ @@ -1178,4 +1180,7 @@ extract_from_minvent( mwepgone(mon); /* unwields and sets weapon_check to NEED_WEAPON */ } } + +#undef w_blocks + /*worn.c*/