]> granicus.if.org Git - nethack/commitdiff
context-sensitive dipping
authorPatR <rankin@nethack.org>
Tue, 12 Apr 2022 09:20:40 +0000 (02:20 -0700)
committerPatR <rankin@nethack.org>
Tue, 12 Apr 2022 09:20:40 +0000 (02:20 -0700)
Normally dipping gets the thing to dip first and what to dip it
into second and the item-action handling knows that.  I'm not sure
why that wasn't working as intended and I couldn't figure out how
to make it do that, so went another way:  this adds an internal
extended command that executes an alternate dip routine which gets
the potion to dip into first and the thing to dip into it second.

The #dip command should allow an 'm' prefix to skip fountains and
pools, similar to how eating accepts it to skip food on the floor.
But this doesn't implement that.

include/extern.h
src/cmd.c
src/invent.c
src/potion.c

index 03495599a42e61dc51d84e5192c8653398ea525a..2bd636c2cca518f774f76e2110ceb3c3feae3e3f 100644 (file)
@@ -2131,6 +2131,7 @@ extern void impact_arti_light(struct obj *, boolean, boolean);
 extern void potionhit(struct monst *, struct obj *, int);
 extern void potionbreathe(struct obj *);
 extern int dodip(void);
+extern int dip_into(void); /* altdip */
 extern void mongrantswish(struct monst **);
 extern void djinni_from_bottle(struct obj *);
 extern struct monst *split_mon(struct monst *, struct monst *);
index d0ce9c5010171cac44dcee2195c36cc779b86f13..17a5547923300ff8ae0ce598de249e56da7c0271 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -2554,7 +2554,8 @@ struct ext_func_tab extcmdlist[] = {
             do_run_southwest, MOVEMENTCMD | CMD_M_PREFIX, NULL },
 
     /* internal commands: only used by game core, not available for user */
-    { '\0',   "clicklook", NULL, doclicklook, INTERNALCMD, NULL },
+    { '\0', "clicklook", NULL, doclicklook, INTERNALCMD, NULL },
+    { '\0', "altdip", NULL, dip_into, INTERNALCMD, NULL },
     { '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
 };
 
index 15f2bc874e9933fd632226f0816a515a22320378..6ca7e53939601f1ea7a45830d095fb873bdf44c4 100644 (file)
@@ -2612,9 +2612,12 @@ itemactions(struct obj *otmp)
     } else if (otmp->otyp == POT_OIL && objects[otmp->otyp].oc_name_known) {
         Sprintf(buf, "%s this oil", light);
         ia_addmenu(win, IA_APPLY_OBJ, 'a', buf);
-    } else if (otmp->oclass == POTION_CLASS)
-        ia_addmenu(win, IA_DIP_OBJ, 'a', "Dip something into this potion");
-    else if (otmp->otyp == EXPENSIVE_CAMERA)
+    } else if (otmp->oclass == POTION_CLASS) {
+        /* FIXME? this should probably be moved to 'D' rather than be 'a' */
+        Sprintf(buf, "Dip something into %s potion%s",
+                is_plural(otmp) ? "one of these" : "this", plur(otmp->quan));
+        ia_addmenu(win, IA_DIP_OBJ, 'a', buf);
+    } else if (otmp->otyp == EXPENSIVE_CAMERA)
         ia_addmenu(win, IA_APPLY_OBJ, 'a', "Take a photograph");
     else if (otmp->otyp == TOWEL)
         ia_addmenu(win, IA_APPLY_OBJ, 'a',
@@ -2825,8 +2828,9 @@ itemactions(struct obj *otmp)
             cmdq_add_key(otmp->invlet);
             break;
         case IA_DIP_OBJ:
-            cmdq_add_ec(dodip);
-            cmdq_add_userinput();
+            /*cmdq_add_ec(dodip);*/
+            /*cmdq_add_userinput();*/
+            cmdq_add_ec(dip_into);
             cmdq_add_key(otmp->invlet);
             break;
         case IA_DROP_OBJ:
index 32343989d9849941ebfe746a1d2a3dd7c55aedae..90ecd626331387591a4b95438406a33cd56216d8 100644 (file)
@@ -40,6 +40,7 @@ static short mixtype(struct obj *, struct obj *);
 static int dip_ok(struct obj *);
 static void hold_potion(struct obj *, const char *, const char *,
                         const char *);
+static int potion_dip(struct obj *obj, struct obj *potion);
 
 /* force `val' to be within valid range for intrinsic timeout value */
 static long
@@ -1037,13 +1038,13 @@ peffect_gain_level(struct obj *otmp)
         /* they went up a level */
         if ((ledger_no(&u.uz) == 1 && u.uhave.amulet)
             || Can_rise_up(u.ux, u.uy, &u.uz)) {
-            const char *riseup = "rise up, through the %s!";
+            static const char *riseup = "rise up, through the %s!";
 
             if (ledger_no(&u.uz) == 1) {
                 You(riseup, ceiling(u.ux, u.uy));
                 goto_level(&earth_level, FALSE, FALSE, FALSE);
             } else {
-                register int newlev = depth(&u.uz) - 1;
+                int newlev = depth(&u.uz) - 1;
                 d_level newlevel;
 
                 get_level(&newlevel, newlev);
@@ -2170,15 +2171,13 @@ hold_potion(struct obj *potobj, const char *drop_fmt, const char *drop_arg,
     return;
 }
 
-/* #dip command */
+/* #dip command - get item to dip, then get potion to dip it into */
 int
 dodip(void)
 {
     static const char Dip_[] = "Dip ";
-    register struct obj *potion, *obj;
-    struct obj *singlepotion;
+    struct obj *potion, *obj;
     uchar here;
-    short mixture;
     char qbuf[QBUFSZ], obuf[QBUFSZ];
     const char *shortestname; /* last resort obj name for prompt */
 
@@ -2237,11 +2236,47 @@ dodip(void)
     }
 
     /* "What do you want to dip <the object> into? [xyz or ?*] " */
-    Snprintf(qbuf, sizeof(qbuf), "dip %s into",
+    Snprintf(qbuf, sizeof qbuf, "dip %s into",
              flags.verbose ? obuf : shortestname);
     potion = getobj(qbuf, drink_ok, GETOBJ_NOFLAGS);
     if (!potion)
         return ECMD_CANCEL;
+    return potion_dip(obj, potion);
+}
+
+/* #altdip - for context-sensitive inventory item-action;
+   potion already selected */
+int
+dip_into(void)
+{
+    struct obj *obj, *potion;
+    char qbuf[QBUFSZ];
+
+    if (!cmdq_peek())
+        panic("dip_into: where is potion?");
+    potion = getobj("dip", drink_ok, GETOBJ_NOFLAGS);
+    if (!potion || potion->oclass != POTION_CLASS)
+        return ECMD_CANCEL;
+
+    /* "What do you want to dip into <the potion>? [abc or ?*] " */
+    Snprintf(qbuf, sizeof qbuf, "dip into %s%s",
+             is_plural(potion) ? "one of " : "", thesimpleoname(potion));
+    obj = getobj(qbuf, dip_ok, GETOBJ_PROMPT);
+    if (!obj)
+        return ECMD_CANCEL;
+    if (inaccessible_equipment(obj, "dip", FALSE))
+        return ECMD_OK;
+    return potion_dip(obj, potion);
+}
+
+/* called by dodip() or dip_into() after obj and potion have been chosen */
+static int
+potion_dip(struct obj *obj, struct obj *potion)
+{
+    struct obj *singlepotion;
+    char qbuf[QBUFSZ];
+    short mixture;
+
     if (potion == obj && potion->quan == 1L) {
         pline("That is a potion bottle, not a Klein bottle!");
         return ECMD_OK;