item-action name/call

Add opportunity to name an individual object or call the type of an
object to the context-sensitive inventory item-actions.
This commit is contained in:
PatR
2022-04-19 04:33:01 -07:00
parent 6880d37b33
commit 9f0e511b00
3 changed files with 62 additions and 7 deletions

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

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

View 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