]> granicus.if.org Git - nethack/commitdiff
item-action name/call
authorPatR <rankin@nethack.org>
Tue, 19 Apr 2022 11:33:01 +0000 (04:33 -0700)
committerPatR <rankin@nethack.org>
Tue, 19 Apr 2022 11:33:01 +0000 (04:33 -0700)
Add opportunity to name an individual object or call the type of an
object to the context-sensitive inventory item-actions.

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

index e6786e8ea0135e64fac1b101d096c82c00c9a17a..d6a4ca252429266bf6e76ff8c53a85a052ec2e0a 100644 (file)
@@ -484,6 +484,8 @@ extern const char *safe_oname(struct obj *);
 extern struct monst *christen_monst(struct monst *, const char *);
 extern struct obj *oname(struct obj *, const char *, unsigned);
 extern boolean objtyp_is_callable(int);
+extern int name_ok(struct obj *);
+extern int call_ok(struct obj *);
 extern int docallcmd(void);
 extern void docall(struct obj *);
 extern const char *rndghostname(void);
index ed88d2daba19671e00842a12ac7b82e7273f61a7..66f124ae30dc5a9b10f85c4dd0231de4cec147d4 100644 (file)
@@ -21,8 +21,6 @@ static void truncate_to_map(int *, int *, schar, schar);
 static void do_mgivenname(void);
 static boolean alreadynamed(struct monst *, char *, char *);
 static void do_oname(struct obj *);
-static int name_ok(struct obj *);
-static int call_ok(struct obj *);
 static char *docall_xname(struct obj *);
 static void namefloorobj(void);
 
@@ -1231,7 +1229,7 @@ do_mgivenname(void)
  * allocates a replacement object, so that old risk is gone.
  */
 static void
-do_oname(register struct obj *obj)
+do_oname(struct obj *obj)
 {
     char *bufp, buf[BUFSZ], bufcpy[BUFSZ], qbuf[QBUFSZ];
     const char *aname;
@@ -1387,17 +1385,20 @@ objtyp_is_callable(int i)
 }
 
 /* getobj callback for object to name (specific item) - anything but gold */
-static int
+int
 name_ok(struct obj *obj)
 {
     if (!obj || obj->oclass == COIN_CLASS)
         return GETOBJ_EXCLUDE;
 
+    if (!obj->dknown || obj->oartifact || obj->otyp == SPE_NOVEL)
+        return GETOBJ_DOWNPLAY;
+
     return GETOBJ_SUGGEST;
 }
 
 /* getobj callback for object to call (name its type) */
-static int
+int
 call_ok(struct obj *obj)
 {
     if (!obj || !objtyp_is_callable(obj->otyp))
@@ -1414,10 +1415,18 @@ docallcmd(void)
     winid win;
     anything any;
     menu_item *pick_list = 0;
-    char ch;
+    struct _cmd_queue *cmdq;
+    char ch = 0;
     /* if player wants a,b,c instead of i,o when looting, do that here too */
     boolean abc = flags.lootabc;
 
+    if ((cmdq = cmdq_pop()) != 0) {
+        if (cmdq->typ == CMDQ_KEY)
+            ch = cmdq->key;
+        else
+            cmdq_clear();
+        goto docallcmd;
+    }
     win = create_nhwindow(NHW_MENU);
     start_menu(win, MENU_BEHAVE_STANDARD);
     any = cg.zeroany;
@@ -1456,6 +1465,7 @@ docallcmd(void)
         ch = 'q';
     destroy_nhwindow(win);
 
+ docallcmd:
     switch (ch) {
     default:
     case 'q':
index e108328fb184429522d904a24a3f512adb5a67ec..e6c2af2cfca4db8114cfe76ae1c5dbd85ac36999 100644 (file)
@@ -35,6 +35,7 @@ static boolean tool_being_used(struct obj *);
 static int adjust_ok(struct obj *);
 static int adjust_gold_ok(struct obj *);
 static char obj_to_let(struct obj *);
+static boolean item_naming_classification(struct obj *, char *, char *);
 static void mime_action(const char *);
 
 /* wizards can wish for venom, which will become an invisible inventory
@@ -2510,6 +2511,8 @@ enum item_action_actions {
     IA_NONE          = 0,
     IA_UNWIELD, /* hack for 'w-' */
     IA_APPLY_OBJ,
+    IA_NAME_OBJ, /* 'c' name individual item */
+    IA_NAME_OTYP, /* 'C' name item's type */
     IA_DIP_OBJ,
     IA_DROP_OBJ,
     IA_EAT_OBJ,
@@ -2530,6 +2533,32 @@ enum item_action_actions {
     IA_SACRIFICE,
 };
 
+/* construct text for the menu entries for IA_NAME_OBJ and IA_NAME_OTYP */
+static boolean
+item_naming_classification(struct obj *obj, char *onamebuf, char *ocallbuf)
+{
+    static const char Name[] = "Name", Rename[] = "Rename or unname";
+
+    onamebuf[0] = ocallbuf[0] = '\0';
+    if (name_ok(obj) == GETOBJ_SUGGEST) {
+        Sprintf(onamebuf, "%s %s %s",
+                (!has_oname(obj) || !*ONAME(obj)) ? Name : Rename,
+                !is_plural(obj) ? "this" : "these",
+                simpleonames(obj));
+    }
+    if (call_ok(obj) == GETOBJ_SUGGEST) {
+        char *callname = simpleonames(obj);
+
+        if (!is_plural(obj)) /* when not already plural, force plural */
+            callname = makeplural(callname);
+        Sprintf(ocallbuf, "%s the type for %s",
+                (!objects[obj->otyp].oc_uname
+                 || !*objects[obj->otyp].oc_uname) ? Name : Rename,
+                callname);
+    }
+    return (*onamebuf || *ocallbuf) ? TRUE : FALSE;
+}
+
 static void
 ia_addmenu(winid win, int act, char let, const char *txt)
 {
@@ -2547,7 +2576,7 @@ itemactions(struct obj *otmp)
 {
     int n, act = IA_NONE;
     winid win;
-    char buf[BUFSZ];
+    char buf[BUFSZ], buf2[BUFSZ];
     menu_item *selected;
     struct monst *mtmp;
     const char *light = otmp->lamplit ? "Extinguish" : "Light";
@@ -2648,6 +2677,14 @@ itemactions(struct obj *otmp)
     else if (otmp->oclass == WAND_CLASS)
         ia_addmenu(win, IA_APPLY_OBJ, 'a', "Break this wand");
 
+    /* 'c', 'C' - call an item or its type something */
+    if (item_naming_classification(otmp, buf, buf2)) {
+        if (*buf)
+            ia_addmenu(win, IA_NAME_OBJ, 'c', buf);
+        if (*buf2)
+            ia_addmenu(win, IA_NAME_OTYP, 'C', buf2);
+    }
+
     /* d: drop item, works on everything except worn items; those will
        always have a takeoff/remove choice so we don't have to worry
        about the menu maybe being empty when 'd' is suppressed */
@@ -2833,6 +2870,12 @@ itemactions(struct obj *otmp)
             cmdq_add_ec(doapply);
             cmdq_add_key(otmp->invlet);
             break;
+        case IA_NAME_OBJ:
+        case IA_NAME_OTYP:
+            cmdq_add_ec(docallcmd);
+            cmdq_add_key((act == IA_NAME_OBJ) ? 'i' : 'o');
+            cmdq_add_key(otmp->invlet);
+            break;
         case IA_DIP_OBJ:
             /* #altdip instead of normal #dip - takes potion to dip into
                first (the inventory item instigating this) and item to