From 98678f603711f8744ee4860ed100df0794f382bf Mon Sep 17 00:00:00 2001 From: "nethack.allison" Date: Mon, 20 Oct 2003 03:46:43 +0000 Subject: [PATCH] more buglist crystal ball detection wrote: - If I set the 'boulder' option, shouldn't I be able to give the symbol I define for them at the crystal ball "object or monster symbol" prompt and have it work? - Could ']' be added as a synonym for 'm', as with genocide? - set boulder symbol to '3'; use '/' or ';' to examine a boulder. Result is "unknown creature causing you disquiet co-located with a boulder" even though there's no warning glyph '3' there. --- doc/fixes34.3 | 3 +++ src/detect.c | 39 ++++++++++++++++++++++++++++++--------- src/drawing.c | 4 ++-- src/options.c | 22 +++++++++++++++++----- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/doc/fixes34.3 b/doc/fixes34.3 index 6b80d81e3..6c995ced4 100644 --- a/doc/fixes34.3 +++ b/doc/fixes34.3 @@ -58,6 +58,9 @@ you could specifiy '~' with crystal ball and have it try to detect monsters, allow a crystal ball to detect ghosts-and-shades via space key, and display the results using detected_mon_to_glyph() so that they show up in inverse video +allow a crystal ball to detect boulders using the user-defined boulder symbol +allow a crystal ball to detect mimics via ']' +prevent boulder option from accepting a symbol that matches a monster symbol Platform- and/or Interface-Specific Fixes diff --git a/src/detect.c b/src/detect.c index 7be5fa662..9f6b56822 100644 --- a/src/detect.c +++ b/src/detect.c @@ -402,6 +402,7 @@ struct obj *detector; /* object doing the detecting */ int class; /* an object class, 0 for all */ { register int x, y; + char stuff[BUFSZ]; int is_cursed = (detector && detector->cursed); int do_dknown = (detector && (detector->oclass == POTION_CLASS || detector->oclass == SPBOOK_CLASS) && @@ -410,22 +411,33 @@ int class; /* an object class, 0 for all */ register struct obj *obj, *otmp = (struct obj *)0; register struct monst *mtmp; int uw = u.uinwater; - const char *stuff; + int sym, boulder = 0; if (class < 0 || class >= MAXOCLASSES) { impossible("object_detect: illegal class %d", class); class = 0; } + /* Special boulder symbol check - does the class symbol happen + * to match iflags.bouldersym which is a user-defined? + * If so, that means we aren't sure what they really wanted to + * detect. Rather than trump anything, show both possibilities. + * We can exclude checking the buried obj chain for boulders below. + */ + sym = class ? def_oc_syms[class] : 0; + if (sym && iflags.bouldersym && sym == iflags.bouldersym) + boulder = ROCK_CLASS; + if (Hallucination || (Confusion && class == SCROLL_CLASS)) - stuff = something; + Strcpy(stuff, something); else - stuff = class ? oclass_names[class] : "objects"; + Strcpy(stuff, class ? oclass_names[class] : "objects"); + if (boulder && class != ROCK_CLASS) Strcat(stuff, " and/or large stones"); if (do_dknown) for(obj = invent; obj; obj = obj->nobj) do_dknown_of(obj); for (obj = fobj; obj; obj = obj->nobj) { - if (!class || o_in(obj, class)) { + if ((!class && !boulder) || o_in(obj, class) || o_in(obj, boulder)) { if (obj->ox == u.ux && obj->oy == u.uy) ctu++; else ct++; } @@ -443,7 +455,7 @@ int class; /* an object class, 0 for all */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if (DEADMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) { - if (!class || o_in(obj, class)) ct++; + if ((!class && !boulder) || o_in(obj, class) || o_in(obj, boulder)) ct++; if (do_dknown) do_dknown_of(obj); } if ((is_cursed && mtmp->m_ap_type == M_AP_OBJECT && @@ -497,8 +509,9 @@ int class; /* an object class, 0 for all */ for (x = 1; x < COLNO; x++) for (y = 0; y < ROWNO; y++) for (obj = level.objects[x][y]; obj; obj = obj->nexthere) - if (!class || (otmp = o_in(obj, class))) { - if (class) { + if ((!class && !boulder) || + (otmp = o_in(obj, class)) || (otmp = o_in(obj, boulder))) { + if (class || boulder) { if (otmp != obj) { otmp->ox = obj->ox; otmp->oy = obj->oy; @@ -513,8 +526,9 @@ int class; /* an object class, 0 for all */ for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon) { if (DEADMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) - if (!class || (otmp = o_in(obj, class))) { - if (!class) otmp = obj; + if ((!class && !boulder) || + (otmp = o_in(obj, class)) || (otmp = o_in(obj, boulder))) { + if (!class && !boulder) otmp = obj; otmp->ox = mtmp->mx; /* at monster location */ otmp->oy = mtmp->my; map_object(otmp, 1); @@ -858,10 +872,17 @@ struct obj *obj; makeknown(CRYSTAL_BALL); consume_obj_charge(obj, TRUE); + /* special case: accept ']' as synonym for mimic + * we have to do this before the def_char_to_objclass check + */ + if (ch == DEF_MIMIC_DEF) ch = DEF_MIMIC; + if ((class = def_char_to_objclass(ch)) != MAXOCLASSES) ret = object_detect((struct obj *)0, class); else if ((class = def_char_to_monclass(ch)) != MAXMCLASSES) ret = monster_detect((struct obj *)0, class); + else if (iflags.bouldersym && (ch == iflags.bouldersym)) + ret = object_detect((struct obj *)0, ROCK_CLASS); else switch(ch) { case '^': ret = trap_detect((struct obj *)0); diff --git a/src/drawing.c b/src/drawing.c index 005a611c2..d926b8a78 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -612,8 +612,8 @@ void NDECL((*ascgraphics_mode_callback)) = 0; /* set in tty_start_screen() */ /* * Convert the given character to an object class. If the character is not - * recognized, then MAXOCLASSES is returned. Used in invent.c, options.c, - * pickup.c, sp_lev.c, and lev_main.c. + * recognized, then MAXOCLASSES is returned. Used in detect.c invent.c, + * options.c, pickup.c, sp_lev.c, and lev_main.c. */ int def_char_to_objclass(ch) diff --git a/src/options.c b/src/options.c index b1ab88111..651581a8f 100644 --- a/src/options.c +++ b/src/options.c @@ -1448,6 +1448,7 @@ goodfruit: /* boulder:symbol */ fullname = "boulder"; if (match_optname(opts, fullname, 7, TRUE)) { + int clash = 0; if (negated) { bad_negation(fullname, FALSE); return; @@ -1456,11 +1457,22 @@ goodfruit: if (!(opts = string_for_opt(opts, FALSE))) return; escapes(opts, opts); - - /* - * Override the default boulder symbol. - */ - iflags.bouldersym = (uchar) opts[0]; + if (def_char_to_monclass(opts[0]) != MAXMCLASSES) + clash = 1; + else if (opts[0] >= '1' && opts[0] <= '5') + clash = 2; + if (clash) { + /* symbol chosen matches a used monster or warning + symbol which is not good - reject it*/ + pline( + "Badoption - boulder symbol '%c' conflicts with a %s symbol.", + opts[0], (clash == 1) ? "monster" : "warning"); + } else { + /* + * Override the default boulder symbol. + */ + iflags.bouldersym = (uchar) opts[0]; + } if (!initial) need_redraw = TRUE; return; } -- 2.40.0