]> granicus.if.org Git - nethack/commitdiff
using #name to call a floor object
authorPatR <rankin@nethack.org>
Fri, 29 May 2015 09:07:50 +0000 (02:07 -0700)
committerPatR <rankin@nethack.org>
Fri, 29 May 2015 09:07:50 +0000 (02:07 -0700)
Implement Boudewijn's suggestion that #name be extended to allow naming
something of the floor.  I'm sure he wants this so that he can avoid
picking up gray stones, but it's something I started to implement years
ago (probably at an earlier suggestion from him...) and then forgot all
about.

This changes the #name menu to be
   m - a monster
   i - a particular object in inventory
   o - the type of an object in inventory
   f - the type of an object upon the floor
   d - the type of an object on discoveries list
   a - record an annotation for the current level
   What do you want to name?
with the i and o choices omitted when inventory is empty.  If the
'lootabc' option is set it will use a through f instead, but then the
last three entries change letters when inventory is empty.  'y' and 'n'
are still accelerators (effectively hidden choices) for the i and o
entries, corresponding to the answers for the 3.4.3 and earlier "name
an individual object?" prompt.

The floor choice asks you to pick a location.  If you pick yourself,
then the top object of the pile underneath you is targetted.  Otherwise,
the target must be an object glyph, and the object must have its dknown
bit set, so have previously been seen up close or revealed via blessed
potion of object detection.  To make it be more useful, targetting an
object on an adjacent square will set the dknown bit.  (Just the top
object if there is a pile there.)  There's no cockatrice corpse touch
check since you aren't actually touching anything, just looking.

The setting of dknown bit for an adjacent object has been extended to
the '/' and ';' commands for examining things on the screen as well.
It's only done for adjacent spots you actively select, not all 8 spots
around you.

include/extern.h
src/do_name.c
src/pager.c

index bfa13669fa5770fe43ea47e793097f0185c8d6be..901326707c9b6fe1f207a874e5a526b6b496845d 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1432249760 2015/05/21 23:09:20 $  $NHDT-Branch: master $:$NHDT-Revision: 1.493 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1432890461 2015/05/29 09:07:41 $  $NHDT-Branch: master $:$NHDT-Revision: 1.498 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1646,6 +1646,7 @@ E void NDECL(msgtype_free);
 /* ### pager.c ### */
 
 E char *FDECL(self_lookat, (char *));
+E boolean FDECL(object_from_map, (int,int,int,struct obj **));
 E int NDECL(dowhatis);
 E int NDECL(doquickwhatis);
 E int NDECL(doidtrap);
index 44d03f71701b4fff9845f5609449d118c4582ff3..ced3c4b68eb11ffecb16913edb5f8111083af35a 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 do_name.c       $NHDT-Date: 1432512768 2015/05/25 00:12:48 $  $NHDT-Branch: master $:$NHDT-Revision: 1.72 $ */
+/* NetHack 3.6 do_name.c       $NHDT-Date: 1432890462 2015/05/29 09:07:42 $  $NHDT-Branch: master $:$NHDT-Revision: 1.73 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -8,6 +8,7 @@ STATIC_DCL char *NDECL(nextmbuf);
 STATIC_DCL void FDECL(getpos_help, (BOOLEAN_P, const char *));
 STATIC_DCL void NDECL(do_mname);
 STATIC_DCL void FDECL(do_oname, (struct obj *));
+STATIC_DCL void NDECL(namefloorobj);
 
 extern const char what_is_an_unknown_object[]; /* from pager.c */
 
@@ -587,9 +588,9 @@ boolean
 objtyp_is_callable(i)
 int i;
 {
-    return (boolean)(
-        objects[i].oc_uname
-        || (OBJ_DESCR(objects[i]) && index(callable, objects[i].oc_class)));
+    return (boolean) (objects[i].oc_uname
+                      || (OBJ_DESCR(objects[i])
+                          && index(callable, objects[i].oc_class)));
 }
 
 /* C and #name commands - player can name monster or object or type of obj */
@@ -601,34 +602,34 @@ docallcmd()
     anything any;
     menu_item *pick_list = 0;
     char ch, allowall[2];
+    /* if player wants a,b,c instead of i,o when looting, do that here too */
+    boolean abc = flags.lootabc;
 
     win = create_nhwindow(NHW_MENU);
     start_menu(win);
     any = zeroany;
-    any.a_char = 'm'; /* entry 'a', group accelator 'C' */
-    add_menu(win, NO_GLYPH, &any, 0, 'C', ATR_NONE, "a monster",
-             MENU_UNSELECTED);
+    any.a_char = 'm'; /* group accelerator 'C' */
+    add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'C', ATR_NONE,
+             "a monster", MENU_UNSELECTED);
     if (invent) {
         /* we use y and n as accelerators so that we can accept user's
            response keyed to old "name an individual object?" prompt */
-        any.a_char = 'i'; /* entry 'b', group accelator 'y' */
-        add_menu(win, NO_GLYPH, &any, 0, 'y', ATR_NONE,
+        any.a_char = 'i'; /* group accelerator 'y' */
+        add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'y', ATR_NONE,
                  "a particular object in inventory", MENU_UNSELECTED);
-        any.a_char = 'o'; /* entry 'c', group accelator 'n' */
-        add_menu(win, NO_GLYPH, &any, 0, 'n', ATR_NONE,
+        any.a_char = 'o'; /* group accelerator 'n' */
+        add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'n', ATR_NONE,
                  "the type of an object in inventory", MENU_UNSELECTED);
     }
-    any.a_char = 'd'; /* entry 'd' (or 'b'), group accelator 'd' */
-    add_menu(win, NO_GLYPH, &any, 0, any.a_char, ATR_NONE,
+    any.a_char = 'f'; /* group accelerator ',' (or ':' instead?) */
+    add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, ',', ATR_NONE,
+             "the type of an object upon the floor", MENU_UNSELECTED);
+    any.a_char = 'd'; /* group accelerator '\' */
+    add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, '\\', ATR_NONE,
              "the type of an object on discoveries list", MENU_UNSELECTED);
-    any.a_char = 'e';
-    add_menu(win, NO_GLYPH, &any, 0, any.a_char, ATR_NONE,
-             "the current level", MENU_UNSELECTED);
-#if 0
-       any.a_char = 'f';       /* entry 'e' (or 'c'), group accelator 'f' */
-       add_menu(win, NO_GLYPH, &any, 0, any.a_char, ATR_NONE,
-                "the type of an object upon the floor", MENU_UNSELECTED);
-#endif
+    any.a_char = 'a'; /* group accelerator 'l' */
+    add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'l', ATR_NONE,
+             "record an annotation for the current level", MENU_UNSELECTED);
     end_menu(win, "What do you want to name?");
     if (select_menu(win, PICK_ONE, &pick_list) > 0) {
         ch = pick_list[0].item.a_char;
@@ -662,25 +663,23 @@ docallcmd()
             if (!obj->dknown) {
                 You("would never recognize another one.");
 #if 0
-                       } else if (!objtyp_is_callable(obj->otyp)) {
-                           You("know those as well as you ever will.");
+            } else if (!objtyp_is_callable(obj->otyp)) {
+                You("know those as well as you ever will.");
 #endif
             } else {
                 docall(obj);
             }
         }
         break;
+    case 'f': /* name a type of object visible on the floor */
+        namefloorobj();
+        break;
     case 'd': /* name a type of object on the discoveries list */
         rename_disco();
         break;
-    case 'e': /* annotate level */
+    case 'a': /* annotate level */
         donamelevel();
         break;
-#if 0
-       case 'f':       /* name a type of object visible on the floor */
-               /* [not implemented] */
-               break;
-#endif
     }
     return 0;
 }
@@ -729,6 +728,57 @@ register struct obj *obj;
     }
 }
 
+STATIC_OVL void
+namefloorobj()
+{
+    coord cc;
+    int glyph;
+    char buf[BUFSZ];
+    struct obj *obj = 0;
+    boolean fakeobj = FALSE, use_plural;
+
+    cc.x = u.ux, cc.y = u.uy;
+    if (getpos(&cc, FALSE, "object on map (or '.' for one under you)") < 0
+        || cc.x <= 0)
+        return;
+    if (cc.x == u.ux && cc.y == u.uy) {
+        obj = vobj_at(u.ux, u.uy);
+    } else {
+        glyph = glyph_at(cc.x, cc.y);
+        if (glyph_is_object(glyph))
+            fakeobj = object_from_map(glyph, cc.x, cc.y, &obj);
+        /* else 'obj' stays null */
+    }
+    if (!obj) {
+        pline("There doesn't seem to be any object %s.",
+              (cc.x == u.ux && cc.y == u.uy) ? "under you" : "there");
+        return;
+    }
+    /* note well: 'obj' might be as instance of STRANGE_OBJECT if target
+       is a mimic; passing that to xname (directly or via simpleonames)
+       would yield "glorkum" so we need to handle it explicitly; it will
+       alwlays fail the Hallucination test and pass the !callable test,
+       resulting in the "can't be assigned a type name" message */
+    Strcpy(buf, (obj->otyp != STRANGE_OBJECT)
+                 ? simpleonames(obj)
+                 : obj_descr[STRANGE_OBJECT].oc_name);
+    use_plural = (obj->quan > 1L);
+    if (Hallucination) {
+        pline("%s %s to call you \"Wibbly Wobbly.\"",
+              The(buf), use_plural ? "decide" : "decides");
+    } else if (!objtyp_is_callable(obj->otyp)) {
+        pline("%s %s can't be assigned a type name.",
+              use_plural ? "Those" : "That", buf);
+    } else if (!obj->dknown) {
+        You("don't know %s %s well enough to name %s.",
+            use_plural ? "those" : "that", buf, use_plural ? "them" : "it");
+    } else {
+        docall(obj);
+    }
+    if (fakeobj)
+        dealloc_obj(obj);
+}
+
 static const char *const ghostnames[] = {
     /* these names should have length < PL_NSIZ */
     /* Capitalize the names for aesthetics -dgk */
index 5ab64103f64a79d0756dfd223920367553938ace..aa7e7ecbd27f1d2b479fe12fb88e6361f61c3f8f 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 pager.c $NHDT-Date: 1432685499 2015/05/27 00:11:39 $  $NHDT-Branch: master $:$NHDT-Revision: 1.73 $ */
+/* NetHack 3.6 pager.c $NHDT-Date: 1432890463 2015/05/29 09:07:43 $  $NHDT-Branch: master $:$NHDT-Revision: 1.74 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -71,6 +71,47 @@ char *outbuf;
     return outbuf;
 }
 
+/* extracted from lookat(); also used by namefloorobj() */
+boolean
+object_from_map(glyph, x, y, obj_p)
+int glyph, x, y;
+struct obj **obj_p;
+{
+    boolean fakeobj = FALSE;
+    struct monst *mtmp;
+    struct obj *otmp = vobj_at(x, y);
+    int glyphotyp = glyph_to_obj(glyph);
+
+    *obj_p = (struct obj *) 0;
+    /* there might be a mimic here posing as an object */
+    mtmp = m_at(x, y);
+    if (mtmp && mtmp->m_ap_type == M_AP_OBJECT
+        && mtmp->mappearance == (unsigned) glyphotyp)
+        otmp = 0;
+    else
+        mtmp = 0;
+
+    if (!otmp || otmp->otyp != glyphotyp) {
+        /* this used to exclude STRANGE_OBJECT; now caller deals with it */
+        otmp = mksobj(glyphotyp, FALSE, FALSE);
+        if (!otmp)
+            return FALSE;
+        fakeobj = TRUE;
+        if (otmp->oclass == COIN_CLASS)
+            otmp->quan = 2L; /* to force pluralization */
+        else if (otmp->otyp == SLIME_MOLD)
+            otmp->spe = context.current_fruit; /* give it a type */
+        if (mtmp && has_mcorpsenm(mtmp)) /* mimic as corpse/statue */
+            otmp->corpsenm = MCORPSENM(mtmp);
+    }
+    /* if located at adajcent spot, mark it as having been seen up close */
+    if (otmp && distu(x, y) <= 2 && !Blind && !Hallucination)
+        otmp->dknown = 1;
+
+    *obj_p = otmp;
+    return fakeobj; /* when True, caller needs to dealloc *obj_p */
+}
+
 /*
  * Return the name of the glyph found at (x,y).
  * If not hallucinating and the glyph is a monster, also monster data.
@@ -226,32 +267,16 @@ char *buf, *monbuf;
         }     /* mtmp */
 
     } else if (glyph_is_object(glyph)) {
-        int glyphotyp = glyph_to_obj(glyph);
-        struct obj *otmp = vobj_at(x, y);
-
-        /* there might be a mimic here posing as an object */
-        mtmp = m_at(x, y);
-        if (mtmp && mtmp->m_ap_type == M_AP_OBJECT
-            && mtmp->mappearance == (unsigned) glyphotyp)
-            otmp = 0;
-        else
-            mtmp = 0;
-
-        if (!otmp || otmp->otyp != glyphotyp) {
-            if (glyphotyp != STRANGE_OBJECT) {
-                otmp = mksobj(glyphotyp, FALSE, FALSE);
-                if (otmp->oclass == COIN_CLASS)
-                    otmp->quan = 2L; /* to force pluralization */
-                else if (otmp->otyp == SLIME_MOLD)
-                    otmp->spe = context.current_fruit; /* give it a type */
-                if (mtmp && has_mcorpsenm(mtmp)) /* mimic as corpse/statue */
-                    otmp->corpsenm = MCORPSENM(mtmp);
-                Strcpy(buf, distant_name(otmp, xname));
-                dealloc_obj(otmp);
-            } else
-                Strcpy(buf, obj_descr[STRANGE_OBJECT].oc_name);
-        } else
-            Strcpy(buf, distant_name(otmp, xname));
+        struct obj *otmp = 0;
+        boolean fakeobj = object_from_map(glyph, x, y, &otmp);
+
+        if (otmp) {
+            Strcpy(buf, (otmp->otyp != STRANGE_OBJECT)
+                         ? distant_name(otmp, xname)
+                         : obj_descr[STRANGE_OBJECT].oc_name);
+            if (fakeobj)
+                dealloc_obj(otmp), otmp = 0;
+        }
 
         if (levl[x][y].typ == STONE || levl[x][y].typ == SCORR)
             Strcat(buf, " embedded in stone");