From: PatR Date: Tue, 12 Apr 2022 09:20:40 +0000 (-0700) Subject: context-sensitive dipping X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=11543620f909caf96b0c4935422a54f46237db9d;p=nethack context-sensitive dipping 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. --- diff --git a/include/extern.h b/include/extern.h index 03495599a..2bd636c2c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 *); diff --git a/src/cmd.c b/src/cmd.c index d0ce9c501..17a554792 100644 --- 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 */ }; diff --git a/src/invent.c b/src/invent.c index 15f2bc874..6ca7e5393 100644 --- a/src/invent.c +++ b/src/invent.c @@ -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: diff --git a/src/potion.c b/src/potion.c index 32343989d..90ecd6263 100644 --- a/src/potion.c +++ b/src/potion.c @@ -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 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 ? [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;