]> granicus.if.org Git - nethack/commitdiff
more buglist crystal ball detection
authornethack.allison <nethack.allison>
Mon, 20 Oct 2003 03:46:43 +0000 (03:46 +0000)
committernethack.allison <nethack.allison>
Mon, 20 Oct 2003 03:46:43 +0000 (03:46 +0000)
<Someone> 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
src/detect.c
src/drawing.c
src/options.c

index 6b80d81e37efeae2b1ec5e0459981bcea6e3f5e7..6c995ced4b6e6c1d9772fd9f71ccf629826e6f6f 100644 (file)
@@ -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
index 7be5fa66219e1e16363c2ae321e3665e85ec8c85..9f6b5682239ea96706b5e9e2b1793449161f15be 100644 (file)
@@ -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);
index 005a611c23b8888134ed492d791d5518946f1d06..d926b8a7810ed62f3decb784c1afcde2e87aeb7e 100644 (file)
@@ -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)
index b1ab8811173c72eb02921905340a36aa26106683..651581a8fcfbf7c00af381e677262eb534c4ceff 100644 (file)
@@ -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;
        }