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.
This commit is contained in:
PatR
2022-04-12 02:20:40 -07:00
parent 699a25c00b
commit 11543620f9
4 changed files with 54 additions and 13 deletions

View 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 *);

View File

@@ -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 */
};

View 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:

View 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;