blindness overhaul

I was working on this at the time 3.6.0 was released and set it aside
until later.  Later has finally arrived.  Redo the Blind, Blinded,
Blindfolded,&c macros to make more complete use of intrinsic property
handling.  Blinded was being treated as a number which could be added
to or subtracted from; now that has to be done via TIMEOUT mask
because it has FROMOUTSIDE (OPTIONS:blind) and FROMFORM (poly'd into
!haseyes() form) bits included.  Object definitions for blindfold and
towel now specify the BLINDED property; overriding blindness via the
Eyes of the Overworld is accomplished via props[BLINDED].blocked.

Code generated for the scores of Blind and !Blind tests throughout
the program should be smaller.

One bug that has been fixed is that putting on the Eyes of the
Overworld cured permanent blindness (from OPTIONS:blind).  The
u.uroleplay.blind flag was cleared and stayed so after taking them
off.  Putting the Eyes on still breaks blind-from-birth conduct but
now blindness will resume when they are removed.

This was untested at the time it was set aside and is only lightly
tested now.  A large number of the changes here are just to switch
from Blinded to BlindedTimeout for current timed value and to call
set_itimeout() for setting a new value.
This commit is contained in:
PatR
2023-04-27 14:53:28 -07:00
parent 57ff993352
commit 1c94bdac89
26 changed files with 142 additions and 85 deletions
+3
View File
@@ -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 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 warnings via impossible() would be unseen if message suppression via ESC at
--More-- prompt was in effect --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 Fixes to 3.7.0-x General Problems Exposed Via git Repository
+20 -7
View File
@@ -850,10 +850,16 @@ MARKER(LAST_AMULET, AMULET_OF_YENDOR)
OBJECT(OBJ(name, desc), \ OBJECT(OBJ(name, desc), \
BITS(kn, 0, chg, 1, mgc, chg, 0, 0, 0, 0, 0, P_NONE, mat), \ 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) 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), \ OBJECT(OBJ(name, desc), \
BITS(kn, 0, 1, 0, mgc, 1, 0, 0, bi, 0, hitbon, sub, mat), \ 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 */ /* containers */
CONTAINER("large box", NoDes, 1, 0, 0, 40, 350, 8, WOOD, HI_WOOD, CONTAINER("large box", NoDes, 1, 0, 0, 40, 350, 8, WOOD, HI_WOOD,
LARGE_BOX), LARGE_BOX),
@@ -891,17 +897,24 @@ TOOL("magic lamp", "lamp", 0, 0, 1, 0, 15, 20, 50, COPPER, CLR_YELLOW,
MAGIC_LAMP), MAGIC_LAMP),
/* other tools */ /* other tools */
TOOL("expensive camera", NoDes, 1, 0, 0, 1, 15, 12,200, PLASTIC, CLR_BLACK, 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, TOOL("mirror", "looking glass", 0, 0, 0, 0, 45, 13, 10, GLASS, HI_SILVER,
MIRROR), MIRROR),
TOOL("crystal ball", "glass orb", 0, 0, 1, 1, 15,150, 60, GLASS, HI_GLASS, TOOL("crystal ball", "glass orb", 0, 0, 1, 1, 15,150, 60, GLASS, HI_GLASS,
CRYSTAL_BALL), 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), 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), 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), TOWEL),
#undef EYEWEAR
/* still other tools */
TOOL("saddle", NoDes, 1, 0, 0, 0, 5,200,150, LEATHER, HI_LEATHER, TOOL("saddle", NoDes, 1, 0, 0, 0, 5,200,150, LEATHER, HI_LEATHER,
SADDLE), SADDLE),
TOOL("leash", NoDes, 1, 0, 0, 0, 65, 12, 20, LEATHER, HI_LEATHER, 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, ROCK("loadstone", "gray", 0, 10, 500, 1, 3, 3, 1, 10, 6, MINERAL, CLR_GRAY,
LOADSTONE), LOADSTONE),
ROCK("touchstone", "gray", 0, 8, 10, 45, 3, 3, 1, 10, 6, MINERAL, CLR_GRAY, 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, ROCK("flint", "gray", 0, 10, 10, 1, 6, 6, 0, 10, 7, MINERAL, CLR_GRAY,
FLINT), FLINT),
ROCK("rock", NoDes, 1, 100, 10, 0, 3, 3, 0, 10, 7, MINERAL, CLR_GRAY, ROCK("rock", NoDes, 1, 100, 10, 0, 3, 3, 0, 10, 7, MINERAL, CLR_GRAY,
+21 -13
View File
@@ -83,20 +83,28 @@
#define HConfusion u.uprops[CONFUSION].intrinsic #define HConfusion u.uprops[CONFUSION].intrinsic
#define Confusion HConfusion #define Confusion HConfusion
#define Blinded u.uprops[BLINDED].intrinsic /* Blindness is more complex than other properties */
#define Blindfolded (ublindf && ublindf->otyp != LENSES) #define HBlinded u.uprops[BLINDED].intrinsic /* TIMEOUT|FROMOUTSIDE|FROMFORM */
/* ...means blind because of a cover */ #define EBlinded u.uprops[BLINDED].extrinsic /* W_TOOL */
#define Blind \ /* wearing the Eyes of the Overworld overrides blindness */
((u.uroleplay.blind || Blinded || Blindfolded \ #define BBlinded u.uprops[BLINDED].blocked /* W_TOOL */
|| !haseyes(gy.youmonst.data)) \ /* non-blindfold: timed effect | u.uroleplay.blind | !haseyes() */
&& !(ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD)) #define Blinded (HBlinded && !BBlinded)
/* ...the Eyes operate even when you really are blind #define BlindedTimeout (HBlinded & TIMEOUT)
or don't have any eyes */ #define PermaBlind ((HBlinded & FROMOUTSIDE) != 0L) /* OPTIONS:blind */
#define Blindfolded_only \ /* worn blindfold (or towel; lenses don't set [BLINDED].extrinsic) */
(Blindfolded && ublindf->oartifact != ART_EYES_OF_THE_OVERWORLD \ #define Blindfolded EBlinded
&& !u.uroleplay.blind && !Blinded && haseyes(gy.youmonst.data)) #define Blindfolded_only (Blindfolded && !Blinded)
/* ...blind because of a blindfold, and *only* that */ /* '#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 Sick u.uprops[SICK].intrinsic
#define Stoned u.uprops[STONED].intrinsic #define Stoned u.uprops[STONED].intrinsic
#define Strangled u.uprops[STRANGLED].intrinsic #define Strangled u.uprops[STRANGLED].intrinsic
+7 -6
View File
@@ -122,7 +122,7 @@ use_towel(struct obj *obj)
u.ucreamed += rn1(10, 3); u.ucreamed += rn1(10, 3);
pline("Yecch! Your %s %s gunk on it!", body_part(FACE), pline("Yecch! Your %s %s gunk on it!", body_part(FACE),
(old ? "has more" : "now has")); (old ? "has more" : "now has"));
make_blinded(Blinded + (long) u.ucreamed - old, TRUE); make_blinded(BlindedTimeout + (long) u.ucreamed - old, TRUE);
} else { } else {
const char *what; const char *what;
@@ -156,12 +156,12 @@ use_towel(struct obj *obj)
dry_a_towel(obj, -1, drying_feedback); dry_a_towel(obj, -1, drying_feedback);
return ECMD_TIME; return ECMD_TIME;
} else if (u.ucreamed) { } else if (u.ucreamed) {
Blinded -= u.ucreamed; incr_itimeout(&HBlinded, -u.ucreamed);
u.ucreamed = 0; u.ucreamed = 0;
if (!Blinded) { if (!Blinded) {
pline("You've got the glop off."); pline("You've got the glop off.");
if (!gulp_blnd_check()) { if (!gulp_blnd_check()) {
Blinded = 1; set_itimeout(&HBlinded, 1L);
make_blinded(0L, TRUE); make_blinded(0L, TRUE);
} }
} else { } else {
@@ -2194,7 +2194,7 @@ use_unicorn_horn(struct obj **optr)
xname(obj), TRUE, SICK_NONVOMITABLE); xname(obj), TRUE, SICK_NONVOMITABLE);
break; break;
case 1: case 1:
make_blinded((Blinded & TIMEOUT) + lcount, TRUE); make_blinded(BlindedTimeout + lcount, TRUE);
break; break;
case 2: case 2:
if (!Confusion) if (!Confusion)
@@ -2235,7 +2235,7 @@ use_unicorn_horn(struct obj **optr)
/* collect property troubles */ /* collect property troubles */
if (TimedTrouble(Sick)) if (TimedTrouble(Sick))
prop_trouble(SICK); prop_trouble(SICK);
if (TimedTrouble(Blinded) > (long) u.ucreamed if (TimedTrouble(Blinded) > (long) u.ucreamed && !PermaBlind
&& !(u.uswallow && !(u.uswallow
&& attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND))) && attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND)))
prop_trouble(BLINDED); prop_trouble(BLINDED);
@@ -3435,8 +3435,9 @@ use_cream_pie(struct obj *obj)
several ? makeplural(the(xname(obj))) : the(xname(obj))); several ? makeplural(the(xname(obj))) : the(xname(obj)));
if (can_blnd((struct monst *) 0, &gy.youmonst, AT_WEAP, obj)) { if (can_blnd((struct monst *) 0, &gy.youmonst, AT_WEAP, obj)) {
int blindinc = rnd(25); int blindinc = rnd(25);
u.ucreamed += blindinc; u.ucreamed += blindinc;
make_blinded(Blinded + (long) blindinc, FALSE); make_blinded(BlindedTimeout + (long) blindinc, FALSE);
if (!Blind || (Blind && wasblind)) if (!Blind || (Blind && wasblind))
pline("There's %ssticky goop all over your %s.", pline("There's %ssticky goop all over your %s.",
wascreamed ? "more " : "", body_part(FACE)); wascreamed ? "more " : "", body_part(FACE));
+9 -1
View File
@@ -1692,6 +1692,14 @@ arti_invoke(struct obj *obj)
healamt = (u.mhmax + 1 - u.mh) / 2; healamt = (u.mhmax + 1 - u.mh) / 2;
if (healamt || Sick || Slimed || Blinded > creamed) if (healamt || Sick || Slimed || Blinded > creamed)
You_feel("better."); 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 else
goto nothing_special; goto nothing_special;
if (healamt > 0) { if (healamt > 0) {
@@ -1704,7 +1712,7 @@ arti_invoke(struct obj *obj)
make_sick(0L, (char *) 0, FALSE, SICK_ALL); make_sick(0L, (char *) 0, FALSE, SICK_ALL);
if (Slimed) if (Slimed)
make_slimed(0L, (char *) 0); make_slimed(0L, (char *) 0);
if (Blinded > creamed) if (BlindedTimeout > creamed)
make_blinded(creamed, FALSE); make_blinded(creamed, FALSE);
gc.context.botl = TRUE; gc.context.botl = TRUE;
break; break;
+7 -1
View File
@@ -914,6 +914,11 @@ from_what(int propidx) /* special cases can have negative values */
: ysimple_name(obj)); : ysimple_name(obj));
else if (propidx == BLINDED && Blindfolded_only) else if (propidx == BLINDED && Blindfolded_only)
Sprintf(buf, because_of, ysimple_name(ublindf)); 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 */ /* remove some verbosity and/or redundancy */
if ((p = strstri(buf, " pair of ")) != 0) 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() */ replace this with what_blocks() comparable to what_gives() */
switch (-propidx) { switch (-propidx) {
case BLINDED: 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)); Sprintf(buf, because_of, bare_artifactname(ublindf));
break; break;
case INVIS: case INVIS:
+1 -1
View File
@@ -2126,7 +2126,7 @@ wiz_intrinsic(void)
oldtimeout ? "increased by" : "set to", amt); oldtimeout ? "increased by" : "set to", amt);
break; break;
} }
/* this has to be after incr_timeout() */ /* this has to be after incr_itimeout() */
if (p == LEVITATION || p == FLYING) if (p == LEVITATION || p == FLYING)
float_vs_flight(); float_vs_flight();
else if (p == PROT_FROM_SHAPE_CHANGERS) else if (p == PROT_FROM_SHAPE_CHANGERS)
+1 -1
View File
@@ -1185,7 +1185,7 @@ use_crystal_ball(struct obj **optr)
case 3: case 3:
if (!resists_blnd(&gy.youmonst)) { if (!resists_blnd(&gy.youmonst)) {
pline("%s your vision!", Tobjnam(obj, "damage")); pline("%s your vision!", Tobjnam(obj, "damage"));
make_blinded((Blinded & TIMEOUT) + impair, FALSE); make_blinded(BlindedTimeout + impair, FALSE);
if (!Blind) if (!Blind)
Your1(vision_clears); Your1(vision_clears);
} else { } else {
+12 -10
View File
@@ -2234,19 +2234,21 @@ donull(void)
static int static int
wipeoff(void) wipeoff(void)
{ {
if (u.ucreamed < 4) unsigned udelta = u.ucreamed;
u.ucreamed = 0; long ldelta = BlindedTimeout;
else
u.ucreamed -= 4; if (udelta > 4)
if (Blinded < 4) udelta = 4;
Blinded = 0; u.ucreamed -= udelta; /*u.ucreamed -= min(u.ucreamed,4);*/
else if (ldelta > 4L)
Blinded -= 4; ldelta = 4L;
if (!Blinded) { incr_itimeout(&HBlinded, -ldelta); /*HBlinded -= min(BlindedTimeout,4L);*/
if (!HBlinded) {
pline("You've got the glop off."); pline("You've got the glop off.");
u.ucreamed = 0; u.ucreamed = 0;
if (!gulp_blnd_check()) { if (!gulp_blnd_check()) {
Blinded = 1; set_itimeout(&HBlinded, 1L);
make_blinded(0L, TRUE); make_blinded(0L, TRUE);
} }
return 0; return 0;
+1 -1
View File
@@ -1289,7 +1289,7 @@ toss_up(struct obj *obj, boolean hitsroof)
if (otyp == BLINDING_VENOM && !Blind) if (otyp == BLINDING_VENOM && !Blind)
pline("It blinds you!"); pline("It blinds you!");
u.ucreamed += blindinc; u.ucreamed += blindinc;
make_blinded(Blinded + (long) blindinc, FALSE); make_blinded(BlindedTimeout + (long) blindinc, FALSE);
if (!Blind) if (!Blind)
Your1(vision_clears); Your1(vision_clears);
} }
+1 -1
View File
@@ -1723,7 +1723,7 @@ rottenfood(struct obj *obj)
pline("Everything suddenly goes dark."); pline("Everything suddenly goes dark.");
/* hero is not Blind, but Blinded timer might be nonzero if /* hero is not Blind, but Blinded timer might be nonzero if
blindness is being overridden by the Eyes of the Overworld */ 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) if (!Blind)
Your1(vision_clears); Your1(vision_clears);
} else if (!rn2(3)) { } else if (!rn2(3)) {
+14 -12
View File
@@ -998,17 +998,16 @@ status_enlightenment(int mode, int final)
if (Hallucination) if (Hallucination)
you_are("hallucinating", ""); you_are("hallucinating", "");
if (Blind) { if (Blind) {
/* from_what() (currently wizard-mode only) checks !haseyes() /* check the reasons in same order as from_what() */
before u.uroleplay.blind, so we should too */
Sprintf(buf, "%s blind", Sprintf(buf, "%s blind",
!haseyes(gy.youmonst.data) ? "innately" (HBlinded & FROMOUTSIDE) != 0L ? "permanently"
: u.uroleplay.blind ? "permanently" : (HBlinded & FROMFORM) ? "innately"
/* better phrasing desperately wanted... */ /* better phrasing desparately wanted... */
: Blindfolded_only ? "deliberately" : Blindfolded_only ? "deliberately"
/* timed, possibly combined with blindfold */
: "temporarily"); : "temporarily");
if (wizard && (Blinded & TIMEOUT) != 0L if (wizard && (HBlinded == BlindedTimeout && !Blindfolded))
&& !u.uroleplay.blind && haseyes(gy.youmonst.data)) Sprintf(eos(buf), " (%ld)", BlindedTimeout);
Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT));
/* !haseyes: avoid "you are innately blind innately" */ /* !haseyes: avoid "you are innately blind innately" */
you_are(buf, !haseyes(gy.youmonst.data) ? "" : from_what(BLINDED)); 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", ""); you_can("recognize detrimental food", "");
/*** Vision and senses ***/ /*** 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 */ you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */
if (See_invisible) { if (See_invisible) {
if (!Blind) if (!Blind)
enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS)); enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS));
else else if (!PermaBlind)
enl_msg(You_, "will see", "would have seen", 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) if (Blind_telepat)
you_are("telepathic", from_what(TELEPAT)); you_are("telepathic", from_what(TELEPAT));
@@ -3177,7 +3179,7 @@ ustatusline(void)
if (Blind) { if (Blind) {
Strcat(info, ", blind"); Strcat(info, ", blind");
if (u.ucreamed) { if (u.ucreamed) {
if ((long) u.ucreamed < Blinded || Blindfolded if ((long) u.ucreamed < BlindedTimeout || Blindfolded
|| !haseyes(gy.youmonst.data)) || !haseyes(gy.youmonst.data))
Strcat(info, ", cover"); Strcat(info, ", cover");
Strcat(info, "ed by sticky goop"); Strcat(info, "ed by sticky goop");
+4 -4
View File
@@ -1259,7 +1259,7 @@ chest_shatter_msg(struct obj *otmp)
{ {
const char *disposition; const char *disposition;
const char *thing; const char *thing;
long save_Blinded; long save_HBlinded, save_BBlinded;
if (otmp->oclass == POTION_CLASS) { if (otmp->oclass == POTION_CLASS) {
You("%s %s shatter!", Blind ? "hear" : "see", an(bottlename())); 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 */ /* We have functions for distant and singular names, but not one */
/* which does _both_... */ /* which does _both_... */
save_Blinded = Blinded; save_HBlinded = HBlinded, save_BBlinded = BBlinded;
Blinded = 1; HBlinded = 1L, BBlinded = 0L;
thing = singular(otmp, xname); thing = singular(otmp, xname);
Blinded = save_Blinded; HBlinded = save_HBlinded, BBlinded = save_BBlinded;
switch (objects[otmp->otyp].oc_material) { switch (objects[otmp->otyp].oc_material) {
case PAPER: case PAPER:
disposition = "is torn to shreds"; disposition = "is torn to shreds";
+1 -1
View File
@@ -1361,7 +1361,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
Your1(vision_clears); Your1(vision_clears);
} else } else
/* keep him blind until disgorged */ /* keep him blind until disgorged */
make_blinded(Blinded + 1, FALSE); incr_itimeout(&HBlinded, 1L);
} }
tmp = 0; tmp = 0;
break; break;
+1 -1
View File
@@ -766,7 +766,7 @@ m_throw(
if (blindinc) { if (blindinc) {
u.ucreamed += blindinc; u.ucreamed += blindinc;
make_blinded(Blinded + (long) blindinc, FALSE); make_blinded(BlindedTimeout + (long) blindinc, FALSE);
if (!Blind) if (!Blind)
Your1(vision_clears); Your1(vision_clears);
} }
+1 -1
View File
@@ -1759,7 +1759,7 @@ use_offensive(struct monst *mtmp)
gm.m_using = TRUE; gm.m_using = TRUE;
if (!Blind) { if (!Blind) {
You("are blinded by the flash of light!"); 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); lightdamage(otmp, TRUE, 5);
gm.m_using = FALSE; gm.m_using = FALSE;
+4 -4
View File
@@ -102,6 +102,7 @@ set_uasmon(void)
PROPSET(PASSES_WALLS, passes_walls(mdat)); PROPSET(PASSES_WALLS, passes_walls(mdat));
PROPSET(REGENERATION, regenerates(mdat)); PROPSET(REGENERATION, regenerates(mdat));
PROPSET(REFLECTING, (mdat == &mons[PM_SILVER_DRAGON])); PROPSET(REFLECTING, (mdat == &mons[PM_SILVER_DRAGON]));
PROPSET(BLINDED, !haseyes(mdat));
#undef PROPSET #undef PROPSET
float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */ 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 */ set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */
} }
if (was_blind && !Blind) { /* reverting from eyeless */ if (was_blind && !Blind) { /* reverting from eyeless */
Blinded = 1L; set_itimeout(&HBlinded, 1L);
make_blinded(0L, TRUE); /* remove blindness */ make_blinded(0L, TRUE); /* remove blindness */
} }
check_strangling(TRUE); check_strangling(TRUE);
@@ -675,8 +676,7 @@ polyself(int psflags)
} }
} }
/* (try to) make a mntmp monster out of the player; /* (try to) make a mntmp monster out of the player; return 1 if successful */
returns 1 if polymorph successful */
int int
polymon(int mntmp) polymon(int mntmp)
{ {
@@ -839,7 +839,7 @@ polymon(int mntmp)
set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */ set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */
} }
if (was_blind && !Blind) { /* previous form was eyeless */ if (was_blind && !Blind) { /* previous form was eyeless */
Blinded = 1L; set_itimeout(&HBlinded, 1L);
make_blinded(0L, TRUE); /* remove blindness */ make_blinded(0L, TRUE); /* remove blindness */
} }
newsym(u.ux, u.uy); /* Change symbol */ newsym(u.ux, u.uy); /* Change symbol */
+10 -10
View File
@@ -54,8 +54,8 @@ itimeout(long val)
{ {
if (val >= TIMEOUT) if (val >= TIMEOUT)
val = TIMEOUT; val = TIMEOUT;
else if (val < 1) else if (val < 1L)
val = 0; val = 0L;
return val; return val;
} }
@@ -257,16 +257,16 @@ static const char eyemsg[] = "%s momentarily %s.";
void void
make_blinded(long xtime, boolean talk) make_blinded(long xtime, boolean talk)
{ {
long old = Blinded; long old = BlindedTimeout;
boolean u_could_see, can_see_now; boolean u_could_see, can_see_now;
const char *eyes; 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 */ are or will be overriding blindness */
u_could_see = !Blind; u_could_see = !Blind;
Blinded = xtime ? 1L : 0L; set_itimeout(&HBlinded, xtime ? 1L : 0L);
can_see_now = !Blind; can_see_now = !Blind;
Blinded = old; /* restore */ set_itimeout(&HBlinded, old);
if (Unaware) if (Unaware)
talk = FALSE; 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 */ if (u_could_see ^ can_see_now) { /* one or the other but not both */
toggle_blindness(); toggle_blindness();
@@ -1048,9 +1048,9 @@ peffect_speed(struct obj *otmp)
static void static void
peffect_blindness(struct obj *otmp) peffect_blindness(struct obj *otmp)
{ {
if (Blind) if (Blind || ((HBlinded || EBlinded) && BBlinded))
gp.potion_nothing++; gp.potion_nothing++;
make_blinded(itimeout_incr(Blinded, make_blinded(itimeout_incr(BlindedTimeout,
rn1(200, 250 - 125 * bcsign(otmp))), rn1(200, 250 - 125 * bcsign(otmp))),
(boolean) !Blind); (boolean) !Blind);
} }
@@ -2037,7 +2037,7 @@ potionbreathe(struct obj *obj)
kn++; kn++;
pline("It suddenly gets dark."); pline("It suddenly gets dark.");
} }
make_blinded(itimeout_incr(Blinded, rnd(5)), FALSE); make_blinded(itimeout_incr(BlindedTimeout, rnd(5)), FALSE);
if (!Blind && !Unaware) if (!Blind && !Unaware)
Your1(vision_clears); Your1(vision_clears);
break; break;
+1 -1
View File
@@ -246,7 +246,7 @@ in_trouble(void)
return TROUBLE_SADDLE; return TROUBLE_SADDLE;
} }
if (Blinded > 1 && haseyes(gy.youmonst.data) if (BlindedTimeout > 1L && !(HBlinded & ~TIMEOUT)
&& (!u.uswallow && (!u.uswallow
|| !attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND))) || !attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND)))
return TROUBLE_BLIND; return TROUBLE_BLIND;
+1 -1
View File
@@ -1238,7 +1238,7 @@ region_safety(void)
pline_The("gas cloud has dissipated."); pline_The("gas cloud has dissipated.");
} }
/* maybe cure blindness too */ /* maybe cure blindness too */
if ((Blinded & TIMEOUT) == 1L) if (BlindedTimeout == 1L)
make_blinded(0L, TRUE); make_blinded(0L, TRUE);
} }
+2 -2
View File
@@ -107,9 +107,9 @@ throne_sit_effect(void)
pline("A voice echoes:"); pline("A voice echoes:");
SetVoice((struct monst *) 0, 0, 80, voice_throne); SetVoice((struct monst *) 0, 0, 80, voice_throne);
verbalize( 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) { if (Luck > 0) {
make_blinded(Blinded + rn1(100, 250), TRUE); make_blinded(BlindedTimeout + rn1(100, 250), TRUE);
change_luck((Luck > 1) ? -rnd(2) : -1); change_luck((Luck > 1) ? -rnd(2) : -1);
} else } else
rndcurse(); rndcurse();
+1 -1
View File
@@ -134,7 +134,7 @@ cursed_book(struct obj* bp)
aggravate(); aggravate();
break; break;
case 2: case 2:
make_blinded(Blinded + rn1(100, 250), TRUE); make_blinded(BlindedTimeout + rn1(100, 250), TRUE);
break; break;
case 3: case 3:
take_gold(); take_gold();
+6 -3
View File
@@ -687,12 +687,15 @@ nh_timeout(void)
if (!Stunned) if (!Stunned)
stop_occupation(); stop_occupation();
break; break;
case BLINDED: case BLINDED: {
set_itimeout(&Blinded, 1L); boolean was_blind = !!Blind;
set_itimeout(&HBlinded, 1L);
make_blinded(0L, TRUE); make_blinded(0L, TRUE);
if (!Blind) if (was_blind && !Blind)
stop_occupation(); stop_occupation();
break; break;
}
case DEAF: case DEAF:
set_itimeout(&HDeaf, 1L); set_itimeout(&HDeaf, 1L);
make_deaf(0L, TRUE); make_deaf(0L, TRUE);
+6
View File
@@ -676,6 +676,12 @@ u_init(void)
*/ */
u.nv_range = 1; u.nv_range = 1;
u.xray_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 ***/ /*** Role-specific initializations ***/
switch (Role_switch) { switch (Role_switch) {
+1 -1
View File
@@ -2773,7 +2773,7 @@ mhitm_ad_blnd(
if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) {
if (!Blind) if (!Blind)
pline("%s blinds you!", Monnam(magr)); 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 */ if (!Blind) /* => Eyes of the Overworld */
Your1(vision_clears); Your1(vision_clears);
} }
+6 -1
View File
@@ -37,7 +37,9 @@ const struct worn {
((o->otyp == MUMMY_WRAPPING && ((m) & W_ARMC) != 0L) ? INVIS \ ((o->otyp == MUMMY_WRAPPING && ((m) & W_ARMC) != 0L) ? INVIS \
: (o->otyp == CORNUTHAUM && ((m) & W_ARMH) != 0L \ : (o->otyp == CORNUTHAUM && ((m) & W_ARMH) != 0L \
&& !Role_if(PM_WIZARD)) ? CLAIRVOYANT \ && !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 /* note: monsters don't have clairvoyance, so dependency on hero's role here
has no significant effect on their use of w_blocks() */ 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 */ mwepgone(mon); /* unwields and sets weapon_check to NEED_WEAPON */
} }
} }
#undef w_blocks
/*worn.c*/ /*worn.c*/